ReactOS  0.4.15-dev-492-ga1108f6
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 - 2020, 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 MERCHANTIBILITY 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  */
57 typedef
60  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
61 
63 {
66 
68 
69 
70 /* Local prototypes */
71 
72 static const ACPI_REPAIR_INFO *
75 
76 static ACPI_STATUS
79  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
80 
81 static ACPI_STATUS
84  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
85 
86 static ACPI_STATUS
89  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
90 
91 static ACPI_STATUS
94  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
95 
96 static ACPI_STATUS
99  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
100 
101 static ACPI_STATUS
104  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
105 
106 static ACPI_STATUS
109  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
110 
111 static ACPI_STATUS
114  ACPI_OPERAND_OBJECT **ReturnObjectPtr);
115 
116 static 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 
131 static void
133  ACPI_OPERAND_OBJECT *ObjDesc,
134  UINT32 Index);
135 
136 static void
138  ACPI_OPERAND_OBJECT **Elements,
139  UINT32 Count,
140  UINT32 Index,
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  /* Check if this name is in the list of repairable names */
217 
218  Predefined = AcpiNsMatchComplexRepair (Node);
219  if (!Predefined)
220  {
221  return (ValidateStatus);
222  }
223 
224  Status = Predefined->RepairFunction (Info, ReturnObjectPtr);
225  return (Status);
226 }
227 
228 
229 /******************************************************************************
230  *
231  * FUNCTION: AcpiNsMatchComplexRepair
232  *
233  * PARAMETERS: Node - Namespace node for the method/object
234  *
235  * RETURN: Pointer to entry in repair table. NULL indicates not found.
236  *
237  * DESCRIPTION: Check an object name against the repairable object list.
238  *
239  *****************************************************************************/
240 
241 static const ACPI_REPAIR_INFO *
244 {
245  const ACPI_REPAIR_INFO *ThisName;
246 
247 
248  /* Search info table for a repairable predefined method/object name */
249 
250  ThisName = AcpiNsRepairableNames;
251  while (ThisName->RepairFunction)
252  {
253  if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, ThisName->Name))
254  {
255  return (ThisName);
256  }
257 
258  ThisName++;
259  }
260 
261  return (NULL); /* Not found */
262 }
263 
264 
265 /******************************************************************************
266  *
267  * FUNCTION: AcpiNsRepair_ALR
268  *
269  * PARAMETERS: Info - Method execution information block
270  * ReturnObjectPtr - Pointer to the object returned from the
271  * evaluation of a method or object
272  *
273  * RETURN: Status. AE_OK if object is OK or was repaired successfully
274  *
275  * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list
276  * ascending by the ambient illuminance values.
277  *
278  *****************************************************************************/
279 
280 static ACPI_STATUS
283  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
284 {
285  ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
287 
288 
289  Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 2, 1,
290  ACPI_SORT_ASCENDING, "AmbientIlluminance");
291 
292  return (Status);
293 }
294 
295 
296 /******************************************************************************
297  *
298  * FUNCTION: AcpiNsRepair_FDE
299  *
300  * PARAMETERS: Info - Method execution information block
301  * ReturnObjectPtr - Pointer to the object returned from the
302  * evaluation of a method or object
303  *
304  * RETURN: Status. AE_OK if object is OK or was repaired successfully
305  *
306  * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return
307  * value is a Buffer of 5 DWORDs. This function repairs a common
308  * problem where the return value is a Buffer of BYTEs, not
309  * DWORDs.
310  *
311  *****************************************************************************/
312 
313 static ACPI_STATUS
316  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
317 {
318  ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
319  ACPI_OPERAND_OBJECT *BufferObject;
320  UINT8 *ByteBuffer;
321  UINT32 *DwordBuffer;
322  UINT32 i;
323 
324 
325  ACPI_FUNCTION_NAME (NsRepair_FDE);
326 
327 
328  switch (ReturnObject->Common.Type)
329  {
330  case ACPI_TYPE_BUFFER:
331 
332  /* This is the expected type. Length should be (at least) 5 DWORDs */
333 
334  if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE)
335  {
336  return (AE_OK);
337  }
338 
339  /* We can only repair if we have exactly 5 BYTEs */
340 
341  if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE)
342  {
344  Info->FullPathname, Info->NodeFlags,
345  "Incorrect return buffer length %u, expected %u",
346  ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE));
347 
348  return (AE_AML_OPERAND_TYPE);
349  }
350 
351  /* Create the new (larger) buffer object */
352 
353  BufferObject = AcpiUtCreateBufferObject (
355  if (!BufferObject)
356  {
357  return (AE_NO_MEMORY);
358  }
359 
360  /* Expand each byte to a DWORD */
361 
362  ByteBuffer = ReturnObject->Buffer.Pointer;
363  DwordBuffer = ACPI_CAST_PTR (UINT32,
364  BufferObject->Buffer.Pointer);
365 
366  for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++)
367  {
368  *DwordBuffer = (UINT32) *ByteBuffer;
369  DwordBuffer++;
370  ByteBuffer++;
371  }
372 
374  "%s Expanded Byte Buffer to expected DWord Buffer\n",
375  Info->FullPathname));
376  break;
377 
378  default:
379 
380  return (AE_AML_OPERAND_TYPE);
381  }
382 
383  /* Delete the original return object, return the new buffer object */
384 
385  AcpiUtRemoveReference (ReturnObject);
386  *ReturnObjectPtr = BufferObject;
387 
388  Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
389  return (AE_OK);
390 }
391 
392 
393 /******************************************************************************
394  *
395  * FUNCTION: AcpiNsRepair_CID
396  *
397  * PARAMETERS: Info - Method execution information block
398  * ReturnObjectPtr - Pointer to the object returned from the
399  * evaluation of a method or object
400  *
401  * RETURN: Status. AE_OK if object is OK or was repaired successfully
402  *
403  * DESCRIPTION: Repair for the _CID object. If a string, ensure that all
404  * letters are uppercase and that there is no leading asterisk.
405  * If a Package, ensure same for all string elements.
406  *
407  *****************************************************************************/
408 
409 static ACPI_STATUS
412  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
413 {
415  ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
416  ACPI_OPERAND_OBJECT **ElementPtr;
417  ACPI_OPERAND_OBJECT *OriginalElement;
418  UINT16 OriginalRefCount;
419  UINT32 i;
420 
421 
422  /* Check for _CID as a simple string */
423 
424  if (ReturnObject->Common.Type == ACPI_TYPE_STRING)
425  {
426  Status = AcpiNsRepair_HID (Info, ReturnObjectPtr);
427  return (Status);
428  }
429 
430  /* Exit if not a Package */
431 
432  if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
433  {
434  return (AE_OK);
435  }
436 
437  /* Examine each element of the _CID package */
438 
439  ElementPtr = ReturnObject->Package.Elements;
440  for (i = 0; i < ReturnObject->Package.Count; i++)
441  {
442  OriginalElement = *ElementPtr;
443  OriginalRefCount = OriginalElement->Common.ReferenceCount;
444 
445  Status = AcpiNsRepair_HID (Info, ElementPtr);
446  if (ACPI_FAILURE (Status))
447  {
448  return (Status);
449  }
450 
451  if (OriginalElement != *ElementPtr)
452  {
453  /* Update reference count of new object */
454 
455  (*ElementPtr)->Common.ReferenceCount =
456  OriginalRefCount;
457  }
458 
459  ElementPtr++;
460  }
461 
462  return (AE_OK);
463 }
464 
465 
466 /******************************************************************************
467  *
468  * FUNCTION: AcpiNsRepair_CST
469  *
470  * PARAMETERS: Info - Method execution information block
471  * ReturnObjectPtr - Pointer to the object returned from the
472  * evaluation of a method or object
473  *
474  * RETURN: Status. AE_OK if object is OK or was repaired successfully
475  *
476  * DESCRIPTION: Repair for the _CST object:
477  * 1. Sort the list ascending by C state type
478  * 2. Ensure type cannot be zero
479  * 3. A subpackage count of zero means _CST is meaningless
480  * 4. Count must match the number of C state subpackages
481  *
482  *****************************************************************************/
483 
484 static ACPI_STATUS
487  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
488 {
489  ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
490  ACPI_OPERAND_OBJECT **OuterElements;
491  UINT32 OuterElementCount;
492  ACPI_OPERAND_OBJECT *ObjDesc;
494  BOOLEAN Removing;
495  UINT32 i;
496 
497 
498  ACPI_FUNCTION_NAME (NsRepair_CST);
499 
500 
501  /*
502  * Check if the C-state type values are proportional.
503  */
504  OuterElementCount = ReturnObject->Package.Count - 1;
505  i = 0;
506  while (i < OuterElementCount)
507  {
508  OuterElements = &ReturnObject->Package.Elements[i + 1];
509  Removing = FALSE;
510 
511  if ((*OuterElements)->Package.Count == 0)
512  {
514  Info->FullPathname, Info->NodeFlags,
515  "SubPackage[%u] - removing entry due to zero count", i));
516  Removing = TRUE;
517  goto RemoveElement;
518  }
519 
520  ObjDesc = (*OuterElements)->Package.Elements[1]; /* Index1 = Type */
521  if ((UINT32) ObjDesc->Integer.Value == 0)
522  {
524  Info->FullPathname, Info->NodeFlags,
525  "SubPackage[%u] - removing entry due to invalid Type(0)", i));
526  Removing = TRUE;
527  }
528 
529 RemoveElement:
530  if (Removing)
531  {
532  AcpiNsRemoveElement (ReturnObject, i + 1);
533  OuterElementCount--;
534  }
535  else
536  {
537  i++;
538  }
539  }
540 
541  /* Update top-level package count, Type "Integer" checked elsewhere */
542 
543  ObjDesc = ReturnObject->Package.Elements[0];
544  ObjDesc->Integer.Value = OuterElementCount;
545 
546  /*
547  * Entries (subpackages) in the _CST Package must be sorted by the
548  * C-state type, in ascending order.
549  */
550  Status = AcpiNsCheckSortedList (Info, ReturnObject, 1, 4, 1,
551  ACPI_SORT_ASCENDING, "C-State Type");
552  if (ACPI_FAILURE (Status))
553  {
554  return (Status);
555  }
556 
557  return (AE_OK);
558 }
559 
560 
561 /******************************************************************************
562  *
563  * FUNCTION: AcpiNsRepair_HID
564  *
565  * PARAMETERS: Info - Method execution information block
566  * ReturnObjectPtr - Pointer to the object returned from the
567  * evaluation of a method or object
568  *
569  * RETURN: Status. AE_OK if object is OK or was repaired successfully
570  *
571  * DESCRIPTION: Repair for the _HID object. If a string, ensure that all
572  * letters are uppercase and that there is no leading asterisk.
573  *
574  *****************************************************************************/
575 
576 static ACPI_STATUS
579  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
580 {
581  ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
582  ACPI_OPERAND_OBJECT *NewString;
583  char *Source;
584  char *Dest;
585 
586 
587  ACPI_FUNCTION_NAME (NsRepair_HID);
588 
589 
590  /* We only care about string _HID objects (not integers) */
591 
592  if (ReturnObject->Common.Type != ACPI_TYPE_STRING)
593  {
594  return (AE_OK);
595  }
596 
597  if (ReturnObject->String.Length == 0)
598  {
600  Info->FullPathname, Info->NodeFlags,
601  "Invalid zero-length _HID or _CID string"));
602 
603  /* Return AE_OK anyway, let driver handle it */
604 
605  Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
606  return (AE_OK);
607  }
608 
609  /* It is simplest to always create a new string object */
610 
611  NewString = AcpiUtCreateStringObject (ReturnObject->String.Length);
612  if (!NewString)
613  {
614  return (AE_NO_MEMORY);
615  }
616 
617  /*
618  * Remove a leading asterisk if present. For some unknown reason, there
619  * are many machines in the field that contains IDs like this.
620  *
621  * Examples: "*PNP0C03", "*ACPI0003"
622  */
623  Source = ReturnObject->String.Pointer;
624  if (*Source == '*')
625  {
626  Source++;
627  NewString->String.Length--;
628 
630  "%s: Removed invalid leading asterisk\n", Info->FullPathname));
631  }
632 
633  /*
634  * Copy and uppercase the string. From the ACPI 5.0 specification:
635  *
636  * A valid PNP ID must be of the form "AAA####" where A is an uppercase
637  * letter and # is a hex digit. A valid ACPI ID must be of the form
638  * "NNNN####" where N is an uppercase letter or decimal digit, and
639  * # is a hex digit.
640  */
641  for (Dest = NewString->String.Pointer; *Source; Dest++, Source++)
642  {
643  *Dest = (char) toupper ((int) *Source);
644  }
645 
646  AcpiUtRemoveReference (ReturnObject);
647  *ReturnObjectPtr = NewString;
648  return (AE_OK);
649 }
650 
651 
652 /******************************************************************************
653  *
654  * FUNCTION: AcpiNsRepair_PRT
655  *
656  * PARAMETERS: Info - Method execution information block
657  * ReturnObjectPtr - Pointer to the object returned from the
658  * evaluation of a method or object
659  *
660  * RETURN: Status. AE_OK if object is OK or was repaired successfully
661  *
662  * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed
663  * SourceName and SourceIndex field, a common BIOS bug.
664  *
665  *****************************************************************************/
666 
667 static ACPI_STATUS
670  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
671 {
672  ACPI_OPERAND_OBJECT *PackageObject = *ReturnObjectPtr;
673  ACPI_OPERAND_OBJECT **TopObjectList;
674  ACPI_OPERAND_OBJECT **SubObjectList;
675  ACPI_OPERAND_OBJECT *ObjDesc;
676  ACPI_OPERAND_OBJECT *SubPackage;
677  UINT32 ElementCount;
678  UINT32 Index;
679 
680 
681  /* Each element in the _PRT package is a subpackage */
682 
683  TopObjectList = PackageObject->Package.Elements;
684  ElementCount = PackageObject->Package.Count;
685 
686  /* Examine each subpackage */
687 
688  for (Index = 0; Index < ElementCount; Index++, TopObjectList++)
689  {
690  SubPackage = *TopObjectList;
691  SubObjectList = SubPackage->Package.Elements;
692 
693  /* Check for minimum required element count */
694 
695  if (SubPackage->Package.Count < 4)
696  {
697  continue;
698  }
699 
700  /*
701  * If the BIOS has erroneously reversed the _PRT SourceName (index 2)
702  * and the SourceIndex (index 3), fix it. _PRT is important enough to
703  * workaround this BIOS error. This also provides compatibility with
704  * other ACPI implementations.
705  */
706  ObjDesc = SubObjectList[3];
707  if (!ObjDesc || (ObjDesc->Common.Type != ACPI_TYPE_INTEGER))
708  {
709  SubObjectList[3] = SubObjectList[2];
710  SubObjectList[2] = ObjDesc;
711  Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
712 
714  Info->FullPathname, Info->NodeFlags,
715  "PRT[%X]: Fixed reversed SourceName and SourceIndex",
716  Index));
717  }
718  }
719 
720  return (AE_OK);
721 }
722 
723 
724 /******************************************************************************
725  *
726  * FUNCTION: AcpiNsRepair_PSS
727  *
728  * PARAMETERS: Info - Method execution information block
729  * ReturnObjectPtr - Pointer to the object returned from the
730  * evaluation of a method or object
731  *
732  * RETURN: Status. AE_OK if object is OK or was repaired successfully
733  *
734  * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list
735  * by the CPU frequencies. Check that the power dissipation values
736  * are all proportional to CPU frequency (i.e., sorting by
737  * frequency should be the same as sorting by power.)
738  *
739  *****************************************************************************/
740 
741 static ACPI_STATUS
744  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
745 {
746  ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
747  ACPI_OPERAND_OBJECT **OuterElements;
748  UINT32 OuterElementCount;
749  ACPI_OPERAND_OBJECT **Elements;
750  ACPI_OPERAND_OBJECT *ObjDesc;
751  UINT32 PreviousValue;
753  UINT32 i;
754 
755 
756  /*
757  * Entries (subpackages) in the _PSS Package must be sorted by power
758  * dissipation, in descending order. If it appears that the list is
759  * incorrectly sorted, sort it. We sort by CpuFrequency, since this
760  * should be proportional to the power.
761  */
762  Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 6, 0,
763  ACPI_SORT_DESCENDING, "CpuFrequency");
764  if (ACPI_FAILURE (Status))
765  {
766  return (Status);
767  }
768 
769  /*
770  * We now know the list is correctly sorted by CPU frequency. Check if
771  * the power dissipation values are proportional.
772  */
773  PreviousValue = ACPI_UINT32_MAX;
774  OuterElements = ReturnObject->Package.Elements;
775  OuterElementCount = ReturnObject->Package.Count;
776 
777  for (i = 0; i < OuterElementCount; i++)
778  {
779  Elements = (*OuterElements)->Package.Elements;
780  ObjDesc = Elements[1]; /* Index1 = PowerDissipation */
781 
782  if ((UINT32) ObjDesc->Integer.Value > PreviousValue)
783  {
785  Info->FullPathname, Info->NodeFlags,
786  "SubPackage[%u,%u] - suspicious power dissipation values",
787  i-1, i));
788  }
789 
790  PreviousValue = (UINT32) ObjDesc->Integer.Value;
791  OuterElements++;
792  }
793 
794  return (AE_OK);
795 }
796 
797 
798 /******************************************************************************
799  *
800  * FUNCTION: AcpiNsRepair_TSS
801  *
802  * PARAMETERS: Info - Method execution information block
803  * ReturnObjectPtr - Pointer to the object returned from the
804  * evaluation of a method or object
805  *
806  * RETURN: Status. AE_OK if object is OK or was repaired successfully
807  *
808  * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
809  * descending by the power dissipation values.
810  *
811  *****************************************************************************/
812 
813 static ACPI_STATUS
816  ACPI_OPERAND_OBJECT **ReturnObjectPtr)
817 {
818  ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr;
821 
822 
823  /*
824  * We can only sort the _TSS return package if there is no _PSS in the
825  * same scope. This is because if _PSS is present, the ACPI specification
826  * dictates that the _TSS Power Dissipation field is to be ignored, and
827  * therefore some BIOSs leave garbage values in the _TSS Power field(s).
828  * In this case, it is best to just return the _TSS package as-is.
829  * (May, 2011)
830  */
831  Status = AcpiNsGetNode (Info->Node, "^_PSS",
833  if (ACPI_SUCCESS (Status))
834  {
835  return (AE_OK);
836  }
837 
838  Status = AcpiNsCheckSortedList (Info, ReturnObject, 0, 5, 1,
839  ACPI_SORT_DESCENDING, "PowerDissipation");
840 
841  return (Status);
842 }
843 
844 
845 /******************************************************************************
846  *
847  * FUNCTION: AcpiNsCheckSortedList
848  *
849  * PARAMETERS: Info - Method execution information block
850  * ReturnObject - Pointer to the top-level returned object
851  * StartIndex - Index of the first subpackage
852  * ExpectedCount - Minimum length of each subpackage
853  * SortIndex - Subpackage entry to sort on
854  * SortDirection - Ascending or descending
855  * SortKeyName - Name of the SortIndex field
856  *
857  * RETURN: Status. AE_OK if the list is valid and is sorted correctly or
858  * has been repaired by sorting the list.
859  *
860  * DESCRIPTION: Check if the package list is valid and sorted correctly by the
861  * SortIndex. If not, then sort the list.
862  *
863  *****************************************************************************/
864 
865 static ACPI_STATUS
868  ACPI_OPERAND_OBJECT *ReturnObject,
869  UINT32 StartIndex,
870  UINT32 ExpectedCount,
871  UINT32 SortIndex,
872  UINT8 SortDirection,
873  char *SortKeyName)
874 {
875  UINT32 OuterElementCount;
876  ACPI_OPERAND_OBJECT **OuterElements;
877  ACPI_OPERAND_OBJECT **Elements;
878  ACPI_OPERAND_OBJECT *ObjDesc;
879  UINT32 i;
880  UINT32 PreviousValue;
881 
882 
883  ACPI_FUNCTION_NAME (NsCheckSortedList);
884 
885 
886  /* The top-level object must be a package */
887 
888  if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
889  {
890  return (AE_AML_OPERAND_TYPE);
891  }
892 
893  /*
894  * NOTE: assumes list of subpackages contains no NULL elements.
895  * Any NULL elements should have been removed by earlier call
896  * to AcpiNsRemoveNullElements.
897  */
898  OuterElementCount = ReturnObject->Package.Count;
899  if (!OuterElementCount || StartIndex >= OuterElementCount)
900  {
901  return (AE_AML_PACKAGE_LIMIT);
902  }
903 
904  OuterElements = &ReturnObject->Package.Elements[StartIndex];
905  OuterElementCount -= StartIndex;
906 
907  PreviousValue = 0;
908  if (SortDirection == ACPI_SORT_DESCENDING)
909  {
910  PreviousValue = ACPI_UINT32_MAX;
911  }
912 
913  /* Examine each subpackage */
914 
915  for (i = 0; i < OuterElementCount; i++)
916  {
917  /* Each element of the top-level package must also be a package */
918 
919  if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE)
920  {
921  return (AE_AML_OPERAND_TYPE);
922  }
923 
924  /* Each subpackage must have the minimum length */
925 
926  if ((*OuterElements)->Package.Count < ExpectedCount)
927  {
928  return (AE_AML_PACKAGE_LIMIT);
929  }
930 
931  Elements = (*OuterElements)->Package.Elements;
932  ObjDesc = Elements[SortIndex];
933 
934  if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
935  {
936  return (AE_AML_OPERAND_TYPE);
937  }
938 
939  /*
940  * The list must be sorted in the specified order. If we detect a
941  * discrepancy, sort the entire list.
942  */
943  if (((SortDirection == ACPI_SORT_ASCENDING) &&
944  (ObjDesc->Integer.Value < PreviousValue)) ||
945  ((SortDirection == ACPI_SORT_DESCENDING) &&
946  (ObjDesc->Integer.Value > PreviousValue)))
947  {
948  AcpiNsSortList (&ReturnObject->Package.Elements[StartIndex],
949  OuterElementCount, SortIndex, SortDirection);
950 
951  Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
952 
954  "%s: Repaired unsorted list - now sorted by %s\n",
955  Info->FullPathname, SortKeyName));
956  return (AE_OK);
957  }
958 
959  PreviousValue = (UINT32) ObjDesc->Integer.Value;
960  OuterElements++;
961  }
962 
963  return (AE_OK);
964 }
965 
966 
967 /******************************************************************************
968  *
969  * FUNCTION: AcpiNsSortList
970  *
971  * PARAMETERS: Elements - Package object element list
972  * Count - Element count for above
973  * Index - Sort by which package element
974  * SortDirection - Ascending or Descending sort
975  *
976  * RETURN: None
977  *
978  * DESCRIPTION: Sort the objects that are in a package element list.
979  *
980  * NOTE: Assumes that all NULL elements have been removed from the package,
981  * and that all elements have been verified to be of type Integer.
982  *
983  *****************************************************************************/
984 
985 static void
987  ACPI_OPERAND_OBJECT **Elements,
988  UINT32 Count,
989  UINT32 Index,
990  UINT8 SortDirection)
991 {
992  ACPI_OPERAND_OBJECT *ObjDesc1;
993  ACPI_OPERAND_OBJECT *ObjDesc2;
994  ACPI_OPERAND_OBJECT *TempObj;
995  UINT32 i;
996  UINT32 j;
997 
998 
999  /* Simple bubble sort */
1000 
1001  for (i = 1; i < Count; i++)
1002  {
1003  for (j = (Count - 1); j >= i; j--)
1004  {
1005  ObjDesc1 = Elements[j-1]->Package.Elements[Index];
1006  ObjDesc2 = Elements[j]->Package.Elements[Index];
1007 
1008  if (((SortDirection == ACPI_SORT_ASCENDING) &&
1009  (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) ||
1010 
1011  ((SortDirection == ACPI_SORT_DESCENDING) &&
1012  (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value)))
1013  {
1014  TempObj = Elements[j-1];
1015  Elements[j-1] = Elements[j];
1016  Elements[j] = TempObj;
1017  }
1018  }
1019  }
1020 }
1021 
1022 
1023 /******************************************************************************
1024  *
1025  * FUNCTION: AcpiNsRemoveElement
1026  *
1027  * PARAMETERS: ObjDesc - Package object element list
1028  * Index - Index of element to remove
1029  *
1030  * RETURN: None
1031  *
1032  * DESCRIPTION: Remove the requested element of a package and delete it.
1033  *
1034  *****************************************************************************/
1035 
1036 static void
1038  ACPI_OPERAND_OBJECT *ObjDesc,
1039  UINT32 Index)
1040 {
1042  ACPI_OPERAND_OBJECT **Dest;
1043  UINT32 Count;
1044  UINT32 NewCount;
1045  UINT32 i;
1046 
1047 
1048  ACPI_FUNCTION_NAME (NsRemoveElement);
1049 
1050 
1051  Count = ObjDesc->Package.Count;
1052  NewCount = Count - 1;
1053 
1054  Source = ObjDesc->Package.Elements;
1055  Dest = Source;
1056 
1057  /* Examine all elements of the package object, remove matched index */
1058 
1059  for (i = 0; i < Count; i++)
1060  {
1061  if (i == Index)
1062  {
1063  AcpiUtRemoveReference (*Source); /* Remove one ref for being in pkg */
1065  }
1066  else
1067  {
1068  *Dest = *Source;
1069  Dest++;
1070  }
1071 
1072  Source++;
1073  }
1074 
1075  /* NULL terminate list and update the package count */
1076 
1077  *Dest = NULL;
1078  ObjDesc->Package.Count = NewCount;
1079 }
#define TRUE
Definition: types.h:120
static const ACPI_REPAIR_INFO AcpiNsRepairableNames[]
Definition: nsrepair2.c:167
#define ACPI_SUCCESS(a)
Definition: acexcep.h:94
char Name[ACPI_NAMESEG_SIZE]
Definition: nsrepair2.c:64
static ACPI_STATUS AcpiNsRepair_FDE(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:314
#define AE_NO_MEMORY
Definition: acexcep.h:112
ACPI_OBJECT_PACKAGE Package
Definition: acobject.h:521
#define ACPI_TYPE_BUFFER
Definition: actypes.h:682
#define ACPI_TYPE_INTEGER
Definition: actypes.h:680
ACPI_OPERAND_OBJECT * AcpiUtCreateBufferObject(ACPI_SIZE BufferSize)
Definition: utobject.c:258
#define ACPI_SORT_ASCENDING
Definition: nsrepair2.c:128
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1173
UINT32 ACPI_STATUS
Definition: actypes.h:460
#define ACPI_DB_REPAIR
Definition: acoutput.h:154
static ACPI_STATUS AcpiNsRepair_CID(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:410
struct TraceInfo Info
#define AE_AML_OPERAND_TYPE
Definition: acexcep.h:182
struct acpi_repair_info ACPI_REPAIR_INFO
#define ACPI_FDE_DWORD_BUFFER_SIZE
Definition: nsrepair2.c:184
#define ACPI_TYPE_PACKAGE
Definition: actypes.h:683
#define ACPI_FAILURE(a)
Definition: acexcep.h:95
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
ACPI_STATUS AcpiNsGetNode(ACPI_NAMESPACE_NODE *PrefixNode, const char *ExternalPathname, UINT32 Flags, ACPI_NAMESPACE_NODE **OutNode)
Definition: nsutils.c:863
unsigned int UINT32
union node Node
Definition: types.h:1255
#define ACPI_OBJECT_REPAIRED
Definition: acstruct.h:235
static ACPI_STATUS AcpiNsRepair_TSS(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:814
#define ACPI_MODULE_NAME(Name)
Definition: acoutput.h:216
ACPI_STATUS(* ACPI_REPAIR_FUNCTION)(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:58
static const ACPI_REPAIR_INFO * AcpiNsMatchComplexRepair(ACPI_NAMESPACE_NODE *Node)
Definition: nsrepair2.c:242
unsigned char BOOLEAN
#define ACPI_WARN_PREDEFINED(plist)
Definition: acmacros.h:464
#define AE_INFO
Definition: acoutput.h:230
smooth NULL
Definition: ftsmooth.c:416
unsigned char
Definition: typeof.h:29
static ACPI_STATUS AcpiNsRepair_ALR(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:281
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
ACPI_OPERAND_OBJECT * AcpiUtCreateStringObject(ACPI_SIZE StringSize)
Definition: utobject.c:320
int toupper(int c)
Definition: utclib.c:881
ACPI_OBJECT_BUFFER Buffer
Definition: acobject.h:520
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 AcpiNsCheckSortedList(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT *ReturnObject, UINT32 StartIndex, UINT32 ExpectedCount, UINT32 SortIndex, UINT8 SortDirection, char *SortKeyName)
Definition: nsrepair2.c:866
#define ACPI_UINT32_MAX
Definition: actypes.h:66
#define ACPI_DEBUG_PRINT(pl)
Definition: acoutput.h:475
static const UCHAR Index[8]
Definition: usbohci.c:18
static ACPI_STATUS AcpiNsRepair_PRT(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:668
#define ACPI_COMPARE_NAMESEG(a, b)
Definition: actypes.h:561
#define ACPI_FDE_FIELD_COUNT
Definition: nsrepair2.c:182
static ACPI_STATUS AcpiNsRepair_CST(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:485
ACPI_OBJECT_INTEGER Integer
Definition: acobject.h:518
ACPI_OBJECT_STRING String
Definition: acobject.h:519
Status
Definition: gdiplustypes.h:24
#define ACPI_SORT_DESCENDING
Definition: nsrepair2.c:129
#define ACPI_NS_NO_UPSEARCH
Definition: acnamesp.h:62
ACPI_OBJECT_COMMON Common
Definition: acobject.h:517
void AcpiUtRemoveReference(ACPI_OPERAND_OBJECT *Object)
Definition: utdelete.c:785
static ACPI_STATUS AcpiNsRepair_PSS(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:742
static void AcpiNsSortList(ACPI_OPERAND_OBJECT **Elements, UINT32 Count, UINT32 Index, UINT8 SortDirection)
Definition: nsrepair2.c:986
unsigned short UINT16
static void AcpiNsRemoveElement(ACPI_OPERAND_OBJECT *ObjDesc, UINT32 Index)
Definition: nsrepair2.c:1037
ACPI_REPAIR_FUNCTION RepairFunction
Definition: nsrepair2.c:65
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
#define ACPI_FUNCTION_NAME(a)
Definition: acoutput.h:479
#define ACPI_TYPE_STRING
Definition: actypes.h:681
#define AE_AML_PACKAGE_LIMIT
Definition: acexcep.h:190
#define ACPI_NAMESEG_SIZE
Definition: actypes.h:415
#define ACPI_CAST_PTR(t, p)
Definition: actypes.h:544
unsigned char UINT8
#define ACPI_FDE_BYTE_BUFFER_SIZE
Definition: nsrepair2.c:183
#define AE_OK
Definition: acexcep.h:97
static ACPI_STATUS AcpiNsRepair_HID(ACPI_EVALUATE_INFO *Info, ACPI_OPERAND_OBJECT **ReturnObjectPtr)
Definition: nsrepair2.c:577
union acpi_operand_object ** Elements
Definition: acobject.h:161
Definition: dlist.c:348