static ACPI_STATUS AeInstallPciHandler ( ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **ReturnValue) { ACPI_STATUS Status; /* Install memory and I/O handlers for the PCI device */ Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_IO, AeRegionHandler, AeRegionInit, &AeMyContext); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "Could not install an OpRegion handler for PCI device (%p)", ObjHandle)); } Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_MEMORY, AeRegionHandler, AeRegionInit, &AeMyContext); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "Could not install an OpRegion handler for PCI device (%p)", ObjHandle)); } return (AE_CTRL_TERMINATE); }
static ACPI_STATUS InstallHandlers (void) { ACPI_STATUS Status; /* Install global notify handler */ Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, NotifyHandler, NULL); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "While installing Notify handler")); return (Status); } Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_SYSTEM_MEMORY, RegionHandler, RegionInit, NULL); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "While installing an OpRegion handler")); return (Status); } return (AE_OK); }
/* * Install acpica-provided (default) address-space handlers * that may be needed before AcpiEnableSubsystem() runs. * See the comment in AcpiInstallAddressSpaceHandler(). * Default handlers for remaining address spaces are * installed later, in AcpiEnableSubsystem. */ static int acpica_install_handlers() { ACPI_STATUS rv = AE_OK; ACPI_STATUS res; /* * Install ACPI CA default handlers */ if ((res = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_SYSTEM_MEMORY, ACPI_DEFAULT_HANDLER, NULL, NULL)) != AE_OK && res != AE_SAME_HANDLER) { cmn_err(CE_WARN, "!acpica: no default handler for" " system memory"); rv = AE_ERROR; } if ((res = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_SYSTEM_IO, ACPI_DEFAULT_HANDLER, NULL, NULL)) != AE_OK && res != AE_SAME_HANDLER) { cmn_err(CE_WARN, "!acpica: no default handler for" " system I/O"); rv = AE_ERROR; } if ((res = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL)) != AE_OK && res != AE_SAME_HANDLER) { cmn_err(CE_WARN, "!acpica: no default handler for" " PCI Config"); rv = AE_ERROR; } if ((res = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_DATA_TABLE, ACPI_DEFAULT_HANDLER, NULL, NULL)) != AE_OK && res != AE_SAME_HANDLER) { cmn_err(CE_WARN, "!acpica: no default handler for" " Data Table"); rv = AE_ERROR; } return (rv); }
ACPI_STATUS AeInstallLateHandlers ( void) { ACPI_STATUS Status; UINT32 i; #if (!ACPI_REDUCED_HARDWARE) if (!AcpiGbl_ReducedHardware) { /* Install a user SCI handler */ Status = AeInstallSciHandler (); AE_CHECK_OK (AeInstallSciHandler, Status); /* Install some fixed event handlers */ Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL, AeEventHandler, NULL); AE_CHECK_OK (AcpiInstallFixedEventHandler, Status); Status = AcpiInstallFixedEventHandler (ACPI_EVENT_RTC, AeEventHandler, NULL); AE_CHECK_OK (AcpiInstallFixedEventHandler, Status); } #endif /* !ACPI_REDUCED_HARDWARE */ AeMyContext.Connection = NULL; AeMyContext.AccessLength = 0xA5; /* * We will install a handler for each EC device, directly under the EC * device definition. This is unlike the other handlers which we install * at the root node. Also install memory and I/O handlers at any PCI * devices. */ AeInstallDeviceHandlers (); /* * Install handlers for some of the "device driver" address spaces * such as SMBus, etc. */ for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++) { /* Install handler at the root object */ Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT, SpaceIdList[i], AeRegionHandler, AeRegionInit, &AeMyContext); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "Could not install an OpRegion handler for %s space(%u)", AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i])); return (Status); } } return (AE_OK); }
status_t install_address_space_handler(acpi_handle handle, uint32 spaceId, acpi_adr_space_handler handler, acpi_adr_space_setup setup, void *data) { return AcpiInstallAddressSpaceHandler(handle, spaceId, (ACPI_ADR_SPACE_HANDLER)handler, (ACPI_ADR_SPACE_SETUP)setup, data) == AE_OK ? B_OK : B_ERROR; }
static void smbus_acpi_install_address_space_handler(struct smbus_acpi_softc *sc) { ACPI_HANDLE handle; ACPI_STATUS s; handle = acpi_get_handle(sc->parent); sc->space_handler_data.dev = sc->parent; s = AcpiInstallAddressSpaceHandler(handle, ACPI_ADR_SPACE_GSBUS, &smbus_acpi_space_handler, NULL, &sc->space_handler_data); if (ACPI_FAILURE(s)) { device_printf(sc->dev, "Failed to install GSBUS Address Space Handler in ACPI\n"); } }
static ACPI_STATUS AeInstallEcHandler ( ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **ReturnValue) { ACPI_STATUS Status; /* Install the handler for this EC device */ Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_EC, AeRegionHandler, AeRegionInit, &AeMyContext); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "Could not install an OpRegion handler for EC device (%p)", ObjHandle)); } return (Status); }
static int acpi_ec_attach(device_t dev) { struct acpi_ec_softc *sc; struct acpi_ec_params *params; ACPI_STATUS Status; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); /* Fetch/initialize softc (assumes softc is pre-zeroed). */ sc = device_get_softc(dev); params = acpi_get_private(dev); sc->ec_dev = dev; sc->ec_handle = acpi_get_handle(dev); ACPI_SERIAL_INIT(ec); /* Retrieve previously probed values via device ivars. */ sc->ec_glk = params->glk; sc->ec_gpebit = params->gpe_bit; sc->ec_gpehandle = params->gpe_handle; sc->ec_uid = params->uid; sc->ec_suspending = FALSE; acpi_set_private(dev, NULL); kfree(params, M_TEMP); /* Attach bus resources for data and command/status ports. */ sc->ec_data_rid = 0; sc->ec_data_res = bus_alloc_resource_any(sc->ec_dev, SYS_RES_IOPORT, &sc->ec_data_rid, RF_ACTIVE); if (sc->ec_data_res == NULL) { device_printf(dev, "can't allocate data port\n"); goto error; } sc->ec_data_tag = rman_get_bustag(sc->ec_data_res); sc->ec_data_handle = rman_get_bushandle(sc->ec_data_res); sc->ec_csr_rid = 1; sc->ec_csr_res = bus_alloc_resource_any(sc->ec_dev, SYS_RES_IOPORT, &sc->ec_csr_rid, RF_ACTIVE); if (sc->ec_csr_res == NULL) { device_printf(dev, "can't allocate command/status port\n"); goto error; } sc->ec_csr_tag = rman_get_bustag(sc->ec_csr_res); sc->ec_csr_handle = rman_get_bushandle(sc->ec_csr_res); /* * Install a handler for this EC's GPE bit. We want edge-triggered * behavior. */ ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "attaching GPE handler\n")); Status = AcpiInstallGpeHandler(sc->ec_gpehandle, sc->ec_gpebit, ACPI_GPE_EDGE_TRIGGERED, &EcGpeHandler, sc); if (ACPI_FAILURE(Status)) { device_printf(dev, "can't install GPE handler for %s - %s\n", acpi_name(sc->ec_handle), AcpiFormatException(Status)); goto error; } /* * Install address space handler */ ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "attaching address space handler\n")); Status = AcpiInstallAddressSpaceHandler(sc->ec_handle, ACPI_ADR_SPACE_EC, &EcSpaceHandler, &EcSpaceSetup, sc); if (ACPI_FAILURE(Status)) { device_printf(dev, "can't install address space handler for %s - %s\n", acpi_name(sc->ec_handle), AcpiFormatException(Status)); goto error; } /* Enable runtime GPEs for the handler */ Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit); if (ACPI_FAILURE(Status)) { device_printf(dev, "AcpiEnableGpe failed: %s\n", AcpiFormatException(Status)); goto error; } ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "acpi_ec_attach complete\n")); return (0); error: AcpiRemoveGpeHandler(sc->ec_gpehandle, sc->ec_gpebit, &EcGpeHandler); AcpiRemoveAddressSpaceHandler(sc->ec_handle, ACPI_ADR_SPACE_EC, EcSpaceHandler); if (sc->ec_csr_res) bus_release_resource(sc->ec_dev, SYS_RES_IOPORT, sc->ec_csr_rid, sc->ec_csr_res); if (sc->ec_data_res) bus_release_resource(sc->ec_dev, SYS_RES_IOPORT, sc->ec_data_rid, sc->ec_data_res); return (ENXIO); }
ACPI_STATUS AcpiEvPciConfigRegionSetup ( ACPI_HANDLE Handle, UINT32 Function, void *HandlerContext, void **RegionContext) { ACPI_STATUS Status = AE_OK; UINT64 PciValue; ACPI_PCI_ID *PciId = *RegionContext; ACPI_OPERAND_OBJECT *HandlerObj; ACPI_NAMESPACE_NODE *ParentNode; ACPI_NAMESPACE_NODE *PciRootNode; ACPI_NAMESPACE_NODE *PciDeviceNode; ACPI_OPERAND_OBJECT *RegionObj = (ACPI_OPERAND_OBJECT *) Handle; ACPI_FUNCTION_TRACE (EvPciConfigRegionSetup); HandlerObj = RegionObj->Region.Handler; 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); } *RegionContext = NULL; if (Function == ACPI_REGION_DEACTIVATE) { if (PciId) { ACPI_FREE (PciId); } return_ACPI_STATUS (Status); } ParentNode = RegionObj->Region.Node->Parent; /* * 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 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->AddressSpace.Node == AcpiGbl_RootNode) { /* Start search from the parent object */ PciRootNode = ParentNode; while (PciRootNode != AcpiGbl_RootNode) { /* Get the _HID/_CID in order to detect a RootBridge */ if (AcpiEvIsPciRootBridge (PciRootNode)) { /* Install a handler for this PCI root bridge */ Status = AcpiInstallAddressSpaceHandler ( (ACPI_HANDLE) PciRootNode, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL); if (ACPI_FAILURE (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_EXCEPTION ((AE_INFO, Status, "Could not install PciConfig handler " "for Root Bridge %4.4s", AcpiUtGetNodeName (PciRootNode))); } } break; } PciRootNode = PciRootNode->Parent; } /* PCI root bridge not found, use namespace root node */ } else { PciRootNode = HandlerObj->AddressSpace.Node; } /* * If this region is now initialized, we are done. * (InstallAddressSpaceHandler could have initialized it) */ if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE) { return_ACPI_STATUS (AE_OK); } /* Region is still not initialized. Create a new context */ PciId = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PCI_ID)); if (!PciId) { return_ACPI_STATUS (AE_NO_MEMORY); } /* * For PCI_Config space access, we need the segment, bus, device and * function numbers. Acquire them here. * * Find the parent device object. (This allows the operation region to be * within a subscope under the device, such as a control method.) */ PciDeviceNode = RegionObj->Region.Node; while (PciDeviceNode && (PciDeviceNode->Type != ACPI_TYPE_DEVICE)) { PciDeviceNode = PciDeviceNode->Parent; } if (!PciDeviceNode) { ACPI_FREE (PciId); return_ACPI_STATUS (AE_AML_OPERAND_TYPE); } /* * Get the PCI device and function numbers from the _ADR object * contained in the parent's scope. */ Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, PciDeviceNode, &PciValue); /* * 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 (PciValue)); PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue)); } /* 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/update the PCI ID for this device */ Status = AcpiHwDerivePciId (PciId, PciRootNode, RegionObj->Region.Node); if (ACPI_FAILURE (Status)) { ACPI_FREE (PciId); return_ACPI_STATUS (Status); } *RegionContext = PciId; return_ACPI_STATUS (AE_OK); }
static status_t acpi_std_ops(int32 op,...) { switch (op) { case B_MODULE_INIT: { ACPI_OBJECT arg; ACPI_OBJECT_LIST parameter; void *settings; bool acpiDisabled = false; AcpiGbl_CopyDsdtLocally = true; settings = load_driver_settings("kernel"); if (settings != NULL) { acpiDisabled = !get_driver_boolean_parameter(settings, "acpi", true, true); unload_driver_settings(settings); } if (!acpiDisabled) { // check if safemode settings disable ACPI settings = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS); if (settings != NULL) { acpiDisabled = get_driver_boolean_parameter(settings, B_SAFEMODE_DISABLE_ACPI, false, false); unload_driver_settings(settings); } } if (acpiDisabled) { ERROR("ACPI disabled\n"); return ENOSYS; } if (gDPC->new_dpc_queue(&gDPCHandle, "acpi_task", B_URGENT_DISPLAY_PRIORITY + 1) != B_OK) { ERROR("failed to create os execution queue\n"); return B_ERROR; } #ifdef ACPI_DEBUG_OUTPUT AcpiDbgLevel = ACPI_DEBUG_ALL | ACPI_LV_VERBOSE; AcpiDbgLayer = ACPI_ALL_COMPONENTS; #endif if (checkAndLogFailure(AcpiInitializeSubsystem(), "AcpiInitializeSubsystem failed")) goto err; if (checkAndLogFailure(AcpiInitializeTables(NULL, 0, TRUE), "AcpiInitializeTables failed")) goto err; if (checkAndLogFailure(AcpiLoadTables(), "AcpiLoadTables failed")) goto err; /* Install the default address space handlers. */ if (checkAndLogFailure(AcpiInstallAddressSpaceHandler( ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_SYSTEM_MEMORY, ACPI_DEFAULT_HANDLER, NULL, NULL), "Could not initialise SystemMemory handler:")) goto err; if (checkAndLogFailure(AcpiInstallAddressSpaceHandler( ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_SYSTEM_IO, ACPI_DEFAULT_HANDLER, NULL, NULL), "Could not initialise SystemIO handler:")) goto err; if (checkAndLogFailure(AcpiInstallAddressSpaceHandler( ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL), "Could not initialise PciConfig handler:")) goto err; arg.Integer.Type = ACPI_TYPE_INTEGER; arg.Integer.Value = apic_available() ? APIC_MODE : PIC_MODE; parameter.Count = 1; parameter.Pointer = &arg; AcpiEvaluateObject(NULL, "\\_PIC", ¶meter, NULL); if (checkAndLogFailure(AcpiEnableSubsystem( ACPI_FULL_INITIALIZATION), "AcpiEnableSubsystem failed")) goto err; if (checkAndLogFailure(AcpiInitializeObjects( ACPI_FULL_INITIALIZATION), "AcpiInitializeObjects failed")) goto err; //TODO: Walk namespace init ALL _PRW's #ifdef ACPI_DEBUG_OUTPUT checkAndLogFailure( AcpiInstallGlobalEventHandler(globalGPEHandler, NULL), "Failed to install global GPE-handler."); checkAndLogFailure(AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT, ACPI_ALL_NOTIFY, globalNotifyHandler, NULL), "Failed to install global Notify-handler."); #endif checkAndLogFailure(AcpiEnableAllRuntimeGpes(), "Failed to enable all runtime Gpes"); checkAndLogFailure(AcpiUpdateAllGpes(), "Failed to update all Gpes"); TRACE("ACPI initialized\n"); return B_OK; err: return B_ERROR; } case B_MODULE_UNINIT: { if (checkAndLogFailure(AcpiTerminate(), "Could not bring system out of ACPI mode. Oh well.")); gDPC->delete_dpc_queue(gDPCHandle); gDPCHandle = NULL; break; } default: return B_ERROR; } return B_OK; }
ACPI_STATUS AeInstallHandlers (void) { ACPI_STATUS Status; UINT32 i; ACPI_HANDLE Handle; ACPI_FUNCTION_ENTRY (); Status = AcpiInstallTableHandler (AeTableHandler, NULL); if (ACPI_FAILURE (Status)) { printf ("Could not install table handler, %s\n", AcpiFormatException (Status)); } Status = AcpiInstallExceptionHandler (AeExceptionHandler); if (ACPI_FAILURE (Status)) { printf ("Could not install exception handler, %s\n", AcpiFormatException (Status)); } /* Install global notify handler */ Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, AeNotifyHandler, NULL); if (ACPI_FAILURE (Status)) { printf ("Could not install a global notify handler, %s\n", AcpiFormatException (Status)); } Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_DEVICE_NOTIFY, AeDeviceNotifyHandler, NULL); if (ACPI_FAILURE (Status)) { printf ("Could not install a global notify handler, %s\n", AcpiFormatException (Status)); } Status = AcpiGetHandle (NULL, "\\_SB", &Handle); if (ACPI_SUCCESS (Status)) { Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY, AeNotifyHandler, NULL); if (ACPI_FAILURE (Status)) { printf ("Could not install a notify handler, %s\n", AcpiFormatException (Status)); } Status = AcpiRemoveNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY, AeNotifyHandler); if (ACPI_FAILURE (Status)) { printf ("Could not remove a notify handler, %s\n", AcpiFormatException (Status)); } Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, AeNotifyHandler, NULL); Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY, AeNotifyHandler); Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, AeNotifyHandler, NULL); if (ACPI_FAILURE (Status)) { printf ("Could not install a notify handler, %s\n", AcpiFormatException (Status)); } Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle); Status = AcpiDetachData (Handle, AeAttachedDataHandler); Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle); } else { printf ("No _SB_ found, %s\n", AcpiFormatException (Status)); } /* Set a handler for all supported operation regions */ for (i = 0; i < AEXEC_NUM_REGIONS; i++) { Status = AcpiRemoveAddressSpaceHandler (AcpiGbl_RootNode, SpaceId[i], AeRegionHandler); /* Install handler at the root object. * TBD: all default handlers should be installed here! */ Status = AcpiInstallAddressSpaceHandler (AcpiGbl_RootNode, SpaceId[i], AeRegionHandler, AeRegionInit, NULL); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "Could not install an OpRegion handler for %s space(%u)", AcpiUtGetRegionName((UINT8) SpaceId[i]), SpaceId[i])); return (Status); } } /* * Initialize the global Region Handler space * MCW 3/23/00 */ AeRegions.NumberOfRegions = 0; AeRegions.RegionList = NULL; return Status; }
ACPI_STATUS AcpiEvInitAddressSpaces ( void) { ACPI_STATUS Status; ACPI_FUNCTION_TRACE ("EvInitAddressSpaces"); /* * All address spaces (PCI Config, EC, SMBus) are scope dependent * and registration must occur for a specific device. In the case * system memory and IO address spaces there is currently no device * associated with the address space. For these we use the root. * We install the default PCI config space handler at the root so * that this space is immediately available even though the we have * not enumerated all the PCI Root Buses yet. This is to conform * to the ACPI specification which states that the PCI config * space must be always available -- even though we are nowhere * near ready to find the PCI root buses at this point. * * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler * has already been installed (via AcpiInstallAddressSpaceHandler) */ Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) AcpiGbl_RootNode, ACPI_ADR_SPACE_SYSTEM_MEMORY, ACPI_DEFAULT_HANDLER, NULL, NULL); if ((ACPI_FAILURE (Status)) && (Status != AE_ALREADY_EXISTS)) { return_ACPI_STATUS (Status); } Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) AcpiGbl_RootNode, ACPI_ADR_SPACE_SYSTEM_IO, ACPI_DEFAULT_HANDLER, NULL, NULL); if ((ACPI_FAILURE (Status)) && (Status != AE_ALREADY_EXISTS)) { return_ACPI_STATUS (Status); } Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) AcpiGbl_RootNode, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL); if ((ACPI_FAILURE (Status)) && (Status != AE_ALREADY_EXISTS)) { return_ACPI_STATUS (Status); } Status = AcpiInstallAddressSpaceHandler ((ACPI_HANDLE) AcpiGbl_RootNode, ACPI_ADR_SPACE_DATA_TABLE, ACPI_DEFAULT_HANDLER, NULL, NULL); if ((ACPI_FAILURE (Status)) && (Status != AE_ALREADY_EXISTS)) { return_ACPI_STATUS (Status); } return_ACPI_STATUS (AE_OK); }
static int acpi_ec_attach(device_t dev) { struct acpi_ec_softc *sc; ACPI_STATUS Status; int errval = 0; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); /* * Fetch/initialise softc */ sc = device_get_softc(dev); bzero(sc, sizeof(*sc)); sc->ec_dev = dev; sc->ec_handle = acpi_get_handle(dev); /* * Attach bus resources */ sc->ec_data_rid = 0; if ((sc->ec_data_res = bus_alloc_resource(sc->ec_dev, SYS_RES_IOPORT, &sc->ec_data_rid, 0, ~0, 1, RF_ACTIVE)) == NULL) { device_printf(dev, "can't allocate data port\n"); errval = ENXIO; goto out; } sc->ec_data_tag = rman_get_bustag(sc->ec_data_res); sc->ec_data_handle = rman_get_bushandle(sc->ec_data_res); sc->ec_csr_rid = 1; if ((sc->ec_csr_res = bus_alloc_resource(sc->ec_dev, SYS_RES_IOPORT, &sc->ec_csr_rid, 0, ~0, 1, RF_ACTIVE)) == NULL) { device_printf(dev, "can't allocate command/status port\n"); errval = ENXIO; goto out; } sc->ec_csr_tag = rman_get_bustag(sc->ec_csr_res); sc->ec_csr_handle = rman_get_bushandle(sc->ec_csr_res); /* * Install GPE handler * * Evaluate the _GPE method to find the GPE bit used by the EC to signal * status (SCI). */ ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "attaching GPE\n")); if (ACPI_FAILURE(Status = acpi_EvaluateInteger(sc->ec_handle, "_GPE", &sc->ec_gpebit))) { device_printf(dev, "can't evaluate _GPE - %s\n", AcpiFormatException(Status)); errval =ENXIO; goto out; } /* * Install a handler for this EC's GPE bit. Note that EC SCIs are * treated as both edge- and level-triggered interrupts; in other words * we clear the status bit immediately after getting an EC-SCI, then * again after we're done processing the event. This guarantees that * events we cause while performing a transaction (e.g. IBE/OBF) get * cleared before re-enabling the GPE. */ if (ACPI_FAILURE(Status = AcpiInstallGpeHandler(sc->ec_gpebit, ACPI_EVENT_LEVEL_TRIGGERED | ACPI_EVENT_EDGE_TRIGGERED, EcGpeHandler, sc))) { device_printf(dev, "can't install GPE handler for %s - %s\n", acpi_name(sc->ec_handle), AcpiFormatException(Status)); errval = ENXIO; goto out; } /* * Install address space handler */ ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "attaching address space handler\n")); if (ACPI_FAILURE(Status = AcpiInstallAddressSpaceHandler(sc->ec_handle, ACPI_ADR_SPACE_EC, EcSpaceHandler, EcSpaceSetup, sc))) { device_printf(dev, "can't install address space handler for %s - %s\n", acpi_name(sc->ec_handle), AcpiFormatException(Status)); panic("very suck"); errval = ENXIO; goto out; } ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "attach complete\n")); return_VALUE(0); out: if(sc->ec_csr_res) bus_release_resource(sc->ec_dev, SYS_RES_IOPORT, sc->ec_csr_rid, sc->ec_csr_res); if(sc->ec_data_res) bus_release_resource(sc->ec_dev, SYS_RES_IOPORT, sc->ec_data_rid, sc->ec_data_res); return_VALUE(errval); }
/* * acpiec_attach: * * Autoconfiguration `attach' routine. */ void acpiec_attach(struct device *parent, struct device *self, void *aux) { struct acpi_ec_softc *sc = (void *) self; struct acpi_attach_args *aa = aux; struct acpi_io *io0, *io1; ACPI_STATUS rv; FUNCTION_TRACE(__FUNCTION__); printf(": ACPI Embedded Controller\n"); sc->sc_node = aa->aa_node; /* Parse our resources. */ ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "parsing EC resources\n")); rv = acpi_resource_parse(&sc->sc_dev, sc->sc_node, &sc->sc_res, &acpi_resource_parse_ops_default); if (rv != AE_OK) { printf("%s: unable to parse resources: %d\n", sc->sc_dev.dv_xname, rv); return; } sc->sc_data_st = aa->aa_iot; io0 = acpi_res_io(&sc->sc_res, 0); if (io0 == NULL) { printf("%s: unable to find data register resource\n", sc->sc_dev.dv_xname); return; } if (bus_space_map(sc->sc_data_st, io0->ar_base, io0->ar_length, 0, &sc->sc_data_sh) != 0) { printf("%s: unable to map data register\n", sc->sc_dev.dv_xname); return; } sc->sc_csr_st = aa->aa_iot; io1 = acpi_res_io(&sc->sc_res, 1); if (io1 == NULL) { printf("%s: unable to find csr register resource\n", sc->sc_dev.dv_xname); return; } if (bus_space_map(sc->sc_csr_st, io1->ar_base, io1->ar_length, 0, &sc->sc_csr_sh) != 0) { printf("%s: unable to map csr register\n", sc->sc_dev.dv_xname); return; } /* * Install GPE handler. * * We evaluate the _GPE method to find the GPE bit used by the * Embedded Controller to signal status (SCI). */ if ((rv = acpi_eval_integer(sc->sc_node->ad_handle, "_GPE", &sc->sc_gpebit)) != AE_OK) { printf("%s: unable to evaluate _GPE: %d\n", sc->sc_dev.dv_xname, rv); return; } /* * Install a handler for this EC's GPE bit. Note that EC SCIs are * treated as both edge- and level-triggered interrupts; in other words * we clear the status bit immediately after getting an EC-SCI, then * again after we're done processing the event. This guarantees that * events we cause while performing a transaction (e.g. IBE/OBF) get * cleared before re-enabling the GPE. */ if ((rv = AcpiInstallGpeHandler(sc->sc_gpebit, ACPI_EVENT_LEVEL_TRIGGERED | ACPI_EVENT_EDGE_TRIGGERED, EcGpeHandler, sc)) != AE_OK) { printf("%s: unable to install GPE handler: %d\n", sc->sc_dev.dv_xname, rv); return; } /* Install address space handler. */ if ((rv = AcpiInstallAddressSpaceHandler(sc->sc_node->ad_handle, ACPI_ADR_SPACE_EC, EcSpaceHandler, EcSpaceSetup, sc)) != AE_OK) { printf("%s: unable to install address space handler: %d\n", sc->sc_dev.dv_xname, rv); return; } return_VOID; }
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); }