static BOOLEAN AcpiEvIsPciRootBridge ( ACPI_NAMESPACE_NODE *Node) { ACPI_STATUS Status; ACPI_PNP_DEVICE_ID *Hid; ACPI_PNP_DEVICE_ID_LIST *Cid; UINT32 i; BOOLEAN Match; /* Get the _HID and check for a PCI Root Bridge */ Status = AcpiUtExecute_HID (Node, &Hid); if (ACPI_FAILURE (Status)) { return (FALSE); } Match = AcpiUtIsPciRootBridge (Hid->String); ACPI_FREE (Hid); if (Match) { return (TRUE); } /* The _HID did not match. Get the _CID and check for a PCI Root Bridge */ Status = AcpiUtExecute_CID (Node, &Cid); if (ACPI_FAILURE (Status)) { return (FALSE); } /* Check all _CIDs in the returned list */ for (i = 0; i < Cid->Count; i++) { if (AcpiUtIsPciRootBridge (Cid->Ids[i].String)) { ACPI_FREE (Cid); return (TRUE); } } ACPI_FREE (Cid); return (FALSE); }
static BOOLEAN AcpiEvIsPciRootBridge ( ACPI_NAMESPACE_NODE *Node) { ACPI_STATUS Status; ACPI_DEVICE_ID Hid; ACPI_COMPATIBLE_ID_LIST *Cid; ACPI_NATIVE_UINT i; /* * Get the _HID and check for a PCI Root Bridge */ Status = AcpiUtExecute_HID (Node, &Hid); if (ACPI_FAILURE (Status)) { return (FALSE); } if (AcpiEvMatchPciRootBridge (Hid.Value)) { return (TRUE); } /* * The _HID did not match. * Get the _CID and check for a PCI Root Bridge */ Status = AcpiUtExecute_CID (Node, &Cid); if (ACPI_FAILURE (Status)) { return (FALSE); } /* Check all _CIDs in the returned list */ for (i = 0; i < Cid->Count; i++) { if (AcpiEvMatchPciRootBridge (Cid->Id[i].Value)) { ACPI_FREE (Cid); return (TRUE); } } ACPI_FREE (Cid); return (FALSE); }
static ACPI_STATUS AcpiNsGetDeviceCallback ( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) { ACPI_GET_DEVICES_INFO *Info = Context; ACPI_STATUS Status; ACPI_NAMESPACE_NODE *Node; UINT32 Flags; ACPI_PNP_DEVICE_ID *Hid; ACPI_PNP_DEVICE_ID_LIST *Cid; UINT32 i; BOOLEAN Found; int NoMatch; Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { return (Status); } Node = AcpiNsValidateHandle (ObjHandle); Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { return (Status); } if (!Node) { return (AE_BAD_PARAMETER); } /* * First, filter based on the device HID and CID. * * 01/2010: For this case where a specific HID is requested, we don't * want to run _STA until we have an actual HID match. Thus, we will * not unnecessarily execute _STA on devices for which the caller * doesn't care about. Previously, _STA was executed unconditionally * on all devices found here. * * A side-effect of this change is that now we will continue to search * for a matching HID even under device trees where the parent device * would have returned a _STA that indicates it is not present or * not functioning (thus aborting the search on that branch). */ if (Info->Hid != NULL) { Status = AcpiUtExecute_HID (Node, &Hid); if (Status == AE_NOT_FOUND) { return (AE_OK); } else if (ACPI_FAILURE (Status)) { return (AE_CTRL_DEPTH); } NoMatch = strcmp (Hid->String, Info->Hid); ACPI_FREE (Hid); if (NoMatch) { /* * HID does not match, attempt match within the * list of Compatible IDs (CIDs) */ Status = AcpiUtExecute_CID (Node, &Cid); if (Status == AE_NOT_FOUND) { return (AE_OK); } else if (ACPI_FAILURE (Status)) { return (AE_CTRL_DEPTH); } /* Walk the CID list */ Found = FALSE; for (i = 0; i < Cid->Count; i++) { if (strcmp (Cid->Ids[i].String, Info->Hid) == 0) { /* Found a matching CID */ Found = TRUE; break; } } ACPI_FREE (Cid); if (!Found) { return (AE_OK); } } } /* Run _STA to determine if device is present */ Status = AcpiUtExecute_STA (Node, &Flags); if (ACPI_FAILURE (Status)) { return (AE_CTRL_DEPTH); } if (!(Flags & ACPI_STA_DEVICE_PRESENT) && !(Flags & ACPI_STA_DEVICE_FUNCTIONING)) { /* * Don't examine the children of the device only when the * device is neither present nor functional. See ACPI spec, * description of _STA for more information. */ return (AE_CTRL_DEPTH); } /* We have a valid device, invoke the user function */ Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context, ReturnValue); return (Status); }
static ACPI_STATUS AcpiNsGetDeviceCallback ( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) { ACPI_GET_DEVICES_INFO *Info = Context; ACPI_STATUS Status; ACPI_NAMESPACE_NODE *Node; UINT32 Flags; ACPI_DEVICE_ID *Hid; ACPI_DEVICE_ID_LIST *Cid; UINT32 i; BOOLEAN Found; int NoMatch; Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { return (Status); } Node = AcpiNsValidateHandle (ObjHandle); Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { return (Status); } if (!Node) { return (AE_BAD_PARAMETER); } /* Run _STA to determine if device is present */ Status = AcpiUtExecute_STA (Node, &Flags); if (ACPI_FAILURE (Status)) { return (AE_CTRL_DEPTH); } if (!(Flags & ACPI_STA_DEVICE_PRESENT) && !(Flags & ACPI_STA_DEVICE_FUNCTIONING)) { /* * Don't examine the children of the device only when the * device is neither present nor functional. See ACPI spec, * description of _STA for more information. */ return (AE_CTRL_DEPTH); } /* Filter based on device HID & CID */ if (Info->Hid != NULL) { Status = AcpiUtExecute_HID (Node, &Hid); if (Status == AE_NOT_FOUND) { return (AE_OK); } else if (ACPI_FAILURE (Status)) { return (AE_CTRL_DEPTH); } NoMatch = ACPI_STRCMP (Hid->String, Info->Hid); ACPI_FREE (Hid); if (NoMatch) { /* * HID does not match, attempt match within the * list of Compatible IDs (CIDs) */ Status = AcpiUtExecute_CID (Node, &Cid); if (Status == AE_NOT_FOUND) { return (AE_OK); } else if (ACPI_FAILURE (Status)) { return (AE_CTRL_DEPTH); } /* Walk the CID list */ Found = FALSE; for (i = 0; i < Cid->Count; i++) { if (ACPI_STRCMP (Cid->Ids[i].String, Info->Hid) == 0) { /* Found a matching CID */ Found = TRUE; break; } } ACPI_FREE (Cid); if (!Found) { return (AE_OK); } } } /* We have a valid device, invoke the user function */ Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context, ReturnValue); return (Status); }
ACPI_STATUS AcpiGetObjectInfo ( ACPI_HANDLE Handle, ACPI_BUFFER *Buffer) { ACPI_STATUS Status; ACPI_NAMESPACE_NODE *Node; ACPI_DEVICE_INFO *Info; ACPI_DEVICE_INFO *ReturnInfo; ACPI_COMPATIBLE_ID_LIST *CidList = NULL; ACPI_SIZE Size; /* Parameter validation */ if (!Handle || !Buffer) { return (AE_BAD_PARAMETER); } Status = AcpiUtValidateBuffer (Buffer); if (ACPI_FAILURE (Status)) { return (Status); } Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_DEVICE_INFO)); if (!Info) { return (AE_NO_MEMORY); } Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { goto Cleanup; } Node = AcpiNsMapHandleToNode (Handle); if (!Node) { (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); goto Cleanup; } /* Init return structure */ Size = sizeof (ACPI_DEVICE_INFO); Info->Type = Node->Type; Info->Name = Node->Name.Integer; Info->Valid = 0; Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { goto Cleanup; } /* If not a device, we are all done */ if (Info->Type == ACPI_TYPE_DEVICE) { /* * Get extra info for ACPI Devices objects only: * Run the Device _HID, _UID, _CID, _STA, _ADR and _SxD methods. * * Note: none of these methods are required, so they may or may * not be present for this device. The Info->Valid bitfield is used * to indicate which methods were found and ran successfully. */ /* Execute the Device._HID method */ Status = AcpiUtExecute_HID (Node, &Info->HardwareId); if (ACPI_SUCCESS (Status)) { Info->Valid |= ACPI_VALID_HID; } /* Execute the Device._UID method */ Status = AcpiUtExecute_UID (Node, &Info->UniqueId); if (ACPI_SUCCESS (Status)) { Info->Valid |= ACPI_VALID_UID; } /* Execute the Device._CID method */ Status = AcpiUtExecute_CID (Node, &CidList); if (ACPI_SUCCESS (Status)) { Size += CidList->Size; Info->Valid |= ACPI_VALID_CID; } /* Execute the Device._STA method */ Status = AcpiUtExecute_STA (Node, &Info->CurrentStatus); if (ACPI_SUCCESS (Status)) { Info->Valid |= ACPI_VALID_STA; } /* Execute the Device._ADR method */ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &Info->Address); if (ACPI_SUCCESS (Status)) { Info->Valid |= ACPI_VALID_ADR; } /* Execute the Device._SxD methods */ Status = AcpiUtExecute_Sxds (Node, Info->HighestDstates); if (ACPI_SUCCESS (Status)) { Info->Valid |= ACPI_VALID_SXDS; } } /* Validate/Allocate/Clear caller buffer */ Status = AcpiUtInitializeBuffer (Buffer, Size); if (ACPI_FAILURE (Status)) { goto Cleanup; } /* Populate the return buffer */ ReturnInfo = Buffer->Pointer; ACPI_MEMCPY (ReturnInfo, Info, sizeof (ACPI_DEVICE_INFO)); if (CidList) { ACPI_MEMCPY (&ReturnInfo->CompatibilityId, CidList, CidList->Size); } Cleanup: ACPI_FREE (Info); if (CidList) { ACPI_FREE (CidList); } return (Status); }
ACPI_STATUS AcpiGetObjectInfo ( ACPI_HANDLE Handle, ACPI_DEVICE_INFO *Info) { ACPI_DEVICE_ID Hid; ACPI_DEVICE_ID Uid; ACPI_STATUS Status; UINT32 DeviceStatus = 0; ACPI_INTEGER Address = 0; ACPI_NAMESPACE_NODE *Node; /* Ensure that ACPI has been initialized */ ACPI_IS_INITIALIZATION_COMPLETE (Status); if (ACPI_FAILURE (Status)) { return (Status); } /* Parameter validation */ if (!Handle || !Info) { return (AE_BAD_PARAMETER); } AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); Node = AcpiNsConvertHandleToEntry (Handle); if (!Node) { AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); return (AE_BAD_PARAMETER); } Info->Type = Node->Type; Info->Name = Node->Name; AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); /* * If not a device, we are all done. */ if (Info->Type != ACPI_TYPE_DEVICE) { return (AE_OK); } /* * Get extra info for ACPI devices only. Run the * _HID, _UID, _STA, and _ADR methods. Note: none * of these methods are required, so they may or may * not be present. The Info->Valid bits are used * to indicate which methods ran successfully. */ Info->Valid = 0; /* Execute the _HID method and save the result */ Status = AcpiUtExecute_HID (Node, &Hid); if (ACPI_SUCCESS (Status)) { STRNCPY (Info->HardwareId, Hid.Buffer, sizeof(Info->HardwareId)); Info->Valid |= ACPI_VALID_HID; } /* Execute the _UID method and save the result */ Status = AcpiUtExecute_UID (Node, &Uid); if (ACPI_SUCCESS (Status)) { STRCPY (Info->UniqueId, Uid.Buffer); Info->Valid |= ACPI_VALID_UID; } /* * Execute the _STA method and save the result * _STA is not always present */ Status = AcpiUtExecute_STA (Node, &DeviceStatus); if (ACPI_SUCCESS (Status)) { Info->CurrentStatus = DeviceStatus; Info->Valid |= ACPI_VALID_STA; } /* * Execute the _ADR method and save result if successful * _ADR is not always present */ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &Address); if (ACPI_SUCCESS (Status)) { Info->Address = Address; Info->Valid |= ACPI_VALID_ADR; } return (AE_OK); }
static ACPI_STATUS AcpiNsGetDeviceCallback ( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) { ACPI_GET_DEVICES_INFO *Info = Context; ACPI_STATUS Status; ACPI_NAMESPACE_NODE *Node; UINT32 Flags; ACPI_DEVICE_ID Hid; ACPI_COMPATIBLE_ID_LIST *Cid; ACPI_NATIVE_UINT i; Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { return (Status); } Node = AcpiNsMapHandleToNode (ObjHandle); Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { return (Status); } if (!Node) { return (AE_BAD_PARAMETER); } /* Run _STA to determine if device is present */ Status = AcpiUtExecute_STA (Node, &Flags); if (ACPI_FAILURE (Status)) { return (AE_CTRL_DEPTH); } if (!(Flags & ACPI_STA_DEVICE_PRESENT)) { /* Don't examine children of the device if not present */ return (AE_CTRL_DEPTH); } /* Filter based on device HID & CID */ if (Info->Hid != NULL) { Status = AcpiUtExecute_HID (Node, &Hid); if (Status == AE_NOT_FOUND) { return (AE_OK); } else if (ACPI_FAILURE (Status)) { return (AE_CTRL_DEPTH); } if (ACPI_STRNCMP (Hid.Value, Info->Hid, sizeof (Hid.Value)) != 0) { /* Get the list of Compatible IDs */ Status = AcpiUtExecute_CID (Node, &Cid); if (Status == AE_NOT_FOUND) { return (AE_OK); } else if (ACPI_FAILURE (Status)) { return (AE_CTRL_DEPTH); } /* Walk the CID list */ for (i = 0; i < Cid->Count; i++) { if (ACPI_STRNCMP (Cid->Id[i].Value, Info->Hid, sizeof (ACPI_COMPATIBLE_ID)) != 0) { ACPI_FREE (Cid); return (AE_OK); } } ACPI_FREE (Cid); } } Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context, ReturnValue); return (Status); }
ACPI_STATUS AcpiEvPciConfigRegionSetup ( ACPI_HANDLE Handle, UINT32 Function, void *HandlerContext, void **RegionContext) { ACPI_STATUS Status = AE_OK; ACPI_INTEGER Temp; ACPI_PCI_ID *PciId = *RegionContext; ACPI_OPERAND_OBJECT *HandlerObj; ACPI_NAMESPACE_NODE *Node; ACPI_OPERAND_OBJECT *RegionObj = (ACPI_OPERAND_OBJECT *) Handle; ACPI_DEVICE_ID ObjectHID; ACPI_FUNCTION_TRACE ("EvPciConfigRegionSetup"); HandlerObj = RegionObj->Region.AddrHandler; if (!HandlerObj) { /* * No installed handler. This shouldn't happen because the dispatch * routine checks before we get here, but we check again just in case. */ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Attempting to init a region %p, with no handler\n", RegionObj)); return_ACPI_STATUS (AE_NOT_EXIST); } 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)); } /* * Get the _SEG and _BBN values from the device upon which the handler * is installed. * * We need to get the _SEG and _BBN objects relative to the PCI BUS device. * This is the device the handler has been registered to handle. */ /* * If the AddrHandler.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) { /* * Node is currently the parent object */ while (Node != AcpiGbl_RootNode) { Status = AcpiUtExecute_HID (Node, &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, sizeof (PCI_ROOT_HID_STRING)))) { /* Install a handler for this PCI root bridge */ Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) Node, 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))); } break; } } Node = AcpiNsGetParentNode (Node); } } else { Node = HandlerObj->AddrHandler.Node; } /* * The PCI segment number comes from the _SEG method */ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG, Node, &Temp); if (ACPI_SUCCESS (Status)) { PciId->Segment = ACPI_LOWORD (Temp); } /* * The PCI bus number comes from the _BBN method */ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN, Node, &Temp); if (ACPI_SUCCESS (Status)) { PciId->Bus = ACPI_LOWORD (Temp); } /* * Complete this device's PciId */ AcpiOsDerivePciId (Node, RegionObj->Region.Node, &PciId); *RegionContext = PciId; return_ACPI_STATUS (AE_OK); }