diff options
author | Bob Moore <robert.moore@intel.com> | 2012-10-30 22:28:38 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2012-11-14 18:31:30 -0500 |
commit | 413fc3f592c65977858f8adce2e7af0e82aa1191 (patch) | |
tree | ba673bcb511b48dd0cf96f793fe2de28c978218a /drivers/acpi | |
parent | 17b1f45a68ebd7944904a801d81a5c4206f9f76b (diff) |
ACPICA: AcpiGetObjectInfo: Add support for ACPI 5 _SUB method
Now calls _SUB in addition to the other ID methods: _HID, _CID,
and _UID.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi')
-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 |
3 files changed, 95 insertions, 5 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 | return_ACPI_STATUS(status); | ||
193 | } | ||
194 | |||
195 | /******************************************************************************* | ||
196 | * | ||
130 | * FUNCTION: acpi_ut_execute_UID | 197 | * FUNCTION: acpi_ut_execute_UID |
131 | * | 198 | * |
132 | * PARAMETERS: device_node - Node for the device | 199 | * PARAMETERS: device_node - Node for the device |