/*ARGSUSED*/ static int pci_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) { int instance = ddi_get_instance(devi); pci_state_t *pcip; pcip = ddi_get_soft_state(pci_statep, ddi_get_instance(devi)); switch (cmd) { case DDI_DETACH: if (pcip->pci_fmcap & DDI_FM_ERRCB_CAPABLE) { ddi_fm_handler_unregister(devi); pci_ereport_teardown(devi); } mutex_destroy(&pcip->pci_peek_poke_mutex); mutex_destroy(&pcip->pci_err_mutex); mutex_destroy(&pcip->pci_mutex); ddi_fm_fini(devi); /* Uninitialize pcitool support. */ pcitool_uninit(devi); /* Uninitialize hotplug support on this bus. */ (void) pcihp_uninit(devi); ddi_soft_state_free(pci_statep, instance); return (DDI_SUCCESS); case DDI_SUSPEND: return (DDI_SUCCESS); default: return (DDI_FAILURE); } }
/*ARGSUSED*/ static int ppb_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) { ppb_devstate_t *ppb; int ret; switch (cmd) { case DDI_DETACH: (void) ddi_prop_remove(DDI_DEV_T_NONE, devi, "device_type"); ppb = ddi_get_soft_state(ppb_state, ddi_get_instance(devi)); if (ppb->ppb_fmcap & DDI_FM_ERRCB_CAPABLE) ddi_fm_handler_unregister(devi); if (ppb->ppb_fmcap & (DDI_FM_ERRCB_CAPABLE | DDI_FM_EREPORT_CAPABLE)) pci_ereport_teardown(devi); /* * Uninitialize hotplug support on this bus. */ ret = (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) ? pcie_uninit(devi) : pcihp_uninit(devi); if (ret != DDI_SUCCESS) return (DDI_FAILURE); mutex_destroy(&ppb->ppb_peek_poke_mutex); mutex_destroy(&ppb->ppb_err_mutex); mutex_destroy(&ppb->ppb_mutex); ddi_fm_fini(devi); /* * And finally free the per-pci soft state. */ ddi_soft_state_free(ppb_state, ddi_get_instance(devi)); return (DDI_SUCCESS); case DDI_SUSPEND: ppb = ddi_get_soft_state(ppb_state, ddi_get_instance(devi)); ppb_save_config_regs(ppb); return (DDI_SUCCESS); default: break; } return (DDI_FAILURE); }
/*ARGSUSED*/ static int pci_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) { /* * Use the minor number as constructed by pcihp, as the index value to * ddi_soft_state_zalloc. */ int instance = ddi_get_instance(devi); pci_state_t *pcip = NULL; switch (cmd) { case DDI_ATTACH: break; case DDI_RESUME: return (DDI_SUCCESS); default: return (DDI_FAILURE); } if (ddi_prop_update_string(DDI_DEV_T_NONE, devi, "device_type", "pci") != DDI_PROP_SUCCESS) { cmn_err(CE_WARN, "pci: 'device_type' prop create failed"); } if (ddi_soft_state_zalloc(pci_statep, instance) == DDI_SUCCESS) { pcip = ddi_get_soft_state(pci_statep, instance); } if (pcip == NULL) { goto bad_soft_state; } pcip->pci_dip = devi; pcip->pci_soft_state = PCI_SOFT_STATE_CLOSED; /* * Initialize hotplug support on this bus. At minimum * (for non hotplug bus) this would create ":devctl" minor * node to support DEVCTL_DEVICE_* and DEVCTL_BUS_* ioctls * to this bus. */ if (pcihp_init(devi) != DDI_SUCCESS) { cmn_err(CE_WARN, "pci: Failed to setup hotplug framework"); goto bad_pcihp_init; } /* Second arg: initialize for pci, not pci_express */ if (pcitool_init(devi, B_FALSE) != DDI_SUCCESS) { goto bad_pcitool_init; } pcip->pci_fmcap = DDI_FM_ERRCB_CAPABLE | DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE; ddi_fm_init(devi, &pcip->pci_fmcap, &pcip->pci_fm_ibc); mutex_init(&pcip->pci_mutex, NULL, MUTEX_DRIVER, NULL); mutex_init(&pcip->pci_err_mutex, NULL, MUTEX_DRIVER, (void *)pcip->pci_fm_ibc); mutex_init(&pcip->pci_peek_poke_mutex, NULL, MUTEX_DRIVER, (void *)pcip->pci_fm_ibc); if (pcip->pci_fmcap & DDI_FM_ERRCB_CAPABLE) { pci_ereport_setup(devi); ddi_fm_handler_register(devi, pci_fm_callback, NULL); } ddi_report_dev(devi); return (DDI_SUCCESS); bad_pcitool_init: (void) pcihp_uninit(devi); bad_pcihp_init: ddi_soft_state_free(pci_statep, instance); bad_soft_state: return (DDI_FAILURE); }