diff options
author | Bob Moore <robert.moore@intel.com> | 2009-06-29 01:39:29 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-08-27 10:17:15 -0400 |
commit | 15b8dd53f5ffaf8e2d9095c423f713423f576c0f (patch) | |
tree | 773f09435b14a810372642502352d46c29b6f148 /drivers/acpi/acpica | |
parent | 9c61b34cf7078da72cce276ff8cfae5d6e9955bc (diff) |
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>
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r-- | drivers/acpi/acpica/Makefile | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/acconfig.h | 5 | ||||
-rw-r--r-- | drivers/acpi/acpica/acglobal.h | 3 | ||||
-rw-r--r-- | drivers/acpi/acpica/acinterp.h | 4 | ||||
-rw-r--r-- | drivers/acpi/acpica/acutils.h | 24 | ||||
-rw-r--r-- | drivers/acpi/acpica/evrgnini.c | 45 | ||||
-rw-r--r-- | drivers/acpi/acpica/exutils.c | 53 | ||||
-rw-r--r-- | drivers/acpi/acpica/nsdumpdv.c | 7 | ||||
-rw-r--r-- | drivers/acpi/acpica/nsxfeval.c | 23 | ||||
-rw-r--r-- | drivers/acpi/acpica/nsxfname.c | 237 | ||||
-rw-r--r-- | drivers/acpi/acpica/uteval.c | 375 | ||||
-rw-r--r-- | drivers/acpi/acpica/utglobal.c | 10 | ||||
-rw-r--r-- | drivers/acpi/acpica/utids.c | 382 | ||||
-rw-r--r-- | drivers/acpi/acpica/utmisc.c | 28 |
14 files changed, 725 insertions, 473 deletions
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 72ac28da14e3..0e7d56185f6d 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -44,4 +44,4 @@ acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o | |||
44 | 44 | ||
45 | acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ | 45 | acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ |
46 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ | 46 | utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ |
47 | utstate.o utmutex.o utobject.o utresrc.o utlock.o | 47 | utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o |
diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index e6777fb883d2..6c1fb2d9f4d5 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h | |||
@@ -203,6 +203,11 @@ | |||
203 | 203 | ||
204 | #define ACPI_SMBUS_BUFFER_SIZE 34 | 204 | #define ACPI_SMBUS_BUFFER_SIZE 34 |
205 | 205 | ||
206 | /* _sx_d and _sx_w control methods */ | ||
207 | |||
208 | #define ACPI_NUM_sx_d_METHODS 4 | ||
209 | #define ACPI_NUM_sx_w_METHODS 5 | ||
210 | |||
206 | /****************************************************************************** | 211 | /****************************************************************************** |
207 | * | 212 | * |
208 | * ACPI AML Debugger | 213 | * ACPI AML Debugger |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 0b73b31c1b53..6389f7c1de59 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -265,7 +265,8 @@ ACPI_EXTERN u8 acpi_gbl_osi_data; | |||
265 | extern u8 acpi_gbl_shutdown; | 265 | extern u8 acpi_gbl_shutdown; |
266 | extern u32 acpi_gbl_startup_flags; | 266 | extern u32 acpi_gbl_startup_flags; |
267 | extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT]; | 267 | extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT]; |
268 | extern const char *acpi_gbl_highest_dstate_names[4]; | 268 | extern const char *acpi_gbl_lowest_dstate_names[ACPI_NUM_sx_w_METHODS]; |
269 | extern const char *acpi_gbl_highest_dstate_names[ACPI_NUM_sx_d_METHODS]; | ||
269 | extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; | 270 | extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; |
270 | extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; | 271 | extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; |
271 | 272 | ||
diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index e8db7a3143a5..5db9f2916f7c 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h | |||
@@ -461,9 +461,9 @@ void acpi_ex_acquire_global_lock(u32 rule); | |||
461 | 461 | ||
462 | void acpi_ex_release_global_lock(u32 rule); | 462 | void acpi_ex_release_global_lock(u32 rule); |
463 | 463 | ||
464 | void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string); | 464 | void acpi_ex_eisa_id_to_string(char *dest, acpi_integer compressed_id); |
465 | 465 | ||
466 | void acpi_ex_unsigned_integer_to_string(acpi_integer value, char *out_string); | 466 | void acpi_ex_integer_to_string(char *dest, acpi_integer value); |
467 | 467 | ||
468 | /* | 468 | /* |
469 | * exregion - default op_region handlers | 469 | * exregion - default op_region handlers |
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 897810ba0ccc..b0add85de308 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
@@ -324,26 +324,30 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
324 | acpi_status | 324 | acpi_status |
325 | acpi_ut_evaluate_numeric_object(char *object_name, | 325 | acpi_ut_evaluate_numeric_object(char *object_name, |
326 | struct acpi_namespace_node *device_node, | 326 | struct acpi_namespace_node *device_node, |
327 | acpi_integer * address); | 327 | acpi_integer *value); |
328 | 328 | ||
329 | acpi_status | 329 | acpi_status |
330 | acpi_ut_execute_HID(struct acpi_namespace_node *device_node, | 330 | acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 *status_flags); |
331 | struct acpica_device_id *hid); | ||
332 | 331 | ||
333 | acpi_status | 332 | acpi_status |
334 | acpi_ut_execute_CID(struct acpi_namespace_node *device_node, | 333 | acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, |
335 | struct acpi_compatible_id_list **return_cid_list); | 334 | const char **method_names, |
335 | u8 method_count, u8 *out_values); | ||
336 | 336 | ||
337 | /* | ||
338 | * utids - device ID support | ||
339 | */ | ||
337 | acpi_status | 340 | acpi_status |
338 | acpi_ut_execute_STA(struct acpi_namespace_node *device_node, | 341 | acpi_ut_execute_HID(struct acpi_namespace_node *device_node, |
339 | u32 * status_flags); | 342 | struct acpica_device_id **return_id); |
340 | 343 | ||
341 | acpi_status | 344 | acpi_status |
342 | acpi_ut_execute_UID(struct acpi_namespace_node *device_node, | 345 | acpi_ut_execute_UID(struct acpi_namespace_node *device_node, |
343 | struct acpica_device_id *uid); | 346 | struct acpica_device_id **return_id); |
344 | 347 | ||
345 | acpi_status | 348 | acpi_status |
346 | acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest); | 349 | acpi_ut_execute_CID(struct acpi_namespace_node *device_node, |
350 | struct acpica_device_id_list **return_cid_list); | ||
347 | 351 | ||
348 | /* | 352 | /* |
349 | * utlock - reader/writer locks | 353 | * utlock - reader/writer locks |
@@ -445,6 +449,8 @@ acpi_ut_short_divide(acpi_integer in_dividend, | |||
445 | */ | 449 | */ |
446 | const char *acpi_ut_validate_exception(acpi_status status); | 450 | const char *acpi_ut_validate_exception(acpi_status status); |
447 | 451 | ||
452 | u8 acpi_ut_is_pci_root_bridge(char *id); | ||
453 | |||
448 | u8 acpi_ut_is_aml_table(struct acpi_table_header *table); | 454 | u8 acpi_ut_is_aml_table(struct acpi_table_header *table); |
449 | 455 | ||
450 | acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id); | 456 | acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id); |
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 284a7becbe96..cf29c4953028 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c | |||
@@ -50,8 +50,6 @@ | |||
50 | ACPI_MODULE_NAME("evrgnini") | 50 | ACPI_MODULE_NAME("evrgnini") |
51 | 51 | ||
52 | /* Local prototypes */ | 52 | /* Local prototypes */ |
53 | static u8 acpi_ev_match_pci_root_bridge(char *id); | ||
54 | |||
55 | static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node); | 53 | static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node); |
56 | 54 | ||
57 | /******************************************************************************* | 55 | /******************************************************************************* |
@@ -332,37 +330,6 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, | |||
332 | 330 | ||
333 | /******************************************************************************* | 331 | /******************************************************************************* |
334 | * | 332 | * |
335 | * FUNCTION: acpi_ev_match_pci_root_bridge | ||
336 | * | ||
337 | * PARAMETERS: Id - The HID/CID in string format | ||
338 | * | ||
339 | * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge | ||
340 | * | ||
341 | * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. | ||
342 | * | ||
343 | ******************************************************************************/ | ||
344 | |||
345 | static u8 acpi_ev_match_pci_root_bridge(char *id) | ||
346 | { | ||
347 | |||
348 | /* | ||
349 | * Check if this is a PCI root. | ||
350 | * ACPI 3.0+: check for a PCI Express root also. | ||
351 | */ | ||
352 | if (!(ACPI_STRNCMP(id, | ||
353 | PCI_ROOT_HID_STRING, | ||
354 | sizeof(PCI_ROOT_HID_STRING))) || | ||
355 | !(ACPI_STRNCMP(id, | ||
356 | PCI_EXPRESS_ROOT_HID_STRING, | ||
357 | sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) { | ||
358 | return (TRUE); | ||
359 | } | ||
360 | |||
361 | return (FALSE); | ||
362 | } | ||
363 | |||
364 | /******************************************************************************* | ||
365 | * | ||
366 | * FUNCTION: acpi_ev_is_pci_root_bridge | 333 | * FUNCTION: acpi_ev_is_pci_root_bridge |
367 | * | 334 | * |
368 | * PARAMETERS: Node - Device node being examined | 335 | * PARAMETERS: Node - Device node being examined |
@@ -377,9 +344,10 @@ static u8 acpi_ev_match_pci_root_bridge(char *id) | |||
377 | static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) | 344 | static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) |
378 | { | 345 | { |
379 | acpi_status status; | 346 | acpi_status status; |
380 | struct acpica_device_id hid; | 347 | struct acpica_device_id *hid; |
381 | struct acpi_compatible_id_list *cid; | 348 | struct acpica_device_id_list *cid; |
382 | u32 i; | 349 | u32 i; |
350 | u8 match; | ||
383 | 351 | ||
384 | /* Get the _HID and check for a PCI Root Bridge */ | 352 | /* Get the _HID and check for a PCI Root Bridge */ |
385 | 353 | ||
@@ -388,7 +356,10 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) | |||
388 | return (FALSE); | 356 | return (FALSE); |
389 | } | 357 | } |
390 | 358 | ||
391 | if (acpi_ev_match_pci_root_bridge(hid.value)) { | 359 | match = acpi_ut_is_pci_root_bridge(hid->string); |
360 | ACPI_FREE(hid); | ||
361 | |||
362 | if (match) { | ||
392 | return (TRUE); | 363 | return (TRUE); |
393 | } | 364 | } |
394 | 365 | ||
@@ -402,7 +373,7 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) | |||
402 | /* Check all _CIDs in the returned list */ | 373 | /* Check all _CIDs in the returned list */ |
403 | 374 | ||
404 | for (i = 0; i < cid->count; i++) { | 375 | for (i = 0; i < cid->count; i++) { |
405 | if (acpi_ev_match_pci_root_bridge(cid->id[i].value)) { | 376 | if (acpi_ut_is_pci_root_bridge(cid->ids[i].string)) { |
406 | ACPI_FREE(cid); | 377 | ACPI_FREE(cid); |
407 | return (TRUE); | 378 | return (TRUE); |
408 | } | 379 | } |
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 87730e944132..7d41f99f7052 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c | |||
@@ -358,50 +358,67 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base) | |||
358 | * | 358 | * |
359 | * FUNCTION: acpi_ex_eisa_id_to_string | 359 | * FUNCTION: acpi_ex_eisa_id_to_string |
360 | * | 360 | * |
361 | * PARAMETERS: numeric_id - EISA ID to be converted | 361 | * PARAMETERS: compressed_id - EISAID to be converted |
362 | * out_string - Where to put the converted string (8 bytes) | 362 | * out_string - Where to put the converted string (8 bytes) |
363 | * | 363 | * |
364 | * RETURN: None | 364 | * RETURN: None |
365 | * | 365 | * |
366 | * DESCRIPTION: Convert a numeric EISA ID to string representation | 366 | * DESCRIPTION: Convert a numeric EISAID to string representation. Return |
367 | * buffer must be large enough to hold the string. The string | ||
368 | * returned is always exactly of length ACPI_EISAID_STRING_SIZE | ||
369 | * (includes null terminator). The EISAID is always 32 bits. | ||
367 | * | 370 | * |
368 | ******************************************************************************/ | 371 | ******************************************************************************/ |
369 | 372 | ||
370 | void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string) | 373 | void acpi_ex_eisa_id_to_string(char *out_string, acpi_integer compressed_id) |
371 | { | 374 | { |
372 | u32 eisa_id; | 375 | u32 swapped_id; |
373 | 376 | ||
374 | ACPI_FUNCTION_ENTRY(); | 377 | ACPI_FUNCTION_ENTRY(); |
375 | 378 | ||
379 | /* The EISAID should be a 32-bit integer */ | ||
380 | |||
381 | if (compressed_id > ACPI_UINT32_MAX) { | ||
382 | ACPI_WARNING((AE_INFO, | ||
383 | "Expected EISAID is larger than 32 bits: 0x%8.8X%8.8X, truncating", | ||
384 | ACPI_FORMAT_UINT64(compressed_id))); | ||
385 | } | ||
386 | |||
376 | /* Swap ID to big-endian to get contiguous bits */ | 387 | /* Swap ID to big-endian to get contiguous bits */ |
377 | 388 | ||
378 | eisa_id = acpi_ut_dword_byte_swap(numeric_id); | 389 | swapped_id = acpi_ut_dword_byte_swap((u32)compressed_id); |
379 | 390 | ||
380 | out_string[0] = (char)('@' + (((unsigned long)eisa_id >> 26) & 0x1f)); | 391 | /* First 3 bytes are uppercase letters. Next 4 bytes are hexadecimal */ |
381 | out_string[1] = (char)('@' + ((eisa_id >> 21) & 0x1f)); | 392 | |
382 | out_string[2] = (char)('@' + ((eisa_id >> 16) & 0x1f)); | 393 | out_string[0] = |
383 | out_string[3] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 12); | 394 | (char)(0x40 + (((unsigned long)swapped_id >> 26) & 0x1F)); |
384 | out_string[4] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 8); | 395 | out_string[1] = (char)(0x40 + ((swapped_id >> 21) & 0x1F)); |
385 | out_string[5] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 4); | 396 | out_string[2] = (char)(0x40 + ((swapped_id >> 16) & 0x1F)); |
386 | out_string[6] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 0); | 397 | out_string[3] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 12); |
398 | out_string[4] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 8); | ||
399 | out_string[5] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 4); | ||
400 | out_string[6] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 0); | ||
387 | out_string[7] = 0; | 401 | out_string[7] = 0; |
388 | } | 402 | } |
389 | 403 | ||
390 | /******************************************************************************* | 404 | /******************************************************************************* |
391 | * | 405 | * |
392 | * FUNCTION: acpi_ex_unsigned_integer_to_string | 406 | * FUNCTION: acpi_ex_integer_to_string |
393 | * | 407 | * |
394 | * PARAMETERS: Value - Value to be converted | 408 | * PARAMETERS: out_string - Where to put the converted string. At least |
395 | * out_string - Where to put the converted string (8 bytes) | 409 | * 21 bytes are needed to hold the largest |
410 | * possible 64-bit integer. | ||
411 | * Value - Value to be converted | ||
396 | * | 412 | * |
397 | * RETURN: None, string | 413 | * RETURN: None, string |
398 | * | 414 | * |
399 | * DESCRIPTION: Convert a number to string representation. Assumes string | 415 | * DESCRIPTION: Convert a 64-bit integer to decimal string representation. |
400 | * buffer is large enough to hold the string. | 416 | * Assumes string buffer is large enough to hold the string. The |
417 | * largest string is (ACPI_MAX64_DECIMAL_DIGITS + 1). | ||
401 | * | 418 | * |
402 | ******************************************************************************/ | 419 | ******************************************************************************/ |
403 | 420 | ||
404 | void acpi_ex_unsigned_integer_to_string(acpi_integer value, char *out_string) | 421 | void acpi_ex_integer_to_string(char *out_string, acpi_integer value) |
405 | { | 422 | { |
406 | u32 count; | 423 | u32 count; |
407 | u32 digits_needed; | 424 | u32 digits_needed; |
diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c index 41994fe7fbb8..0fe87f1aef16 100644 --- a/drivers/acpi/acpica/nsdumpdv.c +++ b/drivers/acpi/acpica/nsdumpdv.c | |||
@@ -70,7 +70,6 @@ static acpi_status | |||
70 | acpi_ns_dump_one_device(acpi_handle obj_handle, | 70 | acpi_ns_dump_one_device(acpi_handle obj_handle, |
71 | u32 level, void *context, void **return_value) | 71 | u32 level, void *context, void **return_value) |
72 | { | 72 | { |
73 | struct acpi_buffer buffer; | ||
74 | struct acpi_device_info *info; | 73 | struct acpi_device_info *info; |
75 | acpi_status status; | 74 | acpi_status status; |
76 | u32 i; | 75 | u32 i; |
@@ -80,17 +79,15 @@ acpi_ns_dump_one_device(acpi_handle obj_handle, | |||
80 | status = | 79 | status = |
81 | acpi_ns_dump_one_object(obj_handle, level, context, return_value); | 80 | acpi_ns_dump_one_object(obj_handle, level, context, return_value); |
82 | 81 | ||
83 | buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | 82 | status = acpi_get_object_info(obj_handle, &info); |
84 | status = acpi_get_object_info(obj_handle, &buffer); | ||
85 | if (ACPI_SUCCESS(status)) { | 83 | if (ACPI_SUCCESS(status)) { |
86 | info = buffer.pointer; | ||
87 | for (i = 0; i < level; i++) { | 84 | for (i = 0; i < level; i++) { |
88 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, " ")); | 85 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, " ")); |
89 | } | 86 | } |
90 | 87 | ||
91 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, | 88 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, |
92 | " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", | 89 | " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", |
93 | info->hardware_id.value, | 90 | info->hardware_id.string, |
94 | ACPI_FORMAT_UINT64(info->address), | 91 | ACPI_FORMAT_UINT64(info->address), |
95 | info->current_status)); | 92 | info->current_status)); |
96 | ACPI_FREE(info); | 93 | ACPI_FREE(info); |
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index daf4ad37896d..4929dbdbc8f0 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c | |||
@@ -535,10 +535,11 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, | |||
535 | acpi_status status; | 535 | acpi_status status; |
536 | struct acpi_namespace_node *node; | 536 | struct acpi_namespace_node *node; |
537 | u32 flags; | 537 | u32 flags; |
538 | struct acpica_device_id hid; | 538 | struct acpica_device_id *hid; |
539 | struct acpi_compatible_id_list *cid; | 539 | struct acpica_device_id_list *cid; |
540 | u32 i; | 540 | u32 i; |
541 | int found; | 541 | u8 found; |
542 | int no_match; | ||
542 | 543 | ||
543 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 544 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
544 | if (ACPI_FAILURE(status)) { | 545 | if (ACPI_FAILURE(status)) { |
@@ -582,10 +583,14 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, | |||
582 | return (AE_CTRL_DEPTH); | 583 | return (AE_CTRL_DEPTH); |
583 | } | 584 | } |
584 | 585 | ||
585 | if (ACPI_STRNCMP(hid.value, info->hid, sizeof(hid.value)) != 0) { | 586 | no_match = ACPI_STRCMP(hid->string, info->hid); |
586 | 587 | ACPI_FREE(hid); | |
587 | /* Get the list of Compatible IDs */ | ||
588 | 588 | ||
589 | if (no_match) { | ||
590 | /* | ||
591 | * HID does not match, attempt match within the | ||
592 | * list of Compatible IDs (CIDs) | ||
593 | */ | ||
589 | status = acpi_ut_execute_CID(node, &cid); | 594 | status = acpi_ut_execute_CID(node, &cid); |
590 | if (status == AE_NOT_FOUND) { | 595 | if (status == AE_NOT_FOUND) { |
591 | return (AE_OK); | 596 | return (AE_OK); |
@@ -597,10 +602,8 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, | |||
597 | 602 | ||
598 | found = 0; | 603 | found = 0; |
599 | for (i = 0; i < cid->count; i++) { | 604 | for (i = 0; i < cid->count; i++) { |
600 | if (ACPI_STRNCMP(cid->id[i].value, info->hid, | 605 | if (ACPI_STRCMP(cid->ids[i].string, info->hid) |
601 | sizeof(struct | 606 | == 0) { |
602 | acpi_compatible_id)) == | ||
603 | 0) { | ||
604 | found = 1; | 607 | found = 1; |
605 | break; | 608 | break; |
606 | } | 609 | } |
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index f23593d6add4..ddc84af6336e 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c | |||
@@ -51,6 +51,11 @@ | |||
51 | #define _COMPONENT ACPI_NAMESPACE | 51 | #define _COMPONENT ACPI_NAMESPACE |
52 | ACPI_MODULE_NAME("nsxfname") | 52 | ACPI_MODULE_NAME("nsxfname") |
53 | 53 | ||
54 | /* Local prototypes */ | ||
55 | static char *acpi_ns_copy_device_id(struct acpica_device_id *dest, | ||
56 | struct acpica_device_id *source, | ||
57 | char *string_area); | ||
58 | |||
54 | /****************************************************************************** | 59 | /****************************************************************************** |
55 | * | 60 | * |
56 | * FUNCTION: acpi_get_handle | 61 | * FUNCTION: acpi_get_handle |
@@ -68,6 +73,7 @@ ACPI_MODULE_NAME("nsxfname") | |||
68 | * namespace handle. | 73 | * namespace handle. |
69 | * | 74 | * |
70 | ******************************************************************************/ | 75 | ******************************************************************************/ |
76 | |||
71 | acpi_status | 77 | acpi_status |
72 | acpi_get_handle(acpi_handle parent, | 78 | acpi_get_handle(acpi_handle parent, |
73 | acpi_string pathname, acpi_handle * ret_handle) | 79 | acpi_string pathname, acpi_handle * ret_handle) |
@@ -210,10 +216,38 @@ ACPI_EXPORT_SYMBOL(acpi_get_name) | |||
210 | 216 | ||
211 | /****************************************************************************** | 217 | /****************************************************************************** |
212 | * | 218 | * |
219 | * FUNCTION: acpi_ns_copy_device_id | ||
220 | * | ||
221 | * PARAMETERS: Dest - Pointer to the destination DEVICE_ID | ||
222 | * Source - Pointer to the source DEVICE_ID | ||
223 | * string_area - Pointer to where to copy the dest string | ||
224 | * | ||
225 | * RETURN: Pointer to the next string area | ||
226 | * | ||
227 | * DESCRIPTION: Copy a single DEVICE_ID, including the string data. | ||
228 | * | ||
229 | ******************************************************************************/ | ||
230 | static char *acpi_ns_copy_device_id(struct acpica_device_id *dest, | ||
231 | struct acpica_device_id *source, | ||
232 | char *string_area) | ||
233 | { | ||
234 | /* Create the destination DEVICE_ID */ | ||
235 | |||
236 | dest->string = string_area; | ||
237 | dest->length = source->length; | ||
238 | |||
239 | /* Copy actual string and return a pointer to the next string area */ | ||
240 | |||
241 | ACPI_MEMCPY(string_area, source->string, source->length); | ||
242 | return (string_area + source->length); | ||
243 | } | ||
244 | |||
245 | /****************************************************************************** | ||
246 | * | ||
213 | * FUNCTION: acpi_get_object_info | 247 | * FUNCTION: acpi_get_object_info |
214 | * | 248 | * |
215 | * PARAMETERS: Handle - Object Handle | 249 | * PARAMETERS: Handle - Object Handle |
216 | * Buffer - Where the info is returned | 250 | * return_buffer - Where the info is returned |
217 | * | 251 | * |
218 | * RETURN: Status | 252 | * RETURN: Status |
219 | * | 253 | * |
@@ -221,33 +255,37 @@ ACPI_EXPORT_SYMBOL(acpi_get_name) | |||
221 | * namespace node and possibly by running several standard | 255 | * namespace node and possibly by running several standard |
222 | * control methods (Such as in the case of a device.) | 256 | * control methods (Such as in the case of a device.) |
223 | * | 257 | * |
258 | * For Device and Processor objects, run the Device _HID, _UID, _CID, _STA, | ||
259 | * _ADR, _sx_w, and _sx_d methods. | ||
260 | * | ||
261 | * Note: Allocates the return buffer, must be freed by the caller. | ||
262 | * | ||
224 | ******************************************************************************/ | 263 | ******************************************************************************/ |
264 | |||
225 | acpi_status | 265 | acpi_status |
226 | acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | 266 | acpi_get_object_info(acpi_handle handle, |
267 | struct acpi_device_info **return_buffer) | ||
227 | { | 268 | { |
228 | acpi_status status; | ||
229 | struct acpi_namespace_node *node; | 269 | struct acpi_namespace_node *node; |
230 | struct acpi_device_info *info; | 270 | struct acpi_device_info *info; |
231 | struct acpi_device_info *return_info; | 271 | struct acpica_device_id_list *cid_list = NULL; |
232 | struct acpi_compatible_id_list *cid_list = NULL; | 272 | struct acpica_device_id *hid = NULL; |
233 | acpi_size size; | 273 | struct acpica_device_id *uid = NULL; |
274 | char *next_id_string; | ||
275 | acpi_object_type type; | ||
276 | acpi_name name; | ||
277 | u8 param_count = 0; | ||
278 | u8 valid = 0; | ||
279 | u32 info_size; | ||
280 | u32 i; | ||
281 | acpi_status status; | ||
234 | 282 | ||
235 | /* Parameter validation */ | 283 | /* Parameter validation */ |
236 | 284 | ||
237 | if (!handle || !buffer) { | 285 | if (!handle || !return_buffer) { |
238 | return (AE_BAD_PARAMETER); | 286 | return (AE_BAD_PARAMETER); |
239 | } | 287 | } |
240 | 288 | ||
241 | status = acpi_ut_validate_buffer(buffer); | ||
242 | if (ACPI_FAILURE(status)) { | ||
243 | return (status); | ||
244 | } | ||
245 | |||
246 | info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_device_info)); | ||
247 | if (!info) { | ||
248 | return (AE_NO_MEMORY); | ||
249 | } | ||
250 | |||
251 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | 289 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); |
252 | if (ACPI_FAILURE(status)) { | 290 | if (ACPI_FAILURE(status)) { |
253 | goto cleanup; | 291 | goto cleanup; |
@@ -256,66 +294,91 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | |||
256 | node = acpi_ns_map_handle_to_node(handle); | 294 | node = acpi_ns_map_handle_to_node(handle); |
257 | if (!node) { | 295 | if (!node) { |
258 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 296 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
259 | status = AE_BAD_PARAMETER; | 297 | return (AE_BAD_PARAMETER); |
260 | goto cleanup; | ||
261 | } | 298 | } |
262 | 299 | ||
263 | /* Init return structure */ | 300 | /* Get the namespace node data while the namespace is locked */ |
264 | |||
265 | size = sizeof(struct acpi_device_info); | ||
266 | 301 | ||
267 | info->type = node->type; | 302 | info_size = sizeof(struct acpi_device_info); |
268 | info->name = node->name.integer; | 303 | type = node->type; |
269 | info->valid = 0; | 304 | name = node->name.integer; |
270 | 305 | ||
271 | if (node->type == ACPI_TYPE_METHOD) { | 306 | if (node->type == ACPI_TYPE_METHOD) { |
272 | info->param_count = node->object->method.param_count; | 307 | param_count = node->object->method.param_count; |
273 | } | 308 | } |
274 | 309 | ||
275 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | 310 | status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); |
276 | if (ACPI_FAILURE(status)) { | 311 | if (ACPI_FAILURE(status)) { |
277 | goto cleanup; | 312 | return (status); |
278 | } | 313 | } |
279 | 314 | ||
280 | /* If not a device, we are all done */ | 315 | if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) { |
281 | |||
282 | if (info->type == ACPI_TYPE_DEVICE) { | ||
283 | /* | 316 | /* |
284 | * Get extra info for ACPI Devices objects only: | 317 | * Get extra info for ACPI Device/Processor objects only: |
285 | * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods. | 318 | * Run the Device _HID, _UID, and _CID methods. |
286 | * | 319 | * |
287 | * Note: none of these methods are required, so they may or may | 320 | * Note: none of these methods are required, so they may or may |
288 | * not be present for this device. The Info->Valid bitfield is used | 321 | * not be present for this device. The Info->Valid bitfield is used |
289 | * to indicate which methods were found and ran successfully. | 322 | * to indicate which methods were found and run successfully. |
290 | */ | 323 | */ |
291 | 324 | ||
292 | /* Execute the Device._HID method */ | 325 | /* Execute the Device._HID method */ |
293 | 326 | ||
294 | status = acpi_ut_execute_HID(node, &info->hardware_id); | 327 | status = acpi_ut_execute_HID(node, &hid); |
295 | if (ACPI_SUCCESS(status)) { | 328 | if (ACPI_SUCCESS(status)) { |
296 | info->valid |= ACPI_VALID_HID; | 329 | info_size += hid->length; |
330 | valid |= ACPI_VALID_HID; | ||
297 | } | 331 | } |
298 | 332 | ||
299 | /* Execute the Device._UID method */ | 333 | /* Execute the Device._UID method */ |
300 | 334 | ||
301 | status = acpi_ut_execute_UID(node, &info->unique_id); | 335 | status = acpi_ut_execute_UID(node, &uid); |
302 | if (ACPI_SUCCESS(status)) { | 336 | if (ACPI_SUCCESS(status)) { |
303 | info->valid |= ACPI_VALID_UID; | 337 | info_size += uid->length; |
338 | valid |= ACPI_VALID_UID; | ||
304 | } | 339 | } |
305 | 340 | ||
306 | /* Execute the Device._CID method */ | 341 | /* Execute the Device._CID method */ |
307 | 342 | ||
308 | status = acpi_ut_execute_CID(node, &cid_list); | 343 | status = acpi_ut_execute_CID(node, &cid_list); |
309 | if (ACPI_SUCCESS(status)) { | 344 | if (ACPI_SUCCESS(status)) { |
310 | size += cid_list->size; | 345 | |
311 | info->valid |= ACPI_VALID_CID; | 346 | /* Add size of CID strings and CID pointer array */ |
347 | |||
348 | info_size += | ||
349 | (cid_list->list_size - | ||
350 | sizeof(struct acpica_device_id_list)); | ||
351 | valid |= ACPI_VALID_CID; | ||
312 | } | 352 | } |
353 | } | ||
354 | |||
355 | /* | ||
356 | * Now that we have the variable-length data, we can allocate the | ||
357 | * return buffer | ||
358 | */ | ||
359 | info = ACPI_ALLOCATE_ZEROED(info_size); | ||
360 | if (!info) { | ||
361 | status = AE_NO_MEMORY; | ||
362 | goto cleanup; | ||
363 | } | ||
364 | |||
365 | /* Get the fixed-length data */ | ||
366 | |||
367 | if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) { | ||
368 | /* | ||
369 | * Get extra info for ACPI Device/Processor objects only: | ||
370 | * Run the _STA, _ADR and, sx_w, and _sx_d methods. | ||
371 | * | ||
372 | * Note: none of these methods are required, so they may or may | ||
373 | * not be present for this device. The Info->Valid bitfield is used | ||
374 | * to indicate which methods were found and run successfully. | ||
375 | */ | ||
313 | 376 | ||
314 | /* Execute the Device._STA method */ | 377 | /* Execute the Device._STA method */ |
315 | 378 | ||
316 | status = acpi_ut_execute_STA(node, &info->current_status); | 379 | status = acpi_ut_execute_STA(node, &info->current_status); |
317 | if (ACPI_SUCCESS(status)) { | 380 | if (ACPI_SUCCESS(status)) { |
318 | info->valid |= ACPI_VALID_STA; | 381 | valid |= ACPI_VALID_STA; |
319 | } | 382 | } |
320 | 383 | ||
321 | /* Execute the Device._ADR method */ | 384 | /* Execute the Device._ADR method */ |
@@ -323,36 +386,100 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) | |||
323 | status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node, | 386 | status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node, |
324 | &info->address); | 387 | &info->address); |
325 | if (ACPI_SUCCESS(status)) { | 388 | if (ACPI_SUCCESS(status)) { |
326 | info->valid |= ACPI_VALID_ADR; | 389 | valid |= ACPI_VALID_ADR; |
390 | } | ||
391 | |||
392 | /* Execute the Device._sx_w methods */ | ||
393 | |||
394 | status = acpi_ut_execute_power_methods(node, | ||
395 | acpi_gbl_lowest_dstate_names, | ||
396 | ACPI_NUM_sx_w_METHODS, | ||
397 | info->lowest_dstates); | ||
398 | if (ACPI_SUCCESS(status)) { | ||
399 | valid |= ACPI_VALID_SXWS; | ||
327 | } | 400 | } |
328 | 401 | ||
329 | /* Execute the Device._sx_d methods */ | 402 | /* Execute the Device._sx_d methods */ |
330 | 403 | ||
331 | status = acpi_ut_execute_sxds(node, info->highest_dstates); | 404 | status = acpi_ut_execute_power_methods(node, |
405 | acpi_gbl_highest_dstate_names, | ||
406 | ACPI_NUM_sx_d_METHODS, | ||
407 | info->highest_dstates); | ||
332 | if (ACPI_SUCCESS(status)) { | 408 | if (ACPI_SUCCESS(status)) { |
333 | info->valid |= ACPI_VALID_SXDS; | 409 | valid |= ACPI_VALID_SXDS; |
334 | } | 410 | } |
335 | } | 411 | } |
336 | 412 | ||
337 | /* Validate/Allocate/Clear caller buffer */ | 413 | /* |
414 | * Create a pointer to the string area of the return buffer. | ||
415 | * Point to the end of the base struct acpi_device_info structure. | ||
416 | */ | ||
417 | next_id_string = ACPI_CAST_PTR(char, info->compatible_id_list.ids); | ||
418 | if (cid_list) { | ||
338 | 419 | ||
339 | status = acpi_ut_initialize_buffer(buffer, size); | 420 | /* Point past the CID DEVICE_ID array */ |
340 | if (ACPI_FAILURE(status)) { | 421 | |
341 | goto cleanup; | 422 | next_id_string += |
423 | ((acpi_size) cid_list->count * | ||
424 | sizeof(struct acpica_device_id)); | ||
342 | } | 425 | } |
343 | 426 | ||
344 | /* Populate the return buffer */ | 427 | /* |
428 | * Copy the HID, UID, and CIDs to the return buffer. The variable-length | ||
429 | * strings are copied to the reserved area at the end of the buffer. | ||
430 | * | ||
431 | * For HID and CID, check if the ID is a PCI Root Bridge. | ||
432 | */ | ||
433 | if (hid) { | ||
434 | next_id_string = acpi_ns_copy_device_id(&info->hardware_id, | ||
435 | hid, next_id_string); | ||
436 | |||
437 | if (acpi_ut_is_pci_root_bridge(hid->string)) { | ||
438 | info->flags |= ACPI_PCI_ROOT_BRIDGE; | ||
439 | } | ||
440 | } | ||
345 | 441 | ||
346 | return_info = buffer->pointer; | 442 | if (uid) { |
347 | ACPI_MEMCPY(return_info, info, sizeof(struct acpi_device_info)); | 443 | next_id_string = acpi_ns_copy_device_id(&info->unique_id, |
444 | uid, next_id_string); | ||
445 | } | ||
348 | 446 | ||
349 | if (cid_list) { | 447 | if (cid_list) { |
350 | ACPI_MEMCPY(&return_info->compatibility_id, cid_list, | 448 | info->compatible_id_list.count = cid_list->count; |
351 | cid_list->size); | 449 | info->compatible_id_list.list_size = cid_list->list_size; |
450 | |||
451 | /* Copy each CID */ | ||
452 | |||
453 | for (i = 0; i < cid_list->count; i++) { | ||
454 | next_id_string = | ||
455 | acpi_ns_copy_device_id(&info->compatible_id_list. | ||
456 | ids[i], &cid_list->ids[i], | ||
457 | next_id_string); | ||
458 | |||
459 | if (acpi_ut_is_pci_root_bridge(cid_list->ids[i].string)) { | ||
460 | info->flags |= ACPI_PCI_ROOT_BRIDGE; | ||
461 | } | ||
462 | } | ||
352 | } | 463 | } |
353 | 464 | ||
465 | /* Copy the fixed-length data */ | ||
466 | |||
467 | info->info_size = info_size; | ||
468 | info->type = type; | ||
469 | info->name = name; | ||
470 | info->param_count = param_count; | ||
471 | info->valid = valid; | ||
472 | |||
473 | *return_buffer = info; | ||
474 | status = AE_OK; | ||
475 | |||
354 | cleanup: | 476 | cleanup: |
355 | ACPI_FREE(info); | 477 | if (hid) { |
478 | ACPI_FREE(hid); | ||
479 | } | ||
480 | if (uid) { | ||
481 | ACPI_FREE(uid); | ||
482 | } | ||
356 | if (cid_list) { | 483 | if (cid_list) { |
357 | ACPI_FREE(cid_list); | 484 | ACPI_FREE(cid_list); |
358 | } | 485 | } |
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 006b16c26017..5503307b8bb7 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c | |||
@@ -44,19 +44,10 @@ | |||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acnamesp.h" | 46 | #include "acnamesp.h" |
47 | #include "acinterp.h" | ||
48 | 47 | ||
49 | #define _COMPONENT ACPI_UTILITIES | 48 | #define _COMPONENT ACPI_UTILITIES |
50 | ACPI_MODULE_NAME("uteval") | 49 | ACPI_MODULE_NAME("uteval") |
51 | 50 | ||
52 | /* Local prototypes */ | ||
53 | static void | ||
54 | acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length); | ||
55 | |||
56 | static acpi_status | ||
57 | acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, | ||
58 | struct acpi_compatible_id *one_cid); | ||
59 | |||
60 | /* | 51 | /* |
61 | * Strings supported by the _OSI predefined (internal) method. | 52 | * Strings supported by the _OSI predefined (internal) method. |
62 | * | 53 | * |
@@ -213,7 +204,7 @@ acpi_status acpi_osi_invalidate(char *interface) | |||
213 | * RETURN: Status | 204 | * RETURN: Status |
214 | * | 205 | * |
215 | * DESCRIPTION: Evaluates a namespace object and verifies the type of the | 206 | * DESCRIPTION: Evaluates a namespace object and verifies the type of the |
216 | * return object. Common code that simplifies accessing objects | 207 | * return object. Common code that simplifies accessing objects |
217 | * that have required return objects of fixed types. | 208 | * that have required return objects of fixed types. |
218 | * | 209 | * |
219 | * NOTE: Internal function, no parameter validation | 210 | * NOTE: Internal function, no parameter validation |
@@ -298,7 +289,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
298 | 289 | ||
299 | if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { | 290 | if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { |
300 | /* | 291 | /* |
301 | * We received a return object, but one was not expected. This can | 292 | * We received a return object, but one was not expected. This can |
302 | * happen frequently if the "implicit return" feature is enabled. | 293 | * happen frequently if the "implicit return" feature is enabled. |
303 | * Just delete the return object and return AE_OK. | 294 | * Just delete the return object and return AE_OK. |
304 | */ | 295 | */ |
@@ -340,12 +331,12 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
340 | * | 331 | * |
341 | * PARAMETERS: object_name - Object name to be evaluated | 332 | * PARAMETERS: object_name - Object name to be evaluated |
342 | * device_node - Node for the device | 333 | * device_node - Node for the device |
343 | * Address - Where the value is returned | 334 | * Value - Where the value is returned |
344 | * | 335 | * |
345 | * RETURN: Status | 336 | * RETURN: Status |
346 | * | 337 | * |
347 | * DESCRIPTION: Evaluates a numeric namespace object for a selected device | 338 | * DESCRIPTION: Evaluates a numeric namespace object for a selected device |
348 | * and stores result in *Address. | 339 | * and stores result in *Value. |
349 | * | 340 | * |
350 | * NOTE: Internal function, no parameter validation | 341 | * NOTE: Internal function, no parameter validation |
351 | * | 342 | * |
@@ -354,7 +345,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, | |||
354 | acpi_status | 345 | acpi_status |
355 | acpi_ut_evaluate_numeric_object(char *object_name, | 346 | acpi_ut_evaluate_numeric_object(char *object_name, |
356 | struct acpi_namespace_node *device_node, | 347 | struct acpi_namespace_node *device_node, |
357 | acpi_integer * address) | 348 | acpi_integer *value) |
358 | { | 349 | { |
359 | union acpi_operand_object *obj_desc; | 350 | union acpi_operand_object *obj_desc; |
360 | acpi_status status; | 351 | acpi_status status; |
@@ -369,295 +360,7 @@ acpi_ut_evaluate_numeric_object(char *object_name, | |||
369 | 360 | ||
370 | /* Get the returned Integer */ | 361 | /* Get the returned Integer */ |
371 | 362 | ||
372 | *address = obj_desc->integer.value; | 363 | *value = obj_desc->integer.value; |
373 | |||
374 | /* On exit, we must delete the return object */ | ||
375 | |||
376 | acpi_ut_remove_reference(obj_desc); | ||
377 | return_ACPI_STATUS(status); | ||
378 | } | ||
379 | |||
380 | /******************************************************************************* | ||
381 | * | ||
382 | * FUNCTION: acpi_ut_copy_id_string | ||
383 | * | ||
384 | * PARAMETERS: Destination - Where to copy the string | ||
385 | * Source - Source string | ||
386 | * max_length - Length of the destination buffer | ||
387 | * | ||
388 | * RETURN: None | ||
389 | * | ||
390 | * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. | ||
391 | * Performs removal of a leading asterisk if present -- workaround | ||
392 | * for a known issue on a bunch of machines. | ||
393 | * | ||
394 | ******************************************************************************/ | ||
395 | |||
396 | static void | ||
397 | acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length) | ||
398 | { | ||
399 | |||
400 | /* | ||
401 | * Workaround for ID strings that have a leading asterisk. This construct | ||
402 | * is not allowed by the ACPI specification (ID strings must be | ||
403 | * alphanumeric), but enough existing machines have this embedded in their | ||
404 | * ID strings that the following code is useful. | ||
405 | */ | ||
406 | if (*source == '*') { | ||
407 | source++; | ||
408 | } | ||
409 | |||
410 | /* Do the actual copy */ | ||
411 | |||
412 | ACPI_STRNCPY(destination, source, max_length); | ||
413 | } | ||
414 | |||
415 | /******************************************************************************* | ||
416 | * | ||
417 | * FUNCTION: acpi_ut_execute_HID | ||
418 | * | ||
419 | * PARAMETERS: device_node - Node for the device | ||
420 | * Hid - Where the HID is returned | ||
421 | * | ||
422 | * RETURN: Status | ||
423 | * | ||
424 | * DESCRIPTION: Executes the _HID control method that returns the hardware | ||
425 | * ID of the device. | ||
426 | * | ||
427 | * NOTE: Internal function, no parameter validation | ||
428 | * | ||
429 | ******************************************************************************/ | ||
430 | |||
431 | acpi_status | ||
432 | acpi_ut_execute_HID(struct acpi_namespace_node *device_node, | ||
433 | struct acpica_device_id *hid) | ||
434 | { | ||
435 | union acpi_operand_object *obj_desc; | ||
436 | acpi_status status; | ||
437 | |||
438 | ACPI_FUNCTION_TRACE(ut_execute_HID); | ||
439 | |||
440 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID, | ||
441 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | ||
442 | &obj_desc); | ||
443 | if (ACPI_FAILURE(status)) { | ||
444 | return_ACPI_STATUS(status); | ||
445 | } | ||
446 | |||
447 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
448 | |||
449 | /* Convert the Numeric HID to string */ | ||
450 | |||
451 | acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, | ||
452 | hid->value); | ||
453 | } else { | ||
454 | /* Copy the String HID from the returned object */ | ||
455 | |||
456 | acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer, | ||
457 | sizeof(hid->value)); | ||
458 | } | ||
459 | |||
460 | /* On exit, we must delete the return object */ | ||
461 | |||
462 | acpi_ut_remove_reference(obj_desc); | ||
463 | return_ACPI_STATUS(status); | ||
464 | } | ||
465 | |||
466 | /******************************************************************************* | ||
467 | * | ||
468 | * FUNCTION: acpi_ut_translate_one_cid | ||
469 | * | ||
470 | * PARAMETERS: obj_desc - _CID object, must be integer or string | ||
471 | * one_cid - Where the CID string is returned | ||
472 | * | ||
473 | * RETURN: Status | ||
474 | * | ||
475 | * DESCRIPTION: Return a numeric or string _CID value as a string. | ||
476 | * (Compatible ID) | ||
477 | * | ||
478 | * NOTE: Assumes a maximum _CID string length of | ||
479 | * ACPI_MAX_CID_LENGTH. | ||
480 | * | ||
481 | ******************************************************************************/ | ||
482 | |||
483 | static acpi_status | ||
484 | acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, | ||
485 | struct acpi_compatible_id *one_cid) | ||
486 | { | ||
487 | |||
488 | switch (obj_desc->common.type) { | ||
489 | case ACPI_TYPE_INTEGER: | ||
490 | |||
491 | /* Convert the Numeric CID to string */ | ||
492 | |||
493 | acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, | ||
494 | one_cid->value); | ||
495 | return (AE_OK); | ||
496 | |||
497 | case ACPI_TYPE_STRING: | ||
498 | |||
499 | if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) { | ||
500 | return (AE_AML_STRING_LIMIT); | ||
501 | } | ||
502 | |||
503 | /* Copy the String CID from the returned object */ | ||
504 | |||
505 | acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer, | ||
506 | ACPI_MAX_CID_LENGTH); | ||
507 | return (AE_OK); | ||
508 | |||
509 | default: | ||
510 | |||
511 | return (AE_TYPE); | ||
512 | } | ||
513 | } | ||
514 | |||
515 | /******************************************************************************* | ||
516 | * | ||
517 | * FUNCTION: acpi_ut_execute_CID | ||
518 | * | ||
519 | * PARAMETERS: device_node - Node for the device | ||
520 | * return_cid_list - Where the CID list is returned | ||
521 | * | ||
522 | * RETURN: Status | ||
523 | * | ||
524 | * DESCRIPTION: Executes the _CID control method that returns one or more | ||
525 | * compatible hardware IDs for the device. | ||
526 | * | ||
527 | * NOTE: Internal function, no parameter validation | ||
528 | * | ||
529 | ******************************************************************************/ | ||
530 | |||
531 | acpi_status | ||
532 | acpi_ut_execute_CID(struct acpi_namespace_node * device_node, | ||
533 | struct acpi_compatible_id_list ** return_cid_list) | ||
534 | { | ||
535 | union acpi_operand_object *obj_desc; | ||
536 | acpi_status status; | ||
537 | u32 count; | ||
538 | u32 size; | ||
539 | struct acpi_compatible_id_list *cid_list; | ||
540 | u32 i; | ||
541 | |||
542 | ACPI_FUNCTION_TRACE(ut_execute_CID); | ||
543 | |||
544 | /* Evaluate the _CID method for this device */ | ||
545 | |||
546 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID, | ||
547 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ||
548 | | ACPI_BTYPE_PACKAGE, &obj_desc); | ||
549 | if (ACPI_FAILURE(status)) { | ||
550 | return_ACPI_STATUS(status); | ||
551 | } | ||
552 | |||
553 | /* Get the number of _CIDs returned */ | ||
554 | |||
555 | count = 1; | ||
556 | if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { | ||
557 | count = obj_desc->package.count; | ||
558 | } | ||
559 | |||
560 | /* Allocate a worst-case buffer for the _CIDs */ | ||
561 | |||
562 | size = (((count - 1) * sizeof(struct acpi_compatible_id)) + | ||
563 | sizeof(struct acpi_compatible_id_list)); | ||
564 | |||
565 | cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); | ||
566 | if (!cid_list) { | ||
567 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
568 | } | ||
569 | |||
570 | /* Init CID list */ | ||
571 | |||
572 | cid_list->count = count; | ||
573 | cid_list->size = size; | ||
574 | |||
575 | /* | ||
576 | * A _CID can return either a single compatible ID or a package of | ||
577 | * compatible IDs. Each compatible ID can be one of the following: | ||
578 | * 1) Integer (32 bit compressed EISA ID) or | ||
579 | * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss") | ||
580 | */ | ||
581 | |||
582 | /* The _CID object can be either a single CID or a package (list) of CIDs */ | ||
583 | |||
584 | if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { | ||
585 | |||
586 | /* Translate each package element */ | ||
587 | |||
588 | for (i = 0; i < count; i++) { | ||
589 | status = | ||
590 | acpi_ut_translate_one_cid(obj_desc->package. | ||
591 | elements[i], | ||
592 | &cid_list->id[i]); | ||
593 | if (ACPI_FAILURE(status)) { | ||
594 | break; | ||
595 | } | ||
596 | } | ||
597 | } else { | ||
598 | /* Only one CID, translate to a string */ | ||
599 | |||
600 | status = acpi_ut_translate_one_cid(obj_desc, cid_list->id); | ||
601 | } | ||
602 | |||
603 | /* Cleanup on error */ | ||
604 | |||
605 | if (ACPI_FAILURE(status)) { | ||
606 | ACPI_FREE(cid_list); | ||
607 | } else { | ||
608 | *return_cid_list = cid_list; | ||
609 | } | ||
610 | |||
611 | /* On exit, we must delete the _CID return object */ | ||
612 | |||
613 | acpi_ut_remove_reference(obj_desc); | ||
614 | return_ACPI_STATUS(status); | ||
615 | } | ||
616 | |||
617 | /******************************************************************************* | ||
618 | * | ||
619 | * FUNCTION: acpi_ut_execute_UID | ||
620 | * | ||
621 | * PARAMETERS: device_node - Node for the device | ||
622 | * Uid - Where the UID is returned | ||
623 | * | ||
624 | * RETURN: Status | ||
625 | * | ||
626 | * DESCRIPTION: Executes the _UID control method that returns the hardware | ||
627 | * ID of the device. | ||
628 | * | ||
629 | * NOTE: Internal function, no parameter validation | ||
630 | * | ||
631 | ******************************************************************************/ | ||
632 | |||
633 | acpi_status | ||
634 | acpi_ut_execute_UID(struct acpi_namespace_node *device_node, | ||
635 | struct acpica_device_id *uid) | ||
636 | { | ||
637 | union acpi_operand_object *obj_desc; | ||
638 | acpi_status status; | ||
639 | |||
640 | ACPI_FUNCTION_TRACE(ut_execute_UID); | ||
641 | |||
642 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID, | ||
643 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | ||
644 | &obj_desc); | ||
645 | if (ACPI_FAILURE(status)) { | ||
646 | return_ACPI_STATUS(status); | ||
647 | } | ||
648 | |||
649 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
650 | |||
651 | /* Convert the Numeric UID to string */ | ||
652 | |||
653 | acpi_ex_unsigned_integer_to_string(obj_desc->integer.value, | ||
654 | uid->value); | ||
655 | } else { | ||
656 | /* Copy the String UID from the returned object */ | ||
657 | |||
658 | acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer, | ||
659 | sizeof(uid->value)); | ||
660 | } | ||
661 | 364 | ||
662 | /* On exit, we must delete the return object */ | 365 | /* On exit, we must delete the return object */ |
663 | 366 | ||
@@ -716,60 +419,64 @@ acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) | |||
716 | 419 | ||
717 | /******************************************************************************* | 420 | /******************************************************************************* |
718 | * | 421 | * |
719 | * FUNCTION: acpi_ut_execute_Sxds | 422 | * FUNCTION: acpi_ut_execute_power_methods |
720 | * | 423 | * |
721 | * PARAMETERS: device_node - Node for the device | 424 | * PARAMETERS: device_node - Node for the device |
722 | * Flags - Where the status flags are returned | 425 | * method_names - Array of power method names |
426 | * method_count - Number of methods to execute | ||
427 | * out_values - Where the power method values are returned | ||
723 | * | 428 | * |
724 | * RETURN: Status | 429 | * RETURN: Status, out_values |
725 | * | 430 | * |
726 | * DESCRIPTION: Executes _STA for selected device and stores results in | 431 | * DESCRIPTION: Executes the specified power methods for the device and returns |
727 | * *Flags. | 432 | * the result(s). |
728 | * | 433 | * |
729 | * NOTE: Internal function, no parameter validation | 434 | * NOTE: Internal function, no parameter validation |
730 | * | 435 | * |
731 | ******************************************************************************/ | 436 | ******************************************************************************/ |
732 | 437 | ||
733 | acpi_status | 438 | acpi_status |
734 | acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest) | 439 | acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, |
440 | const char **method_names, | ||
441 | u8 method_count, u8 *out_values) | ||
735 | { | 442 | { |
736 | union acpi_operand_object *obj_desc; | 443 | union acpi_operand_object *obj_desc; |
737 | acpi_status status; | 444 | acpi_status status; |
445 | acpi_status final_status = AE_NOT_FOUND; | ||
738 | u32 i; | 446 | u32 i; |
739 | 447 | ||
740 | ACPI_FUNCTION_TRACE(ut_execute_sxds); | 448 | ACPI_FUNCTION_TRACE(ut_execute_power_methods); |
741 | 449 | ||
742 | for (i = 0; i < 4; i++) { | 450 | for (i = 0; i < method_count; i++) { |
743 | highest[i] = 0xFF; | 451 | /* |
452 | * Execute the power method (_sx_d or _sx_w). The only allowable | ||
453 | * return type is an Integer. | ||
454 | */ | ||
744 | status = acpi_ut_evaluate_object(device_node, | 455 | status = acpi_ut_evaluate_object(device_node, |
745 | ACPI_CAST_PTR(char, | 456 | ACPI_CAST_PTR(char, |
746 | acpi_gbl_highest_dstate_names | 457 | method_names[i]), |
747 | [i]), | ||
748 | ACPI_BTYPE_INTEGER, &obj_desc); | 458 | ACPI_BTYPE_INTEGER, &obj_desc); |
749 | if (ACPI_FAILURE(status)) { | 459 | if (ACPI_SUCCESS(status)) { |
750 | if (status != AE_NOT_FOUND) { | 460 | out_values[i] = (u8)obj_desc->integer.value; |
751 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
752 | "%s on Device %4.4s, %s\n", | ||
753 | ACPI_CAST_PTR(char, | ||
754 | acpi_gbl_highest_dstate_names | ||
755 | [i]), | ||
756 | acpi_ut_get_node_name | ||
757 | (device_node), | ||
758 | acpi_format_exception | ||
759 | (status))); | ||
760 | |||
761 | return_ACPI_STATUS(status); | ||
762 | } | ||
763 | } else { | ||
764 | /* Extract the Dstate value */ | ||
765 | |||
766 | highest[i] = (u8) obj_desc->integer.value; | ||
767 | 461 | ||
768 | /* Delete the return object */ | 462 | /* Delete the return object */ |
769 | 463 | ||
770 | acpi_ut_remove_reference(obj_desc); | 464 | acpi_ut_remove_reference(obj_desc); |
465 | final_status = AE_OK; /* At least one value is valid */ | ||
466 | continue; | ||
771 | } | 467 | } |
468 | |||
469 | out_values[i] = ACPI_UINT8_MAX; | ||
470 | if (status == AE_NOT_FOUND) { | ||
471 | continue; /* Ignore if not found */ | ||
472 | } | ||
473 | |||
474 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
475 | "Failed %s on Device %4.4s, %s\n", | ||
476 | ACPI_CAST_PTR(char, method_names[i]), | ||
477 | acpi_ut_get_node_name(device_node), | ||
478 | acpi_format_exception(status))); | ||
772 | } | 479 | } |
773 | 480 | ||
774 | return_ACPI_STATUS(AE_OK); | 481 | return_ACPI_STATUS(final_status); |
775 | } | 482 | } |
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 59e46f257c02..ed7a33c67fbe 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -90,7 +90,15 @@ const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { | |||
90 | "\\_S5_" | 90 | "\\_S5_" |
91 | }; | 91 | }; |
92 | 92 | ||
93 | const char *acpi_gbl_highest_dstate_names[4] = { | 93 | const char *acpi_gbl_lowest_dstate_names[ACPI_NUM_sx_w_METHODS] = { |
94 | "_S0W", | ||
95 | "_S1W", | ||
96 | "_S2W", | ||
97 | "_S3W", | ||
98 | "_S4W" | ||
99 | }; | ||
100 | |||
101 | const char *acpi_gbl_highest_dstate_names[ACPI_NUM_sx_d_METHODS] = { | ||
94 | "_S1D", | 102 | "_S1D", |
95 | "_S2D", | 103 | "_S2D", |
96 | "_S3D", | 104 | "_S3D", |
diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c new file mode 100644 index 000000000000..52eaae404554 --- /dev/null +++ b/drivers/acpi/acpica/utids.c | |||
@@ -0,0 +1,382 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: utids - support for device IDs - HID, UID, CID | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2009, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acinterp.h" | ||
47 | |||
48 | #define _COMPONENT ACPI_UTILITIES | ||
49 | ACPI_MODULE_NAME("utids") | ||
50 | |||
51 | /* Local prototypes */ | ||
52 | static void acpi_ut_copy_id_string(char *destination, char *source); | ||
53 | |||
54 | /******************************************************************************* | ||
55 | * | ||
56 | * FUNCTION: acpi_ut_copy_id_string | ||
57 | * | ||
58 | * PARAMETERS: Destination - Where to copy the string | ||
59 | * Source - Source string | ||
60 | * | ||
61 | * RETURN: None | ||
62 | * | ||
63 | * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. | ||
64 | * Performs removal of a leading asterisk if present -- workaround | ||
65 | * for a known issue on a bunch of machines. | ||
66 | * | ||
67 | ******************************************************************************/ | ||
68 | |||
69 | static void acpi_ut_copy_id_string(char *destination, char *source) | ||
70 | { | ||
71 | |||
72 | /* | ||
73 | * Workaround for ID strings that have a leading asterisk. This construct | ||
74 | * is not allowed by the ACPI specification (ID strings must be | ||
75 | * alphanumeric), but enough existing machines have this embedded in their | ||
76 | * ID strings that the following code is useful. | ||
77 | */ | ||
78 | if (*source == '*') { | ||
79 | source++; | ||
80 | } | ||
81 | |||
82 | /* Do the actual copy */ | ||
83 | |||
84 | ACPI_STRCPY(destination, source); | ||
85 | } | ||
86 | |||
87 | /******************************************************************************* | ||
88 | * | ||
89 | * FUNCTION: acpi_ut_execute_HID | ||
90 | * | ||
91 | * PARAMETERS: device_node - Node for the device | ||
92 | * return_id - Where the string HID is returned | ||
93 | * | ||
94 | * RETURN: Status | ||
95 | * | ||
96 | * DESCRIPTION: Executes the _HID control method that returns the hardware | ||
97 | * ID of the device. The HID is either an 32-bit encoded EISAID | ||
98 | * Integer or a String. A string is always returned. An EISAID | ||
99 | * is converted to a string. | ||
100 | * | ||
101 | * NOTE: Internal function, no parameter validation | ||
102 | * | ||
103 | ******************************************************************************/ | ||
104 | |||
105 | acpi_status | ||
106 | acpi_ut_execute_HID(struct acpi_namespace_node *device_node, | ||
107 | struct acpica_device_id **return_id) | ||
108 | { | ||
109 | union acpi_operand_object *obj_desc; | ||
110 | struct acpica_device_id *hid; | ||
111 | u32 length; | ||
112 | acpi_status status; | ||
113 | |||
114 | ACPI_FUNCTION_TRACE(ut_execute_HID); | ||
115 | |||
116 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID, | ||
117 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | ||
118 | &obj_desc); | ||
119 | if (ACPI_FAILURE(status)) { | ||
120 | return_ACPI_STATUS(status); | ||
121 | } | ||
122 | |||
123 | /* Get the size of the String to be returned, includes null terminator */ | ||
124 | |||
125 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
126 | length = ACPI_EISAID_STRING_SIZE; | ||
127 | } else { | ||
128 | length = obj_desc->string.length + 1; | ||
129 | } | ||
130 | |||
131 | /* Allocate a buffer for the HID */ | ||
132 | |||
133 | hid = | ||
134 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpica_device_id) + | ||
135 | (acpi_size) length); | ||
136 | if (!hid) { | ||
137 | status = AE_NO_MEMORY; | ||
138 | goto cleanup; | ||
139 | } | ||
140 | |||
141 | /* Area for the string starts after DEVICE_ID struct */ | ||
142 | |||
143 | hid->string = ACPI_ADD_PTR(char, hid, sizeof(struct acpica_device_id)); | ||
144 | |||
145 | /* Convert EISAID to a string or simply copy existing string */ | ||
146 | |||
147 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
148 | acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value); | ||
149 | } else { | ||
150 | acpi_ut_copy_id_string(hid->string, obj_desc->string.pointer); | ||
151 | } | ||
152 | |||
153 | hid->length = length; | ||
154 | *return_id = hid; | ||
155 | |||
156 | cleanup: | ||
157 | |||
158 | /* On exit, we must delete the return object */ | ||
159 | |||
160 | acpi_ut_remove_reference(obj_desc); | ||
161 | return_ACPI_STATUS(status); | ||
162 | } | ||
163 | |||
164 | /******************************************************************************* | ||
165 | * | ||
166 | * FUNCTION: acpi_ut_execute_UID | ||
167 | * | ||
168 | * PARAMETERS: device_node - Node for the device | ||
169 | * return_id - Where the string UID is returned | ||
170 | * | ||
171 | * RETURN: Status | ||
172 | * | ||
173 | * DESCRIPTION: Executes the _UID control method that returns the unique | ||
174 | * ID of the device. The UID is either a 64-bit Integer (NOT an | ||
175 | * EISAID) or a string. Always returns a string. A 64-bit integer | ||
176 | * is converted to a decimal string. | ||
177 | * | ||
178 | * NOTE: Internal function, no parameter validation | ||
179 | * | ||
180 | ******************************************************************************/ | ||
181 | |||
182 | acpi_status | ||
183 | acpi_ut_execute_UID(struct acpi_namespace_node *device_node, | ||
184 | struct acpica_device_id **return_id) | ||
185 | { | ||
186 | union acpi_operand_object *obj_desc; | ||
187 | struct acpica_device_id *uid; | ||
188 | u32 length; | ||
189 | acpi_status status; | ||
190 | |||
191 | ACPI_FUNCTION_TRACE(ut_execute_UID); | ||
192 | |||
193 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID, | ||
194 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, | ||
195 | &obj_desc); | ||
196 | if (ACPI_FAILURE(status)) { | ||
197 | return_ACPI_STATUS(status); | ||
198 | } | ||
199 | |||
200 | /* Get the size of the String to be returned, includes null terminator */ | ||
201 | |||
202 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
203 | length = ACPI_MAX64_DECIMAL_DIGITS + 1; | ||
204 | } else { | ||
205 | length = obj_desc->string.length + 1; | ||
206 | } | ||
207 | |||
208 | /* Allocate a buffer for the UID */ | ||
209 | |||
210 | uid = | ||
211 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpica_device_id) + | ||
212 | (acpi_size) length); | ||
213 | if (!uid) { | ||
214 | status = AE_NO_MEMORY; | ||
215 | goto cleanup; | ||
216 | } | ||
217 | |||
218 | /* Area for the string starts after DEVICE_ID struct */ | ||
219 | |||
220 | uid->string = ACPI_ADD_PTR(char, uid, sizeof(struct acpica_device_id)); | ||
221 | |||
222 | /* Convert an Integer to string, or just copy an existing string */ | ||
223 | |||
224 | if (obj_desc->common.type == ACPI_TYPE_INTEGER) { | ||
225 | acpi_ex_integer_to_string(uid->string, obj_desc->integer.value); | ||
226 | } else { | ||
227 | acpi_ut_copy_id_string(uid->string, obj_desc->string.pointer); | ||
228 | } | ||
229 | |||
230 | uid->length = length; | ||
231 | *return_id = uid; | ||
232 | |||
233 | cleanup: | ||
234 | |||
235 | /* On exit, we must delete the return object */ | ||
236 | |||
237 | acpi_ut_remove_reference(obj_desc); | ||
238 | return_ACPI_STATUS(status); | ||
239 | } | ||
240 | |||
241 | /******************************************************************************* | ||
242 | * | ||
243 | * FUNCTION: acpi_ut_execute_CID | ||
244 | * | ||
245 | * PARAMETERS: device_node - Node for the device | ||
246 | * return_cid_list - Where the CID list is returned | ||
247 | * | ||
248 | * RETURN: Status, list of CID strings | ||
249 | * | ||
250 | * DESCRIPTION: Executes the _CID control method that returns one or more | ||
251 | * compatible hardware IDs for the device. | ||
252 | * | ||
253 | * NOTE: Internal function, no parameter validation | ||
254 | * | ||
255 | * A _CID method can return either a single compatible ID or a package of | ||
256 | * compatible IDs. Each compatible ID can be one of the following: | ||
257 | * 1) Integer (32 bit compressed EISA ID) or | ||
258 | * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss") | ||
259 | * | ||
260 | * The Integer CIDs are converted to string format by this function. | ||
261 | * | ||
262 | ******************************************************************************/ | ||
263 | |||
264 | acpi_status | ||
265 | acpi_ut_execute_CID(struct acpi_namespace_node *device_node, | ||
266 | struct acpica_device_id_list **return_cid_list) | ||
267 | { | ||
268 | union acpi_operand_object **cid_objects; | ||
269 | union acpi_operand_object *obj_desc; | ||
270 | struct acpica_device_id_list *cid_list; | ||
271 | char *next_id_string; | ||
272 | u32 string_area_size; | ||
273 | u32 length; | ||
274 | u32 cid_list_size; | ||
275 | acpi_status status; | ||
276 | u32 count; | ||
277 | u32 i; | ||
278 | |||
279 | ACPI_FUNCTION_TRACE(ut_execute_CID); | ||
280 | |||
281 | /* Evaluate the _CID method for this device */ | ||
282 | |||
283 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID, | ||
284 | ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ||
285 | | ACPI_BTYPE_PACKAGE, &obj_desc); | ||
286 | if (ACPI_FAILURE(status)) { | ||
287 | return_ACPI_STATUS(status); | ||
288 | } | ||
289 | |||
290 | /* | ||
291 | * Get the count and size of the returned _CIDs. _CID can return either | ||
292 | * a Package of Integers/Strings or a single Integer or String. | ||
293 | * Note: This section also validates that all CID elements are of the | ||
294 | * correct type (Integer or String). | ||
295 | */ | ||
296 | if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { | ||
297 | count = obj_desc->package.count; | ||
298 | cid_objects = obj_desc->package.elements; | ||
299 | } else { /* Single Integer or String CID */ | ||
300 | |||
301 | count = 1; | ||
302 | cid_objects = &obj_desc; | ||
303 | } | ||
304 | |||
305 | string_area_size = 0; | ||
306 | for (i = 0; i < count; i++) { | ||
307 | |||
308 | /* String lengths include null terminator */ | ||
309 | |||
310 | switch (cid_objects[i]->common.type) { | ||
311 | case ACPI_TYPE_INTEGER: | ||
312 | string_area_size += ACPI_EISAID_STRING_SIZE; | ||
313 | break; | ||
314 | |||
315 | case ACPI_TYPE_STRING: | ||
316 | string_area_size += cid_objects[i]->string.length + 1; | ||
317 | break; | ||
318 | |||
319 | default: | ||
320 | status = AE_TYPE; | ||
321 | goto cleanup; | ||
322 | } | ||
323 | } | ||
324 | |||
325 | /* | ||
326 | * Now that we know the length of the CIDs, allocate return buffer: | ||
327 | * 1) Size of the base structure + | ||
328 | * 2) Size of the CID DEVICE_ID array + | ||
329 | * 3) Size of the actual CID strings | ||
330 | */ | ||
331 | cid_list_size = sizeof(struct acpica_device_id_list) + | ||
332 | ((count - 1) * sizeof(struct acpica_device_id)) + string_area_size; | ||
333 | |||
334 | cid_list = ACPI_ALLOCATE_ZEROED(cid_list_size); | ||
335 | if (!cid_list) { | ||
336 | status = AE_NO_MEMORY; | ||
337 | goto cleanup; | ||
338 | } | ||
339 | |||
340 | /* Area for CID strings starts after the CID DEVICE_ID array */ | ||
341 | |||
342 | next_id_string = ACPI_CAST_PTR(char, cid_list->ids) + | ||
343 | ((acpi_size) count * sizeof(struct acpica_device_id)); | ||
344 | |||
345 | /* Copy/convert the CIDs to the return buffer */ | ||
346 | |||
347 | for (i = 0; i < count; i++) { | ||
348 | if (cid_objects[i]->common.type == ACPI_TYPE_INTEGER) { | ||
349 | |||
350 | /* Convert the Integer (EISAID) CID to a string */ | ||
351 | |||
352 | acpi_ex_eisa_id_to_string(next_id_string, | ||
353 | cid_objects[i]->integer. | ||
354 | value); | ||
355 | length = ACPI_EISAID_STRING_SIZE; | ||
356 | } else { /* ACPI_TYPE_STRING */ | ||
357 | |||
358 | /* Copy the String CID from the returned object */ | ||
359 | |||
360 | acpi_ut_copy_id_string(next_id_string, | ||
361 | cid_objects[i]->string.pointer); | ||
362 | length = cid_objects[i]->string.length + 1; | ||
363 | } | ||
364 | |||
365 | cid_list->ids[i].string = next_id_string; | ||
366 | cid_list->ids[i].length = length; | ||
367 | next_id_string += length; | ||
368 | } | ||
369 | |||
370 | /* Finish the CID list */ | ||
371 | |||
372 | cid_list->count = count; | ||
373 | cid_list->list_size = cid_list_size; | ||
374 | *return_cid_list = cid_list; | ||
375 | |||
376 | cleanup: | ||
377 | |||
378 | /* On exit, we must delete the _CID return object */ | ||
379 | |||
380 | acpi_ut_remove_reference(obj_desc); | ||
381 | return_ACPI_STATUS(status); | ||
382 | } | ||
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index fbe782348b0b..9cd65334ca75 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c | |||
@@ -120,6 +120,34 @@ const char *acpi_ut_validate_exception(acpi_status status) | |||
120 | 120 | ||
121 | /******************************************************************************* | 121 | /******************************************************************************* |
122 | * | 122 | * |
123 | * FUNCTION: acpi_ut_is_pci_root_bridge | ||
124 | * | ||
125 | * PARAMETERS: Id - The HID/CID in string format | ||
126 | * | ||
127 | * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge | ||
128 | * | ||
129 | * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. | ||
130 | * | ||
131 | ******************************************************************************/ | ||
132 | |||
133 | u8 acpi_ut_is_pci_root_bridge(char *id) | ||
134 | { | ||
135 | |||
136 | /* | ||
137 | * Check if this is a PCI root bridge. | ||
138 | * ACPI 3.0+: check for a PCI Express root also. | ||
139 | */ | ||
140 | if (!(ACPI_STRCMP(id, | ||
141 | PCI_ROOT_HID_STRING)) || | ||
142 | !(ACPI_STRCMP(id, PCI_EXPRESS_ROOT_HID_STRING))) { | ||
143 | return (TRUE); | ||
144 | } | ||
145 | |||
146 | return (FALSE); | ||
147 | } | ||
148 | |||
149 | /******************************************************************************* | ||
150 | * | ||
123 | * FUNCTION: acpi_ut_is_aml_table | 151 | * FUNCTION: acpi_ut_is_aml_table |
124 | * | 152 | * |
125 | * PARAMETERS: Table - An ACPI table | 153 | * PARAMETERS: Table - An ACPI table |