aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/nsrepair.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/nsrepair.c')
-rw-r--r--drivers/acpi/acpica/nsrepair.c175
1 files changed, 174 insertions, 1 deletions
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c
index 4fd1bdb056b2..d4be37751be4 100644
--- a/drivers/acpi/acpica/nsrepair.c
+++ b/drivers/acpi/acpica/nsrepair.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2009, Intel Corp. 8 * Copyright (C) 2000 - 2010, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -45,6 +45,7 @@
45#include "accommon.h" 45#include "accommon.h"
46#include "acnamesp.h" 46#include "acnamesp.h"
47#include "acinterp.h" 47#include "acinterp.h"
48#include "acpredef.h"
48 49
49#define _COMPONENT ACPI_NAMESPACE 50#define _COMPONENT ACPI_NAMESPACE
50ACPI_MODULE_NAME("nsrepair") 51ACPI_MODULE_NAME("nsrepair")
@@ -71,6 +72,12 @@ ACPI_MODULE_NAME("nsrepair")
71 * Buffer -> Package of Integers 72 * Buffer -> Package of Integers
72 * Package -> Package of one Package 73 * Package -> Package of one Package
73 * 74 *
75 * Additional possible repairs:
76 *
77 * Optional/unnecessary NULL package elements removed
78 * Required package elements that are NULL replaced by Integer/String/Buffer
79 * Incorrect standalone package wrapped with required outer package
80 *
74 ******************************************************************************/ 81 ******************************************************************************/
75/* Local prototypes */ 82/* Local prototypes */
76static acpi_status 83static acpi_status
@@ -506,6 +513,172 @@ acpi_ns_convert_to_package(union acpi_operand_object *original_object,
506 513
507/******************************************************************************* 514/*******************************************************************************
508 * 515 *
516 * FUNCTION: acpi_ns_repair_null_element
517 *
518 * PARAMETERS: Data - Pointer to validation data structure
519 * expected_btypes - Object types expected
520 * package_index - Index of object within parent package (if
521 * applicable - ACPI_NOT_PACKAGE_ELEMENT
522 * otherwise)
523 * return_object_ptr - Pointer to the object returned from the
524 * evaluation of a method or object
525 *
526 * RETURN: Status. AE_OK if repair was successful.
527 *
528 * DESCRIPTION: Attempt to repair a NULL element of a returned Package object.
529 *
530 ******************************************************************************/
531
532acpi_status
533acpi_ns_repair_null_element(struct acpi_predefined_data *data,
534 u32 expected_btypes,
535 u32 package_index,
536 union acpi_operand_object **return_object_ptr)
537{
538 union acpi_operand_object *return_object = *return_object_ptr;
539 union acpi_operand_object *new_object;
540
541 ACPI_FUNCTION_NAME(ns_repair_null_element);
542
543 /* No repair needed if return object is non-NULL */
544
545 if (return_object) {
546 return (AE_OK);
547 }
548
549 /*
550 * Attempt to repair a NULL element of a Package object. This applies to
551 * predefined names that return a fixed-length package and each element
552 * is required. It does not apply to variable-length packages where NULL
553 * elements are allowed, especially at the end of the package.
554 */
555 if (expected_btypes & ACPI_RTYPE_INTEGER) {
556
557 /* Need an Integer - create a zero-value integer */
558
559 new_object = acpi_ut_create_integer_object(0);
560 } else if (expected_btypes & ACPI_RTYPE_STRING) {
561
562 /* Need a String - create a NULL string */
563
564 new_object = acpi_ut_create_string_object(0);
565 } else if (expected_btypes & ACPI_RTYPE_BUFFER) {
566
567 /* Need a Buffer - create a zero-length buffer */
568
569 new_object = acpi_ut_create_buffer_object(0);
570 } else {
571 /* Error for all other expected types */
572
573 return (AE_AML_OPERAND_TYPE);
574 }
575
576 if (!new_object) {
577 return (AE_NO_MEMORY);
578 }
579
580 /* Set the reference count according to the parent Package object */
581
582 new_object->common.reference_count =
583 data->parent_package->common.reference_count;
584
585 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
586 "%s: Converted NULL package element to expected %s at index %u\n",
587 data->pathname,
588 acpi_ut_get_object_type_name(new_object),
589 package_index));
590
591 *return_object_ptr = new_object;
592 data->flags |= ACPI_OBJECT_REPAIRED;
593 return (AE_OK);
594}
595
596/******************************************************************************
597 *
598 * FUNCTION: acpi_ns_remove_null_elements
599 *
600 * PARAMETERS: Data - Pointer to validation data structure
601 * package_type - An acpi_return_package_types value
602 * obj_desc - A Package object
603 *
604 * RETURN: None.
605 *
606 * DESCRIPTION: Remove all NULL package elements from packages that contain
607 * a variable number of sub-packages. For these types of
608 * packages, NULL elements can be safely removed.
609 *
610 *****************************************************************************/
611
612void
613acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
614 u8 package_type,
615 union acpi_operand_object *obj_desc)
616{
617 union acpi_operand_object **source;
618 union acpi_operand_object **dest;
619 u32 count;
620 u32 new_count;
621 u32 i;
622
623 ACPI_FUNCTION_NAME(ns_remove_null_elements);
624
625 /*
626 * PTYPE1 packages contain no subpackages.
627 * PTYPE2 packages contain a variable number of sub-packages. We can
628 * safely remove all NULL elements from the PTYPE2 packages.
629 */
630 switch (package_type) {
631 case ACPI_PTYPE1_FIXED:
632 case ACPI_PTYPE1_VAR:
633 case ACPI_PTYPE1_OPTION:
634 return;
635
636 case ACPI_PTYPE2:
637 case ACPI_PTYPE2_COUNT:
638 case ACPI_PTYPE2_PKG_COUNT:
639 case ACPI_PTYPE2_FIXED:
640 case ACPI_PTYPE2_MIN:
641 case ACPI_PTYPE2_REV_FIXED:
642 break;
643
644 default:
645 return;
646 }
647
648 count = obj_desc->package.count;
649 new_count = count;
650
651 source = obj_desc->package.elements;
652 dest = source;
653
654 /* Examine all elements of the package object, remove nulls */
655
656 for (i = 0; i < count; i++) {
657 if (!*source) {
658 new_count--;
659 } else {
660 *dest = *source;
661 dest++;
662 }
663 source++;
664 }
665
666 /* Update parent package if any null elements were removed */
667
668 if (new_count < count) {
669 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
670 "%s: Found and removed %u NULL elements\n",
671 data->pathname, (count - new_count)));
672
673 /* NULL terminate list and update the package count */
674
675 *dest = NULL;
676 obj_desc->package.count = new_count;
677 }
678}
679
680/*******************************************************************************
681 *
509 * FUNCTION: acpi_ns_repair_package_list 682 * FUNCTION: acpi_ns_repair_package_list
510 * 683 *
511 * PARAMETERS: Data - Pointer to validation data structure 684 * PARAMETERS: Data - Pointer to validation data structure