diff options
Diffstat (limited to 'source/components/utilities')
-rw-r--r-- | source/components/utilities/utdelete.c | 96 | ||||
-rw-r--r-- | source/components/utilities/utmutex.c | 10 | ||||
-rw-r--r-- | source/components/utilities/utosi.c | 29 | ||||
-rw-r--r-- | source/components/utilities/utpredef.c | 451 | ||||
-rw-r--r-- | source/components/utilities/utxface.c | 20 |
5 files changed, 549 insertions, 57 deletions
diff --git a/source/components/utilities/utdelete.c b/source/components/utilities/utdelete.c index a100713..f18d556 100644 --- a/source/components/utilities/utdelete.c +++ b/source/components/utilities/utdelete.c @@ -390,11 +390,11 @@ AcpiUtDeleteInternalObjectList ( * FUNCTION: AcpiUtUpdateRefCount * * PARAMETERS: Object - Object whose ref count is to be updated - * Action - What to do + * Action - What to do (REF_INCREMENT or REF_DECREMENT) * - * RETURN: New ref count + * RETURN: None. Sets new reference count within the object * - * DESCRIPTION: Modify the ref count and return it. + * DESCRIPTION: Modify the reference count for an internal acpi object * ******************************************************************************/ @@ -403,8 +403,9 @@ AcpiUtUpdateRefCount ( ACPI_OPERAND_OBJECT *Object, UINT32 Action) { - UINT16 Count; - UINT16 NewCount; + UINT16 OriginalCount; + UINT16 NewCount = 0; + ACPI_CPU_FLAGS LockFlags; ACPI_FUNCTION_NAME (UtUpdateRefCount); @@ -415,80 +416,85 @@ AcpiUtUpdateRefCount ( return; } - Count = Object->Common.ReferenceCount; - NewCount = Count; - /* - * Perform the reference count action (increment, decrement, force delete) + * Always get the reference count lock. Note: Interpreter and/or + * Namespace is not always locked when this function is called. */ + LockFlags = AcpiOsAcquireLock (AcpiGbl_ReferenceCountLock); + OriginalCount = Object->Common.ReferenceCount; + + /* Perform the reference count action (increment, decrement) */ + switch (Action) { case REF_INCREMENT: - NewCount++; + NewCount = OriginalCount + 1; Object->Common.ReferenceCount = NewCount; + AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags); + + /* The current reference count should never be zero here */ + + if (!OriginalCount) + { + ACPI_WARNING ((AE_INFO, + "Obj %p, Reference Count was zero before increment\n", + Object)); + } ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, - "Obj %p Refs=%X, [Incremented]\n", - Object, NewCount)); + "Obj %p Type %.2X Refs %.2X [Incremented]\n", + Object, Object->Common.Type, NewCount)); break; case REF_DECREMENT: - if (Count < 1) - { - ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, - "Obj %p Refs=%X, can't decrement! (Set to 0)\n", - Object, NewCount)); + /* The current reference count must be non-zero */ - NewCount = 0; - } - else + if (OriginalCount) { - NewCount--; - - ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, - "Obj %p Refs=%X, [Decremented]\n", - Object, NewCount)); + NewCount = OriginalCount - 1; + Object->Common.ReferenceCount = NewCount; } - if (Object->Common.Type == ACPI_TYPE_METHOD) + AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags); + + if (!OriginalCount) { - ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, - "Method Obj %p Refs=%X, [Decremented]\n", Object, NewCount)); + ACPI_WARNING ((AE_INFO, + "Obj %p, Reference Count is already zero, cannot decrement\n", + Object)); } - Object->Common.ReferenceCount = NewCount; + ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, + "Obj %p Type %.2X Refs %.2X [Decremented]\n", + Object, Object->Common.Type, NewCount)); + + /* Actually delete the object on a reference count of zero */ + if (NewCount == 0) { AcpiUtDeleteInternalObj (Object); } break; - case REF_FORCE_DELETE: - - ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, - "Obj %p Refs=%X, Force delete! (Set to 0)\n", Object, Count)); - - NewCount = 0; - Object->Common.ReferenceCount = NewCount; - AcpiUtDeleteInternalObj (Object); - break; - default: - ACPI_ERROR ((AE_INFO, "Unknown action (0x%X)", Action)); - break; + AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags); + ACPI_ERROR ((AE_INFO, "Unknown Reference Count action (0x%X)", + Action)); + return; } /* * Sanity check the reference count, for debug purposes only. * (A deleted object will have a huge reference count) */ - if (Count > ACPI_MAX_REFERENCE_COUNT) + if (NewCount > ACPI_MAX_REFERENCE_COUNT) { ACPI_WARNING ((AE_INFO, - "Large Reference Count (0x%X) in object %p", Count, Object)); + "Large Reference Count (0x%X) in object %p, Type=0x%.2X", + NewCount, Object, Object->Common.Type)); } } @@ -499,8 +505,7 @@ AcpiUtUpdateRefCount ( * * PARAMETERS: Object - Increment ref count for this object * and all sub-objects - * Action - Either REF_INCREMENT or REF_DECREMENT or - * REF_FORCE_DELETE + * Action - Either REF_INCREMENT or REF_DECREMENT * * RETURN: Status * @@ -771,7 +776,6 @@ AcpiUtRemoveReference ( /* * Allow a NULL pointer to be passed in, just ignore it. This saves * each caller from having to check. Also, ignore NS nodes. - * */ if (!Object || (ACPI_GET_DESCRIPTOR_TYPE (Object) == ACPI_DESC_TYPE_NAMED)) diff --git a/source/components/utilities/utmutex.c b/source/components/utilities/utmutex.c index 7755c9b..a74ef81 100644 --- a/source/components/utilities/utmutex.c +++ b/source/components/utilities/utmutex.c @@ -96,7 +96,7 @@ AcpiUtMutexInitialize ( } } - /* Create the spinlocks for use at interrupt level */ + /* Create the spinlocks for use at interrupt level or for speed */ Status = AcpiOsCreateLock (&AcpiGbl_GpeLock); if (ACPI_FAILURE (Status)) @@ -110,7 +110,14 @@ AcpiUtMutexInitialize ( return_ACPI_STATUS (Status); } + Status = AcpiOsCreateLock (&AcpiGbl_ReferenceCountLock); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + /* Mutex for _OSI support */ + Status = AcpiOsCreateMutex (&AcpiGbl_OsiMutex); if (ACPI_FAILURE (Status)) { @@ -160,6 +167,7 @@ AcpiUtMutexTerminate ( AcpiOsDeleteLock (AcpiGbl_GpeLock); AcpiOsDeleteLock (AcpiGbl_HardwareLock); + AcpiOsDeleteLock (AcpiGbl_ReferenceCountLock); /* Delete the reader/writer lock */ diff --git a/source/components/utilities/utosi.c b/source/components/utilities/utosi.c index 7449b26..81d648b 100644 --- a/source/components/utilities/utosi.c +++ b/source/components/utilities/utosi.c @@ -115,10 +115,16 @@ ACPI_STATUS AcpiUtInitializeInterfaces ( void) { + ACPI_STATUS Status; UINT32 i; - (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); + Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + AcpiGbl_SupportedInterfaces = AcpiDefaultSupportedInterfaces; /* Link the static list of supported interfaces */ @@ -140,23 +146,28 @@ AcpiUtInitializeInterfaces ( * * PARAMETERS: None * - * RETURN: None + * RETURN: Status * * DESCRIPTION: Delete all interfaces in the global list. Sets * AcpiGbl_SupportedInterfaces to NULL. * ******************************************************************************/ -void +ACPI_STATUS AcpiUtInterfaceTerminate ( void) { + ACPI_STATUS Status; ACPI_INTERFACE_INFO *NextInterface; - (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); - NextInterface = AcpiGbl_SupportedInterfaces; + Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + NextInterface = AcpiGbl_SupportedInterfaces; while (NextInterface) { AcpiGbl_SupportedInterfaces = NextInterface->Next; @@ -173,6 +184,7 @@ AcpiUtInterfaceTerminate ( } AcpiOsReleaseMutex (AcpiGbl_OsiMutex); + return (AE_OK); } @@ -350,6 +362,7 @@ AcpiUtOsiImplementation ( ACPI_OPERAND_OBJECT *ReturnDesc; ACPI_INTERFACE_INFO *InterfaceInfo; ACPI_INTERFACE_HANDLER InterfaceHandler; + ACPI_STATUS Status; UINT32 ReturnValue; @@ -376,7 +389,11 @@ AcpiUtOsiImplementation ( /* Default return value is 0, NOT SUPPORTED */ ReturnValue = 0; - (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); + Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); + if (ACPI_FAILURE (Status)) + { + return (Status); + } /* Lookup the interface in the global _OSI list */ diff --git a/source/components/utilities/utpredef.c b/source/components/utilities/utpredef.c new file mode 100644 index 0000000..4d85497 --- /dev/null +++ b/source/components/utilities/utpredef.c @@ -0,0 +1,451 @@ +/****************************************************************************** + * + * Module Name: utpredef - support functions for predefined names + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2013, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#define __UTPREDEF_C__ + +#include "acpi.h" +#include "accommon.h" +#include "acpredef.h" + + +#define _COMPONENT ACPI_UTILITIES + ACPI_MODULE_NAME ("utpredef") + + +/* + * Names for the types that can be returned by the predefined objects. + * Used for warning messages. Must be in the same order as the ACPI_RTYPEs + */ +static const char *UtRtypeNames[] = +{ + "/Integer", + "/String", + "/Buffer", + "/Package", + "/Reference", +}; + + +/******************************************************************************* + * + * FUNCTION: AcpiUtGetNextPredefinedMethod + * + * PARAMETERS: ThisName - Entry in the predefined method/name table + * + * RETURN: Pointer to next entry in predefined table. + * + * DESCRIPTION: Get the next entry in the predefine method table. Handles the + * cases where a package info entry follows a method name that + * returns a package. + * + ******************************************************************************/ + +const ACPI_PREDEFINED_INFO * +AcpiUtGetNextPredefinedMethod ( + const ACPI_PREDEFINED_INFO *ThisName) +{ + + /* + * Skip next entry in the table if this name returns a Package + * (next entry contains the package info) + */ + if ((ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE) && + (ThisName->Info.ExpectedBtypes != ACPI_RTYPE_ALL)) + { + ThisName++; + } + + ThisName++; + return (ThisName); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtMatchPredefinedMethod + * + * PARAMETERS: Name - Name to find + * + * RETURN: Pointer to entry in predefined table. NULL indicates not found. + * + * DESCRIPTION: Check an object name against the predefined object list. + * + ******************************************************************************/ + +const ACPI_PREDEFINED_INFO * +AcpiUtMatchPredefinedMethod ( + char *Name) +{ + const ACPI_PREDEFINED_INFO *ThisName; + + + /* Quick check for a predefined name, first character must be underscore */ + + if (Name[0] != '_') + { + return (NULL); + } + + /* Search info table for a predefined method/object name */ + + ThisName = AcpiGbl_PredefinedMethods; + while (ThisName->Info.Name[0]) + { + if (ACPI_COMPARE_NAME (Name, ThisName->Info.Name)) + { + return (ThisName); + } + + ThisName = AcpiUtGetNextPredefinedMethod (ThisName); + } + + return (NULL); /* Not found */ +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtGetExpectedReturnTypes + * + * PARAMETERS: Buffer - Where the formatted string is returned + * ExpectedBTypes - Bitfield of expected data types + * + * RETURN: Formatted string in Buffer. + * + * DESCRIPTION: Format the expected object types into a printable string. + * + ******************************************************************************/ + +void +AcpiUtGetExpectedReturnTypes ( + char *Buffer, + UINT32 ExpectedBtypes) +{ + UINT32 ThisRtype; + UINT32 i; + UINT32 j; + + + j = 1; + Buffer[0] = 0; + ThisRtype = ACPI_RTYPE_INTEGER; + + for (i = 0; i < ACPI_NUM_RTYPES; i++) + { + /* If one of the expected types, concatenate the name of this type */ + + if (ExpectedBtypes & ThisRtype) + { + ACPI_STRCAT (Buffer, &UtRtypeNames[i][j]); + j = 0; /* Use name separator from now on */ + } + + ThisRtype <<= 1; /* Next Rtype */ + } +} + + +/******************************************************************************* + * + * The remaining functions are used by iASL and AcpiHelp only + * + ******************************************************************************/ + +#if (defined ACPI_ASL_COMPILER || defined ACPI_HELP_APP) +#include <stdio.h> +#include <string.h> + +/* Local prototypes */ + +static UINT32 +AcpiUtGetArgumentTypes ( + char *Buffer, + UINT16 ArgumentTypes); + + +/* Types that can be returned externally by a predefined name */ + +static const char *UtExternalTypeNames[] = /* Indexed by ACPI_TYPE_* */ +{ + ", UNSUPPORTED-TYPE", + ", Integer", + ", String", + ", Buffer", + ", Package" +}; + +/* Bit widths for resource descriptor predefined names */ + +static const char *UtResourceTypeNames[] = +{ + "/1", + "/2", + "/3", + "/8", + "/16", + "/32", + "/64", + "/variable", +}; + + +/******************************************************************************* + * + * FUNCTION: AcpiUtMatchResourceName + * + * PARAMETERS: Name - Name to find + * + * RETURN: Pointer to entry in the resource table. NULL indicates not + * found. + * + * DESCRIPTION: Check an object name against the predefined resource + * descriptor object list. + * + ******************************************************************************/ + +const ACPI_PREDEFINED_INFO * +AcpiUtMatchResourceName ( + char *Name) +{ + const ACPI_PREDEFINED_INFO *ThisName; + + + /* Quick check for a predefined name, first character must be underscore */ + + if (Name[0] != '_') + { + return (NULL); + } + + /* Search info table for a predefined method/object name */ + + ThisName = AcpiGbl_ResourceNames; + while (ThisName->Info.Name[0]) + { + if (ACPI_COMPARE_NAME (Name, ThisName->Info.Name)) + { + return (ThisName); + } + + ThisName++; + } + + return (NULL); /* Not found */ +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtDisplayPredefinedMethod + * + * PARAMETERS: Buffer - Scratch buffer for this function + * ThisName - Entry in the predefined method/name table + * MultiLine - TRUE if output should be on >1 line + * + * RETURN: None + * + * DESCRIPTION: Display information about a predefined method. Number and + * type of the input arguments, and expected type(s) for the + * return value, if any. + * + ******************************************************************************/ + +void +AcpiUtDisplayPredefinedMethod ( + char *Buffer, + const ACPI_PREDEFINED_INFO *ThisName, + BOOLEAN MultiLine) +{ + UINT32 ArgCount; + + /* + * Get the argument count and the string buffer + * containing all argument types + */ + ArgCount = AcpiUtGetArgumentTypes (Buffer, + ThisName->Info.ArgumentList); + + if (MultiLine) + { + printf (" "); + } + + printf ("%4.4s Requires %s%u argument%s", + ThisName->Info.Name, + (ThisName->Info.ArgumentList & ARG_COUNT_IS_MINIMUM) ? + "(at least) " : "", + ArgCount, ArgCount != 1 ? "s" : ""); + + /* Display the types for any arguments */ + + if (ArgCount > 0) + { + printf (" (%s)", Buffer); + } + + if (MultiLine) + { + printf ("\n "); + } + + /* Get the return value type(s) allowed */ + + if (ThisName->Info.ExpectedBtypes) + { + AcpiUtGetExpectedReturnTypes (Buffer, ThisName->Info.ExpectedBtypes); + printf (" Return value types: %s\n", Buffer); + } + else + { + printf (" No return value\n"); + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtGetArgumentTypes + * + * PARAMETERS: Buffer - Where to return the formatted types + * ArgumentTypes - Types field for this method + * + * RETURN: Count - the number of arguments required for this method + * + * DESCRIPTION: Format the required data types for this method (Integer, + * String, Buffer, or Package) and return the required argument + * count. + * + ******************************************************************************/ + +static UINT32 +AcpiUtGetArgumentTypes ( + char *Buffer, + UINT16 ArgumentTypes) +{ + UINT16 ThisArgumentType; + UINT16 SubIndex; + UINT16 ArgCount; + UINT32 i; + + + *Buffer = 0; + SubIndex = 2; + + /* First field in the types list is the count of args to follow */ + + ArgCount = (ArgumentTypes & METHOD_ARG_MASK); + ArgumentTypes >>= METHOD_ARG_BIT_WIDTH; + + if (ArgCount > METHOD_PREDEF_ARGS_MAX) + { + printf ("**** Invalid argument count (%u) " + "in predefined info structure\n", ArgCount); + return (ArgCount); + } + + /* Get each argument from the list, convert to ascii, store to buffer */ + + for (i = 0; i < ArgCount; i++) + { + ThisArgumentType = (ArgumentTypes & METHOD_ARG_MASK); + if (!ThisArgumentType || (ThisArgumentType > METHOD_MAX_ARG_TYPE)) + { + printf ("**** Invalid argument type (%u) " + "in predefined info structure\n", ThisArgumentType); + return (ArgCount); + } + + strcat (Buffer, UtExternalTypeNames[ThisArgumentType] + SubIndex); + + /* Shift to next argument type field */ + + ArgumentTypes >>= METHOD_ARG_BIT_WIDTH; + SubIndex = 0; + } + + return (ArgCount); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiUtGetResourceBitWidth + * + * PARAMETERS: Buffer - Where the formatted string is returned + * Types - Bitfield of expected data types + * + * RETURN: Count of return types. Formatted string in Buffer. + * + * DESCRIPTION: Format the resource bit widths into a printable string. + * + ******************************************************************************/ + +UINT32 +AcpiUtGetResourceBitWidth ( + char *Buffer, + UINT16 Types) +{ + UINT32 i; + UINT16 SubIndex; + UINT32 Found; + + + *Buffer = 0; + SubIndex = 1; + Found = 0; + + for (i = 0; i < NUM_RESOURCE_WIDTHS; i++) + { + if (Types & 1) + { + strcat (Buffer, &(UtResourceTypeNames[i][SubIndex])); + SubIndex = 0; + Found++; + } + + Types >>= 1; + } + + return (Found); +} +#endif diff --git a/source/components/utilities/utxface.c b/source/components/utilities/utxface.c index 60405aa..4506980 100644 --- a/source/components/utilities/utxface.c +++ b/source/components/utilities/utxface.c @@ -373,7 +373,11 @@ AcpiInstallInterface ( return (AE_BAD_PARAMETER); } - (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); + Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); + if (ACPI_FAILURE (Status)) + { + return (Status); + } /* Check if the interface name is already in the global list */ @@ -434,7 +438,11 @@ AcpiRemoveInterface ( return (AE_BAD_PARAMETER); } - (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); + Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); + if (ACPI_FAILURE (Status)) + { + return (Status); + } Status = AcpiUtRemoveInterface (InterfaceName); @@ -464,10 +472,14 @@ ACPI_STATUS AcpiInstallInterfaceHandler ( ACPI_INTERFACE_HANDLER Handler) { - ACPI_STATUS Status = AE_OK; + ACPI_STATUS Status; - (void) AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); + Status = AcpiOsAcquireMutex (AcpiGbl_OsiMutex, ACPI_WAIT_FOREVER); + if (ACPI_FAILURE (Status)) + { + return (Status); + } if (Handler && AcpiGbl_InterfaceHandler) { |