linux/drivers/acpi/acpica/nsrepair.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Module Name: nsrepair - Repair for objects returned by predefined methods
   4 *
   5 *****************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2011, 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 "acnamesp.h"
  47#include "acinterp.h"
  48#include "acpredef.h"
  49
  50#define _COMPONENT          ACPI_NAMESPACE
  51ACPI_MODULE_NAME("nsrepair")
  52
  53/*******************************************************************************
  54 *
  55 * This module attempts to repair or convert objects returned by the
  56 * predefined methods to an object type that is expected, as per the ACPI
  57 * specification. The need for this code is dictated by the many machines that
  58 * return incorrect types for the standard predefined methods. Performing these
  59 * conversions here, in one place, eliminates the need for individual ACPI
  60 * device drivers to do the same. Note: Most of these conversions are different
  61 * than the internal object conversion routines used for implicit object
  62 * conversion.
  63 *
  64 * The following conversions can be performed as necessary:
  65 *
  66 * Integer -> String
  67 * Integer -> Buffer
  68 * String  -> Integer
  69 * String  -> Buffer
  70 * Buffer  -> Integer
  71 * Buffer  -> String
  72 * Buffer  -> Package of Integers
  73 * Package -> Package of one Package
  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 *
  81 ******************************************************************************/
  82/* Local prototypes */
  83static acpi_status
  84acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
  85                           union acpi_operand_object **return_object);
  86
  87static acpi_status
  88acpi_ns_convert_to_string(union acpi_operand_object *original_object,
  89                          union acpi_operand_object **return_object);
  90
  91static acpi_status
  92acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
  93                          union acpi_operand_object **return_object);
  94
  95static acpi_status
  96acpi_ns_convert_to_package(union acpi_operand_object *original_object,
  97                           union acpi_operand_object **return_object);
  98
  99/*******************************************************************************
 100 *
 101 * FUNCTION:    acpi_ns_repair_object
 102 *
 103 * PARAMETERS:  Data                - Pointer to validation data structure
 104 *              expected_btypes     - Object types expected
 105 *              package_index       - Index of object within parent package (if
 106 *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
 107 *                                    otherwise)
 108 *              return_object_ptr   - Pointer to the object returned from the
 109 *                                    evaluation of a method or object
 110 *
 111 * RETURN:      Status. AE_OK if repair was successful.
 112 *
 113 * DESCRIPTION: Attempt to repair/convert a return object of a type that was
 114 *              not expected.
 115 *
 116 ******************************************************************************/
 117
 118acpi_status
 119acpi_ns_repair_object(struct acpi_predefined_data *data,
 120                      u32 expected_btypes,
 121                      u32 package_index,
 122                      union acpi_operand_object **return_object_ptr)
 123{
 124        union acpi_operand_object *return_object = *return_object_ptr;
 125        union acpi_operand_object *new_object;
 126        acpi_status status;
 127
 128        ACPI_FUNCTION_NAME(ns_repair_object);
 129
 130        /*
 131         * At this point, we know that the type of the returned object was not
 132         * one of the expected types for this predefined name. Attempt to
 133         * repair the object by converting it to one of the expected object
 134         * types for this predefined name.
 135         */
 136        if (expected_btypes & ACPI_RTYPE_INTEGER) {
 137                status = acpi_ns_convert_to_integer(return_object, &new_object);
 138                if (ACPI_SUCCESS(status)) {
 139                        goto object_repaired;
 140                }
 141        }
 142        if (expected_btypes & ACPI_RTYPE_STRING) {
 143                status = acpi_ns_convert_to_string(return_object, &new_object);
 144                if (ACPI_SUCCESS(status)) {
 145                        goto object_repaired;
 146                }
 147        }
 148        if (expected_btypes & ACPI_RTYPE_BUFFER) {
 149                status = acpi_ns_convert_to_buffer(return_object, &new_object);
 150                if (ACPI_SUCCESS(status)) {
 151                        goto object_repaired;
 152                }
 153        }
 154        if (expected_btypes & ACPI_RTYPE_PACKAGE) {
 155                status = acpi_ns_convert_to_package(return_object, &new_object);
 156                if (ACPI_SUCCESS(status)) {
 157                        goto object_repaired;
 158                }
 159        }
 160
 161        /* We cannot repair this object */
 162
 163        return (AE_AML_OPERAND_TYPE);
 164
 165      object_repaired:
 166
 167        /* Object was successfully repaired */
 168
 169        /*
 170         * If the original object is a package element, we need to:
 171         * 1. Set the reference count of the new object to match the
 172         *    reference count of the old object.
 173         * 2. Decrement the reference count of the original object.
 174         */
 175        if (package_index != ACPI_NOT_PACKAGE_ELEMENT) {
 176                new_object->common.reference_count =
 177                    return_object->common.reference_count;
 178
 179                if (return_object->common.reference_count > 1) {
 180                        return_object->common.reference_count--;
 181                }
 182
 183                ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
 184                                  "%s: Converted %s to expected %s at index %u\n",
 185                                  data->pathname,
 186                                  acpi_ut_get_object_type_name(return_object),
 187                                  acpi_ut_get_object_type_name(new_object),
 188                                  package_index));
 189        } else {
 190                ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
 191                                  "%s: Converted %s to expected %s\n",
 192                                  data->pathname,
 193                                  acpi_ut_get_object_type_name(return_object),
 194                                  acpi_ut_get_object_type_name(new_object)));
 195        }
 196
 197        /* Delete old object, install the new return object */
 198
 199        acpi_ut_remove_reference(return_object);
 200        *return_object_ptr = new_object;
 201        data->flags |= ACPI_OBJECT_REPAIRED;
 202        return (AE_OK);
 203}
 204
 205/*******************************************************************************
 206 *
 207 * FUNCTION:    acpi_ns_convert_to_integer
 208 *
 209 * PARAMETERS:  original_object     - Object to be converted
 210 *              return_object       - Where the new converted object is returned
 211 *
 212 * RETURN:      Status. AE_OK if conversion was successful.
 213 *
 214 * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer.
 215 *
 216 ******************************************************************************/
 217
 218static acpi_status
 219acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
 220                           union acpi_operand_object **return_object)
 221{
 222        union acpi_operand_object *new_object;
 223        acpi_status status;
 224        u64 value = 0;
 225        u32 i;
 226
 227        switch (original_object->common.type) {
 228        case ACPI_TYPE_STRING:
 229
 230                /* String-to-Integer conversion */
 231
 232                status = acpi_ut_strtoul64(original_object->string.pointer,
 233                                           ACPI_ANY_BASE, &value);
 234                if (ACPI_FAILURE(status)) {
 235                        return (status);
 236                }
 237                break;
 238
 239        case ACPI_TYPE_BUFFER:
 240
 241                /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */
 242
 243                if (original_object->buffer.length > 8) {
 244                        return (AE_AML_OPERAND_TYPE);
 245                }
 246
 247                /* Extract each buffer byte to create the integer */
 248
 249                for (i = 0; i < original_object->buffer.length; i++) {
 250                        value |=
 251                            ((u64) original_object->buffer.
 252                             pointer[i] << (i * 8));
 253                }
 254                break;
 255
 256        default:
 257                return (AE_AML_OPERAND_TYPE);
 258        }
 259
 260        new_object = acpi_ut_create_integer_object(value);
 261        if (!new_object) {
 262                return (AE_NO_MEMORY);
 263        }
 264
 265        *return_object = new_object;
 266        return (AE_OK);
 267}
 268
 269/*******************************************************************************
 270 *
 271 * FUNCTION:    acpi_ns_convert_to_string
 272 *
 273 * PARAMETERS:  original_object     - Object to be converted
 274 *              return_object       - Where the new converted object is returned
 275 *
 276 * RETURN:      Status. AE_OK if conversion was successful.
 277 *
 278 * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String.
 279 *
 280 ******************************************************************************/
 281
 282static acpi_status
 283acpi_ns_convert_to_string(union acpi_operand_object *original_object,
 284                          union acpi_operand_object **return_object)
 285{
 286        union acpi_operand_object *new_object;
 287        acpi_size length;
 288        acpi_status status;
 289
 290        switch (original_object->common.type) {
 291        case ACPI_TYPE_INTEGER:
 292                /*
 293                 * Integer-to-String conversion. Commonly, convert
 294                 * an integer of value 0 to a NULL string. The last element of
 295                 * _BIF and _BIX packages occasionally need this fix.
 296                 */
 297                if (original_object->integer.value == 0) {
 298
 299                        /* Allocate a new NULL string object */
 300
 301                        new_object = acpi_ut_create_string_object(0);
 302                        if (!new_object) {
 303                                return (AE_NO_MEMORY);
 304                        }
 305                } else {
 306                        status =
 307                            acpi_ex_convert_to_string(original_object,
 308                                                      &new_object,
 309                                                      ACPI_IMPLICIT_CONVERT_HEX);
 310                        if (ACPI_FAILURE(status)) {
 311                                return (status);
 312                        }
 313                }
 314                break;
 315
 316        case ACPI_TYPE_BUFFER:
 317                /*
 318                 * Buffer-to-String conversion. Use a to_string
 319                 * conversion, no transform performed on the buffer data. The best
 320                 * example of this is the _BIF method, where the string data from
 321                 * the battery is often (incorrectly) returned as buffer object(s).
 322                 */
 323                length = 0;
 324                while ((length < original_object->buffer.length) &&
 325                       (original_object->buffer.pointer[length])) {
 326                        length++;
 327                }
 328
 329                /* Allocate a new string object */
 330
 331                new_object = acpi_ut_create_string_object(length);
 332                if (!new_object) {
 333                        return (AE_NO_MEMORY);
 334                }
 335
 336                /*
 337                 * Copy the raw buffer data with no transform. String is already NULL
 338                 * terminated at Length+1.
 339                 */
 340                ACPI_MEMCPY(new_object->string.pointer,
 341                            original_object->buffer.pointer, length);
 342                break;
 343
 344        default:
 345                return (AE_AML_OPERAND_TYPE);
 346        }
 347
 348        *return_object = new_object;
 349        return (AE_OK);
 350}
 351
 352/*******************************************************************************
 353 *
 354 * FUNCTION:    acpi_ns_convert_to_buffer
 355 *
 356 * PARAMETERS:  original_object     - Object to be converted
 357 *              return_object       - Where the new converted object is returned
 358 *
 359 * RETURN:      Status. AE_OK if conversion was successful.
 360 *
 361 * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer.
 362 *
 363 ******************************************************************************/
 364
 365static acpi_status
 366acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
 367                          union acpi_operand_object **return_object)
 368{
 369        union acpi_operand_object *new_object;
 370        acpi_status status;
 371        union acpi_operand_object **elements;
 372        u32 *dword_buffer;
 373        u32 count;
 374        u32 i;
 375
 376        switch (original_object->common.type) {
 377        case ACPI_TYPE_INTEGER:
 378                /*
 379                 * Integer-to-Buffer conversion.
 380                 * Convert the Integer to a packed-byte buffer. _MAT and other
 381                 * objects need this sometimes, if a read has been performed on a
 382                 * Field object that is less than or equal to the global integer
 383                 * size (32 or 64 bits).
 384                 */
 385                status =
 386                    acpi_ex_convert_to_buffer(original_object, &new_object);
 387                if (ACPI_FAILURE(status)) {
 388                        return (status);
 389                }
 390                break;
 391
 392        case ACPI_TYPE_STRING:
 393
 394                /* String-to-Buffer conversion. Simple data copy */
 395
 396                new_object =
 397                    acpi_ut_create_buffer_object(original_object->string.
 398                                                 length);
 399                if (!new_object) {
 400                        return (AE_NO_MEMORY);
 401                }
 402
 403                ACPI_MEMCPY(new_object->buffer.pointer,
 404                            original_object->string.pointer,
 405                            original_object->string.length);
 406                break;
 407
 408        case ACPI_TYPE_PACKAGE:
 409                /*
 410                 * This case is often seen for predefined names that must return a
 411                 * Buffer object with multiple DWORD integers within. For example,
 412                 * _FDE and _GTM. The Package can be converted to a Buffer.
 413                 */
 414
 415                /* All elements of the Package must be integers */
 416
 417                elements = original_object->package.elements;
 418                count = original_object->package.count;
 419
 420                for (i = 0; i < count; i++) {
 421                        if ((!*elements) ||
 422                            ((*elements)->common.type != ACPI_TYPE_INTEGER)) {
 423                                return (AE_AML_OPERAND_TYPE);
 424                        }
 425                        elements++;
 426                }
 427
 428                /* Create the new buffer object to replace the Package */
 429
 430                new_object = acpi_ut_create_buffer_object(ACPI_MUL_4(count));
 431                if (!new_object) {
 432                        return (AE_NO_MEMORY);
 433                }
 434
 435                /* Copy the package elements (integers) to the buffer as DWORDs */
 436
 437                elements = original_object->package.elements;
 438                dword_buffer = ACPI_CAST_PTR(u32, new_object->buffer.pointer);
 439
 440                for (i = 0; i < count; i++) {
 441                        *dword_buffer = (u32) (*elements)->integer.value;
 442                        dword_buffer++;
 443                        elements++;
 444                }
 445                break;
 446
 447        default:
 448                return (AE_AML_OPERAND_TYPE);
 449        }
 450
 451        *return_object = new_object;
 452        return (AE_OK);
 453}
 454
 455/*******************************************************************************
 456 *
 457 * FUNCTION:    acpi_ns_convert_to_package
 458 *
 459 * PARAMETERS:  original_object     - Object to be converted
 460 *              return_object       - Where the new converted object is returned
 461 *
 462 * RETURN:      Status. AE_OK if conversion was successful.
 463 *
 464 * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of
 465 *              the buffer is converted to a single integer package element.
 466 *
 467 ******************************************************************************/
 468
 469static acpi_status
 470acpi_ns_convert_to_package(union acpi_operand_object *original_object,
 471                           union acpi_operand_object **return_object)
 472{
 473        union acpi_operand_object *new_object;
 474        union acpi_operand_object **elements;
 475        u32 length;
 476        u8 *buffer;
 477
 478        switch (original_object->common.type) {
 479        case ACPI_TYPE_BUFFER:
 480
 481                /* Buffer-to-Package conversion */
 482
 483                length = original_object->buffer.length;
 484                new_object = acpi_ut_create_package_object(length);
 485                if (!new_object) {
 486                        return (AE_NO_MEMORY);
 487                }
 488
 489                /* Convert each buffer byte to an integer package element */
 490
 491                elements = new_object->package.elements;
 492                buffer = original_object->buffer.pointer;
 493
 494                while (length--) {
 495                        *elements =
 496                            acpi_ut_create_integer_object((u64) *buffer);
 497                        if (!*elements) {
 498                                acpi_ut_remove_reference(new_object);
 499                                return (AE_NO_MEMORY);
 500                        }
 501                        elements++;
 502                        buffer++;
 503                }
 504                break;
 505
 506        default:
 507                return (AE_AML_OPERAND_TYPE);
 508        }
 509
 510        *return_object = new_object;
 511        return (AE_OK);
 512}
 513
 514/*******************************************************************************
 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((u64)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 *
 682 * FUNCTION:    acpi_ns_repair_package_list
 683 *
 684 * PARAMETERS:  Data                - Pointer to validation data structure
 685 *              obj_desc_ptr        - Pointer to the object to repair. The new
 686 *                                    package object is returned here,
 687 *                                    overwriting the old object.
 688 *
 689 * RETURN:      Status, new object in *obj_desc_ptr
 690 *
 691 * DESCRIPTION: Repair a common problem with objects that are defined to return
 692 *              a variable-length Package of Packages. If the variable-length
 693 *              is one, some BIOS code mistakenly simply declares a single
 694 *              Package instead of a Package with one sub-Package. This
 695 *              function attempts to repair this error by wrapping a Package
 696 *              object around the original Package, creating the correct
 697 *              Package with one sub-Package.
 698 *
 699 *              Names that can be repaired in this manner include:
 700 *              _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS
 701 *
 702 ******************************************************************************/
 703
 704acpi_status
 705acpi_ns_repair_package_list(struct acpi_predefined_data *data,
 706                            union acpi_operand_object **obj_desc_ptr)
 707{
 708        union acpi_operand_object *pkg_obj_desc;
 709
 710        ACPI_FUNCTION_NAME(ns_repair_package_list);
 711
 712        /*
 713         * Create the new outer package and populate it. The new package will
 714         * have a single element, the lone subpackage.
 715         */
 716        pkg_obj_desc = acpi_ut_create_package_object(1);
 717        if (!pkg_obj_desc) {
 718                return (AE_NO_MEMORY);
 719        }
 720
 721        pkg_obj_desc->package.elements[0] = *obj_desc_ptr;
 722
 723        /* Return the new object in the object pointer */
 724
 725        *obj_desc_ptr = pkg_obj_desc;
 726        data->flags |= ACPI_OBJECT_REPAIRED;
 727
 728        ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
 729                          "%s: Repaired incorrectly formed Package\n",
 730                          data->pathname));
 731
 732        return (AE_OK);
 733}
 734