ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

nsrepair2.c
Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * Module Name: nsrepair2 - Repair for objects returned by specific
00004  *                          predefined methods
00005  *
00006  *****************************************************************************/
00007 
00008 /******************************************************************************
00009  *
00010  * 1. Copyright Notice
00011  *
00012  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
00013  * All rights reserved.
00014  *
00015  * 2. License
00016  *
00017  * 2.1. This is your license from Intel Corp. under its intellectual property
00018  * rights.  You may have additional license terms from the party that provided
00019  * you this software, covering your right to use that party's intellectual
00020  * property rights.
00021  *
00022  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
00023  * copy of the source code appearing in this file ("Covered Code") an
00024  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
00025  * base code distributed originally by Intel ("Original Intel Code") to copy,
00026  * make derivatives, distribute, use and display any portion of the Covered
00027  * Code in any form, with the right to sublicense such rights; and
00028  *
00029  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
00030  * license (with the right to sublicense), under only those claims of Intel
00031  * patents that are infringed by the Original Intel Code, to make, use, sell,
00032  * offer to sell, and import the Covered Code and derivative works thereof
00033  * solely to the minimum extent necessary to exercise the above copyright
00034  * license, and in no event shall the patent license extend to any additions
00035  * to or modifications of the Original Intel Code.  No other license or right
00036  * is granted directly or by implication, estoppel or otherwise;
00037  *
00038  * The above copyright and patent license is granted only if the following
00039  * conditions are met:
00040  *
00041  * 3. Conditions
00042  *
00043  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
00044  * Redistribution of source code of any substantial portion of the Covered
00045  * Code or modification with rights to further distribute source must include
00046  * the above Copyright Notice, the above License, this list of Conditions,
00047  * and the following Disclaimer and Export Compliance provision.  In addition,
00048  * Licensee must cause all Covered Code to which Licensee contributes to
00049  * contain a file documenting the changes Licensee made to create that Covered
00050  * Code and the date of any change.  Licensee must include in that file the
00051  * documentation of any changes made by any predecessor Licensee.  Licensee
00052  * must include a prominent statement that the modification is derived,
00053  * directly or indirectly, from Original Intel Code.
00054  *
00055  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
00056  * Redistribution of source code of any substantial portion of the Covered
00057  * Code or modification without rights to further distribute source must
00058  * include the following Disclaimer and Export Compliance provision in the
00059  * documentation and/or other materials provided with distribution.  In
00060  * addition, Licensee may not authorize further sublicense of source of any
00061  * portion of the Covered Code, and must include terms to the effect that the
00062  * license from Licensee to its licensee is limited to the intellectual
00063  * property embodied in the software Licensee provides to its licensee, and
00064  * not to intellectual property embodied in modifications its licensee may
00065  * make.
00066  *
00067  * 3.3. Redistribution of Executable. Redistribution in executable form of any
00068  * substantial portion of the Covered Code or modification must reproduce the
00069  * above Copyright Notice, and the following Disclaimer and Export Compliance
00070  * provision in the documentation and/or other materials provided with the
00071  * distribution.
00072  *
00073  * 3.4. Intel retains all right, title, and interest in and to the Original
00074  * Intel Code.
00075  *
00076  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
00077  * Intel shall be used in advertising or otherwise to promote the sale, use or
00078  * other dealings in products derived from or relating to the Covered Code
00079  * without prior written authorization from Intel.
00080  *
00081  * 4. Disclaimer and Export Compliance
00082  *
00083  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
00084  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
00085  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
00086  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
00087  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
00088  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
00089  * PARTICULAR PURPOSE.
00090  *
00091  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
00092  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
00093  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
00094  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
00095  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
00096  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
00097  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
00098  * LIMITED REMEDY.
00099  *
00100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
00101  * software or system incorporating such software without first obtaining any
00102  * required license or other approval from the U. S. Department of Commerce or
00103  * any other agency or department of the United States Government.  In the
00104  * event Licensee exports any such software from the United States or
00105  * re-exports any such software from a foreign destination, Licensee shall
00106  * ensure that the distribution and export/re-export of the software is in
00107  * compliance with all laws, regulations, orders, or other restrictions of the
00108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
00109  * any of its subsidiaries will export/re-export any technical data, process,
00110  * software, or service, directly or indirectly, to any country for which the
00111  * United States government or any agency thereof requires an export license,
00112  * other governmental approval, or letter of assurance, without first obtaining
00113  * such license, approval or letter.
00114  *
00115  *****************************************************************************/
00116 
00117 #define __NSREPAIR2_C__
00118 
00119 #include "acpi.h"
00120 #include "accommon.h"
00121 #include "acnamesp.h"
00122 
00123 #define _COMPONENT          ACPI_NAMESPACE
00124         ACPI_MODULE_NAME    ("nsrepair2")
00125 
00126 
00127 /*
00128  * Information structure and handler for ACPI predefined names that can
00129  * be repaired on a per-name basis.
00130  */
00131 typedef
00132 ACPI_STATUS (*ACPI_REPAIR_FUNCTION) (
00133     ACPI_PREDEFINED_DATA    *Data,
00134     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
00135 
00136 typedef struct acpi_repair_info
00137 {
00138     char                    Name[ACPI_NAME_SIZE];
00139     ACPI_REPAIR_FUNCTION    RepairFunction;
00140 
00141 } ACPI_REPAIR_INFO;
00142 
00143 
00144 /* Local prototypes */
00145 
00146 static const ACPI_REPAIR_INFO *
00147 AcpiNsMatchRepairableName (
00148     ACPI_NAMESPACE_NODE     *Node);
00149 
00150 static ACPI_STATUS
00151 AcpiNsRepair_ALR (
00152     ACPI_PREDEFINED_DATA    *Data,
00153     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
00154 
00155 static ACPI_STATUS
00156 AcpiNsRepair_CID (
00157     ACPI_PREDEFINED_DATA    *Data,
00158     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
00159 
00160 static ACPI_STATUS
00161 AcpiNsRepair_FDE (
00162     ACPI_PREDEFINED_DATA    *Data,
00163     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
00164 
00165 static ACPI_STATUS
00166 AcpiNsRepair_HID (
00167     ACPI_PREDEFINED_DATA    *Data,
00168     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
00169 
00170 static ACPI_STATUS
00171 AcpiNsRepair_PSS (
00172     ACPI_PREDEFINED_DATA    *Data,
00173     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
00174 
00175 static ACPI_STATUS
00176 AcpiNsRepair_TSS (
00177     ACPI_PREDEFINED_DATA    *Data,
00178     ACPI_OPERAND_OBJECT     **ReturnObjectPtr);
00179 
00180 static ACPI_STATUS
00181 AcpiNsCheckSortedList (
00182     ACPI_PREDEFINED_DATA    *Data,
00183     ACPI_OPERAND_OBJECT     *ReturnObject,
00184     UINT32                  ExpectedCount,
00185     UINT32                  SortIndex,
00186     UINT8                   SortDirection,
00187     char                    *SortKeyName);
00188 
00189 static void
00190 AcpiNsSortList (
00191     ACPI_OPERAND_OBJECT     **Elements,
00192     UINT32                  Count,
00193     UINT32                  Index,
00194     UINT8                   SortDirection);
00195 
00196 /* Values for SortDirection above */
00197 
00198 #define ACPI_SORT_ASCENDING     0
00199 #define ACPI_SORT_DESCENDING    1
00200 
00201 
00202 /*
00203  * This table contains the names of the predefined methods for which we can
00204  * perform more complex repairs.
00205  *
00206  * As necessary:
00207  *
00208  * _ALR: Sort the list ascending by AmbientIlluminance
00209  * _CID: Strings: uppercase all, remove any leading asterisk
00210  * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
00211  * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
00212  * _HID: Strings: uppercase all, remove any leading asterisk
00213  * _PSS: Sort the list descending by Power
00214  * _TSS: Sort the list descending by Power
00215  *
00216  * Names that must be packages, but cannot be sorted:
00217  *
00218  * _BCL: Values are tied to the Package index where they appear, and cannot
00219  * be moved or sorted. These index values are used for _BQC and _BCM.
00220  * However, we can fix the case where a buffer is returned, by converting
00221  * it to a Package of integers.
00222  */
00223 static const ACPI_REPAIR_INFO       AcpiNsRepairableNames[] =
00224 {
00225     {"_ALR", AcpiNsRepair_ALR},
00226     {"_CID", AcpiNsRepair_CID},
00227     {"_FDE", AcpiNsRepair_FDE},
00228     {"_GTM", AcpiNsRepair_FDE},     /* _GTM has same repair as _FDE */
00229     {"_HID", AcpiNsRepair_HID},
00230     {"_PSS", AcpiNsRepair_PSS},
00231     {"_TSS", AcpiNsRepair_TSS},
00232     {{0,0,0,0}, NULL}               /* Table terminator */
00233 };
00234 
00235 
00236 #define ACPI_FDE_FIELD_COUNT        5
00237 #define ACPI_FDE_BYTE_BUFFER_SIZE   5
00238 #define ACPI_FDE_DWORD_BUFFER_SIZE  (ACPI_FDE_FIELD_COUNT * sizeof (UINT32))
00239 
00240 
00241 /******************************************************************************
00242  *
00243  * FUNCTION:    AcpiNsComplexRepairs
00244  *
00245  * PARAMETERS:  Data                - Pointer to validation data structure
00246  *              Node                - Namespace node for the method/object
00247  *              ValidateStatus      - Original status of earlier validation
00248  *              ReturnObjectPtr     - Pointer to the object returned from the
00249  *                                    evaluation of a method or object
00250  *
00251  * RETURN:      Status. AE_OK if repair was successful. If name is not
00252  *              matched, ValidateStatus is returned.
00253  *
00254  * DESCRIPTION: Attempt to repair/convert a return object of a type that was
00255  *              not expected.
00256  *
00257  *****************************************************************************/
00258 
00259 ACPI_STATUS
00260 AcpiNsComplexRepairs (
00261     ACPI_PREDEFINED_DATA    *Data,
00262     ACPI_NAMESPACE_NODE     *Node,
00263     ACPI_STATUS             ValidateStatus,
00264     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
00265 {
00266     const ACPI_REPAIR_INFO  *Predefined;
00267     ACPI_STATUS             Status;
00268 
00269 
00270     /* Check if this name is in the list of repairable names */
00271 
00272     Predefined = AcpiNsMatchRepairableName (Node);
00273     if (!Predefined)
00274     {
00275         return (ValidateStatus);
00276     }
00277 
00278     Status = Predefined->RepairFunction (Data, ReturnObjectPtr);
00279     return (Status);
00280 }
00281 
00282 
00283 /******************************************************************************
00284  *
00285  * FUNCTION:    AcpiNsMatchRepairableName
00286  *
00287  * PARAMETERS:  Node                - Namespace node for the method/object
00288  *
00289  * RETURN:      Pointer to entry in repair table. NULL indicates not found.
00290  *
00291  * DESCRIPTION: Check an object name against the repairable object list.
00292  *
00293  *****************************************************************************/
00294 
00295 static const ACPI_REPAIR_INFO *
00296 AcpiNsMatchRepairableName (
00297     ACPI_NAMESPACE_NODE     *Node)
00298 {
00299     const ACPI_REPAIR_INFO  *ThisName;
00300 
00301 
00302     /* Search info table for a repairable predefined method/object name */
00303 
00304     ThisName = AcpiNsRepairableNames;
00305     while (ThisName->RepairFunction)
00306     {
00307         if (ACPI_COMPARE_NAME (Node->Name.Ascii, ThisName->Name))
00308         {
00309             return (ThisName);
00310         }
00311         ThisName++;
00312     }
00313 
00314     return (NULL); /* Not found */
00315 }
00316 
00317 
00318 /******************************************************************************
00319  *
00320  * FUNCTION:    AcpiNsRepair_ALR
00321  *
00322  * PARAMETERS:  Data                - Pointer to validation data structure
00323  *              ReturnObjectPtr     - Pointer to the object returned from the
00324  *                                    evaluation of a method or object
00325  *
00326  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
00327  *
00328  * DESCRIPTION: Repair for the _ALR object. If necessary, sort the object list
00329  *              ascending by the ambient illuminance values.
00330  *
00331  *****************************************************************************/
00332 
00333 static ACPI_STATUS
00334 AcpiNsRepair_ALR (
00335     ACPI_PREDEFINED_DATA    *Data,
00336     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
00337 {
00338     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
00339     ACPI_STATUS             Status;
00340 
00341 
00342     Status = AcpiNsCheckSortedList (Data, ReturnObject, 2, 1,
00343                 ACPI_SORT_ASCENDING, "AmbientIlluminance");
00344 
00345     return (Status);
00346 }
00347 
00348 
00349 /******************************************************************************
00350  *
00351  * FUNCTION:    AcpiNsRepair_FDE
00352  *
00353  * PARAMETERS:  Data                - Pointer to validation data structure
00354  *              ReturnObjectPtr     - Pointer to the object returned from the
00355  *                                    evaluation of a method or object
00356  *
00357  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
00358  *
00359  * DESCRIPTION: Repair for the _FDE and _GTM objects. The expected return
00360  *              value is a Buffer of 5 DWORDs. This function repairs a common
00361  *              problem where the return value is a Buffer of BYTEs, not
00362  *              DWORDs.
00363  *
00364  *****************************************************************************/
00365 
00366 static ACPI_STATUS
00367 AcpiNsRepair_FDE (
00368     ACPI_PREDEFINED_DATA    *Data,
00369     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
00370 {
00371     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
00372     ACPI_OPERAND_OBJECT     *BufferObject;
00373     UINT8                   *ByteBuffer;
00374     UINT32                  *DwordBuffer;
00375     UINT32                  i;
00376 
00377 
00378     ACPI_FUNCTION_NAME (NsRepair_FDE);
00379 
00380 
00381     switch (ReturnObject->Common.Type)
00382     {
00383     case ACPI_TYPE_BUFFER:
00384 
00385         /* This is the expected type. Length should be (at least) 5 DWORDs */
00386 
00387         if (ReturnObject->Buffer.Length >= ACPI_FDE_DWORD_BUFFER_SIZE)
00388         {
00389             return (AE_OK);
00390         }
00391 
00392         /* We can only repair if we have exactly 5 BYTEs */
00393 
00394         if (ReturnObject->Buffer.Length != ACPI_FDE_BYTE_BUFFER_SIZE)
00395         {
00396             ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
00397                 "Incorrect return buffer length %u, expected %u",
00398                 ReturnObject->Buffer.Length, ACPI_FDE_DWORD_BUFFER_SIZE));
00399 
00400             return (AE_AML_OPERAND_TYPE);
00401         }
00402 
00403         /* Create the new (larger) buffer object */
00404 
00405         BufferObject = AcpiUtCreateBufferObject (ACPI_FDE_DWORD_BUFFER_SIZE);
00406         if (!BufferObject)
00407         {
00408             return (AE_NO_MEMORY);
00409         }
00410 
00411         /* Expand each byte to a DWORD */
00412 
00413         ByteBuffer = ReturnObject->Buffer.Pointer;
00414         DwordBuffer = ACPI_CAST_PTR (UINT32, BufferObject->Buffer.Pointer);
00415 
00416         for (i = 0; i < ACPI_FDE_FIELD_COUNT; i++)
00417         {
00418             *DwordBuffer = (UINT32) *ByteBuffer;
00419             DwordBuffer++;
00420             ByteBuffer++;
00421         }
00422 
00423         ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
00424             "%s Expanded Byte Buffer to expected DWord Buffer\n",
00425             Data->Pathname));
00426         break;
00427 
00428     default:
00429         return (AE_AML_OPERAND_TYPE);
00430     }
00431 
00432     /* Delete the original return object, return the new buffer object */
00433 
00434     AcpiUtRemoveReference (ReturnObject);
00435     *ReturnObjectPtr = BufferObject;
00436 
00437     Data->Flags |= ACPI_OBJECT_REPAIRED;
00438     return (AE_OK);
00439 }
00440 
00441 
00442 /******************************************************************************
00443  *
00444  * FUNCTION:    AcpiNsRepair_CID
00445  *
00446  * PARAMETERS:  Data                - Pointer to validation data structure
00447  *              ReturnObjectPtr     - Pointer to the object returned from the
00448  *                                    evaluation of a method or object
00449  *
00450  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
00451  *
00452  * DESCRIPTION: Repair for the _CID object. If a string, ensure that all
00453  *              letters are uppercase and that there is no leading asterisk.
00454  *              If a Package, ensure same for all string elements.
00455  *
00456  *****************************************************************************/
00457 
00458 static ACPI_STATUS
00459 AcpiNsRepair_CID (
00460     ACPI_PREDEFINED_DATA    *Data,
00461     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
00462 {
00463     ACPI_STATUS             Status;
00464     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
00465     ACPI_OPERAND_OBJECT     **ElementPtr;
00466     ACPI_OPERAND_OBJECT     *OriginalElement;
00467     UINT16                  OriginalRefCount;
00468     UINT32                  i;
00469 
00470 
00471     /* Check for _CID as a simple string */
00472 
00473     if (ReturnObject->Common.Type == ACPI_TYPE_STRING)
00474     {
00475         Status = AcpiNsRepair_HID (Data, ReturnObjectPtr);
00476         return (Status);
00477     }
00478 
00479     /* Exit if not a Package */
00480 
00481     if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
00482     {
00483         return (AE_OK);
00484     }
00485 
00486     /* Examine each element of the _CID package */
00487 
00488     ElementPtr = ReturnObject->Package.Elements;
00489     for (i = 0; i < ReturnObject->Package.Count; i++)
00490     {
00491         OriginalElement = *ElementPtr;
00492         OriginalRefCount = OriginalElement->Common.ReferenceCount;
00493 
00494         Status = AcpiNsRepair_HID (Data, ElementPtr);
00495         if (ACPI_FAILURE (Status))
00496         {
00497             return (Status);
00498         }
00499 
00500         /* Take care with reference counts */
00501 
00502         if (OriginalElement != *ElementPtr)
00503         {
00504             /* Element was replaced */
00505 
00506             (*ElementPtr)->Common.ReferenceCount =
00507                 OriginalRefCount;
00508 
00509             AcpiUtRemoveReference (OriginalElement);
00510         }
00511 
00512         ElementPtr++;
00513     }
00514 
00515     return (AE_OK);
00516 }
00517 
00518 
00519 /******************************************************************************
00520  *
00521  * FUNCTION:    AcpiNsRepair_HID
00522  *
00523  * PARAMETERS:  Data                - Pointer to validation data structure
00524  *              ReturnObjectPtr     - Pointer to the object returned from the
00525  *                                    evaluation of a method or object
00526  *
00527  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
00528  *
00529  * DESCRIPTION: Repair for the _HID object. If a string, ensure that all
00530  *              letters are uppercase and that there is no leading asterisk.
00531  *
00532  *****************************************************************************/
00533 
00534 static ACPI_STATUS
00535 AcpiNsRepair_HID (
00536     ACPI_PREDEFINED_DATA    *Data,
00537     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
00538 {
00539     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
00540     ACPI_OPERAND_OBJECT     *NewString;
00541     char                    *Source;
00542     char                    *Dest;
00543 
00544 
00545     ACPI_FUNCTION_NAME (NsRepair_HID);
00546 
00547 
00548     /* We only care about string _HID objects (not integers) */
00549 
00550     if (ReturnObject->Common.Type != ACPI_TYPE_STRING)
00551     {
00552         return (AE_OK);
00553     }
00554 
00555     if (ReturnObject->String.Length == 0)
00556     {
00557         ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
00558             "Invalid zero-length _HID or _CID string"));
00559 
00560         /* Return AE_OK anyway, let driver handle it */
00561 
00562         Data->Flags |= ACPI_OBJECT_REPAIRED;
00563         return (AE_OK);
00564     }
00565 
00566     /* It is simplest to always create a new string object */
00567 
00568     NewString = AcpiUtCreateStringObject (ReturnObject->String.Length);
00569     if (!NewString)
00570     {
00571         return (AE_NO_MEMORY);
00572     }
00573 
00574     /*
00575      * Remove a leading asterisk if present. For some unknown reason, there
00576      * are many machines in the field that contains IDs like this.
00577      *
00578      * Examples: "*PNP0C03", "*ACPI0003"
00579      */
00580     Source = ReturnObject->String.Pointer;
00581     if (*Source == '*')
00582     {
00583         Source++;
00584         NewString->String.Length--;
00585 
00586         ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
00587             "%s: Removed invalid leading asterisk\n", Data->Pathname));
00588     }
00589 
00590     /*
00591      * Copy and uppercase the string. From the ACPI specification:
00592      *
00593      * A valid PNP ID must be of the form "AAA####" where A is an uppercase
00594      * letter and # is a hex digit. A valid ACPI ID must be of the form
00595      * "ACPI####" where # is a hex digit.
00596      */
00597     for (Dest = NewString->String.Pointer; *Source; Dest++, Source++)
00598     {
00599         *Dest = (char) ACPI_TOUPPER (*Source);
00600     }
00601 
00602     AcpiUtRemoveReference (ReturnObject);
00603     *ReturnObjectPtr = NewString;
00604     return (AE_OK);
00605 }
00606 
00607 
00608 /******************************************************************************
00609  *
00610  * FUNCTION:    AcpiNsRepair_TSS
00611  *
00612  * PARAMETERS:  Data                - Pointer to validation data structure
00613  *              ReturnObjectPtr     - Pointer to the object returned from the
00614  *                                    evaluation of a method or object
00615  *
00616  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
00617  *
00618  * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
00619  *              descending by the power dissipation values.
00620  *
00621  *****************************************************************************/
00622 
00623 static ACPI_STATUS
00624 AcpiNsRepair_TSS (
00625     ACPI_PREDEFINED_DATA    *Data,
00626     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
00627 {
00628     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
00629     ACPI_STATUS             Status;
00630     ACPI_NAMESPACE_NODE     *Node;
00631 
00632 
00633     /*
00634      * We can only sort the _TSS return package if there is no _PSS in the
00635      * same scope. This is because if _PSS is present, the ACPI specification
00636      * dictates that the _TSS Power Dissipation field is to be ignored, and
00637      * therefore some BIOSs leave garbage values in the _TSS Power field(s).
00638      * In this case, it is best to just return the _TSS package as-is.
00639      * (May, 2011)
00640      */
00641     Status = AcpiNsGetNode (Data->Node, "^_PSS", ACPI_NS_NO_UPSEARCH, &Node);
00642     if (ACPI_SUCCESS (Status))
00643     {
00644         return (AE_OK);
00645     }
00646 
00647     Status = AcpiNsCheckSortedList (Data, ReturnObject, 5, 1,
00648                 ACPI_SORT_DESCENDING, "PowerDissipation");
00649 
00650     return (Status);
00651 }
00652 
00653 
00654 /******************************************************************************
00655  *
00656  * FUNCTION:    AcpiNsRepair_PSS
00657  *
00658  * PARAMETERS:  Data                - Pointer to validation data structure
00659  *              ReturnObjectPtr     - Pointer to the object returned from the
00660  *                                    evaluation of a method or object
00661  *
00662  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
00663  *
00664  * DESCRIPTION: Repair for the _PSS object. If necessary, sort the object list
00665  *              by the CPU frequencies. Check that the power dissipation values
00666  *              are all proportional to CPU frequency (i.e., sorting by
00667  *              frequency should be the same as sorting by power.)
00668  *
00669  *****************************************************************************/
00670 
00671 static ACPI_STATUS
00672 AcpiNsRepair_PSS (
00673     ACPI_PREDEFINED_DATA    *Data,
00674     ACPI_OPERAND_OBJECT     **ReturnObjectPtr)
00675 {
00676     ACPI_OPERAND_OBJECT     *ReturnObject = *ReturnObjectPtr;
00677     ACPI_OPERAND_OBJECT     **OuterElements;
00678     UINT32                  OuterElementCount;
00679     ACPI_OPERAND_OBJECT     **Elements;
00680     ACPI_OPERAND_OBJECT     *ObjDesc;
00681     UINT32                  PreviousValue;
00682     ACPI_STATUS             Status;
00683     UINT32                  i;
00684 
00685 
00686     /*
00687      * Entries (sub-packages) in the _PSS Package must be sorted by power
00688      * dissipation, in descending order. If it appears that the list is
00689      * incorrectly sorted, sort it. We sort by CpuFrequency, since this
00690      * should be proportional to the power.
00691      */
00692     Status =AcpiNsCheckSortedList (Data, ReturnObject, 6, 0,
00693                 ACPI_SORT_DESCENDING, "CpuFrequency");
00694     if (ACPI_FAILURE (Status))
00695     {
00696         return (Status);
00697     }
00698 
00699     /*
00700      * We now know the list is correctly sorted by CPU frequency. Check if
00701      * the power dissipation values are proportional.
00702      */
00703     PreviousValue = ACPI_UINT32_MAX;
00704     OuterElements = ReturnObject->Package.Elements;
00705     OuterElementCount = ReturnObject->Package.Count;
00706 
00707     for (i = 0; i < OuterElementCount; i++)
00708     {
00709         Elements = (*OuterElements)->Package.Elements;
00710         ObjDesc = Elements[1]; /* Index1 = PowerDissipation */
00711 
00712         if ((UINT32) ObjDesc->Integer.Value > PreviousValue)
00713         {
00714             ACPI_WARN_PREDEFINED ((AE_INFO, Data->Pathname, Data->NodeFlags,
00715                 "SubPackage[%u,%u] - suspicious power dissipation values",
00716                 i-1, i));
00717         }
00718 
00719         PreviousValue = (UINT32) ObjDesc->Integer.Value;
00720         OuterElements++;
00721     }
00722 
00723     return (AE_OK);
00724 }
00725 
00726 
00727 /******************************************************************************
00728  *
00729  * FUNCTION:    AcpiNsCheckSortedList
00730  *
00731  * PARAMETERS:  Data                - Pointer to validation data structure
00732  *              ReturnObject        - Pointer to the top-level returned object
00733  *              ExpectedCount       - Minimum length of each sub-package
00734  *              SortIndex           - Sub-package entry to sort on
00735  *              SortDirection       - Ascending or descending
00736  *              SortKeyName         - Name of the SortIndex field
00737  *
00738  * RETURN:      Status. AE_OK if the list is valid and is sorted correctly or
00739  *              has been repaired by sorting the list.
00740  *
00741  * DESCRIPTION: Check if the package list is valid and sorted correctly by the
00742  *              SortIndex. If not, then sort the list.
00743  *
00744  *****************************************************************************/
00745 
00746 static ACPI_STATUS
00747 AcpiNsCheckSortedList (
00748     ACPI_PREDEFINED_DATA    *Data,
00749     ACPI_OPERAND_OBJECT     *ReturnObject,
00750     UINT32                  ExpectedCount,
00751     UINT32                  SortIndex,
00752     UINT8                   SortDirection,
00753     char                    *SortKeyName)
00754 {
00755     UINT32                  OuterElementCount;
00756     ACPI_OPERAND_OBJECT     **OuterElements;
00757     ACPI_OPERAND_OBJECT     **Elements;
00758     ACPI_OPERAND_OBJECT     *ObjDesc;
00759     UINT32                  i;
00760     UINT32                  PreviousValue;
00761 
00762 
00763     ACPI_FUNCTION_NAME (NsCheckSortedList);
00764 
00765 
00766     /* The top-level object must be a package */
00767 
00768     if (ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
00769     {
00770         return (AE_AML_OPERAND_TYPE);
00771     }
00772 
00773     /*
00774      * NOTE: assumes list of sub-packages contains no NULL elements.
00775      * Any NULL elements should have been removed by earlier call
00776      * to AcpiNsRemoveNullElements.
00777      */
00778     OuterElements = ReturnObject->Package.Elements;
00779     OuterElementCount = ReturnObject->Package.Count;
00780     if (!OuterElementCount)
00781     {
00782         return (AE_AML_PACKAGE_LIMIT);
00783     }
00784 
00785     PreviousValue = 0;
00786     if (SortDirection == ACPI_SORT_DESCENDING)
00787     {
00788         PreviousValue = ACPI_UINT32_MAX;
00789     }
00790 
00791     /* Examine each subpackage */
00792 
00793     for (i = 0; i < OuterElementCount; i++)
00794     {
00795         /* Each element of the top-level package must also be a package */
00796 
00797         if ((*OuterElements)->Common.Type != ACPI_TYPE_PACKAGE)
00798         {
00799             return (AE_AML_OPERAND_TYPE);
00800         }
00801 
00802         /* Each sub-package must have the minimum length */
00803 
00804         if ((*OuterElements)->Package.Count < ExpectedCount)
00805         {
00806             return (AE_AML_PACKAGE_LIMIT);
00807         }
00808 
00809         Elements = (*OuterElements)->Package.Elements;
00810         ObjDesc = Elements[SortIndex];
00811 
00812         if (ObjDesc->Common.Type != ACPI_TYPE_INTEGER)
00813         {
00814             return (AE_AML_OPERAND_TYPE);
00815         }
00816 
00817         /*
00818          * The list must be sorted in the specified order. If we detect a
00819          * discrepancy, sort the entire list.
00820          */
00821         if (((SortDirection == ACPI_SORT_ASCENDING) &&
00822                 (ObjDesc->Integer.Value < PreviousValue)) ||
00823             ((SortDirection == ACPI_SORT_DESCENDING) &&
00824                 (ObjDesc->Integer.Value > PreviousValue)))
00825         {
00826             AcpiNsSortList (ReturnObject->Package.Elements,
00827                 OuterElementCount, SortIndex, SortDirection);
00828 
00829             Data->Flags |= ACPI_OBJECT_REPAIRED;
00830 
00831             ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR,
00832                 "%s: Repaired unsorted list - now sorted by %s\n",
00833                 Data->Pathname, SortKeyName));
00834             return (AE_OK);
00835         }
00836 
00837         PreviousValue = (UINT32) ObjDesc->Integer.Value;
00838         OuterElements++;
00839     }
00840 
00841     return (AE_OK);
00842 }
00843 
00844 
00845 /******************************************************************************
00846  *
00847  * FUNCTION:    AcpiNsSortList
00848  *
00849  * PARAMETERS:  Elements            - Package object element list
00850  *              Count               - Element count for above
00851  *              Index               - Sort by which package element
00852  *              SortDirection       - Ascending or Descending sort
00853  *
00854  * RETURN:      None
00855  *
00856  * DESCRIPTION: Sort the objects that are in a package element list.
00857  *
00858  * NOTE: Assumes that all NULL elements have been removed from the package,
00859  *       and that all elements have been verified to be of type Integer.
00860  *
00861  *****************************************************************************/
00862 
00863 static void
00864 AcpiNsSortList (
00865     ACPI_OPERAND_OBJECT     **Elements,
00866     UINT32                  Count,
00867     UINT32                  Index,
00868     UINT8                   SortDirection)
00869 {
00870     ACPI_OPERAND_OBJECT     *ObjDesc1;
00871     ACPI_OPERAND_OBJECT     *ObjDesc2;
00872     ACPI_OPERAND_OBJECT     *TempObj;
00873     UINT32                  i;
00874     UINT32                  j;
00875 
00876 
00877     /* Simple bubble sort */
00878 
00879     for (i = 1; i < Count; i++)
00880     {
00881         for (j = (Count - 1); j >= i; j--)
00882         {
00883             ObjDesc1 = Elements[j-1]->Package.Elements[Index];
00884             ObjDesc2 = Elements[j]->Package.Elements[Index];
00885 
00886             if (((SortDirection == ACPI_SORT_ASCENDING) &&
00887                     (ObjDesc1->Integer.Value > ObjDesc2->Integer.Value)) ||
00888 
00889                 ((SortDirection == ACPI_SORT_DESCENDING) &&
00890                     (ObjDesc1->Integer.Value < ObjDesc2->Integer.Value)))
00891             {
00892                 TempObj = Elements[j-1];
00893                 Elements[j-1] = Elements[j];
00894                 Elements[j] = TempObj;
00895             }
00896         }
00897     }
00898 }

Generated on Sat May 26 2012 04:25:54 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.