int drm_generic_detach(device_t kdev) { struct drm_device *dev; int i; dev = device_get_softc(kdev); drm_put_dev(dev); /* Clean up PCI resources allocated by drm_bufs.c. We're not really * worried about resource consumption while the DRM is inactive (between * lastclose and firstopen or unload) because these aren't actually * taking up KVA, just keeping the PCI resource allocated. */ for (i = 0; i < DRM_MAX_PCI_RESOURCE; i++) { if (dev->pcir[i] == NULL) continue; bus_release_resource(dev->dev, SYS_RES_MEMORY, dev->pcirid[i], dev->pcir[i]); dev->pcir[i] = NULL; } if (pci_disable_busmaster(dev->dev)) DRM_ERROR("Request to disable bus-master failed.\n"); return (0); }
static int bhndb_pci_detach(device_t dev) { struct bhndb_pci_softc *sc; int error; sc = device_get_softc(dev); /* Attempt to detach our children */ if ((error = bus_generic_detach(dev))) return (error); /* Perform generic bridge detach */ if ((error = bhndb_generic_detach(dev))) return (error); /* Disable clocks (if required by this hardware) */ if ((error = bhndb_disable_pci_clocks(sc->dev))) return (error); /* Free our interrupt resources */ bhndb_free_intr_isrc(sc->isrc); /* Release MSI interrupts */ if (sc->msi_count > 0) pci_release_msi(sc->parent); /* Disable PCI bus mastering */ pci_disable_busmaster(sc->parent); BHNDB_PCI_LOCK_DESTROY(sc); return (0); }
static int vga_pci_disable_busmaster(device_t dev, device_t child) { device_printf(dev, "child %s requested pci_disable_busmaster\n", device_get_nameunit(child)); return (pci_disable_busmaster(dev)); }
static int nvme_detach (device_t dev) { struct nvme_controller *ctrlr = DEVICE2SOFTC(dev); nvme_ctrlr_destruct(ctrlr, dev); pci_disable_busmaster(dev); return (0); }
int uhci_pci_detach(device_t self) { uhci_softc_t *sc = device_get_softc(self); device_t bdev; if (sc->sc_bus.bdev) { bdev = sc->sc_bus.bdev; device_detach(bdev); device_delete_child(self, bdev); } /* during module unload there are lots of children leftover */ device_delete_children(self); /* * disable interrupts that might have been switched on in * uhci_init. */ if (sc->sc_io_res) { USB_BUS_LOCK(&sc->sc_bus); /* stop the controller */ uhci_reset(sc); USB_BUS_UNLOCK(&sc->sc_bus); } pci_disable_busmaster(self); if (sc->sc_irq_res && sc->sc_intr_hdl) { int err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl); if (err) { /* XXX or should we panic? */ device_printf(self, "Could not tear down irq, %d\n", err); } sc->sc_intr_hdl = NULL; } if (sc->sc_irq_res) { bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res); sc->sc_irq_res = NULL; } if (sc->sc_io_res) { bus_release_resource(self, SYS_RES_IOPORT, PCI_UHCI_BASE_REG, sc->sc_io_res); sc->sc_io_res = NULL; } usb_bus_mem_free_all(&sc->sc_bus, &uhci_iterate_hw_softc); return (0); }
static int ismt_detach(device_t dev) { struct ismt_softc *sc; int error; ISMT_DEBUG(dev, "%s\n", __func__); sc = device_get_softc(dev); error = bus_generic_detach(dev); if (error) return (error); device_delete_child(dev, sc->smbdev); if (sc->intr_handle != NULL) { bus_teardown_intr(dev, sc->intr_res, sc->intr_handle); sc->intr_handle = NULL; } if (sc->intr_res != NULL) { bus_release_resource(dev, SYS_RES_IRQ, sc->intr_rid, sc->intr_res); sc->intr_res = NULL; } if (sc->using_msi == 1) pci_release_msi(dev); if (sc->mmio_res != NULL) { bus_release_resource(dev, SYS_RES_MEMORY, sc->mmio_rid, sc->mmio_res); sc->mmio_res = NULL; } bus_dmamap_unload(sc->desc_dma_tag, sc->desc_dma_map); bus_dmamap_unload(sc->dma_buffer_dma_tag, sc->dma_buffer_dma_map); bus_dmamem_free(sc->desc_dma_tag, sc->desc, sc->desc_dma_map); bus_dmamem_free(sc->dma_buffer_dma_tag, sc->dma_buffer, sc->dma_buffer_dma_map); bus_dma_tag_destroy(sc->desc_dma_tag); bus_dma_tag_destroy(sc->dma_buffer_dma_tag); pci_disable_busmaster(dev); return 0; }
static void sfxge_destroy(struct sfxge_softc *sc) { efx_nic_t *enp; /* Clean up port state. */ sfxge_port_fini(sc); /* Clean up transmit state. */ sfxge_tx_fini(sc); /* Clean up receive state. */ sfxge_rx_fini(sc); /* Clean up event processing state. */ sfxge_ev_fini(sc); /* Clean up interrupts. */ sfxge_intr_fini(sc); /* Tear down common code subsystems. */ efx_nic_reset(sc->enp); efx_vpd_fini(sc->enp); efx_nvram_fini(sc->enp); efx_nic_unprobe(sc->enp); /* Tear down MCDI. */ sfxge_mcdi_fini(sc); /* Destroy common code context. */ enp = sc->enp; sc->enp = NULL; efx_nic_destroy(enp); /* Free DMA memory. */ sfxge_dma_fini(sc); /* Free mapped BARs. */ sfxge_bar_fini(sc); (void) pci_disable_busmaster(sc->dev); taskqueue_drain(taskqueue_thread, &sc->task_reset); /* Destroy the softc lock. */ sx_destroy(&sc->softc_lock); }
static int siba_bwn_detach(device_t dev) { struct siba_bwn_softc *ssc = device_get_softc(dev); struct siba_softc *siba = &ssc->ssc_siba; /* check if device was removed */ siba->siba_invalid = !bus_child_present(dev); pci_disable_busmaster(dev); bus_generic_detach(dev); siba_core_detach(siba); bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR, siba->siba_mem_res); return (0); }
static int ohci_pci_detach(device_t self) { ohci_softc_t *sc = device_get_softc(self); device_t bdev; if (sc->sc_bus.bdev) { bdev = sc->sc_bus.bdev; device_detach(bdev); device_delete_child(self, bdev); } /* during module unload there are lots of children leftover */ device_delete_all_children(self); pci_disable_busmaster(self); if (sc->sc_irq_res && sc->sc_intr_hdl) { /* * only call ohci_detach() after ohci_init() */ ohci_detach(sc); int err = bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl); if (err) { /* XXX or should we panic? */ device_printf(self, "Could not tear down irq, %d\n", err); } sc->sc_intr_hdl = NULL; } if (sc->sc_irq_res) { bus_release_resource(self, SYS_RES_IRQ, 0, sc->sc_irq_res); sc->sc_irq_res = NULL; } if (sc->sc_io_res) { bus_release_resource(self, SYS_RES_MEMORY, PCI_CBMEM, sc->sc_io_res); sc->sc_io_res = NULL; } usb_bus_mem_free_all(&sc->sc_bus, &ohci_iterate_hw_softc); return (0); }
static int xhci_pci_detach(device_t self) { struct xhci_softc *sc = device_get_softc(self); device_t bdev; if (sc->sc_bus.bdev != NULL) { bdev = sc->sc_bus.bdev; device_detach(bdev); device_delete_child(self, bdev); } /* during module unload there are lots of children leftover */ device_delete_children(self); if (sc->sc_io_res) { usb_callout_drain(&sc->sc_callout); xhci_halt_controller(sc); } pci_disable_busmaster(self); if (sc->sc_irq_res && sc->sc_intr_hdl) { bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl); sc->sc_intr_hdl = NULL; } if (sc->sc_irq_res) { if (sc->sc_irq_rid == 1) pci_release_msi(self); bus_release_resource(self, SYS_RES_IRQ, sc->sc_irq_rid, sc->sc_irq_res); sc->sc_irq_res = NULL; } if (sc->sc_io_res) { bus_release_resource(self, SYS_RES_MEMORY, PCI_XHCI_CBMEM, sc->sc_io_res); sc->sc_io_res = NULL; } xhci_uninit(sc); return (0); }
static int bhndb_pci_detach(device_t dev) { struct bhndb_pci_softc *sc; int error; sc = device_get_softc(dev); if ((error = bhndb_generic_detach(dev))) return (error); /* Apply any hardware workarounds. This may disable the clock, and * thus must be called *after* any children have been detached. */ if ((error = bhndb_pci_wars_hwdown(sc))) return (error); /* Disable PCI bus mastering */ pci_disable_busmaster(device_get_parent(dev)); return (0); }
static int ioat_detach(device_t device) { struct ioat_softc *ioat; ioat = DEVICE2SOFTC(device); ioat_test_detach(); mtx_lock(IOAT_REFLK); ioat->quiescing = TRUE; ioat_channel[ioat->chan_idx] = NULL; ioat_drain_locked(ioat); mtx_unlock(IOAT_REFLK); ioat_teardown_intr(ioat); callout_drain(&ioat->timer); pci_disable_busmaster(device); if (ioat->pci_resource != NULL) bus_release_resource(device, SYS_RES_MEMORY, ioat->pci_resource_id, ioat->pci_resource); if (ioat->ring != NULL) ioat_free_ring(ioat, 1 << ioat->ring_size_order, ioat->ring); if (ioat->comp_update != NULL) { bus_dmamap_unload(ioat->comp_update_tag, ioat->comp_update_map); bus_dmamem_free(ioat->comp_update_tag, ioat->comp_update, ioat->comp_update_map); bus_dma_tag_destroy(ioat->comp_update_tag); } bus_dma_tag_destroy(ioat->hw_desc_tag); return (0); }
static int vga_pci_disable_busmaster(device_t dev, device_t child) { return (pci_disable_busmaster(dev)); }
static int bhndb_pci_attach(device_t dev) { struct bhndb_pci_softc *sc; struct bhnd_chipid cid; struct bhnd_core_info *cores, hostb_core; bhnd_erom_class_t *erom_class; struct bhndb_pci_probe *probe; u_int ncores; int irq_rid; int error; sc = device_get_softc(dev); sc->dev = dev; sc->parent = device_get_parent(dev); sc->pci_devclass = bhndb_expected_pci_devclass(dev); sc->pci_quirks = 0; sc->set_regwin = NULL; BHNDB_PCI_LOCK_INIT(sc); probe = NULL; cores = NULL; /* Enable PCI bus mastering */ pci_enable_busmaster(sc->parent); /* Enable clocks (if required by this hardware) */ if ((error = bhndb_enable_pci_clocks(sc->dev))) goto cleanup; /* Identify the chip and enumerate the bridged cores */ error = bhndb_pci_probe_alloc(&probe, dev, sc->pci_devclass); if (error) goto cleanup; sc->pci_quirks = bhndb_pci_get_core_quirks(&probe->cid, &probe->hostb_core); /* Select the appropriate register window handler */ if (probe->cid.chip_type == BHND_CHIPTYPE_SIBA) { sc->set_regwin = bhndb_pci_compat_setregwin; } else { sc->set_regwin = bhndb_pci_fast_setregwin; } /* * Fix up our PCI base address in the SPROM shadow, if necessary. * * This must be done prior to accessing any static register windows * that map the PCI core. */ if ((error = bhndb_pci_srsh_pi_war(sc, probe))) goto cleanup; /* Set up PCI interrupt handling */ if (bhndb_pci_alloc_msi(sc, &sc->msi_count) == 0) { /* MSI uses resource IDs starting at 1 */ irq_rid = 1; device_printf(dev, "Using MSI interrupts on %s\n", device_get_nameunit(sc->parent)); } else { sc->msi_count = 0; irq_rid = 0; device_printf(dev, "Using INTx interrupts on %s\n", device_get_nameunit(sc->parent)); } sc->isrc = bhndb_alloc_intr_isrc(sc->parent, irq_rid, 0, RM_MAX_END, 1, RF_SHAREABLE | RF_ACTIVE); if (sc->isrc == NULL) { device_printf(sc->dev, "failed to allocate interrupt " "resource\n"); error = ENXIO; goto cleanup; } /* * Copy out the probe results and then free our probe state, releasing * its exclusive ownership of host bridge resources. * * This must be done prior to full configuration of the bridge via * bhndb_attach(). */ cid = probe->cid; erom_class = probe->erom_class; hostb_core = probe->hostb_core; error = bhndb_pci_probe_copy_core_table(probe, &cores, &ncores); if (error) { cores = NULL; goto cleanup; } bhndb_pci_probe_free(probe); probe = NULL; /* Perform bridge attach */ error = bhndb_attach(dev, &cid, cores, ncores, &hostb_core, erom_class); if (error) goto cleanup; /* Add any additional child devices */ if ((error = bhndb_pci_add_children(sc))) goto cleanup; /* Probe and attach our children */ if ((error = bus_generic_attach(dev))) goto cleanup; bhndb_pci_probe_free_core_table(cores); return (0); cleanup: device_delete_children(dev); if (sc->isrc != NULL) bhndb_free_intr_isrc(sc->isrc); if (sc->msi_count > 0) pci_release_msi(sc->parent); if (cores != NULL) bhndb_pci_probe_free_core_table(cores); if (probe != NULL) bhndb_pci_probe_free(probe); bhndb_disable_pci_clocks(sc->dev); pci_disable_busmaster(sc->parent); BHNDB_PCI_LOCK_DESTROY(sc); return (error); }
static int isci_detach(device_t device) { struct isci_softc *isci = DEVICE2SOFTC(device); int i, phy; for (i = 0; i < isci->controller_count; i++) { struct ISCI_CONTROLLER *controller = &isci->controllers[i]; SCI_STATUS status; void *unmap_buffer; if (controller->scif_controller_handle != NULL) { scic_controller_disable_interrupts( scif_controller_get_scic_handle(controller->scif_controller_handle)); mtx_lock(&controller->lock); status = scif_controller_stop(controller->scif_controller_handle, 0); mtx_unlock(&controller->lock); while (controller->is_started == TRUE) { /* Now poll for interrupts until the controller stop complete * callback is received. */ mtx_lock(&controller->lock); isci_interrupt_poll_handler(controller); mtx_unlock(&controller->lock); pause("isci", 1); } if(controller->sim != NULL) { mtx_lock(&controller->lock); xpt_free_path(controller->path); xpt_bus_deregister(cam_sim_path(controller->sim)); cam_sim_free(controller->sim, TRUE); mtx_unlock(&controller->lock); } } if (controller->timer_memory != NULL) free(controller->timer_memory, M_ISCI); if (controller->remote_device_memory != NULL) free(controller->remote_device_memory, M_ISCI); for (phy = 0; phy < SCI_MAX_PHYS; phy++) { if (controller->phys[phy].cdev_fault) led_destroy(controller->phys[phy].cdev_fault); if (controller->phys[phy].cdev_locate) led_destroy(controller->phys[phy].cdev_locate); } while (1) { sci_pool_get(controller->unmap_buffer_pool, unmap_buffer); if (unmap_buffer == NULL) break; contigfree(unmap_buffer, PAGE_SIZE, M_ISCI); } } /* The SCIF controllers have been stopped, so we can now * free the SCI library memory. */ if (isci->sci_library_memory != NULL) free(isci->sci_library_memory, M_ISCI); for (i = 0; i < ISCI_NUM_PCI_BARS; i++) { struct ISCI_PCI_BAR *pci_bar = &isci->pci_bar[i]; if (pci_bar->resource != NULL) bus_release_resource(device, SYS_RES_MEMORY, pci_bar->resource_id, pci_bar->resource); } for (i = 0; i < isci->num_interrupts; i++) { struct ISCI_INTERRUPT_INFO *interrupt_info; interrupt_info = &isci->interrupt_info[i]; if(interrupt_info->tag != NULL) bus_teardown_intr(device, interrupt_info->res, interrupt_info->tag); if(interrupt_info->res != NULL) bus_release_resource(device, SYS_RES_IRQ, rman_get_rid(interrupt_info->res), interrupt_info->res); pci_release_msi(device); } pci_disable_busmaster(device); return (0); }
static int sfxge_create(struct sfxge_softc *sc) { device_t dev; efx_nic_t *enp; int error; dev = sc->dev; sx_init(&sc->softc_lock, "sfxge_softc"); sc->stats_node = SYSCTL_ADD_NODE( device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "stats", CTLFLAG_RD, NULL, "Statistics"); if (!sc->stats_node) { error = ENOMEM; goto fail; } TASK_INIT(&sc->task_reset, 0, sfxge_reset, sc); (void) pci_enable_busmaster(dev); /* Initialize DMA mappings. */ if ((error = sfxge_dma_init(sc)) != 0) goto fail; /* Map the device registers. */ if ((error = sfxge_bar_init(sc)) != 0) goto fail; error = efx_family(pci_get_vendor(dev), pci_get_device(dev), &sc->family); KASSERT(error == 0, ("Family should be filtered by sfxge_probe()")); /* Create the common code nic object. */ mtx_init(&sc->enp_lock, "sfxge_nic", NULL, MTX_DEF); if ((error = efx_nic_create(sc->family, (efsys_identifier_t *)sc, &sc->bar, &sc->enp_lock, &enp)) != 0) goto fail3; sc->enp = enp; /* Initialize MCDI to talk to the microcontroller. */ if ((error = sfxge_mcdi_init(sc)) != 0) goto fail4; /* Probe the NIC and build the configuration data area. */ if ((error = efx_nic_probe(enp)) != 0) goto fail5; /* Initialize the NVRAM. */ if ((error = efx_nvram_init(enp)) != 0) goto fail6; /* Initialize the VPD. */ if ((error = efx_vpd_init(enp)) != 0) goto fail7; /* Reset the NIC. */ if ((error = efx_nic_reset(enp)) != 0) goto fail8; /* Initialize buffer table allocation. */ sc->buffer_table_next = 0; /* Set up interrupts. */ if ((error = sfxge_intr_init(sc)) != 0) goto fail8; /* Initialize event processing state. */ if ((error = sfxge_ev_init(sc)) != 0) goto fail11; /* Initialize receive state. */ if ((error = sfxge_rx_init(sc)) != 0) goto fail12; /* Initialize transmit state. */ if ((error = sfxge_tx_init(sc)) != 0) goto fail13; /* Initialize port state. */ if ((error = sfxge_port_init(sc)) != 0) goto fail14; sc->init_state = SFXGE_INITIALIZED; return (0); fail14: sfxge_tx_fini(sc); fail13: sfxge_rx_fini(sc); fail12: sfxge_ev_fini(sc); fail11: sfxge_intr_fini(sc); fail8: efx_vpd_fini(enp); fail7: efx_nvram_fini(enp); fail6: efx_nic_unprobe(enp); fail5: sfxge_mcdi_fini(sc); fail4: sc->enp = NULL; efx_nic_destroy(enp); mtx_destroy(&sc->enp_lock); fail3: sfxge_bar_fini(sc); (void) pci_disable_busmaster(sc->dev); fail: sc->dev = NULL; sx_destroy(&sc->softc_lock); return (error); }
static void drm_unload(struct drm_device *dev) { int i; DRM_DEBUG("\n"); drm_sysctl_cleanup(dev); if (dev->devnode != NULL) destroy_dev(dev->devnode); drm_ctxbitmap_cleanup(dev); if (dev->driver->driver_features & DRIVER_GEM) drm_gem_destroy(dev); if (dev->agp && dev->agp->agp_mtrr) { int __unused retcode; retcode = drm_mtrr_del(0, dev->agp->agp_info.ai_aperture_base, dev->agp->agp_info.ai_aperture_size, DRM_MTRR_WC); DRM_DEBUG("mtrr_del = %d", retcode); } drm_vblank_cleanup(dev); DRM_LOCK(dev); drm_lastclose(dev); DRM_UNLOCK(dev); /* Clean up PCI resources allocated by drm_bufs.c. We're not really * worried about resource consumption while the DRM is inactive (between * lastclose and firstopen or unload) because these aren't actually * taking up KVA, just keeping the PCI resource allocated. */ for (i = 0; i < DRM_MAX_PCI_RESOURCE; i++) { if (dev->pcir[i] == NULL) continue; bus_release_resource(dev->dev, SYS_RES_MEMORY, dev->pcirid[i], dev->pcir[i]); dev->pcir[i] = NULL; } if (dev->agp) { drm_free(dev->agp, M_DRM); dev->agp = NULL; } if (dev->driver->unload != NULL) { DRM_LOCK(dev); dev->driver->unload(dev); DRM_UNLOCK(dev); } drm_mem_uninit(); if (pci_disable_busmaster(dev->dev)) DRM_ERROR("Request to disable bus-master failed.\n"); lockuninit(&dev->vbl_lock); lockuninit(&dev->dev_lock); lockuninit(&dev->event_lock); lockuninit(&dev->struct_mutex); }