diff options
Diffstat (limited to 'sys/contrib/dev/acpica/evxfregn.c')
-rw-r--r-- | sys/contrib/dev/acpica/evxfregn.c | 175 |
1 files changed, 89 insertions, 86 deletions
diff --git a/sys/contrib/dev/acpica/evxfregn.c b/sys/contrib/dev/acpica/evxfregn.c index 6bd920c..ed16c7a 100644 --- a/sys/contrib/dev/acpica/evxfregn.c +++ b/sys/contrib/dev/acpica/evxfregn.c @@ -2,7 +2,7 @@ * * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and * Address Spaces. - * $Revision: 53 $ + * $Revision: 56 $ * *****************************************************************************/ @@ -234,49 +234,58 @@ AcpiInstallAddressSpaceHandler ( break; default: - Status = AE_NOT_EXIST; + Status = AE_BAD_PARAMETER; goto UnlockAndExit; } } - /* - * If the caller hasn't specified a setup routine, use the default - */ + /* If the caller hasn't specified a setup routine, use the default */ + if (!Setup) { Setup = AcpiEvDefaultRegionSetup; } - /* - * Check for an existing internal object - */ + /* Check for an existing internal object */ + ObjDesc = AcpiNsGetAttachedObject (Node); if (ObjDesc) { /* - * The object exists. + * The attached device object already exists. * Make sure the handler is not already installed. */ + HandlerObj = ObjDesc->Device.AddressSpace; - /* check the address handler the user requested */ + /* Walk the handler list for this device */ - HandlerObj = ObjDesc->Device.AddrHandler; while (HandlerObj) { - /* - * We have an Address handler, see if user requested this - * address space. - */ - if(HandlerObj->AddrHandler.SpaceId == SpaceId) + /* Same SpaceId indicates a handler already installed */ + + if(HandlerObj->AddressSpace.SpaceId == SpaceId) { - Status = AE_ALREADY_EXISTS; + if (HandlerObj->AddressSpace.Handler == Handler) + { + /* + * It is (relatively) OK to attempt to install the SAME + * handler twice. This can easily happen with PCI_Config space. + */ + Status = AE_SAME_HANDLER; + goto UnlockAndExit; + } + else + { + /* A handler is already installed */ + + Status = AE_ALREADY_EXISTS; + } goto UnlockAndExit; } - /* - * Move through the linked list of handlers - */ - HandlerObj = HandlerObj->AddrHandler.Next; + /* Walk the linked list of handlers */ + + HandlerObj = HandlerObj->AddressSpace.Next; } } else @@ -309,9 +318,13 @@ AcpiInstallAddressSpaceHandler ( /* Attach the new object to the Node */ Status = AcpiNsAttachObject (Node, ObjDesc, Type); + + /* Remove local reference to the object */ + + AcpiUtRemoveReference (ObjDesc); + if (ACPI_FAILURE (Status)) { - AcpiUtRemoveReference (ObjDesc); goto UnlockAndExit; } } @@ -321,10 +334,10 @@ AcpiInstallAddressSpaceHandler ( AcpiUtGetRegionName (SpaceId), SpaceId, Node->Name.Ascii, Node, ObjDesc)); /* - * Now we can install the handler + * Install the handler * - * At this point we know that there is no existing handler. - * So, we just allocate the object for the handler and link it + * At this point there is no existing handler. + * Just allocate the object for the handler and link it * into the list. */ HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_ADDRESS_HANDLER); @@ -334,40 +347,41 @@ AcpiInstallAddressSpaceHandler ( goto UnlockAndExit; } - HandlerObj->AddrHandler.SpaceId = (UINT8) SpaceId; - HandlerObj->AddrHandler.Hflags = Flags; - HandlerObj->AddrHandler.Next = ObjDesc->Device.AddrHandler; - HandlerObj->AddrHandler.RegionList = NULL; - HandlerObj->AddrHandler.Node = Node; - HandlerObj->AddrHandler.Handler = Handler; - HandlerObj->AddrHandler.Context = Context; - HandlerObj->AddrHandler.Setup = Setup; + /* Init handler obj */ + + HandlerObj->AddressSpace.SpaceId = (UINT8) SpaceId; + HandlerObj->AddressSpace.Hflags = Flags; + HandlerObj->AddressSpace.RegionList = NULL; + HandlerObj->AddressSpace.Node = Node; + HandlerObj->AddressSpace.Handler = Handler; + HandlerObj->AddressSpace.Context = Context; + HandlerObj->AddressSpace.Setup = Setup; + + /* Install at head of Device.AddressSpace list */ + + HandlerObj->AddressSpace.Next = ObjDesc->Device.AddressSpace; + + /* + * The Device object is the first reference on the HandlerObj. + * Each region that uses the handler adds a reference. + */ + ObjDesc->Device.AddressSpace = HandlerObj; /* - * Now walk the namespace finding all of the regions this + * Walk the namespace finding all of the regions this * handler will manage. * - * We start at the device and search the branch toward + * Start at the device and search the branch toward * the leaf nodes until either the leaf is encountered or * a device is detected that has an address handler of the * same type. * - * In either case we back up and search down the remainder + * In either case, back up and search down the remainder * of the branch */ - Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Device, - ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, - AcpiEvAddrHandlerHelper, - HandlerObj, NULL); - - /* - * Place this handler 1st on the list - */ - HandlerObj->Common.ReferenceCount = - (UINT16) (HandlerObj->Common.ReferenceCount + - ObjDesc->Common.ReferenceCount - 1); - ObjDesc->Device.AddrHandler = HandlerObj; - + Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Device, ACPI_UINT32_MAX, + ACPI_NS_WALK_UNLOCK, AcpiEvInstallHandler, + HandlerObj, NULL); UnlockAndExit: (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); @@ -379,12 +393,13 @@ UnlockAndExit: * * FUNCTION: AcpiRemoveAddressSpaceHandler * - * PARAMETERS: SpaceId - The address space ID + * PARAMETERS: Device - Handle for the device + * SpaceId - The address space ID * Handler - Address of the handler * * RETURN: Status * - * DESCRIPTION: Install a handler for accesses on an Operation Region + * DESCRIPTION: Remove a previously installed handler. * ******************************************************************************/ @@ -436,27 +451,24 @@ AcpiRemoveAddressSpaceHandler ( goto UnlockAndExit; } - /* - * find the address handler the user requested - */ - HandlerObj = ObjDesc->Device.AddrHandler; - LastObjPtr = &ObjDesc->Device.AddrHandler; + /* Find the address handler the user requested */ + + HandlerObj = ObjDesc->Device.AddressSpace; + LastObjPtr = &ObjDesc->Device.AddressSpace; while (HandlerObj) { - /* - * We have a handler, see if user requested this one - */ - if (HandlerObj->AddrHandler.SpaceId == SpaceId) + /* We have a handler, see if user requested this one */ + + if (HandlerObj->AddressSpace.SpaceId == SpaceId) { - /* - * Got it, first dereference this in the Regions - */ + /* Matched SpaceId, first dereference this in the Regions */ + ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Removing address handler %p(%p) for region %s on Device %p(%p)\n", HandlerObj, Handler, AcpiUtGetRegionName (SpaceId), Node, ObjDesc)); - RegionObj = HandlerObj->AddrHandler.RegionList; + RegionObj = HandlerObj->AddressSpace.RegionList; /* Walk the handler's region list */ @@ -472,46 +484,37 @@ AcpiRemoveAddressSpaceHandler ( AcpiEvDetachRegion (RegionObj, TRUE); /* - * Walk the list, since we took the first region and it - * was removed from the list by the dissassociate call - * we just get the first item on the list again + * Walk the list: Just grab the head because the + * DetachRegion removed the previous head. */ - RegionObj = HandlerObj->AddrHandler.RegionList; + RegionObj = HandlerObj->AddressSpace.RegionList; } - /* - * Remove this Handler object from the list - */ - *LastObjPtr = HandlerObj->AddrHandler.Next; + /* Remove this Handler object from the list */ - /* - * Now we can delete the handler object - */ - AcpiUtRemoveReference (HandlerObj); - AcpiUtRemoveReference (HandlerObj); + *LastObjPtr = HandlerObj->AddressSpace.Next; + + /* Now we can delete the handler object */ + AcpiUtRemoveReference (HandlerObj); goto UnlockAndExit; } - /* - * Move through the linked list of handlers - */ - LastObjPtr = &HandlerObj->AddrHandler.Next; - HandlerObj = HandlerObj->AddrHandler.Next; + /* Walk the linked list of handlers */ + + LastObjPtr = &HandlerObj->AddressSpace.Next; + HandlerObj = HandlerObj->AddressSpace.Next; } + /* The handler does not exist */ - /* - * The handler does not exist - */ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Unable to remove address handler %p for %s(%X), DevNode %p, obj %p\n", Handler, AcpiUtGetRegionName (SpaceId), SpaceId, Node, ObjDesc)); Status = AE_NOT_EXIST; - UnlockAndExit: (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (Status); |