Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/external/bsd/acpica/dist/events/evregion.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/external/bsd/acpica/dist/events/evregion.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.1.1.4 retrieving revision 1.1.1.5 diff -u -p -r1.1.1.4 -r1.1.1.5 --- src/sys/external/bsd/acpica/dist/events/evregion.c 2013/12/27 18:46:20 1.1.1.4 +++ src/sys/external/bsd/acpica/dist/events/evregion.c 2014/10/25 20:57:59 1.1.1.5 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2014, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,7 +41,6 @@ * POSSIBILITY OF SUCH DAMAGES. */ - #define __EVREGION_C__ #include "acpi.h" @@ -159,6 +158,7 @@ AcpiEvAddressSpaceDispatch ( ACPI_OPERAND_OBJECT *RegionObj2; void *RegionContext = NULL; ACPI_CONNECTION_INFO *Context; + ACPI_PHYSICAL_ADDRESS Address; ACPI_FUNCTION_TRACE (EvAddressSpaceDispatch); @@ -248,23 +248,23 @@ AcpiEvAddressSpaceDispatch ( /* We have everything we need, we can invoke the address space handler */ Handler = HandlerDesc->AddressSpace.Handler; - - ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, - "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", - &RegionObj->Region.Handler->AddressSpace, Handler, - ACPI_FORMAT_NATIVE_UINT (RegionObj->Region.Address + RegionOffset), - AcpiUtGetRegionName (RegionObj->Region.SpaceId))); + Address = (RegionObj->Region.Address + RegionOffset); /* * Special handling for GenericSerialBus and GeneralPurposeIo: * There are three extra parameters that must be passed to the * handler via the context: - * 1) Connection buffer, a resource template from Connection() op. - * 2) Length of the above buffer. - * 3) Actual access length from the AccessAs() op. + * 1) Connection buffer, a resource template from Connection() op + * 2) Length of the above buffer + * 3) Actual access length from the AccessAs() op + * + * In addition, for GeneralPurposeIo, the Address and BitWidth fields + * are defined as follows: + * 1) Address is the pin number index of the field (bit offset from + * the previous Connection) + * 2) BitWidth is the actual bit length of the field (number of pins) */ - if (((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS) || - (RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO)) && + if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GSBUS) && Context && FieldObj) { @@ -274,6 +274,24 @@ AcpiEvAddressSpaceDispatch ( Context->Length = FieldObj->Field.ResourceLength; Context->AccessLength = FieldObj->Field.AccessLength; } + if ((RegionObj->Region.SpaceId == ACPI_ADR_SPACE_GPIO) && + Context && + FieldObj) + { + /* Get the Connection (ResourceTemplate) buffer */ + + Context->Connection = FieldObj->Field.ResourceBuffer; + Context->Length = FieldObj->Field.ResourceLength; + Context->AccessLength = FieldObj->Field.AccessLength; + Address = FieldObj->Field.PinNumberIndex; + BitWidth = FieldObj->Field.BitLength; + } + + ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, + "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", + &RegionObj->Region.Handler->AddressSpace, Handler, + ACPI_FORMAT_NATIVE_UINT (Address), + AcpiUtGetRegionName (RegionObj->Region.SpaceId))); if (!(HandlerDesc->AddressSpace.HandlerFlags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) @@ -288,9 +306,8 @@ AcpiEvAddressSpaceDispatch ( /* Call the handler */ - Status = Handler (Function, - (RegionObj->Region.Address + RegionOffset), BitWidth, Value, - Context, RegionObj2->Extra.RegionContext); + Status = Handler (Function, Address, BitWidth, Value, Context, + RegionObj2->Extra.RegionContext); if (ACPI_FAILURE (Status)) { @@ -333,6 +350,7 @@ AcpiEvDetachRegion( { ACPI_OPERAND_OBJECT *HandlerObj; ACPI_OPERAND_OBJECT *ObjDesc; + ACPI_OPERAND_OBJECT *StartDesc; ACPI_OPERAND_OBJECT **LastObjPtr; ACPI_ADR_SPACE_SETUP RegionSetup; void **RegionContext; @@ -363,6 +381,7 @@ AcpiEvDetachRegion( /* Find this region in the handler's list */ ObjDesc = HandlerObj->AddressSpace.RegionList; + StartDesc = ObjDesc; LastObjPtr = &HandlerObj->AddressSpace.RegionList; while (ObjDesc) @@ -457,6 +476,16 @@ AcpiEvDetachRegion( LastObjPtr = &ObjDesc->Region.Next; ObjDesc = ObjDesc->Region.Next; + + /* Prevent infinite loop if list is corrupted */ + + if (ObjDesc == StartDesc) + { + ACPI_ERROR ((AE_INFO, + "Circular handler list in region object %p", + RegionObj)); + return_VOID; + } } /* If we get here, the region was not in the handler's region list */