aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/uteval.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/uteval.c')
-rw-r--r--drivers/acpi/acpica/uteval.c378
1 files changed, 44 insertions, 334 deletions
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c
index 006b16c26017..5d54e36ab453 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
50ACPI_MODULE_NAME("uteval") 49ACPI_MODULE_NAME("uteval")
51 50
52/* Local prototypes */
53static void
54acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length);
55
56static acpi_status
57acpi_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 *
@@ -78,6 +69,9 @@ static struct acpi_interface_info acpi_interfaces_supported[] = {
78 {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */ 69 {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */
79 {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */ 70 {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */
80 {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ 71 {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */
72 {"Windows 2006.1", ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */
73 {"Windows 2006 SP1", ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */
74 {"Windows 2009", ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */
81 75
82 /* Feature Group Strings */ 76 /* Feature Group Strings */
83 77
@@ -213,7 +207,7 @@ acpi_status acpi_osi_invalidate(char *interface)
213 * RETURN: Status 207 * RETURN: Status
214 * 208 *
215 * DESCRIPTION: Evaluates a namespace object and verifies the type of the 209 * DESCRIPTION: Evaluates a namespace object and verifies the type of the
216 * return object. Common code that simplifies accessing objects 210 * return object. Common code that simplifies accessing objects
217 * that have required return objects of fixed types. 211 * that have required return objects of fixed types.
218 * 212 *
219 * NOTE: Internal function, no parameter validation 213 * NOTE: Internal function, no parameter validation
@@ -298,7 +292,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
298 292
299 if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { 293 if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) {
300 /* 294 /*
301 * We received a return object, but one was not expected. This can 295 * We received a return object, but one was not expected. This can
302 * happen frequently if the "implicit return" feature is enabled. 296 * happen frequently if the "implicit return" feature is enabled.
303 * Just delete the return object and return AE_OK. 297 * Just delete the return object and return AE_OK.
304 */ 298 */
@@ -340,12 +334,12 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
340 * 334 *
341 * PARAMETERS: object_name - Object name to be evaluated 335 * PARAMETERS: object_name - Object name to be evaluated
342 * device_node - Node for the device 336 * device_node - Node for the device
343 * Address - Where the value is returned 337 * Value - Where the value is returned
344 * 338 *
345 * RETURN: Status 339 * RETURN: Status
346 * 340 *
347 * DESCRIPTION: Evaluates a numeric namespace object for a selected device 341 * DESCRIPTION: Evaluates a numeric namespace object for a selected device
348 * and stores result in *Address. 342 * and stores result in *Value.
349 * 343 *
350 * NOTE: Internal function, no parameter validation 344 * NOTE: Internal function, no parameter validation
351 * 345 *
@@ -354,7 +348,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
354acpi_status 348acpi_status
355acpi_ut_evaluate_numeric_object(char *object_name, 349acpi_ut_evaluate_numeric_object(char *object_name,
356 struct acpi_namespace_node *device_node, 350 struct acpi_namespace_node *device_node,
357 acpi_integer * address) 351 acpi_integer *value)
358{ 352{
359 union acpi_operand_object *obj_desc; 353 union acpi_operand_object *obj_desc;
360 acpi_status status; 354 acpi_status status;
@@ -369,295 +363,7 @@ acpi_ut_evaluate_numeric_object(char *object_name,
369 363
370 /* Get the returned Integer */ 364 /* Get the returned Integer */
371 365
372 *address = obj_desc->integer.value; 366 *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
396static void
397acpi_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
431acpi_status
432acpi_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
483static acpi_status
484acpi_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
531acpi_status
532acpi_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
633acpi_status
634acpi_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 367
662 /* On exit, we must delete the return object */ 368 /* On exit, we must delete the return object */
663 369
@@ -716,60 +422,64 @@ acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags)
716 422
717/******************************************************************************* 423/*******************************************************************************
718 * 424 *
719 * FUNCTION: acpi_ut_execute_Sxds 425 * FUNCTION: acpi_ut_execute_power_methods
720 * 426 *
721 * PARAMETERS: device_node - Node for the device 427 * PARAMETERS: device_node - Node for the device
722 * Flags - Where the status flags are returned 428 * method_names - Array of power method names
429 * method_count - Number of methods to execute
430 * out_values - Where the power method values are returned
723 * 431 *
724 * RETURN: Status 432 * RETURN: Status, out_values
725 * 433 *
726 * DESCRIPTION: Executes _STA for selected device and stores results in 434 * DESCRIPTION: Executes the specified power methods for the device and returns
727 * *Flags. 435 * the result(s).
728 * 436 *
729 * NOTE: Internal function, no parameter validation 437 * NOTE: Internal function, no parameter validation
730 * 438 *
731 ******************************************************************************/ 439******************************************************************************/
732 440
733acpi_status 441acpi_status
734acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest) 442acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node,
443 const char **method_names,
444 u8 method_count, u8 *out_values)
735{ 445{
736 union acpi_operand_object *obj_desc; 446 union acpi_operand_object *obj_desc;
737 acpi_status status; 447 acpi_status status;
448 acpi_status final_status = AE_NOT_FOUND;
738 u32 i; 449 u32 i;
739 450
740 ACPI_FUNCTION_TRACE(ut_execute_sxds); 451 ACPI_FUNCTION_TRACE(ut_execute_power_methods);
741 452
742 for (i = 0; i < 4; i++) { 453 for (i = 0; i < method_count; i++) {
743 highest[i] = 0xFF; 454 /*
455 * Execute the power method (_sx_d or _sx_w). The only allowable
456 * return type is an Integer.
457 */
744 status = acpi_ut_evaluate_object(device_node, 458 status = acpi_ut_evaluate_object(device_node,
745 ACPI_CAST_PTR(char, 459 ACPI_CAST_PTR(char,
746 acpi_gbl_highest_dstate_names 460 method_names[i]),
747 [i]),
748 ACPI_BTYPE_INTEGER, &obj_desc); 461 ACPI_BTYPE_INTEGER, &obj_desc);
749 if (ACPI_FAILURE(status)) { 462 if (ACPI_SUCCESS(status)) {
750 if (status != AE_NOT_FOUND) { 463 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 464
768 /* Delete the return object */ 465 /* Delete the return object */
769 466
770 acpi_ut_remove_reference(obj_desc); 467 acpi_ut_remove_reference(obj_desc);
468 final_status = AE_OK; /* At least one value is valid */
469 continue;
771 } 470 }
471
472 out_values[i] = ACPI_UINT8_MAX;
473 if (status == AE_NOT_FOUND) {
474 continue; /* Ignore if not found */
475 }
476
477 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
478 "Failed %s on Device %4.4s, %s\n",
479 ACPI_CAST_PTR(char, method_names[i]),
480 acpi_ut_get_node_name(device_node),
481 acpi_format_exception(status)));
772 } 482 }
773 483
774 return_ACPI_STATUS(AE_OK); 484 return_ACPI_STATUS(final_status);
775} 485}