uint32 get_object_type(const char* path) { ACPI_HANDLE handle; ACPI_OBJECT_TYPE type; if (AcpiGetHandle(NULL, (ACPI_STRING)path, &handle) != AE_OK) return B_ENTRY_NOT_FOUND; AcpiGetType(handle, &type); return type; }
/* * fujitsu_hk_cap: * * Returns true if and only if (a) the object handle.path exists and * (b) this object is a method or has the given type. */ static bool fujitsu_hk_cap(ACPI_HANDLE handle, const char *path, ACPI_OBJECT_TYPE type) { ACPI_HANDLE hdl; ACPI_OBJECT_TYPE typ; KASSERT(handle != NULL); if (ACPI_FAILURE(AcpiGetHandle(handle, path, &hdl))) return false; if (ACPI_FAILURE(AcpiGetType(hdl, &typ))) return false; if (typ != ACPI_TYPE_METHOD && typ != type) return false; return true; }
static void AfInstallGpeBlock ( void) { ACPI_STATUS Status; ACPI_HANDLE Handle; ACPI_GENERIC_ADDRESS BlockAddress; ACPI_HANDLE GpeDevice; ACPI_OBJECT_TYPE Type; /* _GPE should always exist */ Status = AcpiGetHandle (NULL, "\\_GPE", &Handle); ACPI_CHECK_OK (AcpiGetHandle, Status); if (ACPI_FAILURE (Status)) { return; } memset (&BlockAddress, 0, sizeof (ACPI_GENERIC_ADDRESS)); BlockAddress.SpaceId = ACPI_ADR_SPACE_SYSTEM_MEMORY; BlockAddress.Address = 0x76540000; /* Attempt to install a GPE block on GPE2 (if present) */ Status = AcpiGetHandle (NULL, "\\GPE2", &Handle); if (ACPI_SUCCESS (Status)) { Status = AcpiGetType (Handle, &Type); if (ACPI_FAILURE (Status) || (Type != ACPI_TYPE_DEVICE)) { return; } Status = AcpiInstallGpeBlock (Handle, &BlockAddress, 7, 8); ACPI_CHECK_OK (AcpiInstallGpeBlock, Status); Status = AcpiInstallGpeHandler (Handle, 8, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); ACPI_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (Handle, 8); ACPI_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiGetGpeDevice (0x30, &GpeDevice); ACPI_CHECK_OK (AcpiGetGpeDevice, Status); Status = AcpiGetGpeDevice (0x42, &GpeDevice); ACPI_CHECK_OK (AcpiGetGpeDevice, Status); Status = AcpiGetGpeDevice (AcpiCurrentGpeCount-1, &GpeDevice); ACPI_CHECK_OK (AcpiGetGpeDevice, Status); Status = AcpiGetGpeDevice (AcpiCurrentGpeCount, &GpeDevice); ACPI_CHECK_STATUS (AcpiGetGpeDevice, Status, AE_NOT_EXIST); Status = AcpiRemoveGpeHandler (Handle, 8, AeGpeHandler); ACPI_CHECK_OK (AcpiRemoveGpeHandler, Status); } /* Attempt to install a GPE block on GPE3 (if present) */ Status = AcpiGetHandle (NULL, "\\GPE3", &Handle); if (ACPI_SUCCESS (Status)) { Status = AcpiGetType (Handle, &Type); if (ACPI_FAILURE (Status) || (Type != ACPI_TYPE_DEVICE)) { return; } Status = AcpiInstallGpeBlock (Handle, &BlockAddress, 8, 11); ACPI_CHECK_OK (AcpiInstallGpeBlock, Status); } }
static ACPI_STATUS AcpiHwGetPciDeviceInfo ( ACPI_PCI_ID *PciId, ACPI_HANDLE PciDevice, UINT16 *BusNumber, BOOLEAN *IsBridge) { ACPI_STATUS Status; ACPI_OBJECT_TYPE ObjectType; UINT64 ReturnValue; UINT64 PciValue; /* We only care about objects of type Device */ Status = AcpiGetType (PciDevice, &ObjectType); if (ACPI_FAILURE (Status)) { return (Status); } if (ObjectType != ACPI_TYPE_DEVICE) { return (AE_OK); } /* We need an _ADR. Ignore device if not present */ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, PciDevice, &ReturnValue); if (ACPI_FAILURE (Status)) { return (AE_OK); } /* * From _ADR, get the PCI Device and Function and * update the PCI ID. */ PciId->Device = ACPI_HIWORD (ACPI_LODWORD (ReturnValue)); PciId->Function = ACPI_LOWORD (ACPI_LODWORD (ReturnValue)); /* * If the previous device was a bridge, use the previous * device bus number */ if (*IsBridge) { PciId->Bus = *BusNumber; } /* * Get the bus numbers from PCI Config space: * * First, get the PCI HeaderType */ *IsBridge = FALSE; Status = AcpiOsReadPciConfiguration (PciId, PCI_CFG_HEADER_TYPE_REG, &PciValue, 8); if (ACPI_FAILURE (Status)) { return (Status); } /* We only care about bridges (1=PciBridge, 2=CardBusBridge) */ PciValue &= PCI_HEADER_TYPE_MASK; if ((PciValue != PCI_TYPE_BRIDGE) && (PciValue != PCI_TYPE_CARDBUS_BRIDGE)) { return (AE_OK); } /* Bridge: Get the Primary BusNumber */ Status = AcpiOsReadPciConfiguration (PciId, PCI_CFG_PRIMARY_BUS_NUMBER_REG, &PciValue, 8); if (ACPI_FAILURE (Status)) { return (Status); } *IsBridge = TRUE; PciId->Bus = (UINT16) PciValue; /* Bridge: Get the Secondary BusNumber */ Status = AcpiOsReadPciConfiguration (PciId, PCI_CFG_SECONDARY_BUS_NUMBER_REG, &PciValue, 8); if (ACPI_FAILURE (Status)) { return (Status); } *BusNumber = (UINT16) PciValue; 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); }