diff options
| -rw-r--r-- | drivers/acpi/acpica/acutils.h | 4 | ||||
| -rw-r--r-- | drivers/acpi/acpica/nsxfname.c | 29 | ||||
| -rw-r--r-- | drivers/acpi/acpica/utids.c | 67 | ||||
| -rw-r--r-- | include/acpi/acnames.h | 1 | ||||
| -rw-r--r-- | include/acpi/actypes.h | 12 |
5 files changed, 103 insertions, 10 deletions
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 5a6aa581e244..b0f5f92b674a 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h | |||
| @@ -363,6 +363,10 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node, | |||
| 363 | struct acpi_pnp_device_id ** return_id); | 363 | struct acpi_pnp_device_id ** return_id); |
| 364 | 364 | ||
| 365 | acpi_status | 365 | acpi_status |
| 366 | acpi_ut_execute_SUB(struct acpi_namespace_node *device_node, | ||
| 367 | struct acpi_pnp_device_id **return_id); | ||
| 368 | |||
| 369 | acpi_status | ||
| 366 | acpi_ut_execute_CID(struct acpi_namespace_node *device_node, | 370 | acpi_ut_execute_CID(struct acpi_namespace_node *device_node, |
| 367 | struct acpi_pnp_device_id_list ** return_cid_list); | 371 | struct acpi_pnp_device_id_list ** return_cid_list); |
| 368 | 372 | ||
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index 2d10df2ef660..811c6f13f476 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c | |||
| @@ -231,6 +231,7 @@ static char *acpi_ns_copy_device_id(struct acpi_pnp_device_id *dest, | |||
| 231 | struct acpi_pnp_device_id *source, | 231 | struct acpi_pnp_device_id *source, |
| 232 | char *string_area) | 232 | char *string_area) |
| 233 | { | 233 | { |
| 234 | |||
| 234 | /* Create the destination PNP_DEVICE_ID */ | 235 | /* Create the destination PNP_DEVICE_ID */ |
| 235 | 236 | ||
| 236 | dest->string = string_area; | 237 | dest->string = string_area; |
| @@ -255,8 +256,8 @@ static char *acpi_ns_copy_device_id(struct acpi_pnp_device_id *dest, | |||
| 255 | * namespace node and possibly by running several standard | 256 | * namespace node and possibly by running several standard |
| 256 | * control methods (Such as in the case of a device.) | 257 | * control methods (Such as in the case of a device.) |
| 257 | * | 258 | * |
| 258 | * For Device and Processor objects, run the Device _HID, _UID, _CID, _STA, | 259 | * For Device and Processor objects, run the Device _HID, _UID, _CID, _SUB, |
| 259 | * _ADR, _sx_w, and _sx_d methods. | 260 | * _STA, _ADR, _sx_w, and _sx_d methods. |
| 260 | * | 261 | * |
| 261 | * Note: Allocates the return buffer, must be freed by the caller. | 262 | * Note: Allocates the return buffer, must be freed by the caller. |
| 262 | * | 263 | * |
| @@ -271,6 +272,7 @@ acpi_get_object_info(acpi_handle handle, | |||
| 271 | struct acpi_pnp_device_id_list *cid_list = NULL; | 272 | struct acpi_pnp_device_id_list *cid_list = NULL; |
| 272 | struct acpi_pnp_device_id *hid = NULL; | 273 | struct acpi_pnp_device_id *hid = NULL; |
| 273 | struct acpi_pnp_device_id *uid = NULL; | 274 | struct acpi_pnp_device_id *uid = NULL; |
| 275 | struct acpi_pnp_device_id *sub = NULL; | ||
| 274 | char *next_id_string; | 276 | char *next_id_string; |
| 275 | acpi_object_type type; | 277 | acpi_object_type type; |
| 276 | acpi_name name; | 278 | acpi_name name; |
| @@ -315,7 +317,7 @@ acpi_get_object_info(acpi_handle handle, | |||
| 315 | if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) { | 317 | if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) { |
| 316 | /* | 318 | /* |
| 317 | * Get extra info for ACPI Device/Processor objects only: | 319 | * Get extra info for ACPI Device/Processor objects only: |
| 318 | * Run the Device _HID, _UID, and _CID methods. | 320 | * Run the Device _HID, _UID, _SUB, and _CID methods. |
| 319 | * | 321 | * |
| 320 | * Note: none of these methods are required, so they may or may | 322 | * Note: none of these methods are required, so they may or may |
| 321 | * not be present for this device. The Info->Valid bitfield is used | 323 | * not be present for this device. The Info->Valid bitfield is used |
| @@ -338,6 +340,14 @@ acpi_get_object_info(acpi_handle handle, | |||
| 338 | valid |= ACPI_VALID_UID; | 340 | valid |= ACPI_VALID_UID; |
| 339 | } | 341 | } |
| 340 | 342 | ||
| 343 | /* Execute the Device._SUB method */ | ||
| 344 | |||
| 345 | status = acpi_ut_execute_SUB(node, &sub); | ||
| 346 | if (ACPI_SUCCESS(status)) { | ||
| 347 | info_size += sub->length; | ||
| 348 | valid |= ACPI_VALID_SUB; | ||
| 349 | } | ||
| 350 | |||
| 341 | /* Execute the Device._CID method */ | 351 | /* Execute the Device._CID method */ |
| 342 | 352 | ||
| 343 | status = acpi_ut_execute_CID(node, &cid_list); | 353 | status = acpi_ut_execute_CID(node, &cid_list); |
| @@ -425,8 +435,9 @@ acpi_get_object_info(acpi_handle handle, | |||
| 425 | } | 435 | } |
| 426 | 436 | ||
| 427 | /* | 437 | /* |
| 428 | * Copy the HID, UID, and CIDs to the return buffer. The variable-length | 438 | * Copy the HID, UID, SUB, and CIDs to the return buffer. |
| 429 | * strings are copied to the reserved area at the end of the buffer. | 439 | * The variable-length strings are copied to the reserved area |
| 440 | * at the end of the buffer. | ||
| 430 | * | 441 | * |
| 431 | * For HID and CID, check if the ID is a PCI Root Bridge. | 442 | * For HID and CID, check if the ID is a PCI Root Bridge. |
| 432 | */ | 443 | */ |
| @@ -444,6 +455,11 @@ acpi_get_object_info(acpi_handle handle, | |||
| 444 | uid, next_id_string); | 455 | uid, next_id_string); |
| 445 | } | 456 | } |
| 446 | 457 | ||
| 458 | if (sub) { | ||
| 459 | next_id_string = acpi_ns_copy_device_id(&info->subsystem_id, | ||
| 460 | sub, next_id_string); | ||
| 461 | } | ||
| 462 | |||
| 447 | if (cid_list) { | 463 | if (cid_list) { |
| 448 | info->compatible_id_list.count = cid_list->count; | 464 | info->compatible_id_list.count = cid_list->count; |
| 449 | info->compatible_id_list.list_size = cid_list->list_size; | 465 | info->compatible_id_list.list_size = cid_list->list_size; |
| @@ -480,6 +496,9 @@ acpi_get_object_info(acpi_handle handle, | |||
| 480 | if (uid) { | 496 | if (uid) { |
| 481 | ACPI_FREE(uid); | 497 | ACPI_FREE(uid); |
| 482 | } | 498 | } |
| 499 | if (sub) { | ||
| 500 | ACPI_FREE(sub); | ||
| 501 | } | ||
| 483 | if (cid_list) { | 502 | if (cid_list) { |
| 484 | ACPI_FREE(cid_list); | 503 | ACPI_FREE(cid_list); |
| 485 | } | 504 | } |
diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c index f18ac81c8399..774c3aefbf5d 100644 --- a/drivers/acpi/acpica/utids.c +++ b/drivers/acpi/acpica/utids.c | |||
| @@ -127,6 +127,73 @@ cleanup: | |||
| 127 | 127 | ||
| 128 | /******************************************************************************* | 128 | /******************************************************************************* |
| 129 | * | 129 | * |
| 130 | * FUNCTION: acpi_ut_execute_SUB | ||
| 131 | * | ||
| 132 | * PARAMETERS: device_node - Node for the device | ||
| 133 | * return_id - Where the _SUB is returned | ||
| 134 | * | ||
| 135 | * RETURN: Status | ||
| 136 | * | ||
| 137 | * DESCRIPTION: Executes the _SUB control method that returns the subsystem | ||
| 138 | * ID of the device. The _SUB value is always a string containing | ||
| 139 | * either a valid PNP or ACPI ID. | ||
| 140 | * | ||
| 141 | * NOTE: Internal function, no parameter validation | ||
| 142 | * | ||
| 143 | ******************************************************************************/ | ||
| 144 | |||
| 145 | acpi_status | ||
| 146 | acpi_ut_execute_SUB(struct acpi_namespace_node *device_node, | ||
| 147 | struct acpi_pnp_device_id **return_id) | ||
| 148 | { | ||
| 149 | union acpi_operand_object *obj_desc; | ||
| 150 | struct acpi_pnp_device_id *sub; | ||
| 151 | u32 length; | ||
| 152 | acpi_status status; | ||
| 153 | |||
| 154 | ACPI_FUNCTION_TRACE(ut_execute_SUB); | ||
| 155 | |||
| 156 | status = acpi_ut_evaluate_object(device_node, METHOD_NAME__SUB, | ||
| 157 | ACPI_BTYPE_STRING, &obj_desc); | ||
| 158 | if (ACPI_FAILURE(status)) { | ||
| 159 | return_ACPI_STATUS(status); | ||
| 160 | } | ||
| 161 | |||
| 162 | /* Get the size of the String to be returned, includes null terminator */ | ||
| 163 | |||
| 164 | length = obj_desc->string.length + 1; | ||
| 165 | |||
| 166 | /* Allocate a buffer for the SUB */ | ||
| 167 | |||
| 168 | sub = | ||
| 169 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pnp_device_id) + | ||
| 170 | (acpi_size) length); | ||
| 171 | if (!sub) { | ||
| 172 | status = AE_NO_MEMORY; | ||
| 173 | goto cleanup; | ||
| 174 | } | ||
| 175 | |||
| 176 | /* Area for the string starts after PNP_DEVICE_ID struct */ | ||
| 177 | |||
| 178 | sub->string = | ||
| 179 | ACPI_ADD_PTR(char, sub, sizeof(struct acpi_pnp_device_id)); | ||
| 180 | |||
| 181 | /* Simply copy existing string */ | ||
| 182 | |||
| 183 | ACPI_STRCPY(sub->string, obj_desc->string.pointer); | ||
| 184 | sub->length = length; | ||
| 185 | *return_id = sub; | ||
| 186 | |||
| 187 | cleanup: | ||
| 188 | |||
| 189 | /* On exit, we must delete the return object */ | ||
| 190 | |||
| 191 | acpi_ut_remove_reference(obj_desc); | ||
| 192 | |||
