static ACPI_STATUS AcpiNsDumpOneDevice ( ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **ReturnValue) { ACPI_BUFFER Buffer; ACPI_DEVICE_INFO *Info; ACPI_STATUS Status; UINT32 i; ACPI_FUNCTION_NAME (NsDumpOneDevice); Status = AcpiNsDumpOneObject (ObjHandle, Level, Context, ReturnValue); Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; Status = AcpiGetObjectInfo (ObjHandle, &Buffer); if (ACPI_SUCCESS (Status)) { Info = Buffer.Pointer; for (i = 0; i < Level; i++) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ")); } ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", Info->HardwareId.Value, ACPI_FORMAT_UINT64 (Info->Address), Info->CurrentStatus)); ACPI_FREE (Info); } return (Status); }
static PyObject *bits_acpi_get_object_info(PyObject *self, PyObject *args) { char *pathname; ACPI_HANDLE handle = 0; ACPI_DEVICE_INFO *info = NULL; PyObject *ret; ACPI_DEVICE_INFO *addr; if (!PyArg_ParseTuple(args, "s", &pathname)) return NULL; if (acpica_init() != GRUB_ERR_NONE) return PyErr_Format(PyExc_RuntimeError, "ACPICA module failed to initialize."); if (ACPI_FAILURE(AcpiGetHandle(NULL, pathname, &handle)) || (handle == 0)) return PyErr_Format(PyExc_RuntimeError, "Couldn't get object handle for \"%s\"", pathname); if (ACPI_FAILURE(AcpiGetObjectInfo(handle, &info))) return PyErr_Format(PyExc_RuntimeError, "Couldn't get object info for \"%s\"", pathname); ret = Py_BuildValue("(s#k)", info, info->InfoSize, info); ACPI_FREE(info); return ret; }
static ACPI_STATUS AcpiDbBusWalk ( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) { ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; ACPI_STATUS Status; ACPI_BUFFER Buffer; ACPI_NAMESPACE_NODE *TempNode; ACPI_DEVICE_INFO *Info; UINT32 i; if ((Node->Type != ACPI_TYPE_DEVICE) && (Node->Type != ACPI_TYPE_PROCESSOR)) { return (AE_OK); } /* Exit if there is no _PRT under this device */ Status = AcpiGetHandle (Node, METHOD_NAME__PRT, ACPI_CAST_PTR (ACPI_HANDLE, &TempNode)); if (ACPI_FAILURE (Status)) { return (AE_OK); } /* Get the full path to this device object */ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, FALSE); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle); return (AE_OK); } Status = AcpiGetObjectInfo (ObjHandle, &Info); if (ACPI_FAILURE (Status)) { return (AE_OK); } /* Display the full path */ AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type); ACPI_FREE (Buffer.Pointer); if (Info->Flags & ACPI_PCI_ROOT_BRIDGE) { AcpiOsPrintf (" - Is PCI Root Bridge"); } AcpiOsPrintf ("\n"); /* _PRT info */ AcpiOsPrintf ("_PRT: %p\n", TempNode); /* Dump _ADR, _HID, _UID, _CID */ if (Info->Valid & ACPI_VALID_ADR) { AcpiOsPrintf ("_ADR: %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Info->Address)); } else { AcpiOsPrintf ("_ADR: <Not Present>\n"); } if (Info->Valid & ACPI_VALID_HID) { AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String); } else { AcpiOsPrintf ("_HID: <Not Present>\n"); } if (Info->Valid & ACPI_VALID_UID) { AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String); } else { AcpiOsPrintf ("_UID: <Not Present>\n"); } if (Info->Valid & ACPI_VALID_CID) { for (i = 0; i < Info->CompatibleIdList.Count; i++) { AcpiOsPrintf ("_CID: %s\n", Info->CompatibleIdList.Ids[i].String); } } else { AcpiOsPrintf ("_CID: <Not Present>\n"); } ACPI_FREE (Info); return (AE_OK); }
static ACPI_STATUS AcpiDbWalkForExecute ( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) { ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; ACPI_DB_EXECUTE_WALK *Info = (ACPI_DB_EXECUTE_WALK *) Context; char *Pathname; const ACPI_PREDEFINED_INFO *Predefined; ACPI_DEVICE_INFO *ObjInfo; ACPI_OBJECT_LIST ParamObjects; ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; ACPI_OBJECT *ThisParam; ACPI_BUFFER ReturnObj; ACPI_STATUS Status; UINT16 ArgTypeList; UINT8 ArgCount; UINT8 ArgType; UINT32 i; /* The name must be a predefined ACPI name */ Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii); if (!Predefined) { return (AE_OK); } if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) { return (AE_OK); } Pathname = AcpiNsGetExternalPathname (Node); if (!Pathname) { return (AE_OK); } /* Get the object info for number of method parameters */ Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo); if (ACPI_FAILURE (Status)) { return (Status); } ParamObjects.Count = 0; ParamObjects.Pointer = NULL; if (ObjInfo->Type == ACPI_TYPE_METHOD) { /* Setup default parameters (with proper types) */ ArgTypeList = Predefined->Info.ArgumentList; ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList); /* * Setup the ACPI-required number of arguments, regardless of what * the actual method defines. If there is a difference, then the * method is wrong and a warning will be issued during execution. */ ThisParam = Params; for (i = 0; i < ArgCount; i++) { ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList); ThisParam->Type = ArgType; switch (ArgType) { case ACPI_TYPE_INTEGER: ThisParam->Integer.Value = 1; break; case ACPI_TYPE_STRING: ThisParam->String.Pointer = __UNCONST( "This is the default argument string"); ThisParam->String.Length = ACPI_STRLEN (ThisParam->String.Pointer); break; case ACPI_TYPE_BUFFER: ThisParam->Buffer.Pointer = (UINT8 *) Params; /* just a garbage buffer */ ThisParam->Buffer.Length = 48; break; case ACPI_TYPE_PACKAGE: ThisParam->Package.Elements = NULL; ThisParam->Package.Count = 0; break; default: AcpiOsPrintf ("%s: Unsupported argument type: %u\n", Pathname, ArgType); break; } ThisParam++; } ParamObjects.Count = ArgCount; ParamObjects.Pointer = Params; } ACPI_FREE (ObjInfo); ReturnObj.Pointer = NULL; ReturnObj.Length = ACPI_ALLOCATE_BUFFER; /* Do the actual method execution */ AcpiGbl_MethodExecuting = TRUE; Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj); AcpiOsPrintf ("%-32s returned %s\n", Pathname, AcpiFormatException (Status)); AcpiGbl_MethodExecuting = FALSE; ACPI_FREE (Pathname); /* Ignore status from method execution */ Status = AE_OK; /* Update count, check if we have executed enough methods */ Info->Count++; if (Info->Count >= Info->MaxCount) { Status = AE_CTRL_TERMINATE; } return (Status); }
void AcpiDbDisplayObjectType ( char *Name) { ACPI_NAMESPACE_NODE *Node; ACPI_DEVICE_INFO *Info; ACPI_STATUS Status; UINT32 i; Node = AcpiDbConvertToNode (Name); if (!Node) { return; } Status = AcpiGetObjectInfo (ACPI_CAST_PTR (ACPI_HANDLE, Node), &Info); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Could not get object info, %s\n", AcpiFormatException (Status)); return; } if (Info->Valid & ACPI_VALID_ADR) { AcpiOsPrintf ("ADR: %8.8X%8.8X, STA: %8.8X, Flags: %X\n", ACPI_FORMAT_UINT64 (Info->Address), Info->CurrentStatus, Info->Flags); } if (Info->Valid & ACPI_VALID_SXDS) { AcpiOsPrintf ("S1D-%2.2X S2D-%2.2X S3D-%2.2X S4D-%2.2X\n", Info->HighestDstates[0], Info->HighestDstates[1], Info->HighestDstates[2], Info->HighestDstates[3]); } if (Info->Valid & ACPI_VALID_SXWS) { AcpiOsPrintf ("S0W-%2.2X S1W-%2.2X S2W-%2.2X S3W-%2.2X S4W-%2.2X\n", Info->LowestDstates[0], Info->LowestDstates[1], Info->LowestDstates[2], Info->LowestDstates[3], Info->LowestDstates[4]); } if (Info->Valid & ACPI_VALID_HID) { AcpiOsPrintf ("HID: %s\n", Info->HardwareId.String); } if (Info->Valid & ACPI_VALID_UID) { AcpiOsPrintf ("UID: %s\n", Info->UniqueId.String); } if (Info->Valid & ACPI_VALID_SUB) { AcpiOsPrintf ("SUB: %s\n", Info->SubsystemId.String); } if (Info->Valid & ACPI_VALID_CID) { for (i = 0; i < Info->CompatibleIdList.Count; i++) { AcpiOsPrintf ("CID %u: %s\n", i, Info->CompatibleIdList.Ids[i].String); } } ACPI_FREE (Info); }
static ACPI_STATUS AcpiDbWalkForExecute ( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue) { ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; ACPI_EXECUTE_WALK *Info = (ACPI_EXECUTE_WALK *) Context; ACPI_BUFFER ReturnObj; ACPI_STATUS Status; char *Pathname; UINT32 i; ACPI_DEVICE_INFO *ObjInfo; ACPI_OBJECT_LIST ParamObjects; ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; const ACPI_PREDEFINED_INFO *Predefined; Predefined = AcpiNsCheckForPredefinedName (Node); if (!Predefined) { return (AE_OK); } if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) { return (AE_OK); } Pathname = AcpiNsGetExternalPathname (Node); if (!Pathname) { return (AE_OK); } /* Get the object info for number of method parameters */ Status = AcpiGetObjectInfo (ObjHandle, &ObjInfo); if (ACPI_FAILURE (Status)) { return (Status); } ParamObjects.Pointer = NULL; ParamObjects.Count = 0; if (ObjInfo->Type == ACPI_TYPE_METHOD) { /* Setup default parameters */ for (i = 0; i < ObjInfo->ParamCount; i++) { Params[i].Type = ACPI_TYPE_INTEGER; Params[i].Integer.Value = 1; } ParamObjects.Pointer = Params; ParamObjects.Count = ObjInfo->ParamCount; } ACPI_FREE (ObjInfo); ReturnObj.Pointer = NULL; ReturnObj.Length = ACPI_ALLOCATE_BUFFER; /* Do the actual method execution */ AcpiGbl_MethodExecuting = TRUE; Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj); AcpiOsPrintf ("%-32s returned %s\n", Pathname, AcpiFormatException (Status)); AcpiGbl_MethodExecuting = FALSE; ACPI_FREE (Pathname); /* Ignore status from method execution */ Status = AE_OK; /* Update count, check if we have executed enough methods */ Info->Count++; if (Info->Count >= Info->MaxCount) { Status = AE_CTRL_TERMINATE; } return (Status); }
static ACPI_STATUS AcpiDbExecuteMethod ( ACPI_DB_METHOD_INFO *Info, ACPI_BUFFER *ReturnObj) { ACPI_STATUS Status; ACPI_OBJECT_LIST ParamObjects; ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; ACPI_HANDLE Handle; UINT32 i; ACPI_DEVICE_INFO *ObjInfo; if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel) { AcpiOsPrintf ("Warning: debug output is not enabled!\n"); } /* Get the NS node, determines existence also */ Status = AcpiGetHandle (NULL, Info->Pathname, &Handle); if (ACPI_FAILURE (Status)) { return (Status); } /* Get the object info for number of method parameters */ Status = AcpiGetObjectInfo (Handle, &ObjInfo); if (ACPI_FAILURE (Status)) { return (Status); } ParamObjects.Pointer = NULL; ParamObjects.Count = 0; if (ObjInfo->Type == ACPI_TYPE_METHOD) { /* Are there arguments to the method? */ if (Info->Args && Info->Args[0]) { for (i = 0; Info->Args[i] && i < ACPI_METHOD_NUM_ARGS; i++) { Params[i].Type = ACPI_TYPE_INTEGER; Params[i].Integer.Value = ACPI_STRTOUL (Info->Args[i], NULL, 16); } ParamObjects.Pointer = Params; ParamObjects.Count = i; } else { /* Setup default parameters */ for (i = 0; i < ObjInfo->ParamCount; i++) { switch (i) { case 0: Params[0].Type = ACPI_TYPE_INTEGER; Params[0].Integer.Value = 0x01020304; break; case 1: Params[1].Type = ACPI_TYPE_STRING; Params[1].String.Length = 12; Params[1].String.Pointer = "AML Debugger"; break; default: Params[i].Type = ACPI_TYPE_INTEGER; Params[i].Integer.Value = i * (UINT64) 0x1000; break; } } ParamObjects.Pointer = Params; ParamObjects.Count = ObjInfo->ParamCount; } } ACPI_FREE (ObjInfo); /* Prepare for a return object of arbitrary size */ ReturnObj->Pointer = AcpiGbl_DbBuffer; ReturnObj->Length = ACPI_DEBUG_BUFFER_SIZE; /* Do the actual method execution */ AcpiGbl_MethodExecuting = TRUE; Status = AcpiEvaluateObject (NULL, Info->Pathname, &ParamObjects, ReturnObj); AcpiGbl_CmSingleStep = FALSE; AcpiGbl_MethodExecuting = FALSE; return (Status); }
static ACPI_STATUS AcpiDbExecuteMethod ( ACPI_DB_METHOD_INFO *Info, ACPI_BUFFER *ReturnObj) { ACPI_STATUS Status; ACPI_OBJECT_LIST ParamObjects; ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; ACPI_DEVICE_INFO *ObjInfo; UINT32 i; ACPI_FUNCTION_TRACE (DbExecuteMethod); if (AcpiGbl_DbOutputToFile && !AcpiDbgLevel) { AcpiOsPrintf ("Warning: debug output is not enabled!\n"); } /* Get the object info for number of method parameters */ Status = AcpiGetObjectInfo (Info->Method, &ObjInfo); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } ParamObjects.Pointer = NULL; ParamObjects.Count = 0; if (ObjInfo->Type == ACPI_TYPE_METHOD) { /* Are there arguments to the method? */ i = 0; if (Info->Args && Info->Args[0]) { /* Get arguments passed on the command line */ for (; Info->Args[i] && (i < ACPI_METHOD_NUM_ARGS) && (i < ObjInfo->ParamCount); i++) { /* Convert input string (token) to an actual ACPI_OBJECT */ Status = AcpiDbConvertToObject (Info->Types[i], Info->Args[i], &Params[i]); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "While parsing method arguments")); goto Cleanup; } } } /* Create additional "default" parameters as needed */ if (i < ObjInfo->ParamCount) { AcpiOsPrintf ("Adding %u arguments containing default values\n", ObjInfo->ParamCount - i); for (; i < ObjInfo->ParamCount; i++) { switch (i) { case 0: Params[0].Type = ACPI_TYPE_INTEGER; Params[0].Integer.Value = 0x01020304; break; case 1: Params[1].Type = ACPI_TYPE_STRING; Params[1].String.Length = 12; Params[1].String.Pointer = "AML Debugger"; break; default: Params[i].Type = ACPI_TYPE_INTEGER; Params[i].Integer.Value = i * (UINT64) 0x1000; break; } } } ParamObjects.Count = ObjInfo->ParamCount; ParamObjects.Pointer = Params; } /* Prepare for a return object of arbitrary size */ ReturnObj->Pointer = AcpiGbl_DbBuffer; ReturnObj->Length = ACPI_DEBUG_BUFFER_SIZE; /* Do the actual method execution */ AcpiGbl_MethodExecuting = TRUE; Status = AcpiEvaluateObject (NULL, Info->Pathname, &ParamObjects, ReturnObj); AcpiGbl_CmSingleStep = FALSE; AcpiGbl_MethodExecuting = FALSE; if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "while executing %s from debugger", Info->Pathname)); if (Status == AE_BUFFER_OVERFLOW) { ACPI_ERROR ((AE_INFO, "Possible overflow of internal debugger buffer (size 0x%X needed 0x%X)", ACPI_DEBUG_BUFFER_SIZE, (UINT32) ReturnObj->Length)); } } Cleanup: AcpiDbDeleteObjects (ObjInfo->ParamCount, Params); ACPI_FREE (ObjInfo); return_ACPI_STATUS (Status); }
ACPI_STATUS DisplayOneDevice (ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **RetVal) { ACPI_STATUS Status; ACPI_DEVICE_INFO *Info; ACPI_BUFFER Path; ACPI_BUFFER Result; ACPI_OBJECT Obj; char Buffer[256]; uint8 prt_buf[1024]; ACPI_BUFFER Prt = { .Length = sizeof (prt_buf), .Pointer = prt_buf }; ACPI_PCI_ROUTING_TABLE *prtd; uint32 addr=0; uint32 fun = 0; bool pcibus=FALSE; u8 busnum; Path.Length = sizeof (Buffer); Path.Pointer = Buffer; Status = AcpiGetName (ObjHandle, ACPI_FULL_PATHNAME, &Path); if (ACPI_SUCCESS (Status)) { DLOG_COM1 ("%s: \n", Path.Pointer); } Status = AcpiGetObjectInfo (ObjHandle, &Info); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" "); if (Info->Flags & ACPI_PCI_ROOT_BRIDGE) { DLOG_COM1 (" PCI_ROOT"); busnum = 0; pcibus = TRUE; } if (Info->Valid & ACPI_VALID_STA) DLOG_COM1 (" STA %.8X", Info->CurrentStatus); if (Info->Valid & ACPI_VALID_ADR) { DLOG_COM1 (" ADR %.8X", Info->Address); addr = Info->Address >> 16; fun = Info->Address & 0x7; } if (Info->Valid & ACPI_VALID_HID) DLOG_COM1 (" HID %s", Info->HardwareId.String); if (Info->Valid & ACPI_VALID_UID) DLOG_COM1 (" UID %s", Info->UniqueId.String); if (Info->Valid & ACPI_VALID_CID) DLOG_COM1 (" CID"); ACPI_FREE (Info); } Result.Length = sizeof (Obj); Result.Pointer = &Obj; Status = AcpiEvaluateObjectTyped (ObjHandle, "_DDN", NULL, &Result, ACPI_TYPE_STRING); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" DDN=%s", Obj.String.Pointer); } Result.Length = sizeof (Obj); Result.Pointer = &Obj; Status = AcpiEvaluateObjectTyped (ObjHandle, "_STR", NULL, &Result, ACPI_TYPE_STRING); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" STR=%s", Obj.String.Pointer); } Result.Length = sizeof (Obj); Result.Pointer = &Obj; Status = AcpiEvaluateObjectTyped (ObjHandle, "_MLS", NULL, &Result, ACPI_TYPE_STRING); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" MLS=%s", Obj.String.Pointer); } Status = AcpiEvaluateObjectTyped (ObjHandle, "_BBN", NULL, &Result, ACPI_TYPE_INTEGER); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" BBN=%d", Obj.Integer.Value); } else if (Status != AE_NOT_FOUND) DLOG_COM1 (" bbnERR=%d", Status); Status = AcpiEvaluateObjectTyped (ObjHandle, "_PXM", NULL, &Result, ACPI_TYPE_INTEGER); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" PXM=%d", Obj.Integer.Value); } else if (Status != AE_NOT_FOUND) DLOG_COM1 (" pxmERR=%d", Status); DLOG_COM1 ("\n"); for (;;) { Status = AcpiGetIrqRoutingTable (ObjHandle, &Prt); if (ACPI_FAILURE (Status)) { if (Status == AE_BUFFER_OVERFLOW) { DLOG_COM1 ("AcpiGetIrqRoutingTable failed: BUFFER OVERFLOW\n"); } break; } else break; } if (ACPI_SUCCESS (Status)) { int i; /* Check if ObjHandle refers to a non-root PCI bus */ if (READ (0, addr, fun, 0, dword) != 0xFFFFFFFF) { u8 hdrtype = READ (0, addr, fun, 0x0E, byte); if ((hdrtype & 0x7F) == 1) { /* PCI-to-PCI bridge headerType == 1 */ busnum = READ (0, addr, fun, 0x19, byte); //busnum = READ (0, addr, fun, 0x1A, byte); DLOG_COM1 (" bus=0x%.02X\n", busnum); pcibus = TRUE; } } for (i=0;i<sizeof(prt_buf);) { pci_irq_t irq; prtd = (ACPI_PCI_ROUTING_TABLE *)(&prt_buf[i]); if (prtd->Length == 0) break; if (pcibus) { irq.pin = prtd->Pin + 1; /* ACPI numbers pins from 0 */ irq.gsi = 0; } if (prtd->Source[0]) { DLOG_COM1 (" PRT entry: len=%d pin=%d addr=%p srcidx=0x%x src=%s\n", prtd->Length, prtd->Pin, (uint32)prtd->Address, prtd->SourceIndex, &prtd->Source[0]); GetLnkInfo (&prtd->Source[0], &irq); } else { DLOG_COM1 (" PRT entry: len=%d pin=%d addr=%p fixed IRQ=0x%x\n", prtd->Length, prtd->Pin, (uint32)prtd->Address, prtd->SourceIndex); irq.gsi = prtd->SourceIndex; irq.polarity = POLARITY_DEFAULT; irq.trigger = TRIGGER_DEFAULT; } if (pcibus && irq.gsi != 0) pci_irq_register (&irq); i+=prtd->Length; } } #if 0 ACPI_STATUS DisplayResource (ACPI_RESOURCE *Resource, void *Context); DLOG_COM1 (" _PRS:\n"); AcpiWalkResources (ObjHandle, "_PRS", DisplayResource, NULL); DLOG_COM1 (" _CRS:\n"); AcpiWalkResources (ObjHandle, "_CRS", DisplayResource, NULL); #endif return AE_OK; }
/* * Install/uninstall ACPI system event handler for child objects of hdl. * Return DDI_SUCCESS on success, and DDI_FAILURE on failure. */ static int acpinex_event_walk(boolean_t init, acpinex_softstate_t *sp, ACPI_HANDLE hdl) { int rc; int retval = DDI_SUCCESS; dev_info_t *dip; ACPI_HANDLE child = NULL; ACPI_OBJECT_TYPE type; ACPI_DEVICE_INFO *infop; acpidev_data_handle_t dhdl; /* Walk all child objects. */ ASSERT(hdl != NULL); while (ACPI_SUCCESS(AcpiGetNextObject(ACPI_TYPE_ANY, hdl, child, &child))) { /* Skip unwanted object types. */ if (ACPI_FAILURE(AcpiGetType(child, &type)) || type > ACPI_TYPE_NS_NODE_MAX || BT_TEST(acpinex_object_type_mask, type) == 0) { continue; } /* Get data associated with the object. Skip it if fails. */ dhdl = acpidev_data_get_handle(child); if (dhdl == NULL) { ACPINEX_DEBUG(CE_NOTE, "!acpinex: failed to get data " "associated with %p, skip.", child); continue; } /* Query ACPI object info for the object. */ if (ACPI_FAILURE(AcpiGetObjectInfo(child, &infop))) { cmn_err(CE_WARN, "!acpidnex: failed to get object info for %p.", child); continue; } if (init) { rc = acpinex_event_install_handler(child, sp, infop, dhdl); if (rc != DDI_SUCCESS) { ACPINEX_DEBUG(CE_WARN, "!acpinex: failed to " "install handler for child %p of %s.", child, sp->ans_path); retval = DDI_FAILURE; /* * Try to handle descendants if both of the * following two conditions are true: * 1) Device corresponding to the current object is * enabled. If the device is absent/disabled, * no notification should be generated from * descendant objects of it. * 2) No Solaris device node has been created for the * current object yet. If the device node has been * created for the current object, notification * events from child objects should be handled by * the corresponding driver. */ } else if (acpidev_check_device_enabled( acpidev_data_get_status(dhdl)) && ACPI_FAILURE(acpica_get_devinfo(child, &dip))) { rc = acpinex_event_walk(B_TRUE, sp, child); if (rc != DDI_SUCCESS) { ACPINEX_DEBUG(CE_WARN, "!acpinex: failed to install " "handler for descendants of %s.", sp->ans_path); retval = DDI_FAILURE; } } } else { rc = DDI_SUCCESS; /* Uninstall handler for descendants if needed. */ if (ACPI_FAILURE(acpica_get_devinfo(child, &dip))) { rc = acpinex_event_walk(B_FALSE, sp, child); } if (rc == DDI_SUCCESS) { rc = acpinex_event_uninstall_handler(child, infop, dhdl); } /* Undo will be done by caller in case of failure. */ if (rc != DDI_SUCCESS) { ACPINEX_DEBUG(CE_WARN, "!acpinex: failed to " "uninstall handler for descendants of %s.", sp->ans_path); AcpiOsFree(infop); retval = DDI_FAILURE; break; } } /* Release cached resources. */ AcpiOsFree(infop); } return (retval); }