summaryrefslogtreecommitdiffstats
path: root/sys/contrib/dev/acpica/evrgnini.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/evrgnini.c')
-rw-r--r--sys/contrib/dev/acpica/evrgnini.c179
1 files changed, 98 insertions, 81 deletions
diff --git a/sys/contrib/dev/acpica/evrgnini.c b/sys/contrib/dev/acpica/evrgnini.c
index 2a53764..12bb927 100644
--- a/sys/contrib/dev/acpica/evrgnini.c
+++ b/sys/contrib/dev/acpica/evrgnini.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: evrgnini- ACPI AddressSpace (OpRegion) init
- * $Revision: 66 $
+ * $Revision: 69 $
*
*****************************************************************************/
@@ -245,10 +245,11 @@ AcpiEvPciConfigRegionSetup (
void **RegionContext)
{
ACPI_STATUS Status = AE_OK;
- ACPI_INTEGER Temp;
+ ACPI_INTEGER PciValue;
ACPI_PCI_ID *PciId = *RegionContext;
ACPI_OPERAND_OBJECT *HandlerObj;
- ACPI_NAMESPACE_NODE *Node;
+ ACPI_NAMESPACE_NODE *ParentNode;
+ ACPI_NAMESPACE_NODE *PciRootNode;
ACPI_OPERAND_OBJECT *RegionObj = (ACPI_OPERAND_OBJECT *) Handle;
ACPI_DEVICE_ID ObjectHID;
@@ -256,7 +257,7 @@ AcpiEvPciConfigRegionSetup (
ACPI_FUNCTION_TRACE ("EvPciConfigRegionSetup");
- HandlerObj = RegionObj->Region.AddrHandler;
+ HandlerObj = RegionObj->Region.AddressSpace;
if (!HandlerObj)
{
/*
@@ -268,49 +269,17 @@ AcpiEvPciConfigRegionSetup (
return_ACPI_STATUS (AE_NOT_EXIST);
}
+ *RegionContext = NULL;
if (Function == ACPI_REGION_DEACTIVATE)
{
if (PciId)
{
ACPI_MEM_FREE (PciId);
- *RegionContext = NULL;
}
-
return_ACPI_STATUS (Status);
}
- /* Create a new context */
-
- PciId = ACPI_MEM_CALLOCATE (sizeof (ACPI_PCI_ID));
- if (!PciId)
- {
- return_ACPI_STATUS (AE_NO_MEMORY);
- }
-
- /*
- * For PCI Config space access, we have to pass the segment, bus,
- * device and function numbers. This routine must acquire those.
- */
-
- /*
- * First get device and function numbers from the _ADR object
- * in the parent's scope.
- */
- Node = AcpiNsGetParentNode (RegionObj->Region.Node);
-
- /* Evaluate the _ADR object */
-
- Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &Temp);
-
- /*
- * The default is zero, and since the allocation above zeroed
- * the data, just do nothing on failure.
- */
- if (ACPI_SUCCESS (Status))
- {
- PciId->Device = ACPI_HIWORD (ACPI_LODWORD (Temp));
- PciId->Function = ACPI_LOWORD (ACPI_LODWORD (Temp));
- }
+ ParentNode = AcpiNsGetParentNode (RegionObj->Region.Node);
/*
* Get the _SEG and _BBN values from the device upon which the handler
@@ -321,69 +290,119 @@ AcpiEvPciConfigRegionSetup (
*/
/*
- * If the AddrHandler.Node is still pointing to the root, we need
+ * If the AddressSpace.Node is still pointing to the root, we need
* to scan upward for a PCI Root bridge and re-associate the OpRegion
* handlers with that device.
*/
- if (HandlerObj->AddrHandler.Node == AcpiGbl_RootNode)
+ if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode)
{
- /*
- * Node is currently the parent object
- */
- while (Node != AcpiGbl_RootNode)
+ /* Start search from the parent object */
+
+ PciRootNode = ParentNode;
+ while (PciRootNode != AcpiGbl_RootNode)
{
- Status = AcpiUtExecute_HID (Node, &ObjectHID);
+ Status = AcpiUtExecute_HID (PciRootNode, &ObjectHID);
if (ACPI_SUCCESS (Status))
{
/* Got a valid _HID, check if this is a PCI root */
- if (!(ACPI_STRNCMP (ObjectHID.Buffer, PCI_ROOT_HID_STRING,
+ if (!(ACPI_STRNCMP (ObjectHID.Value, PCI_ROOT_HID_STRING,
sizeof (PCI_ROOT_HID_STRING))))
{
/* Install a handler for this PCI root bridge */
- Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) Node,
+ Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) PciRootNode,
ACPI_ADR_SPACE_PCI_CONFIG,
ACPI_DEFAULT_HANDLER, NULL, NULL);
if (ACPI_FAILURE (Status))
{
- ACPI_REPORT_ERROR (("Could not install PciConfig handler for %4.4s, %s\n",
- Node->Name.Ascii, AcpiFormatException (Status)));
+ if (Status == AE_SAME_HANDLER)
+ {
+ /*
+ * It is OK if the handler is already installed on the root
+ * bridge. Still need to return a context object for the
+ * new PCI_Config operation region, however.
+ */
+ Status = AE_OK;
+ }
+ else
+ {
+ ACPI_REPORT_ERROR ((
+ "Could not install PciConfig handler for Root Bridge %4.4s, %s\n",
+ PciRootNode->Name.Ascii, AcpiFormatException (Status)));
+ }
}
break;
}
}
- Node = AcpiNsGetParentNode (Node);
+ PciRootNode = AcpiNsGetParentNode (PciRootNode);
}
+
+ /* PCI root bridge not found, use namespace root node */
}
else
{
- Node = HandlerObj->AddrHandler.Node;
+ PciRootNode = HandlerObj->AddressSpace.Node;
}
/*
- * The PCI segment number comes from the _SEG method
+ * If this region is now initialized, we are done.
+ * (InstallAddressSpaceHandler could have initialized it)
*/
- Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG, Node, &Temp);
- if (ACPI_SUCCESS (Status))
+ if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE)
+ {
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /* Region is still not initialized. Create a new context */
+
+ PciId = ACPI_MEM_CALLOCATE (sizeof (ACPI_PCI_ID));
+ if (!PciId)
{
- PciId->Segment = ACPI_LOWORD (Temp);
+ return_ACPI_STATUS (AE_NO_MEMORY);
}
/*
- * The PCI bus number comes from the _BBN method
+ * For PCI_Config space access, we need the segment, bus,
+ * device and function numbers. Acquire them here.
+ */
+
+ /*
+ * Get the PCI device and function numbers from the _ADR object
+ * contained in the parent's scope.
+ */
+ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, ParentNode, &PciValue);
+
+ /*
+ * The default is zero, and since the allocation above zeroed
+ * the data, just do nothing on failure.
*/
- Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN, Node, &Temp);
if (ACPI_SUCCESS (Status))
{
- PciId->Bus = ACPI_LOWORD (Temp);
+ PciId->Device = ACPI_HIWORD (ACPI_LODWORD (PciValue));
+ PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue));
}
- /*
- * Complete this device's PciId
- */
- AcpiOsDerivePciId (Node, RegionObj->Region.Node, &PciId);
+ /* The PCI segment number comes from the _SEG method */
+
+ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG, PciRootNode, &PciValue);
+ if (ACPI_SUCCESS (Status))
+ {
+ PciId->Segment = ACPI_LOWORD (PciValue);
+ }
+
+ /* The PCI bus number comes from the _BBN method */
+
+ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN, PciRootNode, &PciValue);
+ if (ACPI_SUCCESS (Status))
+ {
+ PciId->Bus = ACPI_LOWORD (PciValue);
+ }
+
+ /* Complete this device's PciId */
+
+ AcpiOsDerivePciId (PciRootNode, RegionObj->Region.Node, &PciId);
*RegionContext = PciId;
return_ACPI_STATUS (AE_OK);
@@ -549,16 +568,17 @@ AcpiEvInitializeRegion (
Node = AcpiNsGetParentNode (RegionObj->Region.Node);
SpaceId = RegionObj->Region.SpaceId;
- RegionObj->Region.AddrHandler = NULL;
+ /* Setup defaults */
+
+ RegionObj->Region.AddressSpace = NULL;
RegionObj2->Extra.Method_REG = NULL;
RegionObj->Common.Flags &= ~(AOPOBJ_SETUP_COMPLETE);
RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED;
- /*
- * Find any "_REG" method associated with this region definition
- */
+ /* Find any "_REG" method associated with this region definition */
+
Status = AcpiNsSearchNode (*RegNamePtr, Node,
- ACPI_TYPE_METHOD, &MethodNode);
+ ACPI_TYPE_METHOD, &MethodNode);
if (ACPI_SUCCESS (Status))
{
/*
@@ -575,31 +595,29 @@ AcpiEvInitializeRegion (
*/
while (Node)
{
- /*
- * Check to see if a handler exists
- */
+ /* Check to see if a handler exists */
+
HandlerObj = NULL;
ObjDesc = AcpiNsGetAttachedObject (Node);
if (ObjDesc)
{
- /*
- * Can only be a handler if the object exists
- */
+ /* Can only be a handler if the object exists */
+
switch (Node->Type)
{
case ACPI_TYPE_DEVICE:
- HandlerObj = ObjDesc->Device.AddrHandler;
+ HandlerObj = ObjDesc->Device.AddressSpace;
break;
case ACPI_TYPE_PROCESSOR:
- HandlerObj = ObjDesc->Processor.AddrHandler;
+ HandlerObj = ObjDesc->Processor.AddressSpace;
break;
case ACPI_TYPE_THERMAL:
- HandlerObj = ObjDesc->ThermalZone.AddrHandler;
+ HandlerObj = ObjDesc->ThermalZone.AddressSpace;
break;
default:
@@ -611,7 +629,7 @@ AcpiEvInitializeRegion (
{
/* Is this handler of the correct type? */
- if (HandlerObj->AddrHandler.SpaceId == SpaceId)
+ if (HandlerObj->AddressSpace.SpaceId == SpaceId)
{
/* Found correct handler */
@@ -627,7 +645,7 @@ AcpiEvInitializeRegion (
/* Try next handler in the list */
- HandlerObj = HandlerObj->AddrHandler.Next;
+ HandlerObj = HandlerObj->AddressSpace.Next;
}
}
@@ -638,9 +656,8 @@ AcpiEvInitializeRegion (
Node = AcpiNsGetParentNode (Node);
}
- /*
- * If we get here, there is no handler for this region
- */
+ /* If we get here, there is no handler for this region */
+
ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
"No handler for RegionType %s(%X) (RegionObj %p)\n",
AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj));
OpenPOWER on IntegriCloud