ReactOS 0.4.15-dev-8058-ga7cbb60
nsrepair2.c
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Module Name: nsrepair2 - Repair for objects returned by specific
4 * predefined methods
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2022, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45#include "acpi.h"
46#include "accommon.h"
47#include "acnamesp.h"
48
49#define _COMPONENT ACPI_NAMESPACE
50 ACPI_MODULE_NAME ("nsrepair2")
51
52
53/*
54 * Information structure and handler for ACPI predefined names that can
55 * be repaired on a per-name basis.
56 */
57typedef
60 ACPI_OPERAND_OBJECT **ReturnObjectPtr);
61
63{
66
68
69
70/* Local prototypes */
71
72static const ACPI_REPAIR_INFO *
75
76static ACPI_STATUS
79 ACPI_OPERAND_OBJECT **ReturnObjectPtr);
80
81static ACPI_STATUS
84 ACPI_OPERAND_OBJECT **ReturnObjectPtr);
85
86static ACPI_STATUS
89 ACPI_OPERAND_OBJECT **ReturnObjectPtr);
90
91static ACPI_STATUS
94 ACPI_OPERAND_OBJECT **ReturnObjectPtr);
95
96static ACPI_STATUS
99 ACPI_OPERAND_OBJECT **ReturnObjectPtr);
100
101static ACPI_STATUS
104 ACPI_OPERAND_OBJECT **ReturnObjectPtr);
105
106static ACPI_STATUS
109 ACPI_OPERAND_OBJECT **ReturnObjectPtr);
110
111static ACPI_STATUS
114 ACPI_OPERAND_OBJECT **ReturnObjectPtr);
115
116static ACPI_STATUS
119 ACPI_OPERAND_OBJECT *ReturnObject,
120 UINT32 StartIndex,
121 UINT32 ExpectedCount,
122 UINT32 SortIndex,
123 UINT8 SortDirection,
124 char *SortKeyName);
125
126/* Values for SortDirection above */
127
128#define ACPI_SORT_ASCENDING 0
129#define ACPI_SORT_DESCENDING 1
130
131static void
133 ACPI_OPERAND_OBJECT *ObjDesc,
134 UINT32 Index);
135
136static void
138 ACPI_OPERAND_OBJECT **Elements,
141 UINT8 SortDirection);
142
143
144/*
145 * This table contains the names of the predefined methods for which we can
146 * perform more complex repairs.
147 *
148 * As necessary:
149 *
150 * _ALR: Sort the list ascending by AmbientIlluminance
151 * _CID: Strings: uppercase all, remove any leading asterisk
152 * _CST: Sort the list ascending by C state type
153 * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
154 * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
155 * _HID: Strings: uppercase all, remove any leading asterisk
156 * _PRT: Fix reversed SourceName and SourceIndex
157 * _PSS: Sort the list descending by Power
158 * _TSS: Sort the list descending by Power
159 *
160 * Names that must be packages, but cannot be sorted:
161 *
162 * _BCL: Values are tied to the Package index where they appear, and cannot
163 * be moved or sorted. These index values are used for _BQC and _BCM.
164 * However, we can fix the case where a buffer is returned, by converting
165 * it to a Package of integers.
166 */
168{
169 {"_ALR", AcpiNsRepair_ALR},
170 {"_CID", AcpiNsRepair_CID},
171 {"_CST", AcpiNsRepair_CST},
172 {"_FDE", AcpiNsRepair_FDE},
173 {"_GTM", AcpiNsRepair_FDE}, /* _GTM has same repair as _FDE */
174 {"_HID", AcpiNsRepair_HID},
175 {"_PRT", AcpiNsRepair_PRT},
176 {"_PSS", AcpiNsRepair_PSS},
177 {"_TSS", AcpiNsRepair_TSS},
178 {{0,0,0,0}, NULL} /* Table terminator */
179};
180
181
182#define ACPI_FDE_FIELD_COUNT 5
183#define ACPI_FDE_BYTE_BUFFER_SIZE 5
184#define ACPI_FDE_DWORD_BUFFER_SIZE (ACPI_FDE_FIELD_COUNT * (UINT32) sizeof (UINT32))
185
186
187/******************************************************************************
188 *
189 * FUNCTION: AcpiNsComplexRepairs
190 *
191 * PARAMETERS: Info - Method execution information block
192 * Node - Namespace node for the method/object
193 * ValidateStatus - Original status of earlier validation
194 * ReturnObjectPtr - Pointer to the object returned from the
195 * evaluation of a method or object
196 *
197 * RETURN: Status. AE_OK if repair was successful. If name is not
198 * matched, ValidateStatus is returned.
199 *
200 * DESCRIPTION: Attempt to repair/convert a return object of a type that was
201 * not expected.
202 *
203 *****************************************************************************/
204
209 ACPI_STATUS ValidateStatus,
210 ACPI_OPERAND_OBJECT **ReturnObjectPtr)
211{
212 const ACPI_REPAIR_INFO *Predefined;
214
215
216 ACPI_FUNCTION_TRACE (NsComplexRepairs);
217
218 /* Check if this name is in the list of repairable names */
219
220 Predefined = AcpiNsMatchComplexRepair (Node);
221 if (!Predefined)
222 {
223 return_ACPI_STATUS (ValidateStatus);
224 }
225
226 Status = Predefined->RepairFunction (Info, ReturnObjectPtr);
228}
229
230
231/******************************************************************************
232 *
233 * FUNCTION: AcpiNsMatchComplexRepair
234 *
235 * PARAMETERS: Node - Namespace node for the method/object
236 *
237 * RETURN: Pointer to entry in repair table. NULL indicates not found.
238 *
239 * DESCRIPTION: Check an object name against the repairable object list.
240 *
241 *****************************************************************************/
242
243static const ACPI_REPAIR_INFO *
246{
247 const ACPI_REPAIR_INFO *ThisName;
248
249
250 /* Search info table for a repairable predefined method/object name */
251
252 ThisName = AcpiNsRepairableNames;
253 while (ThisName->RepairFunction)
254 {
255 if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, ThisName->Name))
256 {
257 return (ThisName);
258 }
259
260 ThisName++;
261 }
262
263 return (NULL); /* Not found */
264}
265
266
267/******************************************************************************
268 *
269 * FUNCTION: AcpiNsRepair_ALR
270 *
271 * PARAMETERS: Info - Method execution information block
272 * ReturnObjectPtr - Pointer to the object returned from the
273 * evaluation of a method or object
274 *
275 * RETURN: Status. AE_OK if object is OK or was repaired successfully
276 *
277 * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list
278 * ascending by the ambient illuminance values.
279 *
280 *****************************************************************************/
281
282static ACPI_STATUS
285 ACPI_OPERAND_OBJECT **ReturnObjectPtr)
286{
287 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
289
290
291 Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 2, 1,
292 ACPI_SORT_ASCENDING, "AmbientIlluminance");
293
294 return (Status);
295}
296
297
298/******************************************************************************
299 *
300 * FUNCTION: AcpiNsRepair_FDE
301 *
302 * PARAMETERS: Info - Method execution information block
303 * ReturnObjectPtr - Pointer to the object returned from the
304 * evaluation of a method or object
305 *
306 * RETURN: Status. AE_OK if object is OK or was repaired successfully
307 *
308 * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return
309 * value is a Buffer of 5 DWORDs. This function repairs a common
310 * problem where the return value is a Buffer of BYTEs, not
311 * DWORDs.
312 *
313 *****************************************************************************/
314
315static ACPI_STATUS
318 ACPI_OPERAND_OBJECT **ReturnObjectPtr)
319{
320 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
321 ACPI_OPERAND_OBJECT *BufferObject;
322 UINT8 *ByteBuffer;
323 UINT32 *DwordBuffer;
324 UINT32 i;
325
326
327 ACPI_FUNCTION_NAME (NsRepair_FDE);
328
329
330 switch (ReturnObject->Common.Type)
331 {
332 case ACPI_TYPE_BUFFER:
333
334 /* This is the expected type. Length should be (at least) 5 DWORDs */
335
336 if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE)
337 {
338 return (AE_OK);
339 }
340
341 /* We can only repair if we have exactly 5 BYTEs */
342
343 if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE)
344 {
346 Info->FullPathname, Info->NodeFlags,
347 "Incorrect return buffer length %u, expected %u",
348 ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE));
349
350 return (AE_AML_OPERAND_TYPE);
351 }
352
353 /* Create the new (larger) buffer object */
354
355 BufferObject = AcpiUtCreateBufferObject (
357 if (!BufferObject)
358 {
359 return (AE_NO_MEMORY);
360 }
361
362 /* Expand each byte to a DWORD */
363
364 ByteBuffer = ReturnObject->Buffer.Pointer;
365 DwordBuffer = ACPI_CAST_PTR (UINT32,
366 BufferObject->Buffer.Pointer);
367
368 for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++)
369 {
370 *DwordBuffer = (UINT32) *ByteBuffer;
371 DwordBuffer++;
372 ByteBuffer++;
373 }
374
376 "%s Expanded Byte Buffer to expected DWord Buffer\n",
377 Info->FullPathname));
378 break;
379
380 default:
381
382 return (AE_AML_OPERAND_TYPE);
383 }
384
385 /* Delete the original return object, return the new buffer object */
386
387 AcpiUtRemoveReference (ReturnObject);
388 *ReturnObjectPtr = BufferObject;
389
390 Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
391 return (AE_OK);
392}
393
394
395/******************************************************************************
396 *
397 * FUNCTION: AcpiNsRepair_CID
398 *
399 * PARAMETERS: Info - Method execution information block
400 * ReturnObjectPtr - Pointer to the object returned from the
401 * evaluation of a method or object
402 *
403 * RETURN: Status. AE_OK if object is OK or was repaired successfully
404 *
405 * DESCRIPTION: Repair for the _CID object. If a string, ensure that all
406 * letters are uppercase and that there is no leading asterisk.
407 * If a Package, ensure same for all string elements.
408 *
409 *****************************************************************************/
410
411static ACPI_STATUS
414 ACPI_OPERAND_OBJECT **ReturnObjectPtr)
415{
417 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
418 ACPI_OPERAND_OBJECT **ElementPtr;
419 ACPI_OPERAND_OBJECT *OriginalElement;
420 UINT16 OriginalRefCount;
421 UINT32 i;
422
423 ACPI_FUNCTION_TRACE (NsRepair_CID);
424
425 /* Check for _CID as a simple string */
426
427 if (ReturnObject->Common.Type == ACPI_TYPE_STRING)
428 {
429 Status = AcpiNsRepair_HID (Info, ReturnObjectPtr);
431 }
432
433 /* Exit if not a Package */
434
435 if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
436 {
438 }
439
440 /* Examine each element of the _CID package */
441
442 ElementPtr = ReturnObject->Package.Elements;
443 for (i = 0; i < ReturnObject->Package.Count; i++)
444 {
445 OriginalElement = *ElementPtr;
446 OriginalRefCount = OriginalElement->Common.ReferenceCount;
447
448 Status = AcpiNsRepair_HID (Info, ElementPtr);
449 if (ACPI_FAILURE (Status))
450 {
452 }
453
454 if (OriginalElement != *ElementPtr)
455 {
456 /* Update reference count of new object */
457
458 (*ElementPtr)->Common.ReferenceCount =
459 OriginalRefCount;
460
461 /*
462 * The OriginalElement holds a reference from the package object
463 * that represents _HID. Since a new element was created by _HID,
464 * remove the reference from the _CID package.
465 */
466 AcpiUtRemoveReference (OriginalElement);
467 }
468
469 ElementPtr++;
470 }
471
473}
474
475
476/******************************************************************************
477 *
478 * FUNCTION: AcpiNsRepair_CST
479 *
480 * PARAMETERS: Info - Method execution information block
481 * ReturnObjectPtr - Pointer to the object returned from the
482 * evaluation of a method or object
483 *
484 * RETURN: Status. AE_OK if object is OK or was repaired successfully
485 *
486 * DESCRIPTION: Repair for the _CST object:
487 * 1. Sort the list ascending by C state type
488 * 2. Ensure type cannot be zero
489 * 3. A subpackage count of zero means _CST is meaningless
490 * 4. Count must match the number of C state subpackages
491 *
492 *****************************************************************************/
493
494static ACPI_STATUS
497 ACPI_OPERAND_OBJECT **ReturnObjectPtr)
498{
499 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
500 ACPI_OPERAND_OBJECT **OuterElements;
501 UINT32 OuterElementCount;
502 ACPI_OPERAND_OBJECT *ObjDesc;
504 BOOLEAN Removing;
505 UINT32 i;
506
507
508 ACPI_FUNCTION_NAME (NsRepair_CST);
509
510
511 /*
512 * Check if the C-state type values are proportional.
513 */
514 OuterElementCount = ReturnObject->Package.Count - 1;
515 i = 0;
516 while (i < OuterElementCount)
517 {
518 OuterElements = &ReturnObject->Package.Elements[i + 1];
519 Removing = FALSE;
520
521 if ((*OuterElements)->Package.Count == 0)
522 {
524 Info->FullPathname, Info->NodeFlags,
525 "SubPackage[%u] - removing entry due to zero count", i));
526 Removing = TRUE;
527 goto RemoveElement;
528 }
529
530 ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */
531 if ((UINT32) ObjDesc->Integer.Value == 0)
532 {
534 Info->FullPathname, Info->NodeFlags,
535 "SubPackage[%u] - removing entry due to invalid Type(0)", i));
536 Removing = TRUE;
537 }
538
539RemoveElement:
540 if (Removing)
541 {
542 AcpiNsRemoveElement (ReturnObject, i + 1);
543 OuterElementCount--;
544 }
545 else
546 {
547 i++;
548 }
549 }
550
551 /* Update top-level package count, Type "Integer" checked elsewhere */
552
553 ObjDesc = ReturnObject->Package.Elements[0];
554 ObjDesc->Integer.Value = OuterElementCount;
555
556 /*
557 * Entries (subpackages) in the _CST Package must be sorted by the
558 * C-state type, in ascending order.
559 */
560 Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1,
561 ACPI_SORT_ASCENDING, "C-State Type");
562 if (ACPI_FAILURE (Status))
563 {
564 return (Status);
565 }
566
567 return (AE_OK);
568}
569
570
571/******************************************************************************
572 *
573 * FUNCTION: AcpiNsRepair_HID
574 *
575 * PARAMETERS: Info - Method execution information block
576 * ReturnObjectPtr - Pointer to the object returned from the
577 * evaluation of a method or object
578 *
579 * RETURN: Status. AE_OK if object is OK or was repaired successfully
580 *
581 * DESCRIPTION: Repair for the _HID object. If a string, ensure that all
582 * letters are uppercase and that there is no leading asterisk.
583 *
584 *****************************************************************************/
585
586static ACPI_STATUS
589 ACPI_OPERAND_OBJECT **ReturnObjectPtr)
590{
591 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
592 ACPI_OPERAND_OBJECT *NewString;
593 char *Source;
594 char *Dest;
595
596
597 ACPI_FUNCTION_NAME (NsRepair_HID);
598
599
600 /* We only care about string _HID objects (not integers) */
601
602 if (ReturnObject->Common.Type != ACPI_TYPE_STRING)
603 {
605 }
606
607 if (ReturnObject->String.Length == 0)
608 {
610 Info->FullPathname, Info->NodeFlags,
611 "Invalid zero-length _HID or _CID string"));
612
613 /* Return AE_OK anyway, let driver handle it */
614
615 Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
617 }
618
619 /* It is simplest to always create a new string object */
620
621 NewString = AcpiUtCreateStringObject (ReturnObject->String.Length);
622 if (!NewString)
623 {
625 }
626
627 /*
628 * Remove a leading asterisk if present. For some unknown reason, there
629 * are many machines in the field that contains IDs like this.
630 *
631 * Examples: "*PNP0C03", "*ACPI0003"
632 */
633 Source = ReturnObject->String.Pointer;
634 if (*Source == '*')
635 {
636 Source++;
637 NewString->String.Length--;
638
640 "%s: Removed invalid leading asterisk\n", Info->FullPathname));
641 }
642
643 /*
644 * Copy and uppercase the string. From the ACPI 5.0 specification:
645 *
646 * A valid PNP ID must be of the form "AAA####" where A is an uppercase
647 * letter and # is a hex digit. A valid ACPI ID must be of the form
648 * "NNNN####" where N is an uppercase letter or decimal digit, and
649 * # is a hex digit.
650 */
651 for (Dest = NewString->String.Pointer; *Source; Dest++, Source++)
652 {
653 *Dest = (char) toupper ((int) *Source);
654 }
655
656 AcpiUtRemoveReference (ReturnObject);
657 *ReturnObjectPtr = NewString;
659}
660
661
662/******************************************************************************
663 *
664 * FUNCTION: AcpiNsRepair_PRT
665 *
666 * PARAMETERS: Info - Method execution information block
667 * ReturnObjectPtr - Pointer to the object returned from the
668 * evaluation of a method or object
669 *
670 * RETURN: Status. AE_OK if object is OK or was repaired successfully
671 *
672 * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed
673 * SourceName and SourceIndex field, a common BIOS bug.
674 *
675 *****************************************************************************/
676
677static ACPI_STATUS
680 ACPI_OPERAND_OBJECT **ReturnObjectPtr)
681{
682 ACPI_OPERAND_OBJECT *PackageObject = *ReturnObjectPtr;
683 ACPI_OPERAND_OBJECT **TopObjectList;
684 ACPI_OPERAND_OBJECT **SubObjectList;
685 ACPI_OPERAND_OBJECT *ObjDesc;
686 ACPI_OPERAND_OBJECT *SubPackage;
687 UINT32 ElementCount;
689
690
691 /* Each element in the _PRT package is a subpackage */
692
693 TopObjectList = PackageObject->Package.Elements;
694 ElementCount = PackageObject->Package.Count;
695
696 /* Examine each subpackage */
697
698 for (Index = 0; Index < ElementCount; Index++, TopObjectList++)
699 {
700 SubPackage = *TopObjectList;
701 SubObjectList = SubPackage->Package.Elements;
702
703 /* Check for minimum required element count */
704
705 if (SubPackage->Package.Count < 4)
706 {
707 continue;
708 }
709
710 /*
711 * If the BIOS has erroneously reversed the _PRT SourceName (index 2)
712 * and the SourceIndex (index 3), fix it. _PRT is important enough to
713 * workaround this BIOS error. This also provides compatibility with
714 * other ACPI implementations.
715 */
716 ObjDesc = SubObjectList[3];
717 if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER))
718 {
719 SubObjectList[3] = SubObjectList[2];
720 SubObjectList[2] = ObjDesc;
721 Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
722
724 Info->FullPathname, Info->NodeFlags,
725 "PRT[%X]: Fixed reversed SourceName and SourceIndex",
726 Index));
727 }
728 }
729
730 return (AE_OK);
731}
732
733
734/******************************************************************************
735 *
736 * FUNCTION: AcpiNsRepair_PSS
737 *
738 * PARAMETERS: Info - Method execution information block
739 * ReturnObjectPtr - Pointer to the object returned from the
740 * evaluation of a method or object
741 *
742 * RETURN: Status. AE_OK if object is OK or was repaired successfully
743 *
744 * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list
745 * by the CPU frequencies. Check that the power dissipation values
746 * are all proportional to CPU frequency (i.e., sorting by
747 * frequency should be the same as sorting by power.)
748 *
749 *****************************************************************************/
750
751static ACPI_STATUS
754 ACPI_OPERAND_OBJECT **ReturnObjectPtr)
755{
756 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
757 ACPI_OPERAND_OBJECT **OuterElements;
758 UINT32 OuterElementCount;
759 ACPI_OPERAND_OBJECT **Elements;
760 ACPI_OPERAND_OBJECT *ObjDesc;
761 UINT32 PreviousValue;
763 UINT32 i;
764
765
766 /*
767 * Entries (subpackages) in the _PSS Package must be sorted by power
768 * dissipation, in descending order. If it appears that the list is
769 * incorrectly sorted, sort it. We sort by CpuFrequency, since this
770 * should be proportional to the power.
771 */
772 Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 6, 0,
773 ACPI_SORT_DESCENDING, "CpuFrequency");
774 if (ACPI_FAILURE (Status))
775 {
776 return (Status);
777 }
778
779 /*
780 * We now know the list is correctly sorted by CPU frequency. Check if
781 * the power dissipation values are proportional.
782 */
783 PreviousValue = ACPI_UINT32_MAX;
784 OuterElements = ReturnObject->Package.Elements;
785 OuterElementCount = ReturnObject->Package.Count;
786
787 for (i = 0; i < OuterElementCount; i++)
788 {
789 Elements = (*OuterElements)->Package.Elements;
790 ObjDesc = Elements[1]; /* Index1 = PowerDissipation */
791
792 if ((UINT32) ObjDesc->Integer.Value > PreviousValue)
793 {
795 Info->FullPathname, Info->NodeFlags,
796 "SubPackage[%u,%u] - suspicious power dissipation values",
797 i-1, i));
798 }
799
800 PreviousValue = (UINT32) ObjDesc->Integer.Value;
801 OuterElements++;
802 }
803
804 return (AE_OK);
805}
806
807
808/******************************************************************************
809 *
810 * FUNCTION: AcpiNsRepair_TSS
811 *
812 * PARAMETERS: Info - Method execution information block
813 * ReturnObjectPtr - Pointer to the object returned from the
814 * evaluation of a method or object
815 *
816 * RETURN: Status. AE_OK if object is OK or was repaired successfully
817 *
818 * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
819 * descending by the power dissipation values.
820 *
821 *****************************************************************************/
822
823static ACPI_STATUS
826 ACPI_OPERAND_OBJECT **ReturnObjectPtr)
827{
828 ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
831
832
833 /*
834 * We can only sort the _TSS return package if there is no _PSS in the
835 * same scope. This is because if _PSS is present, the ACPI specification
836 * dictates that the _TSS Power Dissipation field is to be ignored, and
837 * therefore some BIOSs leave garbage values in the _TSS Power field(s).
838 * In this case, it is best to just return the _TSS package as-is.
839 * (May, 2011)
840 */
841 Status = AcpiNsGetNode (Info->Node, "^_PSS",
843 if (ACPI_SUCCESS (Status))
844 {
845 return (AE_OK);
846 }
847
848 Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1,
849 ACPI_SORT_DESCENDING, "PowerDissipation");
850
851 return (Status);
852}
853
854
855/******************************************************************************
856 *
857 * FUNCTION: AcpiNsCheckSortedList
858 *
859 * PARAMETERS: Info - Method execution information block
860 * ReturnObject - Pointer to the top-level returned object
861 * StartIndex - Index of the first subpackage
862 * ExpectedCount - Minimum length of each subpackage
863 * SortIndex - Subpackage entry to sort on
864 * SortDirection - Ascending or descending
865 * SortKeyName - Name of the SortIndex field
866 *
867 * RETURN: Status. AE_OK if the list is valid and is sorted correctly or
868 * has been repaired by sorting the list.
869 *
870 * DESCRIPTION: Check if the package list is valid and sorted correctly by the
871 * SortIndex. If not, then sort the list.
872 *
873 *****************************************************************************/
874
875static ACPI_STATUS
878 ACPI_OPERAND_OBJECT *ReturnObject,
879 UINT32 StartIndex,
880 UINT32 ExpectedCount,
881 UINT32 SortIndex,
882 UINT8 SortDirection,
883 char *SortKeyName)
884{
885 UINT32 OuterElementCount;
886 ACPI_OPERAND_OBJECT **OuterElements;
887 ACPI_OPERAND_OBJECT **Elements;
888 ACPI_OPERAND_OBJECT *ObjDesc;
889 UINT32 i;
890 UINT32 PreviousValue;
891
892
893 ACPI_FUNCTION_NAME (NsCheckSortedList);
894
895
896 /* The top-level object must be a package */
897
898 if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
899 {
900 return (AE_AML_OPERAND_TYPE);
901 }
902
903 /*
904 * NOTE: assumes list of subpackages contains no NULL elements.
905 * Any NULL elements should have been removed by earlier call
906 * to AcpiNsRemoveNullElements.
907 */
908 OuterElementCount = ReturnObject->Package.Count;
909 if (!OuterElementCount || StartIndex >= OuterElementCount)
910 {
911 return (AE_AML_PACKAGE_LIMIT);
912 }
913
914 OuterElements = &ReturnObject->Package.Elements[StartIndex];
915 OuterElementCount -= StartIndex;
916
917 PreviousValue = 0;
918 if (SortDirection == ACPI_SORT_DESCENDING)
919 {
920 PreviousValue = ACPI_UINT32_MAX;
921 }
922
923 /* Examine each subpackage */
924
925 for (i = 0; i < OuterElementCount; i++)
926 {
927 /* Each element of the top-level package must also be a package */
928
929 if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE)
930 {
931 return (AE_AML_OPERAND_TYPE);
932 }
933
934 /* Each subpackage must have the minimum length */
935
936 if ((*OuterElements)->Package.Count < ExpectedCount)
937 {
938 return (AE_AML_PACKAGE_LIMIT);
939 }
940
941 Elements = (*OuterElements)->Package.Elements;
942 ObjDesc = Elements[SortIndex];
943
944 if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
945 {
946 return (AE_AML_OPERAND_TYPE);
947 }
948
949 /*
950 * The list must be sorted in the specified order. If we detect a
951 * discrepancy, sort the entire list.
952 */
953 if (((SortDirection == ACPI_SORT_ASCENDING) &&
954 (ObjDesc->Integer.Value < PreviousValue)) ||
955 ((SortDirection == ACPI_SORT_DESCENDING) &&
956 (ObjDesc->Integer.Value > PreviousValue)))
957 {
958 AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex],
959 OuterElementCount, SortIndex, SortDirection);
960
961 Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
962
964 "%s: Repaired unsorted list - now sorted by %s\n",
965 Info->FullPathname, SortKeyName));
966 return (AE_OK);
967 }
968
969 PreviousValue = (UINT32) ObjDesc->Integer.Value;
970 OuterElements++;
971 }
972
973 return (AE_OK);
974}
975
976
977/******************************************************************************
978 *
979 * FUNCTION: AcpiNsSortList
980 *
981 * PARAMETERS: Elements - Package object element list
982 * Count - Element count for above
983 * Index - Sort by which package element
984 * SortDirection - Ascending or Descending sort
985 *
986 * RETURN: None
987 *
988 * DESCRIPTION: Sort the objects that are in a package element list.
989 *
990 * NOTE: Assumes that all NULL elements have been removed from the package,
991 * and that all elements have been verified to be of type Integer.
992 *
993 *****************************************************************************/
994
995static void
997 ACPI_OPERAND_OBJECT **Elements,
1000 UINT8 SortDirection)
1001{
1002 ACPI_OPERAND_OBJECT *ObjDesc1;
1003 ACPI_OPERAND_OBJECT *ObjDesc2;
1004 ACPI_OPERAND_OBJECT *TempObj;
1005 UINT32 i;
1006 UINT32 j;
1007
1008
1009 /* Simple bubble sort */
1010
1011 for (i = 1; i < Count; i++)
1012 {
1013 for (j = (Count - 1); j >= i; j--)
1014 {
1015 ObjDesc1 = Elements[j-1]->Package.Elements[Index];
1016 ObjDesc2 = Elements[j]->Package.Elements[Index];
1017
1018 if (((SortDirection == ACPI_SORT_ASCENDING) &&
1019 (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) ||
1020
1021 ((SortDirection == ACPI_SORT_DESCENDING) &&
1022 (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value)))
1023 {
1024 TempObj = Elements[j-1];
1025 Elements[j-1] = Elements[j];
1026 Elements[j] = TempObj;
1027 }
1028 }
1029 }
1030}
1031
1032
1033/******************************************************************************
1034 *
1035 * FUNCTION: AcpiNsRemoveElement
1036 *
1037 * PARAMETERS: ObjDesc - Package object element list
1038 * Index - Index of element to remove
1039 *
1040 * RETURN: None
1041 *
1042 * DESCRIPTION: Remove the requested element of a package and delete it.
1043 *
1044 *****************************************************************************/
1045
1046static void
1048 ACPI_OPERAND_OBJECT *ObjDesc,
1049 UINT32 Index)
1050{
1052 ACPI_OPERAND_OBJECT **Dest;
1053 UINT32 Count;
1054 UINT32 NewCount;
1055 UINT32 i;
1056
1057
1058 ACPI_FUNCTION_NAME (NsRemoveElement);
1059
1060
1061 Count = ObjDesc->Package.Count;
1062 NewCount = Count - 1;
1063
1064 Source = ObjDesc->Package.Elements;
1065 Dest = Source;
1066
1067 /* Examine all elements of the package object, remove matched index */
1068
1069 for (i = 0; i < Count; i++)
1070 {
1071 if (i == Index)
1072 {
1073 AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */
1075 }
1076 else
1077 {
1078 *Dest = *Source;
1079 Dest++;
1080 }
1081
1082 Source++;
1083 }
1084
1085 /* NULL terminate list and update the package count */
1086
1087 *Dest = NULL;
1088 ObjDesc->Package.Count = NewCount;
1089}
unsigned short UINT16
unsigned char BOOLEAN
unsigned char UINT8
unsigned int UINT32
int toupper(int c)
Definition: utclib.c:881
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
#define AE_AML_PACKAGE_LIMIT
Definition: acexcep.h:190
#define AE_NO_MEMORY
Definition: acexcep.h:112
#define AE_AML_OPERAND_TYPE
Definition: acexcep.h:182
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
#define AE_OK
Definition: acexcep.h:97
#define ACPI_WARN_PREDEFINED(plist)
Definition: acmacros.h:464
ACPI_STATUS AcpiNsGetNode(ACPI_NAMESPACE_NODE *PrefixNode, const char *ExternalPathname, UINT32 Flags, ACPI_NAMESPACE_NODE **OutNode)
Definition: nsutils.c:863
#define ACPI_NS_NO_UPSEARCH
Definition: acnamesp.h:62
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
#define return_ACPI_STATUS(s)
Definition: acoutput.h:496
#define ACPI_FUNCTION_TRACE(a)
Definition: acoutput.h:480
#define ACPI_DB_REPAIR
Definition: acoutput.h:154
#define AE_INFO
Definition: acoutput.h:230
#define ACPI_FUNCTION_NAME(a)
Definition: acoutput.h:479
#define ACPI_OBJECT_REPAIRED
Definition: acstruct.h:235
#define ACPI_TYPE_STRING
Definition: actypes.h:689
#define ACPI_TYPE_BUFFER
Definition: actypes.h:690
#define ACPI_COMPARE_NAMESEG(a, b)
Definition: actypes.h:564
#define ACPI_TYPE_INTEGER
Definition: actypes.h:688
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_CAST_PTR(t, p)
Definition: actypes.h:544
#define ACPI_UINT32_MAX
Definition: actypes.h:66
#define ACPI_TYPE_PACKAGE
Definition: actypes.h:691
#define ACPI_NAMESEG_SIZE
Definition: actypes.h:415
void AcpiUtRemoveReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:790
ACPI_OPERAND_OBJECT * AcpiUtCreateStringObject(ACPI_SIZE StringSize)
Definition: utobject.c:320
ACPI_OPERAND_OBJECT * AcpiUtCreateBufferObject(ACPI_SIZE BufferSize)
Definition: utobject.c:258
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
union node Node
Definition: types.h:1255
unsigned char
Definition: typeof.h:29
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
int Count
Definition: noreturn.cpp:7
static ACPI_STATUS AcpiNsRepair_TSS(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:824
static ACPI_STATUS AcpiNsCheckSortedList(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT *ReturnObject, UINT32 StartIndex, UINT32 ExpectedCount, UINT32 SortIndex, UINT8 SortDirection, char *SortKeyName)
Definition: nsrepair2.c:876
static ACPI_STATUS AcpiNsRepair_PRT(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:678
static ACPI_STATUS AcpiNsRepair_FDE(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:316
ACPI_STATUS AcpiNsComplexRepairs(ACPI_EVALUATE_INFO *Info, ACPI_NAMESPACE_NODE *Node, ACPI_STATUS ValidateStatus, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:206
static ACPI_STATUS AcpiNsRepair_ALR(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:283
static void AcpiNsRemoveElement(ACPI_OPERAND_OBJECT *ObjDesc, UINT32 Index)
Definition: nsrepair2.c:1047
static const ACPI_REPAIR_INFO AcpiNsRepairableNames[]
Definition: nsrepair2.c:167
static ACPI_STATUS AcpiNsRepair_PSS(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:752
#define ACPI_SORT_DESCENDING
Definition: nsrepair2.c:129
ACPI_STATUS(* ACPI_REPAIR_FUNCTION)(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:58
#define ACPI_FDE_DWORD_BUFFER_SIZE
Definition: nsrepair2.c:184
#define ACPI_SORT_ASCENDING
Definition: nsrepair2.c:128
static ACPI_STATUS AcpiNsRepair_CID(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:412
static const ACPI_REPAIR_INFO * AcpiNsMatchComplexRepair(ACPI_NAMESPACE_NODE *Node)
Definition: nsrepair2.c:244
static ACPI_STATUS AcpiNsRepair_HID(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:587
struct acpi_repair_info ACPI_REPAIR_INFO
static void AcpiNsSortList(ACPI_OPERAND_OBJECT **Elements, UINT32 Count, UINT32 Index, UINT8 SortDirection)
Definition: nsrepair2.c:996
static ACPI_STATUS AcpiNsRepair_CST(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:495
#define ACPI_FDE_FIELD_COUNT
Definition: nsrepair2.c:182
#define ACPI_FDE_BYTE_BUFFER_SIZE
Definition: nsrepair2.c:183
union acpi_operand_object ** Elements
Definition: acobject.h:161
ACPI_REPAIR_FUNCTION RepairFunction
Definition: nsrepair2.c:65
char Name[ACPI_NAMESEG_SIZE]
Definition: nsrepair2.c:64
ACPI_OBJECT_INTEGER Integer
Definition: acobject.h:520
ACPI_OBJECT_COMMON Common
Definition: acobject.h:519
ACPI_OBJECT_PACKAGE Package
Definition: acobject.h:523
ACPI_OBJECT_STRING String
Definition: acobject.h:521
ACPI_OBJECT_BUFFER Buffer
Definition: acobject.h:522
Definition: dlist.c:348
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_In_ WDFCOLLECTION _In_ ULONG Index