/* * Intialize hot plug control for ACPI mode. */ static int pciehpc_acpi_hpc_init(pcie_hp_ctrl_t *ctrl_p) { ACPI_HANDLE pcibus_obj; int status = AE_ERROR; ACPI_HANDLE slot_dev_obj; ACPI_HANDLE hdl; pciehpc_acpi_t *acpi_p; uint16_t bus_methods = 0; uint16_t slot_methods = 0; /* get the ACPI object for the bus node */ status = acpica_get_handle(ctrl_p->hc_dip, &pcibus_obj); if (status != AE_OK) return (DDI_FAILURE); /* get the ACPI object handle for the child node */ status = AcpiGetNextObject(ACPI_TYPE_DEVICE, pcibus_obj, NULL, &slot_dev_obj); if (status != AE_OK) return (DDI_FAILURE); /* * gather the info about the ACPI methods present on the bus node * and the child nodes. */ if (AcpiGetHandle(pcibus_obj, "_OSC", &hdl) == AE_OK) bus_methods |= PCIEHPC_ACPI_OSC_PRESENT; if (AcpiGetHandle(pcibus_obj, "_OSHP", &hdl) == AE_OK) bus_methods |= PCIEHPC_ACPI_OSHP_PRESENT; if (AcpiGetHandle(pcibus_obj, "_HPX", &hdl) == AE_OK) bus_methods |= PCIEHPC_ACPI_HPX_PRESENT; if (AcpiGetHandle(pcibus_obj, "_HPP", &hdl) == AE_OK) bus_methods |= PCIEHPC_ACPI_HPP_PRESENT; if (AcpiGetHandle(pcibus_obj, "_DSM", &hdl) == AE_OK) bus_methods |= PCIEHPC_ACPI_DSM_PRESENT; if (AcpiGetHandle(slot_dev_obj, "_SUN", &hdl) == AE_OK) slot_methods |= PCIEHPC_ACPI_SUN_PRESENT; if (AcpiGetHandle(slot_dev_obj, "_PS0", &hdl) == AE_OK) slot_methods |= PCIEHPC_ACPI_PS0_PRESENT; if (AcpiGetHandle(slot_dev_obj, "_EJ0", &hdl) == AE_OK) slot_methods |= PCIEHPC_ACPI_EJ0_PRESENT; if (AcpiGetHandle(slot_dev_obj, "_STA", &hdl) == AE_OK) slot_methods |= PCIEHPC_ACPI_STA_PRESENT; /* save ACPI object handles, etc. */ acpi_p = kmem_zalloc(sizeof (pciehpc_acpi_t), KM_SLEEP); acpi_p->bus_obj = pcibus_obj; acpi_p->slot_dev_obj = slot_dev_obj; acpi_p->bus_methods = bus_methods; acpi_p->slot_methods = slot_methods; ctrl_p->hc_misc_data = acpi_p; return (DDI_SUCCESS); }
/* * Look first for an ACPI PCI bus node matching busid, then for a _PRT on the * parent node; then drop into the bridge-chasing code (which will also * look for _PRTs on the way up the tree of bridges) * * Stores polarity and sensitivity in the structure pointed to by * intr_flagp, and irqno in the value pointed to by pci_irqp. * * Returns: * ACPI_PSM_SUCCESS on success. * ACPI_PSM_PARTIAL to indicate need to configure the interrupt * link device. * ACPI_PSM_FAILURE if an error prevented the system from * obtaining irq information for dip. */ int acpi_translate_pci_irq(dev_info_t *dip, int ipin, int *pci_irqp, iflag_t *intr_flagp, acpi_psm_lnk_t *acpipsmlnkp) { ACPI_HANDLE pciobj; int status = AE_ERROR; dev_info_t *curdip, *parentdip; int curpin, curbus, curdev; curpin = ipin; curdip = dip; while (curdip != ddi_root_node()) { parentdip = ddi_get_parent(curdip); ASSERT(parentdip != NULL); if (get_bdf(curdip, &curbus, &curdev, NULL) != 0) break; status = acpica_get_handle(parentdip, &pciobj); if ((status == AE_OK) && psm_node_has_prt(pciobj)) { return (acpi_get_gsiv(curdip, pciobj, curdev, curpin, pci_irqp, intr_flagp, acpipsmlnkp)); } /* if we got here, we need to traverse a bridge upwards */ if (!psm_is_pci_bridge(parentdip)) break; /* * This is the rotating scheme that Compaq is using * and documented in the PCI-PCI spec. Also, if the * PCI-PCI bridge is behind another PCI-PCI bridge, * then it needs to keep ascending until an interrupt * entry is found or the top is reached */ curpin = (curdev + curpin) % PCI_INTD; curdip = parentdip; } /* * We should never, ever get here; didn't find a _PRT */ return (ACPI_PSM_FAILURE); }
static int acpinex_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) { int instance; acpinex_softstate_t *softsp; switch (cmd) { case DDI_ATTACH: break; case DDI_RESUME: return (DDI_SUCCESS); default: return (DDI_FAILURE); } /* Get and check instance number. */ instance = ddi_get_instance(devi); if (instance >= ACPINEX_INSTANCE_MAX) { cmn_err(CE_WARN, "acpinex: instance number %d is out of range " "in acpinex_attach(), max %d.", instance, ACPINEX_INSTANCE_MAX - 1); return (DDI_FAILURE); } /* Get soft state structure. */ if (ddi_soft_state_zalloc(acpinex_softstates, instance) != DDI_SUCCESS) { cmn_err(CE_WARN, "!acpinex: failed to allocate soft state " "object in acpinex_attach()."); return (DDI_FAILURE); } softsp = ddi_get_soft_state(acpinex_softstates, instance); /* Initialize soft state structure */ softsp->ans_dip = devi; (void) ddi_pathname(devi, softsp->ans_path); if (ACPI_FAILURE(acpica_get_handle(devi, &softsp->ans_hdl))) { ACPINEX_DEBUG(CE_WARN, "!acpinex: failed to get ACPI handle for %s.", softsp->ans_path); ddi_soft_state_free(acpinex_softstates, instance); return (DDI_FAILURE); } mutex_init(&softsp->ans_lock, NULL, MUTEX_DRIVER, NULL); /* Install event handler for child/descendant objects. */ if (acpinex_event_scan(softsp, B_TRUE) != DDI_SUCCESS) { cmn_err(CE_WARN, "!acpinex: failed to install event handler " "for children of %s.", softsp->ans_path); } /* nothing to suspend/resume here */ (void) ddi_prop_update_string(DDI_DEV_T_NONE, devi, "pm-hardware-state", "no-suspend-resume"); (void) ddi_prop_update_int(DDI_DEV_T_NONE, devi, DDI_NO_AUTODETACH, 1); acpinex_fm_init(softsp); ddi_report_dev(devi); return (DDI_SUCCESS); }