forked from Minki/linux
ACPICA: Major update for acpi_get_object_info external interface
Completed a major update for the acpi_get_object_info external interface. Changes include: - Support for variable, unlimited length HID, UID, and CID strings - Support Processor objects the same as Devices (HID,UID,CID,ADR,STA, etc.) - Call the _SxW power methods on behalf of a device object - Determine if a device is a PCI root bridge - Change the ACPI_BUFFER parameter to ACPI_DEVICE_INFO. These changes will require an update to all callers of this interface. See the ACPICA Programmer Reference for details. Also, update all invocations of acpi_get_object_info interface Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
parent
9c61b34cf7
commit
15b8dd53f5
@ -2026,24 +2026,21 @@ acpi_sba_ioc_add(struct acpi_device *device)
|
|||||||
struct ioc *ioc;
|
struct ioc *ioc;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
u64 hpa, length;
|
u64 hpa, length;
|
||||||
struct acpi_buffer buffer;
|
|
||||||
struct acpi_device_info *dev_info;
|
struct acpi_device_info *dev_info;
|
||||||
|
|
||||||
status = hp_acpi_csr_space(device->handle, &hpa, &length);
|
status = hp_acpi_csr_space(device->handle, &hpa, &length);
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
|
status = acpi_get_object_info(device->handle, &dev_info);
|
||||||
status = acpi_get_object_info(device->handle, &buffer);
|
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
return 1;
|
return 1;
|
||||||
dev_info = buffer.pointer;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For HWP0001, only SBA appears in ACPI namespace. It encloses the PCI
|
* For HWP0001, only SBA appears in ACPI namespace. It encloses the PCI
|
||||||
* root bridges, and its CSR space includes the IOC function.
|
* root bridges, and its CSR space includes the IOC function.
|
||||||
*/
|
*/
|
||||||
if (strncmp("HWP0001", dev_info->hardware_id.value, 7) == 0) {
|
if (strncmp("HWP0001", dev_info->hardware_id.string, 7) == 0) {
|
||||||
hpa += ZX1_IOC_OFFSET;
|
hpa += ZX1_IOC_OFFSET;
|
||||||
/* zx1 based systems default to kernel page size iommu pages */
|
/* zx1 based systems default to kernel page size iommu pages */
|
||||||
if (!iovp_shift)
|
if (!iovp_shift)
|
||||||
|
@ -481,26 +481,23 @@ static acpi_status is_memory_device(acpi_handle handle)
|
|||||||
{
|
{
|
||||||
char *hardware_id;
|
char *hardware_id;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
|
||||||
struct acpi_device_info *info;
|
struct acpi_device_info *info;
|
||||||
|
|
||||||
|
status = acpi_get_object_info(handle, &info);
|
||||||
status = acpi_get_object_info(handle, &buffer);
|
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
info = buffer.pointer;
|
|
||||||
if (!(info->valid & ACPI_VALID_HID)) {
|
if (!(info->valid & ACPI_VALID_HID)) {
|
||||||
kfree(buffer.pointer);
|
kfree(info);
|
||||||
return AE_ERROR;
|
return AE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
hardware_id = info->hardware_id.value;
|
hardware_id = info->hardware_id.string;
|
||||||
if ((hardware_id == NULL) ||
|
if ((hardware_id == NULL) ||
|
||||||
(strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID)))
|
(strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID)))
|
||||||
status = AE_ERROR;
|
status = AE_ERROR;
|
||||||
|
|
||||||
kfree(buffer.pointer);
|
kfree(info);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,4 +44,4 @@ acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o
|
|||||||
|
|
||||||
acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
|
acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
|
||||||
utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
|
utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
|
||||||
utstate.o utmutex.o utobject.o utresrc.o utlock.o
|
utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o
|
||||||
|
@ -203,6 +203,11 @@
|
|||||||
|
|
||||||
#define ACPI_SMBUS_BUFFER_SIZE 34
|
#define ACPI_SMBUS_BUFFER_SIZE 34
|
||||||
|
|
||||||
|
/* _sx_d and _sx_w control methods */
|
||||||
|
|
||||||
|
#define ACPI_NUM_sx_d_METHODS 4
|
||||||
|
#define ACPI_NUM_sx_w_METHODS 5
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* ACPI AML Debugger
|
* ACPI AML Debugger
|
||||||
|
@ -265,7 +265,8 @@ ACPI_EXTERN u8 acpi_gbl_osi_data;
|
|||||||
extern u8 acpi_gbl_shutdown;
|
extern u8 acpi_gbl_shutdown;
|
||||||
extern u32 acpi_gbl_startup_flags;
|
extern u32 acpi_gbl_startup_flags;
|
||||||
extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT];
|
extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT];
|
||||||
extern const char *acpi_gbl_highest_dstate_names[4];
|
extern const char *acpi_gbl_lowest_dstate_names[ACPI_NUM_sx_w_METHODS];
|
||||||
|
extern const char *acpi_gbl_highest_dstate_names[ACPI_NUM_sx_d_METHODS];
|
||||||
extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES];
|
extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES];
|
||||||
extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS];
|
extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS];
|
||||||
|
|
||||||
|
@ -461,9 +461,9 @@ void acpi_ex_acquire_global_lock(u32 rule);
|
|||||||
|
|
||||||
void acpi_ex_release_global_lock(u32 rule);
|
void acpi_ex_release_global_lock(u32 rule);
|
||||||
|
|
||||||
void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string);
|
void acpi_ex_eisa_id_to_string(char *dest, acpi_integer compressed_id);
|
||||||
|
|
||||||
void acpi_ex_unsigned_integer_to_string(acpi_integer value, char *out_string);
|
void acpi_ex_integer_to_string(char *dest, acpi_integer value);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* exregion - default op_region handlers
|
* exregion - default op_region handlers
|
||||||
|
@ -324,26 +324,30 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
|
|||||||
acpi_status
|
acpi_status
|
||||||
acpi_ut_evaluate_numeric_object(char *object_name,
|
acpi_ut_evaluate_numeric_object(char *object_name,
|
||||||
struct acpi_namespace_node *device_node,
|
struct acpi_namespace_node *device_node,
|
||||||
acpi_integer * address);
|
acpi_integer *value);
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
|
acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 *status_flags);
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node,
|
||||||
|
const char **method_names,
|
||||||
|
u8 method_count, u8 *out_values);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* utids - device ID support
|
||||||
|
*/
|
||||||
|
acpi_status
|
||||||
acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
|
acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
|
||||||
struct acpica_device_id *hid);
|
struct acpica_device_id **return_id);
|
||||||
|
|
||||||
acpi_status
|
|
||||||
acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
|
|
||||||
struct acpi_compatible_id_list **return_cid_list);
|
|
||||||
|
|
||||||
acpi_status
|
|
||||||
acpi_ut_execute_STA(struct acpi_namespace_node *device_node,
|
|
||||||
u32 * status_flags);
|
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
|
acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
|
||||||
struct acpica_device_id *uid);
|
struct acpica_device_id **return_id);
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest);
|
acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
|
||||||
|
struct acpica_device_id_list **return_cid_list);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* utlock - reader/writer locks
|
* utlock - reader/writer locks
|
||||||
@ -445,6 +449,8 @@ acpi_ut_short_divide(acpi_integer in_dividend,
|
|||||||
*/
|
*/
|
||||||
const char *acpi_ut_validate_exception(acpi_status status);
|
const char *acpi_ut_validate_exception(acpi_status status);
|
||||||
|
|
||||||
|
u8 acpi_ut_is_pci_root_bridge(char *id);
|
||||||
|
|
||||||
u8 acpi_ut_is_aml_table(struct acpi_table_header *table);
|
u8 acpi_ut_is_aml_table(struct acpi_table_header *table);
|
||||||
|
|
||||||
acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id);
|
acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id);
|
||||||
|
@ -50,8 +50,6 @@
|
|||||||
ACPI_MODULE_NAME("evrgnini")
|
ACPI_MODULE_NAME("evrgnini")
|
||||||
|
|
||||||
/* Local prototypes */
|
/* Local prototypes */
|
||||||
static u8 acpi_ev_match_pci_root_bridge(char *id);
|
|
||||||
|
|
||||||
static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node);
|
static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node);
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -330,37 +328,6 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
|
|||||||
return_ACPI_STATUS(AE_OK);
|
return_ACPI_STATUS(AE_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ev_match_pci_root_bridge
|
|
||||||
*
|
|
||||||
* PARAMETERS: Id - The HID/CID in string format
|
|
||||||
*
|
|
||||||
* RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static u8 acpi_ev_match_pci_root_bridge(char *id)
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if this is a PCI root.
|
|
||||||
* ACPI 3.0+: check for a PCI Express root also.
|
|
||||||
*/
|
|
||||||
if (!(ACPI_STRNCMP(id,
|
|
||||||
PCI_ROOT_HID_STRING,
|
|
||||||
sizeof(PCI_ROOT_HID_STRING))) ||
|
|
||||||
!(ACPI_STRNCMP(id,
|
|
||||||
PCI_EXPRESS_ROOT_HID_STRING,
|
|
||||||
sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) {
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ev_is_pci_root_bridge
|
* FUNCTION: acpi_ev_is_pci_root_bridge
|
||||||
@ -377,9 +344,10 @@ static u8 acpi_ev_match_pci_root_bridge(char *id)
|
|||||||
static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
|
static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
|
||||||
{
|
{
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
struct acpica_device_id hid;
|
struct acpica_device_id *hid;
|
||||||
struct acpi_compatible_id_list *cid;
|
struct acpica_device_id_list *cid;
|
||||||
u32 i;
|
u32 i;
|
||||||
|
u8 match;
|
||||||
|
|
||||||
/* Get the _HID and check for a PCI Root Bridge */
|
/* Get the _HID and check for a PCI Root Bridge */
|
||||||
|
|
||||||
@ -388,7 +356,10 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
|
|||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (acpi_ev_match_pci_root_bridge(hid.value)) {
|
match = acpi_ut_is_pci_root_bridge(hid->string);
|
||||||
|
ACPI_FREE(hid);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,7 +373,7 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
|
|||||||
/* Check all _CIDs in the returned list */
|
/* Check all _CIDs in the returned list */
|
||||||
|
|
||||||
for (i = 0; i < cid->count; i++) {
|
for (i = 0; i < cid->count; i++) {
|
||||||
if (acpi_ev_match_pci_root_bridge(cid->id[i].value)) {
|
if (acpi_ut_is_pci_root_bridge(cid->ids[i].string)) {
|
||||||
ACPI_FREE(cid);
|
ACPI_FREE(cid);
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
@ -358,50 +358,67 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base)
|
|||||||
*
|
*
|
||||||
* FUNCTION: acpi_ex_eisa_id_to_string
|
* FUNCTION: acpi_ex_eisa_id_to_string
|
||||||
*
|
*
|
||||||
* PARAMETERS: numeric_id - EISA ID to be converted
|
* PARAMETERS: compressed_id - EISAID to be converted
|
||||||
* out_string - Where to put the converted string (8 bytes)
|
* out_string - Where to put the converted string (8 bytes)
|
||||||
*
|
*
|
||||||
* RETURN: None
|
* RETURN: None
|
||||||
*
|
*
|
||||||
* DESCRIPTION: Convert a numeric EISA ID to string representation
|
* DESCRIPTION: Convert a numeric EISAID to string representation. Return
|
||||||
|
* buffer must be large enough to hold the string. The string
|
||||||
|
* returned is always exactly of length ACPI_EISAID_STRING_SIZE
|
||||||
|
* (includes null terminator). The EISAID is always 32 bits.
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string)
|
void acpi_ex_eisa_id_to_string(char *out_string, acpi_integer compressed_id)
|
||||||
{
|
{
|
||||||
u32 eisa_id;
|
u32 swapped_id;
|
||||||
|
|
||||||
ACPI_FUNCTION_ENTRY();
|
ACPI_FUNCTION_ENTRY();
|
||||||
|
|
||||||
|
/* The EISAID should be a 32-bit integer */
|
||||||
|
|
||||||
|
if (compressed_id > ACPI_UINT32_MAX) {
|
||||||
|
ACPI_WARNING((AE_INFO,
|
||||||
|
"Expected EISAID is larger than 32 bits: 0x%8.8X%8.8X, truncating",
|
||||||
|
ACPI_FORMAT_UINT64(compressed_id)));
|
||||||
|
}
|
||||||
|
|
||||||
/* Swap ID to big-endian to get contiguous bits */
|
/* Swap ID to big-endian to get contiguous bits */
|
||||||
|
|
||||||
eisa_id = acpi_ut_dword_byte_swap(numeric_id);
|
swapped_id = acpi_ut_dword_byte_swap((u32)compressed_id);
|
||||||
|
|
||||||
out_string[0] = (char)('@' + (((unsigned long)eisa_id >> 26) & 0x1f));
|
/* First 3 bytes are uppercase letters. Next 4 bytes are hexadecimal */
|
||||||
out_string[1] = (char)('@' + ((eisa_id >> 21) & 0x1f));
|
|
||||||
out_string[2] = (char)('@' + ((eisa_id >> 16) & 0x1f));
|
out_string[0] =
|
||||||
out_string[3] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 12);
|
(char)(0x40 + (((unsigned long)swapped_id >> 26) & 0x1F));
|
||||||
out_string[4] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 8);
|
out_string[1] = (char)(0x40 + ((swapped_id >> 21) & 0x1F));
|
||||||
out_string[5] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 4);
|
out_string[2] = (char)(0x40 + ((swapped_id >> 16) & 0x1F));
|
||||||
out_string[6] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 0);
|
out_string[3] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 12);
|
||||||
|
out_string[4] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 8);
|
||||||
|
out_string[5] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 4);
|
||||||
|
out_string[6] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 0);
|
||||||
out_string[7] = 0;
|
out_string[7] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ex_unsigned_integer_to_string
|
* FUNCTION: acpi_ex_integer_to_string
|
||||||
*
|
*
|
||||||
* PARAMETERS: Value - Value to be converted
|
* PARAMETERS: out_string - Where to put the converted string. At least
|
||||||
* out_string - Where to put the converted string (8 bytes)
|
* 21 bytes are needed to hold the largest
|
||||||
|
* possible 64-bit integer.
|
||||||
|
* Value - Value to be converted
|
||||||
*
|
*
|
||||||
* RETURN: None, string
|
* RETURN: None, string
|
||||||
*
|
*
|
||||||
* DESCRIPTION: Convert a number to string representation. Assumes string
|
* DESCRIPTION: Convert a 64-bit integer to decimal string representation.
|
||||||
* buffer is large enough to hold the string.
|
* Assumes string buffer is large enough to hold the string. The
|
||||||
|
* largest string is (ACPI_MAX64_DECIMAL_DIGITS + 1).
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
void acpi_ex_unsigned_integer_to_string(acpi_integer value, char *out_string)
|
void acpi_ex_integer_to_string(char *out_string, acpi_integer value)
|
||||||
{
|
{
|
||||||
u32 count;
|
u32 count;
|
||||||
u32 digits_needed;
|
u32 digits_needed;
|
||||||
|
@ -70,7 +70,6 @@ static acpi_status
|
|||||||
acpi_ns_dump_one_device(acpi_handle obj_handle,
|
acpi_ns_dump_one_device(acpi_handle obj_handle,
|
||||||
u32 level, void *context, void **return_value)
|
u32 level, void *context, void **return_value)
|
||||||
{
|
{
|
||||||
struct acpi_buffer buffer;
|
|
||||||
struct acpi_device_info *info;
|
struct acpi_device_info *info;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
u32 i;
|
u32 i;
|
||||||
@ -80,17 +79,15 @@ acpi_ns_dump_one_device(acpi_handle obj_handle,
|
|||||||
status =
|
status =
|
||||||
acpi_ns_dump_one_object(obj_handle, level, context, return_value);
|
acpi_ns_dump_one_object(obj_handle, level, context, return_value);
|
||||||
|
|
||||||
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
|
status = acpi_get_object_info(obj_handle, &info);
|
||||||
status = acpi_get_object_info(obj_handle, &buffer);
|
|
||||||
if (ACPI_SUCCESS(status)) {
|
if (ACPI_SUCCESS(status)) {
|
||||||
info = buffer.pointer;
|
|
||||||
for (i = 0; i < level; i++) {
|
for (i = 0; i < level; i++) {
|
||||||
ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, " "));
|
ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, " "));
|
||||||
}
|
}
|
||||||
|
|
||||||
ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES,
|
ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES,
|
||||||
" HID: %s, ADR: %8.8X%8.8X, Status: %X\n",
|
" HID: %s, ADR: %8.8X%8.8X, Status: %X\n",
|
||||||
info->hardware_id.value,
|
info->hardware_id.string,
|
||||||
ACPI_FORMAT_UINT64(info->address),
|
ACPI_FORMAT_UINT64(info->address),
|
||||||
info->current_status));
|
info->current_status));
|
||||||
ACPI_FREE(info);
|
ACPI_FREE(info);
|
||||||
|
@ -535,10 +535,11 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
|
|||||||
acpi_status status;
|
acpi_status status;
|
||||||
struct acpi_namespace_node *node;
|
struct acpi_namespace_node *node;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
struct acpica_device_id hid;
|
struct acpica_device_id *hid;
|
||||||
struct acpi_compatible_id_list *cid;
|
struct acpica_device_id_list *cid;
|
||||||
u32 i;
|
u32 i;
|
||||||
int found;
|
u8 found;
|
||||||
|
int no_match;
|
||||||
|
|
||||||
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
|
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
@ -582,10 +583,14 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
|
|||||||
return (AE_CTRL_DEPTH);
|
return (AE_CTRL_DEPTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ACPI_STRNCMP(hid.value, info->hid, sizeof(hid.value)) != 0) {
|
no_match = ACPI_STRCMP(hid->string, info->hid);
|
||||||
|
ACPI_FREE(hid);
|
||||||
/* Get the list of Compatible IDs */
|
|
||||||
|
|
||||||
|
if (no_match) {
|
||||||
|
/*
|
||||||
|
* HID does not match, attempt match within the
|
||||||
|
* list of Compatible IDs (CIDs)
|
||||||
|
*/
|
||||||
status = acpi_ut_execute_CID(node, &cid);
|
status = acpi_ut_execute_CID(node, &cid);
|
||||||
if (status == AE_NOT_FOUND) {
|
if (status == AE_NOT_FOUND) {
|
||||||
return (AE_OK);
|
return (AE_OK);
|
||||||
@ -597,10 +602,8 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
|
|||||||
|
|
||||||
found = 0;
|
found = 0;
|
||||||
for (i = 0; i < cid->count; i++) {
|
for (i = 0; i < cid->count; i++) {
|
||||||
if (ACPI_STRNCMP(cid->id[i].value, info->hid,
|
if (ACPI_STRCMP(cid->ids[i].string, info->hid)
|
||||||
sizeof(struct
|
== 0) {
|
||||||
acpi_compatible_id)) ==
|
|
||||||
0) {
|
|
||||||
found = 1;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,11 @@
|
|||||||
#define _COMPONENT ACPI_NAMESPACE
|
#define _COMPONENT ACPI_NAMESPACE
|
||||||
ACPI_MODULE_NAME("nsxfname")
|
ACPI_MODULE_NAME("nsxfname")
|
||||||
|
|
||||||
|
/* Local prototypes */
|
||||||
|
static char *acpi_ns_copy_device_id(struct acpica_device_id *dest,
|
||||||
|
struct acpica_device_id *source,
|
||||||
|
char *string_area);
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_get_handle
|
* FUNCTION: acpi_get_handle
|
||||||
@ -68,6 +73,7 @@ ACPI_MODULE_NAME("nsxfname")
|
|||||||
* namespace handle.
|
* namespace handle.
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
acpi_get_handle(acpi_handle parent,
|
acpi_get_handle(acpi_handle parent,
|
||||||
acpi_string pathname, acpi_handle * ret_handle)
|
acpi_string pathname, acpi_handle * ret_handle)
|
||||||
@ -208,12 +214,40 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer)
|
|||||||
|
|
||||||
ACPI_EXPORT_SYMBOL(acpi_get_name)
|
ACPI_EXPORT_SYMBOL(acpi_get_name)
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ns_copy_device_id
|
||||||
|
*
|
||||||
|
* PARAMETERS: Dest - Pointer to the destination DEVICE_ID
|
||||||
|
* Source - Pointer to the source DEVICE_ID
|
||||||
|
* string_area - Pointer to where to copy the dest string
|
||||||
|
*
|
||||||
|
* RETURN: Pointer to the next string area
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Copy a single DEVICE_ID, including the string data.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
static char *acpi_ns_copy_device_id(struct acpica_device_id *dest,
|
||||||
|
struct acpica_device_id *source,
|
||||||
|
char *string_area)
|
||||||
|
{
|
||||||
|
/* Create the destination DEVICE_ID */
|
||||||
|
|
||||||
|
dest->string = string_area;
|
||||||
|
dest->length = source->length;
|
||||||
|
|
||||||
|
/* Copy actual string and return a pointer to the next string area */
|
||||||
|
|
||||||
|
ACPI_MEMCPY(string_area, source->string, source->length);
|
||||||
|
return (string_area + source->length);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_get_object_info
|
* FUNCTION: acpi_get_object_info
|
||||||
*
|
*
|
||||||
* PARAMETERS: Handle - Object Handle
|
* PARAMETERS: Handle - Object Handle
|
||||||
* Buffer - Where the info is returned
|
* return_buffer - Where the info is returned
|
||||||
*
|
*
|
||||||
* RETURN: Status
|
* RETURN: Status
|
||||||
*
|
*
|
||||||
@ -221,33 +255,37 @@ ACPI_EXPORT_SYMBOL(acpi_get_name)
|
|||||||
* namespace node and possibly by running several standard
|
* namespace node and possibly by running several standard
|
||||||
* control methods (Such as in the case of a device.)
|
* control methods (Such as in the case of a device.)
|
||||||
*
|
*
|
||||||
|
* For Device and Processor objects, run the Device _HID, _UID, _CID, _STA,
|
||||||
|
* _ADR, _sx_w, and _sx_d methods.
|
||||||
|
*
|
||||||
|
* Note: Allocates the return buffer, must be freed by the caller.
|
||||||
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer)
|
acpi_get_object_info(acpi_handle handle,
|
||||||
|
struct acpi_device_info **return_buffer)
|
||||||
{
|
{
|
||||||
acpi_status status;
|
|
||||||
struct acpi_namespace_node *node;
|
struct acpi_namespace_node *node;
|
||||||
struct acpi_device_info *info;
|
struct acpi_device_info *info;
|
||||||
struct acpi_device_info *return_info;
|
struct acpica_device_id_list *cid_list = NULL;
|
||||||
struct acpi_compatible_id_list *cid_list = NULL;
|
struct acpica_device_id *hid = NULL;
|
||||||
acpi_size size;
|
struct acpica_device_id *uid = NULL;
|
||||||
|
char *next_id_string;
|
||||||
|
acpi_object_type type;
|
||||||
|
acpi_name name;
|
||||||
|
u8 param_count = 0;
|
||||||
|
u8 valid = 0;
|
||||||
|
u32 info_size;
|
||||||
|
u32 i;
|
||||||
|
acpi_status status;
|
||||||
|
|
||||||
/* Parameter validation */
|
/* Parameter validation */
|
||||||
|
|
||||||
if (!handle || !buffer) {
|
if (!handle || !return_buffer) {
|
||||||
return (AE_BAD_PARAMETER);
|
return (AE_BAD_PARAMETER);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = acpi_ut_validate_buffer(buffer);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return (status);
|
|
||||||
}
|
|
||||||
|
|
||||||
info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_device_info));
|
|
||||||
if (!info) {
|
|
||||||
return (AE_NO_MEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
|
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -256,66 +294,91 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer)
|
|||||||
node = acpi_ns_map_handle_to_node(handle);
|
node = acpi_ns_map_handle_to_node(handle);
|
||||||
if (!node) {
|
if (!node) {
|
||||||
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
||||||
status = AE_BAD_PARAMETER;
|
return (AE_BAD_PARAMETER);
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init return structure */
|
/* Get the namespace node data while the namespace is locked */
|
||||||
|
|
||||||
size = sizeof(struct acpi_device_info);
|
info_size = sizeof(struct acpi_device_info);
|
||||||
|
type = node->type;
|
||||||
info->type = node->type;
|
name = node->name.integer;
|
||||||
info->name = node->name.integer;
|
|
||||||
info->valid = 0;
|
|
||||||
|
|
||||||
if (node->type == ACPI_TYPE_METHOD) {
|
if (node->type == ACPI_TYPE_METHOD) {
|
||||||
info->param_count = node->object->method.param_count;
|
param_count = node->object->method.param_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
goto cleanup;
|
return (status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If not a device, we are all done */
|
if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) {
|
||||||
|
|
||||||
if (info->type == ACPI_TYPE_DEVICE) {
|
|
||||||
/*
|
/*
|
||||||
* Get extra info for ACPI Devices objects only:
|
* Get extra info for ACPI Device/Processor objects only:
|
||||||
* Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods.
|
* Run the Device _HID, _UID, and _CID methods.
|
||||||
*
|
*
|
||||||
* Note: none of these methods are required, so they may or may
|
* Note: none of these methods are required, so they may or may
|
||||||
* not be present for this device. The Info->Valid bitfield is used
|
* not be present for this device. The Info->Valid bitfield is used
|
||||||
* to indicate which methods were found and ran successfully.
|
* to indicate which methods were found and run successfully.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Execute the Device._HID method */
|
/* Execute the Device._HID method */
|
||||||
|
|
||||||
status = acpi_ut_execute_HID(node, &info->hardware_id);
|
status = acpi_ut_execute_HID(node, &hid);
|
||||||
if (ACPI_SUCCESS(status)) {
|
if (ACPI_SUCCESS(status)) {
|
||||||
info->valid |= ACPI_VALID_HID;
|
info_size += hid->length;
|
||||||
|
valid |= ACPI_VALID_HID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute the Device._UID method */
|
/* Execute the Device._UID method */
|
||||||
|
|
||||||
status = acpi_ut_execute_UID(node, &info->unique_id);
|
status = acpi_ut_execute_UID(node, &uid);
|
||||||
if (ACPI_SUCCESS(status)) {
|
if (ACPI_SUCCESS(status)) {
|
||||||
info->valid |= ACPI_VALID_UID;
|
info_size += uid->length;
|
||||||
|
valid |= ACPI_VALID_UID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute the Device._CID method */
|
/* Execute the Device._CID method */
|
||||||
|
|
||||||
status = acpi_ut_execute_CID(node, &cid_list);
|
status = acpi_ut_execute_CID(node, &cid_list);
|
||||||
if (ACPI_SUCCESS(status)) {
|
if (ACPI_SUCCESS(status)) {
|
||||||
size += cid_list->size;
|
|
||||||
info->valid |= ACPI_VALID_CID;
|
/* Add size of CID strings and CID pointer array */
|
||||||
|
|
||||||
|
info_size +=
|
||||||
|
(cid_list->list_size -
|
||||||
|
sizeof(struct acpica_device_id_list));
|
||||||
|
valid |= ACPI_VALID_CID;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now that we have the variable-length data, we can allocate the
|
||||||
|
* return buffer
|
||||||
|
*/
|
||||||
|
info = ACPI_ALLOCATE_ZEROED(info_size);
|
||||||
|
if (!info) {
|
||||||
|
status = AE_NO_MEMORY;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the fixed-length data */
|
||||||
|
|
||||||
|
if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) {
|
||||||
|
/*
|
||||||
|
* Get extra info for ACPI Device/Processor objects only:
|
||||||
|
* Run the _STA, _ADR and, sx_w, and _sx_d methods.
|
||||||
|
*
|
||||||
|
* Note: none of these methods are required, so they may or may
|
||||||
|
* not be present for this device. The Info->Valid bitfield is used
|
||||||
|
* to indicate which methods were found and run successfully.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Execute the Device._STA method */
|
/* Execute the Device._STA method */
|
||||||
|
|
||||||
status = acpi_ut_execute_STA(node, &info->current_status);
|
status = acpi_ut_execute_STA(node, &info->current_status);
|
||||||
if (ACPI_SUCCESS(status)) {
|
if (ACPI_SUCCESS(status)) {
|
||||||
info->valid |= ACPI_VALID_STA;
|
valid |= ACPI_VALID_STA;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute the Device._ADR method */
|
/* Execute the Device._ADR method */
|
||||||
@ -323,36 +386,100 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer)
|
|||||||
status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node,
|
status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node,
|
||||||
&info->address);
|
&info->address);
|
||||||
if (ACPI_SUCCESS(status)) {
|
if (ACPI_SUCCESS(status)) {
|
||||||
info->valid |= ACPI_VALID_ADR;
|
valid |= ACPI_VALID_ADR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Execute the Device._sx_w methods */
|
||||||
|
|
||||||
|
status = acpi_ut_execute_power_methods(node,
|
||||||
|
acpi_gbl_lowest_dstate_names,
|
||||||
|
ACPI_NUM_sx_w_METHODS,
|
||||||
|
info->lowest_dstates);
|
||||||
|
if (ACPI_SUCCESS(status)) {
|
||||||
|
valid |= ACPI_VALID_SXWS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Execute the Device._sx_d methods */
|
/* Execute the Device._sx_d methods */
|
||||||
|
|
||||||
status = acpi_ut_execute_sxds(node, info->highest_dstates);
|
status = acpi_ut_execute_power_methods(node,
|
||||||
|
acpi_gbl_highest_dstate_names,
|
||||||
|
ACPI_NUM_sx_d_METHODS,
|
||||||
|
info->highest_dstates);
|
||||||
if (ACPI_SUCCESS(status)) {
|
if (ACPI_SUCCESS(status)) {
|
||||||
info->valid |= ACPI_VALID_SXDS;
|
valid |= ACPI_VALID_SXDS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate/Allocate/Clear caller buffer */
|
/*
|
||||||
|
* Create a pointer to the string area of the return buffer.
|
||||||
|
* Point to the end of the base struct acpi_device_info structure.
|
||||||
|
*/
|
||||||
|
next_id_string = ACPI_CAST_PTR(char, info->compatible_id_list.ids);
|
||||||
|
if (cid_list) {
|
||||||
|
|
||||||
status = acpi_ut_initialize_buffer(buffer, size);
|
/* Point past the CID DEVICE_ID array */
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
goto cleanup;
|
next_id_string +=
|
||||||
|
((acpi_size) cid_list->count *
|
||||||
|
sizeof(struct acpica_device_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Populate the return buffer */
|
/*
|
||||||
|
* Copy the HID, UID, and CIDs to the return buffer. The variable-length
|
||||||
|
* strings are copied to the reserved area at the end of the buffer.
|
||||||
|
*
|
||||||
|
* For HID and CID, check if the ID is a PCI Root Bridge.
|
||||||
|
*/
|
||||||
|
if (hid) {
|
||||||
|
next_id_string = acpi_ns_copy_device_id(&info->hardware_id,
|
||||||
|
hid, next_id_string);
|
||||||
|
|
||||||
return_info = buffer->pointer;
|
if (acpi_ut_is_pci_root_bridge(hid->string)) {
|
||||||
ACPI_MEMCPY(return_info, info, sizeof(struct acpi_device_info));
|
info->flags |= ACPI_PCI_ROOT_BRIDGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uid) {
|
||||||
|
next_id_string = acpi_ns_copy_device_id(&info->unique_id,
|
||||||
|
uid, next_id_string);
|
||||||
|
}
|
||||||
|
|
||||||
if (cid_list) {
|
if (cid_list) {
|
||||||
ACPI_MEMCPY(&return_info->compatibility_id, cid_list,
|
info->compatible_id_list.count = cid_list->count;
|
||||||
cid_list->size);
|
info->compatible_id_list.list_size = cid_list->list_size;
|
||||||
|
|
||||||
|
/* Copy each CID */
|
||||||
|
|
||||||
|
for (i = 0; i < cid_list->count; i++) {
|
||||||
|
next_id_string =
|
||||||
|
acpi_ns_copy_device_id(&info->compatible_id_list.
|
||||||
|
ids[i], &cid_list->ids[i],
|
||||||
|
next_id_string);
|
||||||
|
|
||||||
|
if (acpi_ut_is_pci_root_bridge(cid_list->ids[i].string)) {
|
||||||
|
info->flags |= ACPI_PCI_ROOT_BRIDGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copy the fixed-length data */
|
||||||
|
|
||||||
|
info->info_size = info_size;
|
||||||
|
info->type = type;
|
||||||
|
info->name = name;
|
||||||
|
info->param_count = param_count;
|
||||||
|
info->valid = valid;
|
||||||
|
|
||||||
|
*return_buffer = info;
|
||||||
|
status = AE_OK;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
ACPI_FREE(info);
|
if (hid) {
|
||||||
|
ACPI_FREE(hid);
|
||||||
|
}
|
||||||
|
if (uid) {
|
||||||
|
ACPI_FREE(uid);
|
||||||
|
}
|
||||||
if (cid_list) {
|
if (cid_list) {
|
||||||
ACPI_FREE(cid_list);
|
ACPI_FREE(cid_list);
|
||||||
}
|
}
|
||||||
|
@ -44,19 +44,10 @@
|
|||||||
#include <acpi/acpi.h>
|
#include <acpi/acpi.h>
|
||||||
#include "accommon.h"
|
#include "accommon.h"
|
||||||
#include "acnamesp.h"
|
#include "acnamesp.h"
|
||||||
#include "acinterp.h"
|
|
||||||
|
|
||||||
#define _COMPONENT ACPI_UTILITIES
|
#define _COMPONENT ACPI_UTILITIES
|
||||||
ACPI_MODULE_NAME("uteval")
|
ACPI_MODULE_NAME("uteval")
|
||||||
|
|
||||||
/* Local prototypes */
|
|
||||||
static void
|
|
||||||
acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length);
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
|
|
||||||
struct acpi_compatible_id *one_cid);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Strings supported by the _OSI predefined (internal) method.
|
* Strings supported by the _OSI predefined (internal) method.
|
||||||
*
|
*
|
||||||
@ -340,12 +331,12 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
|
|||||||
*
|
*
|
||||||
* PARAMETERS: object_name - Object name to be evaluated
|
* PARAMETERS: object_name - Object name to be evaluated
|
||||||
* device_node - Node for the device
|
* device_node - Node for the device
|
||||||
* Address - Where the value is returned
|
* Value - Where the value is returned
|
||||||
*
|
*
|
||||||
* RETURN: Status
|
* RETURN: Status
|
||||||
*
|
*
|
||||||
* DESCRIPTION: Evaluates a numeric namespace object for a selected device
|
* DESCRIPTION: Evaluates a numeric namespace object for a selected device
|
||||||
* and stores result in *Address.
|
* and stores result in *Value.
|
||||||
*
|
*
|
||||||
* NOTE: Internal function, no parameter validation
|
* NOTE: Internal function, no parameter validation
|
||||||
*
|
*
|
||||||
@ -354,7 +345,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
|
|||||||
acpi_status
|
acpi_status
|
||||||
acpi_ut_evaluate_numeric_object(char *object_name,
|
acpi_ut_evaluate_numeric_object(char *object_name,
|
||||||
struct acpi_namespace_node *device_node,
|
struct acpi_namespace_node *device_node,
|
||||||
acpi_integer * address)
|
acpi_integer *value)
|
||||||
{
|
{
|
||||||
union acpi_operand_object *obj_desc;
|
union acpi_operand_object *obj_desc;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
@ -369,295 +360,7 @@ acpi_ut_evaluate_numeric_object(char *object_name,
|
|||||||
|
|
||||||
/* Get the returned Integer */
|
/* Get the returned Integer */
|
||||||
|
|
||||||
*address = obj_desc->integer.value;
|
*value = obj_desc->integer.value;
|
||||||
|
|
||||||
/* On exit, we must delete the return object */
|
|
||||||
|
|
||||||
acpi_ut_remove_reference(obj_desc);
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_copy_id_string
|
|
||||||
*
|
|
||||||
* PARAMETERS: Destination - Where to copy the string
|
|
||||||
* Source - Source string
|
|
||||||
* max_length - Length of the destination buffer
|
|
||||||
*
|
|
||||||
* RETURN: None
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
|
|
||||||
* Performs removal of a leading asterisk if present -- workaround
|
|
||||||
* for a known issue on a bunch of machines.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static void
|
|
||||||
acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length)
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Workaround for ID strings that have a leading asterisk. This construct
|
|
||||||
* is not allowed by the ACPI specification (ID strings must be
|
|
||||||
* alphanumeric), but enough existing machines have this embedded in their
|
|
||||||
* ID strings that the following code is useful.
|
|
||||||
*/
|
|
||||||
if (*source == '*') {
|
|
||||||
source++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do the actual copy */
|
|
||||||
|
|
||||||
ACPI_STRNCPY(destination, source, max_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_execute_HID
|
|
||||||
*
|
|
||||||
* PARAMETERS: device_node - Node for the device
|
|
||||||
* Hid - Where the HID is returned
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Executes the _HID control method that returns the hardware
|
|
||||||
* ID of the device.
|
|
||||||
*
|
|
||||||
* NOTE: Internal function, no parameter validation
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
acpi_status
|
|
||||||
acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
|
|
||||||
struct acpica_device_id *hid)
|
|
||||||
{
|
|
||||||
union acpi_operand_object *obj_desc;
|
|
||||||
acpi_status status;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ut_execute_HID);
|
|
||||||
|
|
||||||
status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID,
|
|
||||||
ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
|
|
||||||
&obj_desc);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
|
|
||||||
|
|
||||||
/* Convert the Numeric HID to string */
|
|
||||||
|
|
||||||
acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
|
|
||||||
hid->value);
|
|
||||||
} else {
|
|
||||||
/* Copy the String HID from the returned object */
|
|
||||||
|
|
||||||
acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer,
|
|
||||||
sizeof(hid->value));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* On exit, we must delete the return object */
|
|
||||||
|
|
||||||
acpi_ut_remove_reference(obj_desc);
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_translate_one_cid
|
|
||||||
*
|
|
||||||
* PARAMETERS: obj_desc - _CID object, must be integer or string
|
|
||||||
* one_cid - Where the CID string is returned
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Return a numeric or string _CID value as a string.
|
|
||||||
* (Compatible ID)
|
|
||||||
*
|
|
||||||
* NOTE: Assumes a maximum _CID string length of
|
|
||||||
* ACPI_MAX_CID_LENGTH.
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static acpi_status
|
|
||||||
acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
|
|
||||||
struct acpi_compatible_id *one_cid)
|
|
||||||
{
|
|
||||||
|
|
||||||
switch (obj_desc->common.type) {
|
|
||||||
case ACPI_TYPE_INTEGER:
|
|
||||||
|
|
||||||
/* Convert the Numeric CID to string */
|
|
||||||
|
|
||||||
acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value,
|
|
||||||
one_cid->value);
|
|
||||||
return (AE_OK);
|
|
||||||
|
|
||||||
case ACPI_TYPE_STRING:
|
|
||||||
|
|
||||||
if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) {
|
|
||||||
return (AE_AML_STRING_LIMIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy the String CID from the returned object */
|
|
||||||
|
|
||||||
acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer,
|
|
||||||
ACPI_MAX_CID_LENGTH);
|
|
||||||
return (AE_OK);
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
return (AE_TYPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_execute_CID
|
|
||||||
*
|
|
||||||
* PARAMETERS: device_node - Node for the device
|
|
||||||
* return_cid_list - Where the CID list is returned
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Executes the _CID control method that returns one or more
|
|
||||||
* compatible hardware IDs for the device.
|
|
||||||
*
|
|
||||||
* NOTE: Internal function, no parameter validation
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
acpi_status
|
|
||||||
acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
|
|
||||||
struct acpi_compatible_id_list ** return_cid_list)
|
|
||||||
{
|
|
||||||
union acpi_operand_object *obj_desc;
|
|
||||||
acpi_status status;
|
|
||||||
u32 count;
|
|
||||||
u32 size;
|
|
||||||
struct acpi_compatible_id_list *cid_list;
|
|
||||||
u32 i;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ut_execute_CID);
|
|
||||||
|
|
||||||
/* Evaluate the _CID method for this device */
|
|
||||||
|
|
||||||
status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID,
|
|
||||||
ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING
|
|
||||||
| ACPI_BTYPE_PACKAGE, &obj_desc);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the number of _CIDs returned */
|
|
||||||
|
|
||||||
count = 1;
|
|
||||||
if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
|
|
||||||
count = obj_desc->package.count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate a worst-case buffer for the _CIDs */
|
|
||||||
|
|
||||||
size = (((count - 1) * sizeof(struct acpi_compatible_id)) +
|
|
||||||
sizeof(struct acpi_compatible_id_list));
|
|
||||||
|
|
||||||
cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size);
|
|
||||||
if (!cid_list) {
|
|
||||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Init CID list */
|
|
||||||
|
|
||||||
cid_list->count = count;
|
|
||||||
cid_list->size = size;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A _CID can return either a single compatible ID or a package of
|
|
||||||
* compatible IDs. Each compatible ID can be one of the following:
|
|
||||||
* 1) Integer (32 bit compressed EISA ID) or
|
|
||||||
* 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* The _CID object can be either a single CID or a package (list) of CIDs */
|
|
||||||
|
|
||||||
if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
|
|
||||||
|
|
||||||
/* Translate each package element */
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
status =
|
|
||||||
acpi_ut_translate_one_cid(obj_desc->package.
|
|
||||||
elements[i],
|
|
||||||
&cid_list->id[i]);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Only one CID, translate to a string */
|
|
||||||
|
|
||||||
status = acpi_ut_translate_one_cid(obj_desc, cid_list->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cleanup on error */
|
|
||||||
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
ACPI_FREE(cid_list);
|
|
||||||
} else {
|
|
||||||
*return_cid_list = cid_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* On exit, we must delete the _CID return object */
|
|
||||||
|
|
||||||
acpi_ut_remove_reference(obj_desc);
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* FUNCTION: acpi_ut_execute_UID
|
|
||||||
*
|
|
||||||
* PARAMETERS: device_node - Node for the device
|
|
||||||
* Uid - Where the UID is returned
|
|
||||||
*
|
|
||||||
* RETURN: Status
|
|
||||||
*
|
|
||||||
* DESCRIPTION: Executes the _UID control method that returns the hardware
|
|
||||||
* ID of the device.
|
|
||||||
*
|
|
||||||
* NOTE: Internal function, no parameter validation
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
acpi_status
|
|
||||||
acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
|
|
||||||
struct acpica_device_id *uid)
|
|
||||||
{
|
|
||||||
union acpi_operand_object *obj_desc;
|
|
||||||
acpi_status status;
|
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ut_execute_UID);
|
|
||||||
|
|
||||||
status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID,
|
|
||||||
ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
|
|
||||||
&obj_desc);
|
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
|
|
||||||
|
|
||||||
/* Convert the Numeric UID to string */
|
|
||||||
|
|
||||||
acpi_ex_unsigned_integer_to_string(obj_desc->integer.value,
|
|
||||||
uid->value);
|
|
||||||
} else {
|
|
||||||
/* Copy the String UID from the returned object */
|
|
||||||
|
|
||||||
acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer,
|
|
||||||
sizeof(uid->value));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* On exit, we must delete the return object */
|
/* On exit, we must delete the return object */
|
||||||
|
|
||||||
@ -716,60 +419,64 @@ acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
|
|||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ut_execute_Sxds
|
* FUNCTION: acpi_ut_execute_power_methods
|
||||||
*
|
*
|
||||||
* PARAMETERS: device_node - Node for the device
|
* PARAMETERS: device_node - Node for the device
|
||||||
* Flags - Where the status flags are returned
|
* method_names - Array of power method names
|
||||||
|
* method_count - Number of methods to execute
|
||||||
|
* out_values - Where the power method values are returned
|
||||||
*
|
*
|
||||||
* RETURN: Status
|
* RETURN: Status, out_values
|
||||||
*
|
*
|
||||||
* DESCRIPTION: Executes _STA for selected device and stores results in
|
* DESCRIPTION: Executes the specified power methods for the device and returns
|
||||||
* *Flags.
|
* the result(s).
|
||||||
*
|
*
|
||||||
* NOTE: Internal function, no parameter validation
|
* NOTE: Internal function, no parameter validation
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest)
|
acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node,
|
||||||
|
const char **method_names,
|
||||||
|
u8 method_count, u8 *out_values)
|
||||||
{
|
{
|
||||||
union acpi_operand_object *obj_desc;
|
union acpi_operand_object *obj_desc;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
|
acpi_status final_status = AE_NOT_FOUND;
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ut_execute_sxds);
|
ACPI_FUNCTION_TRACE(ut_execute_power_methods);
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < method_count; i++) {
|
||||||
highest[i] = 0xFF;
|
/*
|
||||||
|
* Execute the power method (_sx_d or _sx_w). The only allowable
|
||||||
|
* return type is an Integer.
|
||||||
|
*/
|
||||||
status = acpi_ut_evaluate_object(device_node,
|
status = acpi_ut_evaluate_object(device_node,
|
||||||
ACPI_CAST_PTR(char,
|
ACPI_CAST_PTR(char,
|
||||||
acpi_gbl_highest_dstate_names
|
method_names[i]),
|
||||||
[i]),
|
|
||||||
ACPI_BTYPE_INTEGER, &obj_desc);
|
ACPI_BTYPE_INTEGER, &obj_desc);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_SUCCESS(status)) {
|
||||||
if (status != AE_NOT_FOUND) {
|
out_values[i] = (u8)obj_desc->integer.value;
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
|
||||||
"%s on Device %4.4s, %s\n",
|
|
||||||
ACPI_CAST_PTR(char,
|
|
||||||
acpi_gbl_highest_dstate_names
|
|
||||||
[i]),
|
|
||||||
acpi_ut_get_node_name
|
|
||||||
(device_node),
|
|
||||||
acpi_format_exception
|
|
||||||
(status)));
|
|
||||||
|
|
||||||
return_ACPI_STATUS(status);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Extract the Dstate value */
|
|
||||||
|
|
||||||
highest[i] = (u8) obj_desc->integer.value;
|
|
||||||
|
|
||||||
/* Delete the return object */
|
/* Delete the return object */
|
||||||
|
|
||||||
acpi_ut_remove_reference(obj_desc);
|
acpi_ut_remove_reference(obj_desc);
|
||||||
}
|
final_status = AE_OK; /* At least one value is valid */
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return_ACPI_STATUS(AE_OK);
|
out_values[i] = ACPI_UINT8_MAX;
|
||||||
|
if (status == AE_NOT_FOUND) {
|
||||||
|
continue; /* Ignore if not found */
|
||||||
|
}
|
||||||
|
|
||||||
|
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||||
|
"Failed %s on Device %4.4s, %s\n",
|
||||||
|
ACPI_CAST_PTR(char, method_names[i]),
|
||||||
|
acpi_ut_get_node_name(device_node),
|
||||||
|
acpi_format_exception(status)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return_ACPI_STATUS(final_status);
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,15 @@ const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = {
|
|||||||
"\\_S5_"
|
"\\_S5_"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *acpi_gbl_highest_dstate_names[4] = {
|
const char *acpi_gbl_lowest_dstate_names[ACPI_NUM_sx_w_METHODS] = {
|
||||||
|
"_S0W",
|
||||||
|
"_S1W",
|
||||||
|
"_S2W",
|
||||||
|
"_S3W",
|
||||||
|
"_S4W"
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *acpi_gbl_highest_dstate_names[ACPI_NUM_sx_d_METHODS] = {
|
||||||
"_S1D",
|
"_S1D",
|
||||||
"_S2D",
|
"_S2D",
|
||||||
"_S3D",
|
"_S3D",
|
||||||
|
382
drivers/acpi/acpica/utids.c
Normal file
382
drivers/acpi/acpica/utids.c
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Module Name: utids - support for device IDs - HID, UID, CID
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2000 - 2009, Intel Corp.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions, and the following disclaimer,
|
||||||
|
* without modification.
|
||||||
|
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||||
|
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||||
|
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||||
|
* including a substantially similar Disclaimer requirement for further
|
||||||
|
* binary redistribution.
|
||||||
|
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||||
|
* of any contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* Alternatively, this software may be distributed under the terms of the
|
||||||
|
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||||
|
* Software Foundation.
|
||||||
|
*
|
||||||
|
* NO WARRANTY
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <acpi/acpi.h>
|
||||||
|
#include "accommon.h"
|
||||||
|
#include "acinterp.h"
|
||||||
|
|
||||||
|
#define _COMPONENT ACPI_UTILITIES
|
||||||
|
ACPI_MODULE_NAME("utids")
|
||||||
|
|
||||||
|
/* Local prototypes */
|
||||||
|
static void acpi_ut_copy_id_string(char *destination, char *source);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_copy_id_string
|
||||||
|
*
|
||||||
|
* PARAMETERS: Destination - Where to copy the string
|
||||||
|
* Source - Source string
|
||||||
|
*
|
||||||
|
* RETURN: None
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
|
||||||
|
* Performs removal of a leading asterisk if present -- workaround
|
||||||
|
* for a known issue on a bunch of machines.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
static void acpi_ut_copy_id_string(char *destination, char *source)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Workaround for ID strings that have a leading asterisk. This construct
|
||||||
|
* is not allowed by the ACPI specification (ID strings must be
|
||||||
|
* alphanumeric), but enough existing machines have this embedded in their
|
||||||
|
* ID strings that the following code is useful.
|
||||||
|
*/
|
||||||
|
if (*source == '*') {
|
||||||
|
source++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the actual copy */
|
||||||
|
|
||||||
|
ACPI_STRCPY(destination, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_execute_HID
|
||||||
|
*
|
||||||
|
* PARAMETERS: device_node - Node for the device
|
||||||
|
* return_id - Where the string HID is returned
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Executes the _HID control method that returns the hardware
|
||||||
|
* ID of the device. The HID is either an 32-bit encoded EISAID
|
||||||
|
* Integer or a String. A string is always returned. An EISAID
|
||||||
|
* is converted to a string.
|
||||||
|
*
|
||||||
|
* NOTE: Internal function, no parameter validation
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
|
||||||
|
struct acpica_device_id **return_id)
|
||||||
|
{
|
||||||
|
union acpi_operand_object *obj_desc;
|
||||||
|
struct acpica_device_id *hid;
|
||||||
|
u32 length;
|
||||||
|
acpi_status status;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE(ut_execute_HID);
|
||||||
|
|
||||||
|
status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID,
|
||||||
|
ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
|
||||||
|
&obj_desc);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the size of the String to be returned, includes null terminator */
|
||||||
|
|
||||||
|
if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
|
||||||
|
length = ACPI_EISAID_STRING_SIZE;
|
||||||
|
} else {
|
||||||
|
length = obj_desc->string.length + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a buffer for the HID */
|
||||||
|
|
||||||
|
hid =
|
||||||
|
ACPI_ALLOCATE_ZEROED(sizeof(struct acpica_device_id) +
|
||||||
|
(acpi_size) length);
|
||||||
|
if (!hid) {
|
||||||
|
status = AE_NO_MEMORY;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Area for the string starts after DEVICE_ID struct */
|
||||||
|
|
||||||
|
hid->string = ACPI_ADD_PTR(char, hid, sizeof(struct acpica_device_id));
|
||||||
|
|
||||||
|
/* Convert EISAID to a string or simply copy existing string */
|
||||||
|
|
||||||
|
if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
|
||||||
|
acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value);
|
||||||
|
} else {
|
||||||
|
acpi_ut_copy_id_string(hid->string, obj_desc->string.pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
hid->length = length;
|
||||||
|
*return_id = hid;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
/* On exit, we must delete the return object */
|
||||||
|
|
||||||
|
acpi_ut_remove_reference(obj_desc);
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_execute_UID
|
||||||
|
*
|
||||||
|
* PARAMETERS: device_node - Node for the device
|
||||||
|
* return_id - Where the string UID is returned
|
||||||
|
*
|
||||||
|
* RETURN: Status
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Executes the _UID control method that returns the unique
|
||||||
|
* ID of the device. The UID is either a 64-bit Integer (NOT an
|
||||||
|
* EISAID) or a string. Always returns a string. A 64-bit integer
|
||||||
|
* is converted to a decimal string.
|
||||||
|
*
|
||||||
|
* NOTE: Internal function, no parameter validation
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
|
||||||
|
struct acpica_device_id **return_id)
|
||||||
|
{
|
||||||
|
union acpi_operand_object *obj_desc;
|
||||||
|
struct acpica_device_id *uid;
|
||||||
|
u32 length;
|
||||||
|
acpi_status status;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE(ut_execute_UID);
|
||||||
|
|
||||||
|
status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID,
|
||||||
|
ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING,
|
||||||
|
&obj_desc);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the size of the String to be returned, includes null terminator */
|
||||||
|
|
||||||
|
if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
|
||||||
|
length = ACPI_MAX64_DECIMAL_DIGITS + 1;
|
||||||
|
} else {
|
||||||
|
length = obj_desc->string.length + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a buffer for the UID */
|
||||||
|
|
||||||
|
uid =
|
||||||
|
ACPI_ALLOCATE_ZEROED(sizeof(struct acpica_device_id) +
|
||||||
|
(acpi_size) length);
|
||||||
|
if (!uid) {
|
||||||
|
status = AE_NO_MEMORY;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Area for the string starts after DEVICE_ID struct */
|
||||||
|
|
||||||
|
uid->string = ACPI_ADD_PTR(char, uid, sizeof(struct acpica_device_id));
|
||||||
|
|
||||||
|
/* Convert an Integer to string, or just copy an existing string */
|
||||||
|
|
||||||
|
if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
|
||||||
|
acpi_ex_integer_to_string(uid->string, obj_desc->integer.value);
|
||||||
|
} else {
|
||||||
|
acpi_ut_copy_id_string(uid->string, obj_desc->string.pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
uid->length = length;
|
||||||
|
*return_id = uid;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
/* On exit, we must delete the return object */
|
||||||
|
|
||||||
|
acpi_ut_remove_reference(obj_desc);
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_execute_CID
|
||||||
|
*
|
||||||
|
* PARAMETERS: device_node - Node for the device
|
||||||
|
* return_cid_list - Where the CID list is returned
|
||||||
|
*
|
||||||
|
* RETURN: Status, list of CID strings
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Executes the _CID control method that returns one or more
|
||||||
|
* compatible hardware IDs for the device.
|
||||||
|
*
|
||||||
|
* NOTE: Internal function, no parameter validation
|
||||||
|
*
|
||||||
|
* A _CID method can return either a single compatible ID or a package of
|
||||||
|
* compatible IDs. Each compatible ID can be one of the following:
|
||||||
|
* 1) Integer (32 bit compressed EISA ID) or
|
||||||
|
* 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
|
||||||
|
*
|
||||||
|
* The Integer CIDs are converted to string format by this function.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
acpi_status
|
||||||
|
acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
|
||||||
|
struct acpica_device_id_list **return_cid_list)
|
||||||
|
{
|
||||||
|
union acpi_operand_object **cid_objects;
|
||||||
|
union acpi_operand_object *obj_desc;
|
||||||
|
struct acpica_device_id_list *cid_list;
|
||||||
|
char *next_id_string;
|
||||||
|
u32 string_area_size;
|
||||||
|
u32 length;
|
||||||
|
u32 cid_list_size;
|
||||||
|
acpi_status status;
|
||||||
|
u32 count;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
ACPI_FUNCTION_TRACE(ut_execute_CID);
|
||||||
|
|
||||||
|
/* Evaluate the _CID method for this device */
|
||||||
|
|
||||||
|
status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID,
|
||||||
|
ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING
|
||||||
|
| ACPI_BTYPE_PACKAGE, &obj_desc);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the count and size of the returned _CIDs. _CID can return either
|
||||||
|
* a Package of Integers/Strings or a single Integer or String.
|
||||||
|
* Note: This section also validates that all CID elements are of the
|
||||||
|
* correct type (Integer or String).
|
||||||
|
*/
|
||||||
|
if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
|
||||||
|
count = obj_desc->package.count;
|
||||||
|
cid_objects = obj_desc->package.elements;
|
||||||
|
} else { /* Single Integer or String CID */
|
||||||
|
|
||||||
|
count = 1;
|
||||||
|
cid_objects = &obj_desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
string_area_size = 0;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
|
||||||
|
/* String lengths include null terminator */
|
||||||
|
|
||||||
|
switch (cid_objects[i]->common.type) {
|
||||||
|
case ACPI_TYPE_INTEGER:
|
||||||
|
string_area_size += ACPI_EISAID_STRING_SIZE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACPI_TYPE_STRING:
|
||||||
|
string_area_size += cid_objects[i]->string.length + 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
status = AE_TYPE;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now that we know the length of the CIDs, allocate return buffer:
|
||||||
|
* 1) Size of the base structure +
|
||||||
|
* 2) Size of the CID DEVICE_ID array +
|
||||||
|
* 3) Size of the actual CID strings
|
||||||
|
*/
|
||||||
|
cid_list_size = sizeof(struct acpica_device_id_list) +
|
||||||
|
((count - 1) * sizeof(struct acpica_device_id)) + string_area_size;
|
||||||
|
|
||||||
|
cid_list = ACPI_ALLOCATE_ZEROED(cid_list_size);
|
||||||
|
if (!cid_list) {
|
||||||
|
status = AE_NO_MEMORY;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Area for CID strings starts after the CID DEVICE_ID array */
|
||||||
|
|
||||||
|
next_id_string = ACPI_CAST_PTR(char, cid_list->ids) +
|
||||||
|
((acpi_size) count * sizeof(struct acpica_device_id));
|
||||||
|
|
||||||
|
/* Copy/convert the CIDs to the return buffer */
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (cid_objects[i]->common.type == ACPI_TYPE_INTEGER) {
|
||||||
|
|
||||||
|
/* Convert the Integer (EISAID) CID to a string */
|
||||||
|
|
||||||
|
acpi_ex_eisa_id_to_string(next_id_string,
|
||||||
|
cid_objects[i]->integer.
|
||||||
|
value);
|
||||||
|
length = ACPI_EISAID_STRING_SIZE;
|
||||||
|
} else { /* ACPI_TYPE_STRING */
|
||||||
|
|
||||||
|
/* Copy the String CID from the returned object */
|
||||||
|
|
||||||
|
acpi_ut_copy_id_string(next_id_string,
|
||||||
|
cid_objects[i]->string.pointer);
|
||||||
|
length = cid_objects[i]->string.length + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cid_list->ids[i].string = next_id_string;
|
||||||
|
cid_list->ids[i].length = length;
|
||||||
|
next_id_string += length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Finish the CID list */
|
||||||
|
|
||||||
|
cid_list->count = count;
|
||||||
|
cid_list->list_size = cid_list_size;
|
||||||
|
*return_cid_list = cid_list;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
/* On exit, we must delete the _CID return object */
|
||||||
|
|
||||||
|
acpi_ut_remove_reference(obj_desc);
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
@ -118,6 +118,34 @@ const char *acpi_ut_validate_exception(acpi_status status)
|
|||||||
return (ACPI_CAST_PTR(const char, exception));
|
return (ACPI_CAST_PTR(const char, exception));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* FUNCTION: acpi_ut_is_pci_root_bridge
|
||||||
|
*
|
||||||
|
* PARAMETERS: Id - The HID/CID in string format
|
||||||
|
*
|
||||||
|
* RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
|
||||||
|
*
|
||||||
|
* DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
u8 acpi_ut_is_pci_root_bridge(char *id)
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if this is a PCI root bridge.
|
||||||
|
* ACPI 3.0+: check for a PCI Express root also.
|
||||||
|
*/
|
||||||
|
if (!(ACPI_STRCMP(id,
|
||||||
|
PCI_ROOT_HID_STRING)) ||
|
||||||
|
!(ACPI_STRCMP(id, PCI_EXPRESS_ROOT_HID_STRING))) {
|
||||||
|
return (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* FUNCTION: acpi_ut_is_aml_table
|
* FUNCTION: acpi_ut_is_aml_table
|
||||||
|
@ -200,20 +200,17 @@ container_walk_namespace_cb(acpi_handle handle,
|
|||||||
u32 lvl, void *context, void **rv)
|
u32 lvl, void *context, void **rv)
|
||||||
{
|
{
|
||||||
char *hid = NULL;
|
char *hid = NULL;
|
||||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
|
||||||
struct acpi_device_info *info;
|
struct acpi_device_info *info;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
int *action = context;
|
int *action = context;
|
||||||
|
|
||||||
|
status = acpi_get_object_info(handle, &info);
|
||||||
status = acpi_get_object_info(handle, &buffer);
|
if (ACPI_FAILURE(status)) {
|
||||||
if (ACPI_FAILURE(status) || !buffer.pointer) {
|
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
info = buffer.pointer;
|
|
||||||
if (info->valid & ACPI_VALID_HID)
|
if (info->valid & ACPI_VALID_HID)
|
||||||
hid = info->hardware_id.value;
|
hid = info->hardware_id.string;
|
||||||
|
|
||||||
if (hid == NULL) {
|
if (hid == NULL) {
|
||||||
goto end;
|
goto end;
|
||||||
@ -240,7 +237,7 @@ container_walk_namespace_cb(acpi_handle handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
kfree(buffer.pointer);
|
kfree(info);
|
||||||
|
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
@ -231,18 +231,16 @@ static int is_ata(acpi_handle handle)
|
|||||||
static int is_battery(acpi_handle handle)
|
static int is_battery(acpi_handle handle)
|
||||||
{
|
{
|
||||||
struct acpi_device_info *info;
|
struct acpi_device_info *info;
|
||||||
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
|
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
|
||||||
if (!ACPI_SUCCESS(acpi_get_object_info(handle, &buffer)))
|
if (!ACPI_SUCCESS(acpi_get_object_info(handle, &info)))
|
||||||
return 0;
|
return 0;
|
||||||
info = buffer.pointer;
|
|
||||||
if (!(info->valid & ACPI_VALID_HID))
|
if (!(info->valid & ACPI_VALID_HID))
|
||||||
ret = 0;
|
ret = 0;
|
||||||
else
|
else
|
||||||
ret = !strcmp("PNP0C0A", info->hardware_id.value);
|
ret = !strcmp("PNP0C0A", info->hardware_id.string);
|
||||||
|
|
||||||
kfree(buffer.pointer);
|
kfree(info);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,15 +93,13 @@ do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv)
|
|||||||
{
|
{
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
struct acpi_device_info *info;
|
struct acpi_device_info *info;
|
||||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
|
||||||
struct acpi_find_child *find = context;
|
struct acpi_find_child *find = context;
|
||||||
|
|
||||||
status = acpi_get_object_info(handle, &buffer);
|
status = acpi_get_object_info(handle, &info);
|
||||||
if (ACPI_SUCCESS(status)) {
|
if (ACPI_SUCCESS(status)) {
|
||||||
info = buffer.pointer;
|
|
||||||
if (info->address == find->address)
|
if (info->address == find->address)
|
||||||
find->handle = handle;
|
find->handle = handle;
|
||||||
kfree(buffer.pointer);
|
kfree(info);
|
||||||
}
|
}
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
@ -60,13 +60,13 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (acpi_dev->flags.compatible_ids) {
|
if (acpi_dev->flags.compatible_ids) {
|
||||||
struct acpi_compatible_id_list *cid_list;
|
struct acpica_device_id_list *cid_list;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
cid_list = acpi_dev->pnp.cid_list;
|
cid_list = acpi_dev->pnp.cid_list;
|
||||||
for (i = 0; i < cid_list->count; i++) {
|
for (i = 0; i < cid_list->count; i++) {
|
||||||
count = snprintf(&modalias[len], size, "%s:",
|
count = snprintf(&modalias[len], size, "%s:",
|
||||||
cid_list->id[i].value);
|
cid_list->ids[i].string);
|
||||||
if (count < 0 || count >= size) {
|
if (count < 0 || count >= size) {
|
||||||
printk(KERN_ERR PREFIX "%s cid[%i] exceeds event buffer size",
|
printk(KERN_ERR PREFIX "%s cid[%i] exceeds event buffer size",
|
||||||
acpi_dev->pnp.device_name, i);
|
acpi_dev->pnp.device_name, i);
|
||||||
@ -287,14 +287,14 @@ int acpi_match_device_ids(struct acpi_device *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (device->flags.compatible_ids) {
|
if (device->flags.compatible_ids) {
|
||||||
struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
|
struct acpica_device_id_list *cid_list = device->pnp.cid_list;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (id = ids; id->id[0]; id++) {
|
for (id = ids; id->id[0]; id++) {
|
||||||
/* compare multiple _CID entries against driver ids */
|
/* compare multiple _CID entries against driver ids */
|
||||||
for (i = 0; i < cid_list->count; i++) {
|
for (i = 0; i < cid_list->count; i++) {
|
||||||
if (!strcmp((char*)id->id,
|
if (!strcmp((char*)id->id,
|
||||||
cid_list->id[i].value))
|
cid_list->ids[i].string))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -999,33 +999,89 @@ static int acpi_dock_match(struct acpi_device *device)
|
|||||||
return acpi_get_handle(device->handle, "_DCK", &tmp);
|
return acpi_get_handle(device->handle, "_DCK", &tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct acpica_device_id_list*
|
||||||
|
acpi_add_cid(
|
||||||
|
struct acpi_device_info *info,
|
||||||
|
struct acpica_device_id *new_cid)
|
||||||
|
{
|
||||||
|
struct acpica_device_id_list *cid;
|
||||||
|
char *next_id_string;
|
||||||
|
acpi_size cid_length;
|
||||||
|
acpi_size new_cid_length;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
|
||||||
|
/* Allocate new CID list with room for the new CID */
|
||||||
|
|
||||||
|
if (!new_cid)
|
||||||
|
new_cid_length = info->compatible_id_list.list_size;
|
||||||
|
else if (info->compatible_id_list.list_size)
|
||||||
|
new_cid_length = info->compatible_id_list.list_size +
|
||||||
|
new_cid->length + sizeof(struct acpica_device_id);
|
||||||
|
else
|
||||||
|
new_cid_length = sizeof(struct acpica_device_id_list) + new_cid->length;
|
||||||
|
|
||||||
|
cid = ACPI_ALLOCATE_ZEROED(new_cid_length);
|
||||||
|
if (!cid) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cid->list_size = new_cid_length;
|
||||||
|
cid->count = info->compatible_id_list.count;
|
||||||
|
if (new_cid)
|
||||||
|
cid->count++;
|
||||||
|
next_id_string = (char *) cid->ids + (cid->count * sizeof(struct acpica_device_id));
|
||||||
|
|
||||||
|
/* Copy all existing CIDs */
|
||||||
|
|
||||||
|
for (i = 0; i < info->compatible_id_list.count; i++) {
|
||||||
|
cid_length = info->compatible_id_list.ids[i].length;
|
||||||
|
cid->ids[i].string = next_id_string;
|
||||||
|
cid->ids[i].length = cid_length;
|
||||||
|
|
||||||
|
ACPI_MEMCPY(next_id_string, info->compatible_id_list.ids[i].string,
|
||||||
|
cid_length);
|
||||||
|
|
||||||
|
next_id_string += cid_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Append the new CID */
|
||||||
|
|
||||||
|
if (new_cid) {
|
||||||
|
cid->ids[i].string = next_id_string;
|
||||||
|
cid->ids[i].length = new_cid->length;
|
||||||
|
|
||||||
|
ACPI_MEMCPY(next_id_string, new_cid->string, new_cid->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cid;
|
||||||
|
}
|
||||||
|
|
||||||
static void acpi_device_set_id(struct acpi_device *device,
|
static void acpi_device_set_id(struct acpi_device *device,
|
||||||
struct acpi_device *parent, acpi_handle handle,
|
struct acpi_device *parent, acpi_handle handle,
|
||||||
int type)
|
int type)
|
||||||
{
|
{
|
||||||
struct acpi_device_info *info;
|
struct acpi_device_info *info = NULL;
|
||||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
|
||||||
char *hid = NULL;
|
char *hid = NULL;
|
||||||
char *uid = NULL;
|
char *uid = NULL;
|
||||||
struct acpi_compatible_id_list *cid_list = NULL;
|
struct acpica_device_id_list *cid_list = NULL;
|
||||||
const char *cid_add = NULL;
|
char *cid_add = NULL;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ACPI_BUS_TYPE_DEVICE:
|
case ACPI_BUS_TYPE_DEVICE:
|
||||||
status = acpi_get_object_info(handle, &buffer);
|
status = acpi_get_object_info(handle, &info);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__);
|
printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info = buffer.pointer;
|
|
||||||
if (info->valid & ACPI_VALID_HID)
|
if (info->valid & ACPI_VALID_HID)
|
||||||
hid = info->hardware_id.value;
|
hid = info->hardware_id.string;
|
||||||
if (info->valid & ACPI_VALID_UID)
|
if (info->valid & ACPI_VALID_UID)
|
||||||
uid = info->unique_id.value;
|
uid = info->unique_id.string;
|
||||||
if (info->valid & ACPI_VALID_CID)
|
if (info->valid & ACPI_VALID_CID)
|
||||||
cid_list = &info->compatibility_id;
|
cid_list = &info->compatible_id_list;
|
||||||
if (info->valid & ACPI_VALID_ADR) {
|
if (info->valid & ACPI_VALID_ADR) {
|
||||||
device->pnp.bus_address = info->address;
|
device->pnp.bus_address = info->address;
|
||||||
device->flags.bus_address = 1;
|
device->flags.bus_address = 1;
|
||||||
@ -1076,55 +1132,44 @@ static void acpi_device_set_id(struct acpi_device *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hid) {
|
if (hid) {
|
||||||
|
device->pnp.hardware_id = ACPI_ALLOCATE_ZEROED(strlen (hid) + 1);
|
||||||
|
if (device->pnp.hardware_id) {
|
||||||
strcpy(device->pnp.hardware_id, hid);
|
strcpy(device->pnp.hardware_id, hid);
|
||||||
device->flags.hardware_id = 1;
|
device->flags.hardware_id = 1;
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
device->pnp.hardware_id = NULL;
|
||||||
|
|
||||||
if (uid) {
|
if (uid) {
|
||||||
|
device->pnp.unique_id = ACPI_ALLOCATE_ZEROED(strlen (uid) + 1);
|
||||||
|
if (device->pnp.unique_id) {
|
||||||
strcpy(device->pnp.unique_id, uid);
|
strcpy(device->pnp.unique_id, uid);
|
||||||
device->flags.unique_id = 1;
|
device->flags.unique_id = 1;
|
||||||
}
|
}
|
||||||
if (cid_list || cid_add) {
|
} else
|
||||||
struct acpi_compatible_id_list *list;
|
device->pnp.unique_id = NULL;
|
||||||
int size = 0;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
if (cid_list) {
|
if (cid_list || cid_add) {
|
||||||
size = cid_list->size;
|
struct acpica_device_id_list *list;
|
||||||
} else if (cid_add) {
|
|
||||||
size = sizeof(struct acpi_compatible_id_list);
|
if (cid_add) {
|
||||||
cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size);
|
struct acpica_device_id cid;
|
||||||
if (!cid_list) {
|
cid.length = strlen (cid_add) + 1;
|
||||||
printk(KERN_ERR "Memory allocation error\n");
|
cid.string = cid_add;
|
||||||
kfree(buffer.pointer);
|
|
||||||
return;
|
list = acpi_add_cid(info, &cid);
|
||||||
} else {
|
} else {
|
||||||
cid_list->count = 0;
|
list = acpi_add_cid(info, NULL);
|
||||||
cid_list->size = size;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (cid_add)
|
|
||||||
size += sizeof(struct acpi_compatible_id);
|
|
||||||
list = kmalloc(size, GFP_KERNEL);
|
|
||||||
|
|
||||||
if (list) {
|
if (list) {
|
||||||
if (cid_list) {
|
device->pnp.cid_list = list;
|
||||||
memcpy(list, cid_list, cid_list->size);
|
if (cid_add)
|
||||||
count = cid_list->count;
|
|
||||||
}
|
|
||||||
if (cid_add) {
|
|
||||||
strncpy(list->id[count].value, cid_add,
|
|
||||||
ACPI_MAX_CID_LENGTH);
|
|
||||||
count++;
|
|
||||||
device->flags.compatible_ids = 1;
|
device->flags.compatible_ids = 1;
|
||||||
}
|
}
|
||||||
list->size = size;
|
|
||||||
list->count = count;
|
|
||||||
device->pnp.cid_list = list;
|
|
||||||
} else
|
|
||||||
printk(KERN_ERR PREFIX "Memory allocation error\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(buffer.pointer);
|
kfree(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int acpi_device_set_context(struct acpi_device *device, int type)
|
static int acpi_device_set_context(struct acpi_device *device, int type)
|
||||||
|
@ -478,7 +478,6 @@ zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret)
|
|||||||
{
|
{
|
||||||
acpi_handle handle, parent;
|
acpi_handle handle, parent;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
struct acpi_buffer buffer;
|
|
||||||
struct acpi_device_info *info;
|
struct acpi_device_info *info;
|
||||||
u64 lba_hpa, sba_hpa, length;
|
u64 lba_hpa, sba_hpa, length;
|
||||||
int match;
|
int match;
|
||||||
@ -490,13 +489,11 @@ zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret)
|
|||||||
/* Look for an enclosing IOC scope and find its CSR space */
|
/* Look for an enclosing IOC scope and find its CSR space */
|
||||||
handle = obj;
|
handle = obj;
|
||||||
do {
|
do {
|
||||||
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
|
status = acpi_get_object_info(handle, &info);
|
||||||
status = acpi_get_object_info(handle, &buffer);
|
|
||||||
if (ACPI_SUCCESS(status)) {
|
if (ACPI_SUCCESS(status)) {
|
||||||
/* TBD check _CID also */
|
/* TBD check _CID also */
|
||||||
info = buffer.pointer;
|
info->hardware_id.string[sizeof(info->hardware_id.length)-1] = '\0';
|
||||||
info->hardware_id.value[sizeof(info->hardware_id)-1] = '\0';
|
match = (strcmp(info->hardware_id.string, "HWP0001") == 0);
|
||||||
match = (strcmp(info->hardware_id.value, "HWP0001") == 0);
|
|
||||||
kfree(info);
|
kfree(info);
|
||||||
if (match) {
|
if (match) {
|
||||||
status = hp_acpi_csr_space(handle, &sba_hpa, &length);
|
status = hp_acpi_csr_space(handle, &sba_hpa, &length);
|
||||||
|
@ -114,8 +114,6 @@ static int ide_get_dev_handle(struct device *dev, acpi_handle *handle,
|
|||||||
unsigned int bus, devnum, func;
|
unsigned int bus, devnum, func;
|
||||||
acpi_integer addr;
|
acpi_integer addr;
|
||||||
acpi_handle dev_handle;
|
acpi_handle dev_handle;
|
||||||
struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER,
|
|
||||||
.pointer = NULL};
|
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
struct acpi_device_info *dinfo = NULL;
|
struct acpi_device_info *dinfo = NULL;
|
||||||
int ret = -ENODEV;
|
int ret = -ENODEV;
|
||||||
@ -134,12 +132,11 @@ static int ide_get_dev_handle(struct device *dev, acpi_handle *handle,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = acpi_get_object_info(dev_handle, &buffer);
|
status = acpi_get_object_info(dev_handle, &dinfo);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
DEBPRINT("get_object_info for device failed\n");
|
DEBPRINT("get_object_info for device failed\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
dinfo = buffer.pointer;
|
|
||||||
if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
|
if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
|
||||||
dinfo->address == addr) {
|
dinfo->address == addr) {
|
||||||
*pcidevfn = addr;
|
*pcidevfn = addr;
|
||||||
|
@ -398,23 +398,21 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle,
|
|||||||
acpi_handle *phandle = (acpi_handle *)context;
|
acpi_handle *phandle = (acpi_handle *)context;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
struct acpi_device_info *info;
|
struct acpi_device_info *info;
|
||||||
struct acpi_buffer info_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
status = acpi_get_object_info(handle, &info_buffer);
|
status = acpi_get_object_info(handle, &info);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
err("%s: Failed to get device information status=0x%x\n",
|
err("%s: Failed to get device information status=0x%x\n",
|
||||||
__func__, status);
|
__func__, status);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
info = info_buffer.pointer;
|
info->hardware_id.string[sizeof(info->hardware_id.length) - 1] = '\0';
|
||||||
info->hardware_id.value[sizeof(info->hardware_id.value) - 1] = '\0';
|
|
||||||
|
|
||||||
if (info->current_status && (info->valid & ACPI_VALID_HID) &&
|
if (info->current_status && (info->valid & ACPI_VALID_HID) &&
|
||||||
(!strcmp(info->hardware_id.value, IBM_HARDWARE_ID1) ||
|
(!strcmp(info->hardware_id.string, IBM_HARDWARE_ID1) ||
|
||||||
!strcmp(info->hardware_id.value, IBM_HARDWARE_ID2))) {
|
!strcmp(info->hardware_id.string, IBM_HARDWARE_ID2))) {
|
||||||
dbg("found hardware: %s, handle: %p\n",
|
dbg("found hardware: %s, handle: %p\n",
|
||||||
info->hardware_id.value, handle);
|
info->hardware_id.string, handle);
|
||||||
*phandle = handle;
|
*phandle = handle;
|
||||||
/* returning non-zero causes the search to stop
|
/* returning non-zero causes the search to stop
|
||||||
* and returns this value to the caller of
|
* and returns this value to the caller of
|
||||||
|
@ -976,15 +976,12 @@ static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
|
|||||||
void *context, void **return_value)
|
void *context, void **return_value)
|
||||||
{
|
{
|
||||||
struct acpi_device_info *info;
|
struct acpi_device_info *info;
|
||||||
struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
|
|
||||||
|
|
||||||
if (ACPI_SUCCESS(acpi_get_object_info(handle, &buffer))) {
|
|
||||||
info = buffer.pointer;
|
|
||||||
|
|
||||||
|
if (ACPI_SUCCESS(acpi_get_object_info(handle, &info))) {
|
||||||
printk(KERN_WARNING DRV_PFX "method: name: %4.4s, args %X\n",
|
printk(KERN_WARNING DRV_PFX "method: name: %4.4s, args %X\n",
|
||||||
(char *)&info->name, info->param_count);
|
(char *)&info->name, info->param_count);
|
||||||
|
|
||||||
kfree(buffer.pointer);
|
kfree(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
|
@ -194,13 +194,13 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
|
|||||||
pnpacpi_parse_resource_option_data(dev);
|
pnpacpi_parse_resource_option_data(dev);
|
||||||
|
|
||||||
if (device->flags.compatible_ids) {
|
if (device->flags.compatible_ids) {
|
||||||
struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
|
struct acpica_device_id_list *cid_list = device->pnp.cid_list;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < cid_list->count; i++) {
|
for (i = 0; i < cid_list->count; i++) {
|
||||||
if (!ispnpidacpi(cid_list->id[i].value))
|
if (!ispnpidacpi(cid_list->ids[i].string))
|
||||||
continue;
|
continue;
|
||||||
pnp_add_id(dev, cid_list->id[i].value);
|
pnp_add_id(dev, cid_list->ids[i].string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,17 +173,15 @@ struct acpi_device_dir {
|
|||||||
|
|
||||||
typedef char acpi_bus_id[8];
|
typedef char acpi_bus_id[8];
|
||||||
typedef unsigned long acpi_bus_address;
|
typedef unsigned long acpi_bus_address;
|
||||||
typedef char acpi_hardware_id[15];
|
|
||||||
typedef char acpi_unique_id[9];
|
|
||||||
typedef char acpi_device_name[40];
|
typedef char acpi_device_name[40];
|
||||||
typedef char acpi_device_class[20];
|
typedef char acpi_device_class[20];
|
||||||
|
|
||||||
struct acpi_device_pnp {
|
struct acpi_device_pnp {
|
||||||
acpi_bus_id bus_id; /* Object name */
|
acpi_bus_id bus_id; /* Object name */
|
||||||
acpi_bus_address bus_address; /* _ADR */
|
acpi_bus_address bus_address; /* _ADR */
|
||||||
acpi_hardware_id hardware_id; /* _HID */
|
char *hardware_id; /* _HID */
|
||||||
struct acpi_compatible_id_list *cid_list; /* _CIDs */
|
struct acpica_device_id_list *cid_list; /* _CIDs */
|
||||||
acpi_unique_id unique_id; /* _UID */
|
char *unique_id; /* _UID */
|
||||||
acpi_device_name device_name; /* Driver-determined */
|
acpi_device_name device_name; /* Driver-determined */
|
||||||
acpi_device_class device_class; /* " */
|
acpi_device_class device_class; /* " */
|
||||||
};
|
};
|
||||||
|
@ -200,7 +200,8 @@ acpi_evaluate_object_typed(acpi_handle object,
|
|||||||
acpi_object_type return_type);
|
acpi_object_type return_type);
|
||||||
|
|
||||||
acpi_status
|
acpi_status
|
||||||
acpi_get_object_info(acpi_handle handle, struct acpi_buffer *return_buffer);
|
acpi_get_object_info(acpi_handle handle,
|
||||||
|
struct acpi_device_info **return_buffer);
|
||||||
|
|
||||||
acpi_status acpi_install_method(u8 *buffer);
|
acpi_status acpi_install_method(u8 *buffer);
|
||||||
|
|
||||||
|
@ -969,38 +969,60 @@ acpi_status(*acpi_walk_callback) (acpi_handle obj_handle,
|
|||||||
#define ACPI_INTERRUPT_NOT_HANDLED 0x00
|
#define ACPI_INTERRUPT_NOT_HANDLED 0x00
|
||||||
#define ACPI_INTERRUPT_HANDLED 0x01
|
#define ACPI_INTERRUPT_HANDLED 0x01
|
||||||
|
|
||||||
/* Length of _HID, _UID, _CID, and UUID values */
|
/* Length of 32-bit EISAID values when converted back to a string */
|
||||||
|
|
||||||
|
#define ACPI_EISAID_STRING_SIZE 8 /* Includes null terminator */
|
||||||
|
|
||||||
|
/* Length of UUID (string) values */
|
||||||
|
|
||||||
#define ACPI_DEVICE_ID_LENGTH 0x09
|
|
||||||
#define ACPI_MAX_CID_LENGTH 48
|
|
||||||
#define ACPI_UUID_LENGTH 16
|
#define ACPI_UUID_LENGTH 16
|
||||||
|
|
||||||
/* Common string version of device HIDs and UIDs */
|
/* Structures used for device/processor HID, UID, CID */
|
||||||
|
|
||||||
struct acpica_device_id {
|
struct acpica_device_id {
|
||||||
char value[ACPI_DEVICE_ID_LENGTH];
|
u32 length; /* Length of string + null */
|
||||||
|
char *string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Common string version of device CIDs */
|
struct acpica_device_id_list {
|
||||||
|
u32 count; /* Number of IDs in Ids array */
|
||||||
struct acpi_compatible_id {
|
u32 list_size; /* Size of list, including ID strings */
|
||||||
char value[ACPI_MAX_CID_LENGTH];
|
struct acpica_device_id ids[1]; /* ID array */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct acpi_compatible_id_list {
|
/*
|
||||||
u32 count;
|
* Structure returned from acpi_get_object_info.
|
||||||
u32 size;
|
* Optimized for both 32- and 64-bit builds
|
||||||
struct acpi_compatible_id id[1];
|
*/
|
||||||
|
struct acpi_device_info {
|
||||||
|
u32 info_size; /* Size of info, including ID strings */
|
||||||
|
u32 name; /* ACPI object Name */
|
||||||
|
acpi_object_type type; /* ACPI object Type */
|
||||||
|
u8 param_count; /* If a method, required parameter count */
|
||||||
|
u8 valid; /* Indicates which optional fields are valid */
|
||||||
|
u8 flags; /* Miscellaneous info */
|
||||||
|
u8 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */
|
||||||
|
u8 lowest_dstates[5]; /* _sx_w values: 0xFF indicates not valid */
|
||||||
|
u32 current_status; /* _STA value */
|
||||||
|
acpi_integer address; /* _ADR value */
|
||||||
|
struct acpica_device_id hardware_id; /* _HID value */
|
||||||
|
struct acpica_device_id unique_id; /* _UID value */
|
||||||
|
struct acpica_device_id_list compatible_id_list; /* _CID list <must be last> */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Structure and flags for acpi_get_object_info */
|
/* Values for Flags field above (acpi_get_object_info) */
|
||||||
|
|
||||||
#define ACPI_VALID_STA 0x0001
|
#define ACPI_PCI_ROOT_BRIDGE 0x01
|
||||||
#define ACPI_VALID_ADR 0x0002
|
|
||||||
#define ACPI_VALID_HID 0x0004
|
/* Flags for Valid field above (acpi_get_object_info) */
|
||||||
#define ACPI_VALID_UID 0x0008
|
|
||||||
#define ACPI_VALID_CID 0x0010
|
#define ACPI_VALID_STA 0x01
|
||||||
#define ACPI_VALID_SXDS 0x0020
|
#define ACPI_VALID_ADR 0x02
|
||||||
|
#define ACPI_VALID_HID 0x04
|
||||||
|
#define ACPI_VALID_UID 0x08
|
||||||
|
#define ACPI_VALID_CID 0x10
|
||||||
|
#define ACPI_VALID_SXDS 0x20
|
||||||
|
#define ACPI_VALID_SXWS 0x40
|
||||||
|
|
||||||
/* Flags for _STA method */
|
/* Flags for _STA method */
|
||||||
|
|
||||||
@ -1011,29 +1033,6 @@ struct acpi_compatible_id_list {
|
|||||||
#define ACPI_STA_DEVICE_OK 0x08 /* Synonym */
|
#define ACPI_STA_DEVICE_OK 0x08 /* Synonym */
|
||||||
#define ACPI_STA_BATTERY_PRESENT 0x10
|
#define ACPI_STA_BATTERY_PRESENT 0x10
|
||||||
|
|
||||||
#define ACPI_COMMON_OBJ_INFO \
|
|
||||||
acpi_object_type type; /* ACPI object type */ \
|
|
||||||
acpi_name name /* ACPI object Name */
|
|
||||||
|
|
||||||
struct acpi_obj_info_header {
|
|
||||||
ACPI_COMMON_OBJ_INFO;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Structure returned from Get Object Info */
|
|
||||||
|
|
||||||
struct acpi_device_info {
|
|
||||||
ACPI_COMMON_OBJ_INFO;
|
|
||||||
|
|
||||||
u32 param_count; /* If a method, required parameter count */
|
|
||||||
u32 valid; /* Indicates which fields below are valid */
|
|
||||||
u32 current_status; /* _STA value */
|
|
||||||
acpi_integer address; /* _ADR value if any */
|
|
||||||
struct acpica_device_id hardware_id; /* _HID value if any */
|
|
||||||
struct acpica_device_id unique_id; /* _UID value if any */
|
|
||||||
u8 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */
|
|
||||||
struct acpi_compatible_id_list compatibility_id; /* List of _CIDs if any */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Context structs for address space handlers */
|
/* Context structs for address space handlers */
|
||||||
|
|
||||||
struct acpi_pci_id {
|
struct acpi_pci_id {
|
||||||
|
Loading…
Reference in New Issue
Block a user