nsrepair.c revision 1.1.1.2 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 #define __NSREPAIR_C__
45
46 #include "acpi.h"
47 #include "accommon.h"
48 #include "acnamesp.h"
49 #include "acinterp.h"
50 #include "acpredef.h"
51
52 #define _COMPONENT ACPI_NAMESPACE
53 ACPI_MODULE_NAME ("nsrepair")
54
55
56 /*******************************************************************************
57 *
58 * This module attempts to repair or convert objects returned by the
59 * predefined methods to an object type that is expected, as per the ACPI
60 * specification. The need for this code is dictated by the many machines that
61 * return incorrect types for the standard predefined methods. Performing these
62 * conversions here, in one place, eliminates the need for individual ACPI
63 * device drivers to do the same. Note: Most of these conversions are different
64 * than the internal object conversion routines used for implicit object
65 * conversion.
66 *
67 * The following conversions can be performed as necessary:
68 *
69 * Integer -> String
70 * Integer -> Buffer
71 * String -> Integer
72 * String -> Buffer
73 * Buffer -> Integer
74 * Buffer -> String
75 * Buffer -> Package of Integers
76 * Package -> Package of one Package
77 *
78 * Additional possible repairs:
79 *
80 * Optional/unnecessary NULL package elements removed
81 * Required package elements that are NULL replaced by Integer/String/Buffer
82 * Incorrect standalone package wrapped with required outer package
83 *
84 ******************************************************************************/
85
86
87 /* Local prototypes */
88
89 static ACPI_STATUS
90 AcpiNsConvertToInteger (
91 ACPI_OPERAND_OBJECT *OriginalObject,
92 ACPI_OPERAND_OBJECT **ReturnObject);
93
94 static ACPI_STATUS
95 AcpiNsConvertToString (
96 ACPI_OPERAND_OBJECT *OriginalObject,
97 ACPI_OPERAND_OBJECT **ReturnObject);
98
99 static ACPI_STATUS
100 AcpiNsConvertToBuffer (
101 ACPI_OPERAND_OBJECT *OriginalObject,
102 ACPI_OPERAND_OBJECT **ReturnObject);
103
104 static ACPI_STATUS
105 AcpiNsConvertToPackage (
106 ACPI_OPERAND_OBJECT *OriginalObject,
107 ACPI_OPERAND_OBJECT **ReturnObject);
108
109
110 /*******************************************************************************
111 *
112 * FUNCTION: AcpiNsRepairObject
113 *
114 * PARAMETERS: Data - Pointer to validation data structure
115 * ExpectedBtypes - Object types expected
116 * PackageIndex - Index of object within parent package (if
117 * applicable - ACPI_NOT_PACKAGE_ELEMENT
118 * otherwise)
119 * ReturnObjectPtr - Pointer to the object returned from the
120 * evaluation of a method or object
121 *
122 * RETURN: Status. AE_OK if repair was successful.
123 *
124 * DESCRIPTION: Attempt to repair/convert a return object of a type that was
125 * not expected.
126 *
127 ******************************************************************************/
128
129 ACPI_STATUS
130 AcpiNsRepairObject (
131 ACPI_PREDEFINED_DATA *Data,
132 UINT32 ExpectedBtypes,
133 UINT32 PackageIndex,
134 ACPI_OPERAND_OBJECT **ReturnObjectPtr)
135 {
136 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
137 ACPI_OPERAND_OBJECT *NewObject;
138 ACPI_STATUS Status;
139
140
141 ACPI_FUNCTION_NAME (NsRepairObject);
142
143
144 /*
145 * At this point, we know that the type of the returned object was not
146 * one of the expected types for this predefined name. Attempt to
147 * repair the object by converting it to one of the expected object
148 * types for this predefined name.
149 */
150 if (ExpectedBtypes & ACPI_RTYPE_INTEGER)
151 {
152 Status = AcpiNsConvertToInteger (ReturnObject, &NewObject);
153 if (ACPI_SUCCESS (Status))
154 {
155 goto ObjectRepaired;
156 }
157 }
158 if (ExpectedBtypes & ACPI_RTYPE_STRING)
159 {
160 Status = AcpiNsConvertToString (ReturnObject, &NewObject);
161 if (ACPI_SUCCESS (Status))
162 {
163 goto ObjectRepaired;
164 }
165 }
166 if (ExpectedBtypes & ACPI_RTYPE_BUFFER)
167 {
168 Status = AcpiNsConvertToBuffer (ReturnObject, &NewObject);
169 if (ACPI_SUCCESS (Status))
170 {
171 goto ObjectRepaired;
172 }
173 }
174 if (ExpectedBtypes & ACPI_RTYPE_PACKAGE)
175 {
176 Status = AcpiNsConvertToPackage (ReturnObject, &NewObject);
177 if (ACPI_SUCCESS (Status))
178 {
179 goto ObjectRepaired;
180 }
181 }
182
183 /* We cannot repair this object */
184
185 return (AE_AML_OPERAND_TYPE);
186
187
188 ObjectRepaired:
189
190 /* Object was successfully repaired */
191
192 /*
193 * If the original object is a package element, we need to:
194 * 1. Set the reference count of the new object to match the
195 * reference count of the old object.
196 * 2. Decrement the reference count of the original object.
197 */
198 if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT)
199 {
200 NewObject->Common.ReferenceCount =
201 ReturnObject->Common.ReferenceCount;
202
203 if (ReturnObject->Common.ReferenceCount > 1)
204 {
205 ReturnObject->Common.ReferenceCount--;
206 }
207
208 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
209 "%s: Converted %s to expected %s at index %u\n",
210 Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject),
211 AcpiUtGetObjectTypeName (NewObject), PackageIndex));
212 }
213 else
214 {
215 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
216 "%s: Converted %s to expected %s\n",
217 Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject),
218 AcpiUtGetObjectTypeName (NewObject)));
219 }
220
221 /* Delete old object, install the new return object */
222
223 AcpiUtRemoveReference (ReturnObject);
224 *ReturnObjectPtr = NewObject;
225 Data->Flags |= ACPI_OBJECT_REPAIRED;
226 return (AE_OK);
227 }
228
229
230 /*******************************************************************************
231 *
232 * FUNCTION: AcpiNsConvertToInteger
233 *
234 * PARAMETERS: OriginalObject - Object to be converted
235 * ReturnObject - Where the new converted object is returned
236 *
237 * RETURN: Status. AE_OK if conversion was successful.
238 *
239 * DESCRIPTION: Attempt to convert a String/Buffer object to an Integer.
240 *
241 ******************************************************************************/
242
243 static ACPI_STATUS
244 AcpiNsConvertToInteger (
245 ACPI_OPERAND_OBJECT *OriginalObject,
246 ACPI_OPERAND_OBJECT **ReturnObject)
247 {
248 ACPI_OPERAND_OBJECT *NewObject;
249 ACPI_STATUS Status;
250 UINT64 Value = 0;
251 UINT32 i;
252
253
254 switch (OriginalObject->Common.Type)
255 {
256 case ACPI_TYPE_STRING:
257
258 /* String-to-Integer conversion */
259
260 Status = AcpiUtStrtoul64 (OriginalObject->String.Pointer,
261 ACPI_ANY_BASE, &Value);
262 if (ACPI_FAILURE (Status))
263 {
264 return (Status);
265 }
266 break;
267
268 case ACPI_TYPE_BUFFER:
269
270 /* Buffer-to-Integer conversion. Max buffer size is 64 bits. */
271
272 if (OriginalObject->Buffer.Length > 8)
273 {
274 return (AE_AML_OPERAND_TYPE);
275 }
276
277 /* Extract each buffer byte to create the integer */
278
279 for (i = 0; i < OriginalObject->Buffer.Length; i++)
280 {
281 Value |= ((UINT64) OriginalObject->Buffer.Pointer[i] << (i * 8));
282 }
283 break;
284
285 default:
286 return (AE_AML_OPERAND_TYPE);
287 }
288
289 NewObject = AcpiUtCreateIntegerObject (Value);
290 if (!NewObject)
291 {
292 return (AE_NO_MEMORY);
293 }
294
295 *ReturnObject = NewObject;
296 return (AE_OK);
297 }
298
299
300 /*******************************************************************************
301 *
302 * FUNCTION: AcpiNsConvertToString
303 *
304 * PARAMETERS: OriginalObject - Object to be converted
305 * ReturnObject - Where the new converted object is returned
306 *
307 * RETURN: Status. AE_OK if conversion was successful.
308 *
309 * DESCRIPTION: Attempt to convert a Integer/Buffer object to a String.
310 *
311 ******************************************************************************/
312
313 static ACPI_STATUS
314 AcpiNsConvertToString (
315 ACPI_OPERAND_OBJECT *OriginalObject,
316 ACPI_OPERAND_OBJECT **ReturnObject)
317 {
318 ACPI_OPERAND_OBJECT *NewObject;
319 ACPI_SIZE Length;
320 ACPI_STATUS Status;
321
322
323 switch (OriginalObject->Common.Type)
324 {
325 case ACPI_TYPE_INTEGER:
326 /*
327 * Integer-to-String conversion. Commonly, convert
328 * an integer of value 0 to a NULL string. The last element of
329 * _BIF and _BIX packages occasionally need this fix.
330 */
331 if (OriginalObject->Integer.Value == 0)
332 {
333 /* Allocate a new NULL string object */
334
335 NewObject = AcpiUtCreateStringObject (0);
336 if (!NewObject)
337 {
338 return (AE_NO_MEMORY);
339 }
340 }
341 else
342 {
343 Status = AcpiExConvertToString (OriginalObject, &NewObject,
344 ACPI_IMPLICIT_CONVERT_HEX);
345 if (ACPI_FAILURE (Status))
346 {
347 return (Status);
348 }
349 }
350 break;
351
352 case ACPI_TYPE_BUFFER:
353 /*
354 * Buffer-to-String conversion. Use a ToString
355 * conversion, no transform performed on the buffer data. The best
356 * example of this is the _BIF method, where the string data from
357 * the battery is often (incorrectly) returned as buffer object(s).
358 */
359 Length = 0;
360 while ((Length < OriginalObject->Buffer.Length) &&
361 (OriginalObject->Buffer.Pointer[Length]))
362 {
363 Length++;
364 }
365
366 /* Allocate a new string object */
367
368 NewObject = AcpiUtCreateStringObject (Length);
369 if (!NewObject)
370 {
371 return (AE_NO_MEMORY);
372 }
373
374 /*
375 * Copy the raw buffer data with no transform. String is already NULL
376 * terminated at Length+1.
377 */
378 ACPI_MEMCPY (NewObject->String.Pointer,
379 OriginalObject->Buffer.Pointer, Length);
380 break;
381
382 default:
383 return (AE_AML_OPERAND_TYPE);
384 }
385
386 *ReturnObject = NewObject;
387 return (AE_OK);
388 }
389
390
391 /*******************************************************************************
392 *
393 * FUNCTION: AcpiNsConvertToBuffer
394 *
395 * PARAMETERS: OriginalObject - Object to be converted
396 * ReturnObject - Where the new converted object is returned
397 *
398 * RETURN: Status. AE_OK if conversion was successful.
399 *
400 * DESCRIPTION: Attempt to convert a Integer/String/Package object to a Buffer.
401 *
402 ******************************************************************************/
403
404 static ACPI_STATUS
405 AcpiNsConvertToBuffer (
406 ACPI_OPERAND_OBJECT *OriginalObject,
407 ACPI_OPERAND_OBJECT **ReturnObject)
408 {
409 ACPI_OPERAND_OBJECT *NewObject;
410 ACPI_STATUS Status;
411 ACPI_OPERAND_OBJECT **Elements;
412 UINT32 *DwordBuffer;
413 UINT32 Count;
414 UINT32 i;
415
416
417 switch (OriginalObject->Common.Type)
418 {
419 case ACPI_TYPE_INTEGER:
420 /*
421 * Integer-to-Buffer conversion.
422 * Convert the Integer to a packed-byte buffer. _MAT and other
423 * objects need this sometimes, if a read has been performed on a
424 * Field object that is less than or equal to the global integer
425 * size (32 or 64 bits).
426 */
427 Status = AcpiExConvertToBuffer (OriginalObject, &NewObject);
428 if (ACPI_FAILURE (Status))
429 {
430 return (Status);
431 }
432 break;
433
434 case ACPI_TYPE_STRING:
435
436 /* String-to-Buffer conversion. Simple data copy */
437
438 NewObject = AcpiUtCreateBufferObject (OriginalObject->String.Length);
439 if (!NewObject)
440 {
441 return (AE_NO_MEMORY);
442 }
443
444 ACPI_MEMCPY (NewObject->Buffer.Pointer,
445 OriginalObject->String.Pointer, OriginalObject->String.Length);
446 break;
447
448 case ACPI_TYPE_PACKAGE:
449 /*
450 * This case is often seen for predefined names that must return a
451 * Buffer object with multiple DWORD integers within. For example,
452 * _FDE and _GTM. The Package can be converted to a Buffer.
453 */
454
455 /* All elements of the Package must be integers */
456
457 Elements = OriginalObject->Package.Elements;
458 Count = OriginalObject->Package.Count;
459
460 for (i = 0; i < Count; i++)
461 {
462 if ((!*Elements) ||
463 ((*Elements)->Common.Type != ACPI_TYPE_INTEGER))
464 {
465 return (AE_AML_OPERAND_TYPE);
466 }
467 Elements++;
468 }
469
470 /* Create the new buffer object to replace the Package */
471
472 NewObject = AcpiUtCreateBufferObject (ACPI_MUL_4 (Count));
473 if (!NewObject)
474 {
475 return (AE_NO_MEMORY);
476 }
477
478 /* Copy the package elements (integers) to the buffer as DWORDs */
479
480 Elements = OriginalObject->Package.Elements;
481 DwordBuffer = ACPI_CAST_PTR (UINT32, NewObject->Buffer.Pointer);
482
483 for (i = 0; i < Count; i++)
484 {
485 *DwordBuffer = (UINT32) (*Elements)->Integer.Value;
486 DwordBuffer++;
487 Elements++;
488 }
489 break;
490
491 default:
492 return (AE_AML_OPERAND_TYPE);
493 }
494
495 *ReturnObject = NewObject;
496 return (AE_OK);
497 }
498
499
500 /*******************************************************************************
501 *
502 * FUNCTION: AcpiNsConvertToPackage
503 *
504 * PARAMETERS: OriginalObject - Object to be converted
505 * ReturnObject - Where the new converted object is returned
506 *
507 * RETURN: Status. AE_OK if conversion was successful.
508 *
509 * DESCRIPTION: Attempt to convert a Buffer object to a Package. Each byte of
510 * the buffer is converted to a single integer package element.
511 *
512 ******************************************************************************/
513
514 static ACPI_STATUS
515 AcpiNsConvertToPackage (
516 ACPI_OPERAND_OBJECT *OriginalObject,
517 ACPI_OPERAND_OBJECT **ReturnObject)
518 {
519 ACPI_OPERAND_OBJECT *NewObject;
520 ACPI_OPERAND_OBJECT **Elements;
521 UINT32 Length;
522 UINT8 *Buffer;
523
524
525 switch (OriginalObject->Common.Type)
526 {
527 case ACPI_TYPE_BUFFER:
528
529 /* Buffer-to-Package conversion */
530
531 Length = OriginalObject->Buffer.Length;
532 NewObject = AcpiUtCreatePackageObject (Length);
533 if (!NewObject)
534 {
535 return (AE_NO_MEMORY);
536 }
537
538 /* Convert each buffer byte to an integer package element */
539
540 Elements = NewObject->Package.Elements;
541 Buffer = OriginalObject->Buffer.Pointer;
542
543 while (Length--)
544 {
545 *Elements = AcpiUtCreateIntegerObject ((UINT64) *Buffer);
546 if (!*Elements)
547 {
548 AcpiUtRemoveReference (NewObject);
549 return (AE_NO_MEMORY);
550 }
551 Elements++;
552 Buffer++;
553 }
554 break;
555
556 default:
557 return (AE_AML_OPERAND_TYPE);
558 }
559
560 *ReturnObject = NewObject;
561 return (AE_OK);
562 }
563
564
565 /*******************************************************************************
566 *
567 * FUNCTION: AcpiNsRepairNullElement
568 *
569 * PARAMETERS: Data - Pointer to validation data structure
570 * ExpectedBtypes - Object types expected
571 * PackageIndex - Index of object within parent package (if
572 * applicable - ACPI_NOT_PACKAGE_ELEMENT
573 * otherwise)
574 * ReturnObjectPtr - Pointer to the object returned from the
575 * evaluation of a method or object
576 *
577 * RETURN: Status. AE_OK if repair was successful.
578 *
579 * DESCRIPTION: Attempt to repair a NULL element of a returned Package object.
580 *
581 ******************************************************************************/
582
583 ACPI_STATUS
584 AcpiNsRepairNullElement (
585 ACPI_PREDEFINED_DATA *Data,
586 UINT32 ExpectedBtypes,
587 UINT32 PackageIndex,
588 ACPI_OPERAND_OBJECT **ReturnObjectPtr)
589 {
590 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
591 ACPI_OPERAND_OBJECT *NewObject;
592
593
594 ACPI_FUNCTION_NAME (NsRepairNullElement);
595
596
597 /* No repair needed if return object is non-NULL */
598
599 if (ReturnObject)
600 {
601 return (AE_OK);
602 }
603
604 /*
605 * Attempt to repair a NULL element of a Package object. This applies to
606 * predefined names that return a fixed-length package and each element
607 * is required. It does not apply to variable-length packages where NULL
608 * elements are allowed, especially at the end of the package.
609 */
610 if (ExpectedBtypes & ACPI_RTYPE_INTEGER)
611 {
612 /* Need an Integer - create a zero-value integer */
613
614 NewObject = AcpiUtCreateIntegerObject ((UINT64) 0);
615 }
616 else if (ExpectedBtypes & ACPI_RTYPE_STRING)
617 {
618 /* Need a String - create a NULL string */
619
620 NewObject = AcpiUtCreateStringObject (0);
621 }
622 else if (ExpectedBtypes & ACPI_RTYPE_BUFFER)
623 {
624 /* Need a Buffer - create a zero-length buffer */
625
626 NewObject = AcpiUtCreateBufferObject (0);
627 }
628 else
629 {
630 /* Error for all other expected types */
631
632 return (AE_AML_OPERAND_TYPE);
633 }
634
635 if (!NewObject)
636 {
637 return (AE_NO_MEMORY);
638 }
639
640 /* Set the reference count according to the parent Package object */
641
642 NewObject->Common.ReferenceCount = Data->ParentPackage->Common.ReferenceCount;
643
644 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
645 "%s: Converted NULL package element to expected %s at index %u\n",
646 Data->Pathname, AcpiUtGetObjectTypeName (NewObject), PackageIndex));
647
648 *ReturnObjectPtr = NewObject;
649 Data->Flags |= ACPI_OBJECT_REPAIRED;
650 return (AE_OK);
651 }
652
653
654 /******************************************************************************
655 *
656 * FUNCTION: AcpiNsRemoveNullElements
657 *
658 * PARAMETERS: Data - Pointer to validation data structure
659 * PackageType - An AcpiReturnPackageTypes value
660 * ObjDesc - A Package object
661 *
662 * RETURN: None.
663 *
664 * DESCRIPTION: Remove all NULL package elements from packages that contain
665 * a variable number of sub-packages. For these types of
666 * packages, NULL elements can be safely removed.
667 *
668 *****************************************************************************/
669
670 void
671 AcpiNsRemoveNullElements (
672 ACPI_PREDEFINED_DATA *Data,
673 UINT8 PackageType,
674 ACPI_OPERAND_OBJECT *ObjDesc)
675 {
676 ACPI_OPERAND_OBJECT **Source;
677 ACPI_OPERAND_OBJECT **Dest;
678 UINT32 Count;
679 UINT32 NewCount;
680 UINT32 i;
681
682
683 ACPI_FUNCTION_NAME (NsRemoveNullElements);
684
685
686 /*
687 * PTYPE1 packages contain no subpackages.
688 * PTYPE2 packages contain a variable number of sub-packages. We can
689 * safely remove all NULL elements from the PTYPE2 packages.
690 */
691 switch (PackageType)
692 {
693 case ACPI_PTYPE1_FIXED:
694 case ACPI_PTYPE1_VAR:
695 case ACPI_PTYPE1_OPTION:
696 return;
697
698 case ACPI_PTYPE2:
699 case ACPI_PTYPE2_COUNT:
700 case ACPI_PTYPE2_PKG_COUNT:
701 case ACPI_PTYPE2_FIXED:
702 case ACPI_PTYPE2_MIN:
703 case ACPI_PTYPE2_REV_FIXED:
704 break;
705
706 default:
707 return;
708 }
709
710 Count = ObjDesc->Package.Count;
711 NewCount = Count;
712
713 Source = ObjDesc->Package.Elements;
714 Dest = Source;
715
716 /* Examine all elements of the package object, remove nulls */
717
718 for (i = 0; i < Count; i++)
719 {
720 if (!*Source)
721 {
722 NewCount--;
723 }
724 else
725 {
726 *Dest = *Source;
727 Dest++;
728 }
729 Source++;
730 }
731
732 /* Update parent package if any null elements were removed */
733
734 if (NewCount < Count)
735 {
736 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
737 "%s: Found and removed %u NULL elements\n",
738 Data->Pathname, (Count - NewCount)));
739
740 /* NULL terminate list and update the package count */
741
742 *Dest = NULL;
743 ObjDesc->Package.Count = NewCount;
744 }
745 }
746
747
748 /*******************************************************************************
749 *
750 * FUNCTION: AcpiNsRepairPackageList
751 *
752 * PARAMETERS: Data - Pointer to validation data structure
753 * ObjDescPtr - Pointer to the object to repair. The new
754 * package object is returned here,
755 * overwriting the old object.
756 *
757 * RETURN: Status, new object in *ObjDescPtr
758 *
759 * DESCRIPTION: Repair a common problem with objects that are defined to return
760 * a variable-length Package of Packages. If the variable-length
761 * is one, some BIOS code mistakenly simply declares a single
762 * Package instead of a Package with one sub-Package. This
763 * function attempts to repair this error by wrapping a Package
764 * object around the original Package, creating the correct
765 * Package with one sub-Package.
766 *
767 * Names that can be repaired in this manner include:
768 * _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS
769 *
770 ******************************************************************************/
771
772 ACPI_STATUS
773 AcpiNsRepairPackageList (
774 ACPI_PREDEFINED_DATA *Data,
775 ACPI_OPERAND_OBJECT **ObjDescPtr)
776 {
777 ACPI_OPERAND_OBJECT *PkgObjDesc;
778
779
780 ACPI_FUNCTION_NAME (NsRepairPackageList);
781
782
783 /*
784 * Create the new outer package and populate it. The new package will
785 * have a single element, the lone subpackage.
786 */
787 PkgObjDesc = AcpiUtCreatePackageObject (1);
788 if (!PkgObjDesc)
789 {
790 return (AE_NO_MEMORY);
791 }
792
793 PkgObjDesc->Package.Elements[0] = *ObjDescPtr;
794
795 /* Return the new object in the object pointer */
796
797 *ObjDescPtr = PkgObjDesc;
798 Data->Flags |= ACPI_OBJECT_REPAIRED;
799
800 ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
801 "%s: Repaired incorrectly formed Package\n", Data->Pathname));
802
803 return (AE_OK);
804 }
805