int ata_detach(device_t dev) { struct ata_channel *ch = device_get_softc(dev); device_t *children; int nchildren, i; /* check that we have a valid channel to detach */ if (!ch->r_irq) return ENXIO; /* grap the channel lock so no new requests gets launched */ lockmgr(&ch->state_mtx, LK_EXCLUSIVE); ch->state |= ATA_STALL_QUEUE; lockmgr(&ch->state_mtx, LK_RELEASE); /* detach & delete all children */ if (!device_get_children(dev, &children, &nchildren)) { for (i = 0; i < nchildren; i++) if (children[i]) device_delete_child(dev, children[i]); kfree(children, M_TEMP); } /* release resources */ bus_teardown_intr(dev, ch->r_irq, ch->ih); bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq); ch->r_irq = NULL; lockuninit(&ch->state_mtx); lockuninit(&ch->queue_mtx); return 0; }
int ubt_detach(device_t dev) { struct ubt_softc *sc = device_get_softc(dev); node_p node = sc->sc_node; /* Destroy Netgraph node */ if (node != NULL) { sc->sc_node = NULL; NG_NODE_REALLY_DIE(node); ng_rmnode_self(node); } /* Make sure ubt_task in gone */ taskqueue_drain(taskqueue_swi, &sc->sc_task); /* Free USB transfers, if any */ usbd_transfer_unsetup(sc->sc_xfer, UBT_N_TRANSFER); /* Destroy queues */ UBT_NG_LOCK(sc); NG_BT_MBUFQ_DESTROY(&sc->sc_cmdq); NG_BT_MBUFQ_DESTROY(&sc->sc_aclq); NG_BT_MBUFQ_DESTROY(&sc->sc_scoq); UBT_NG_UNLOCK(sc); lockuninit(&sc->sc_if_lock); lockuninit(&sc->sc_ng_lock); return (0); } /* ubt_detach */
/* * Release the resources allocated by cmx_allocate_resources. */ void cmx_release_resources(device_t dev) { struct cmx_softc *sc = device_get_softc(dev); lockuninit(&sc->mtx); #ifdef CMX_INTR if (sc->ih) { bus_teardown_intr(dev, sc->irq, sc->ih); sc->ih = NULL; } if (sc->irq) { bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); sc->irq = NULL; } #endif if (sc->ioport) { bus_deactivate_resource(dev, SYS_RES_IOPORT, sc->ioport_rid, sc->ioport); bus_release_resource(dev, SYS_RES_IOPORT, sc->ioport_rid, sc->ioport); sc->ioport = NULL; } return; }
static int ndisusb_detach(device_t self) { int i; struct ndis_softc *sc = device_get_softc(self); struct ndisusb_ep *ne; sc->ndisusb_status |= NDISUSB_STATUS_DETACH; ndis_pnpevent_nic(self, NDIS_PNP_EVENT_SURPRISE_REMOVED); if (sc->ndisusb_status & NDISUSB_STATUS_SETUP_EP) { usbd_transfer_unsetup(sc->ndisusb_dread_ep.ne_xfer, 1); usbd_transfer_unsetup(sc->ndisusb_dwrite_ep.ne_xfer, 1); } for (i = 0; i < NDISUSB_ENDPT_MAX; i++) { ne = &sc->ndisusb_ep[i]; usbd_transfer_unsetup(ne->ne_xfer, 1); } (void)ndis_detach(self); lockuninit(&sc->ndisusb_lock); return (0); }
static int ig4iic_pci_detach(device_t dev) { ig4iic_softc_t *sc = device_get_softc(dev); int error; if (sc->pci_attached) { error = ig4iic_detach(sc); if (error) return error; sc->pci_attached = 0; } if (sc->intr_res) { bus_release_resource(dev, SYS_RES_IRQ, sc->intr_rid, sc->intr_res); sc->intr_res = NULL; } if (sc->intr_type == PCI_INTR_TYPE_MSI) pci_release_msi(dev); if (sc->regs_res) { bus_release_resource(dev, SYS_RES_MEMORY, sc->regs_rid, sc->regs_res); sc->regs_res = NULL; } sc->regs_t = 0; sc->regs_h = 0; lockuninit(&sc->lk); return 0; }
static void nukepark(void *obj, void *privdata) { struct puffs_msgpark *park = obj; cv_destroy(&park->park_cv); lockuninit(&park->park_mtx); }
void drm_global_release(void) { int i; for (i = 0; i < DRM_GLOBAL_NUM; ++i) { struct drm_global_item *item = &glob[i]; KKASSERT(item->object == NULL); KKASSERT(item->refcount == 0); lockuninit(&item->mutex); } }
/* * Destroy all variables in table_head */ void dm_table_head_destroy(dm_table_head_t * head) { KKASSERT(lockcount(&head->table_mtx) == 0); /* tables doens't exists when I call this routine, therefore it * doesn't make sense to have io_cnt != 0 */ KKASSERT(head->io_cnt == 0); lockuninit(&head->table_mtx); }
/*------------------------------------------------------------------------* * usb_bus_mem_free_all - factored out code *------------------------------------------------------------------------*/ void usb_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb) { #if USB_HAVE_BUSDMA if (cb) { cb(bus, &usb_bus_mem_free_all_cb); } usb_dma_tag_unsetup(bus->dma_parent_tag); #endif lockuninit(&bus->bus_lock); }
static void ucom_uninit(void *arg) { struct unrhdr *hdr; hdr = ucom_unrhdr; ucom_unrhdr = NULL; DPRINTF("\n"); if (hdr != NULL) delete_unrhdr(hdr); lockuninit(&ucom_lock); }
static int ipheth_detach(device_t dev) { struct ipheth_softc *sc = device_get_softc(dev); struct usb_ether *ue = &sc->sc_ue; /* stop all USB transfers first */ usbd_transfer_unsetup(sc->sc_xfer, IPHETH_N_TRANSFER); uether_ifdetach(ue); lockuninit(&sc->sc_lock); return (0); }
int ichsmb_detach(device_t dev) { const sc_p sc = device_get_softc(dev); int error; error = bus_generic_detach(dev); if (error) return (error); device_delete_child(dev, sc->smb); ichsmb_release_resources(sc); lockuninit(&sc->mutex); return 0; }
/* * Terminate a thread. This function will silently return if the thread * was never initialized or has already been deleted. * * This is accomplished by setting the STOP flag and waiting for the td * structure to become NULL. */ void hammer2_thr_delete(hammer2_thread_t *thr) { if (thr->td == NULL) return; lockmgr(&thr->lk, LK_EXCLUSIVE); atomic_set_int(&thr->flags, HAMMER2_THREAD_STOP); wakeup(&thr->flags); while (thr->td) { lksleep(thr, &thr->lk, 0, "h2thr", hz); } lockmgr(&thr->lk, LK_RELEASE); thr->pmp = NULL; lockuninit(&thr->lk); }
static int alpm_detach(device_t dev) { struct alpm_softc *alpm = device_get_softc(dev); if (alpm->smbus) { device_delete_child(dev, alpm->smbus); alpm->smbus = NULL; } lockuninit(&alpm->lock); if (alpm->res) bus_release_resource(dev, SYS_RES_IOPORT, SMBBA, alpm->res); return (0); }
/* * Stop the OS-specific port helper thread and kill the per-port lock. */ void sili_os_stop_port(struct sili_port *ap) { if (ap->ap_thread) { sili_os_signal_port_thread(ap, AP_SIGF_STOP); sili_os_sleep(10); if (ap->ap_thread) { kprintf("%s: Waiting for thread to terminate\n", PORTNAME(ap)); while (ap->ap_thread) sili_os_sleep(100); kprintf("%s: thread terminated\n", PORTNAME(ap)); } } lockuninit(&ap->ap_lock); }
/* * Function name: tw_osli_cam_detach * Description: Detaches the driver from CAM. * * Input: sc -- ptr to OSL internal ctlr context * Output: None * Return value: None */ TW_VOID tw_osli_cam_detach(struct twa_softc *sc) { tw_osli_dbg_dprintf(3, sc, "entered"); lockmgr(sc->sim_lock, LK_EXCLUSIVE); if (sc->path) xpt_free_path(sc->path); if (sc->sim) { xpt_bus_deregister(cam_sim_path(sc->sim)); /* Passing TRUE to cam_sim_free will free the devq as well. */ cam_sim_free(sc->sim); } /* It's ok have 1 hold count while destroying the mutex */ lockuninit(sc->sim_lock); }
static int amdsmb_detach(device_t dev) { struct amdsmb_softc *amdsmb_sc = device_get_softc(dev); if (amdsmb_sc->smbus) { device_delete_child(dev, amdsmb_sc->smbus); amdsmb_sc->smbus = NULL; } lockuninit(&amdsmb_sc->lock); if (amdsmb_sc->res) bus_release_resource(dev, SYS_RES_IOPORT, amdsmb_sc->rid, amdsmb_sc->res); return (0); }
static int g_modem_detach(device_t dev) { struct g_modem_softc *sc = device_get_softc(dev); DPRINTF("\n"); lockmgr(&sc->sc_lock, LK_EXCLUSIVE); usb_callout_stop(&sc->sc_callout); usb_callout_stop(&sc->sc_watchdog); lockmgr(&sc->sc_lock, LK_RELEASE); usbd_transfer_unsetup(sc->sc_xfer, G_MODEM_N_TRANSFER); usb_callout_drain(&sc->sc_callout); usb_callout_drain(&sc->sc_watchdog); lockuninit(&sc->sc_lock); return (0); }
/* * Handle attach-time duties that are independent of the bus * our device lives on. */ int ichsmb_attach(device_t dev) { const sc_p sc = device_get_softc(dev); int error; /* Create mutex */ lockinit(&sc->mutex, "ichsmb", 0, LK_CANRECURSE); /* Add child: an instance of the "smbus" device */ if ((sc->smb = device_add_child(dev, DRIVER_SMBUS, -1)) == NULL) { device_printf(dev, "no \"%s\" child found\n", DRIVER_SMBUS); error = ENXIO; goto fail; } /* Clear interrupt conditions */ bus_write_1(sc->io_res, ICH_HST_STA, 0xff); /* Set up interrupt handler */ error = bus_setup_intr(dev, sc->irq_res, 0, ichsmb_device_intr, sc, &sc->irq_handle, NULL); if (error != 0) { device_printf(dev, "can't setup irq\n"); goto fail; } /* Attach "smbus" child */ if ((error = bus_generic_attach(dev)) != 0) { device_printf(dev, "failed to attach child: %d\n", error); goto fail; } return (0); fail: lockuninit(&sc->mutex); return (error); }
static int intsmb_detach(device_t dev) { struct intsmb_softc *sc = device_get_softc(dev); int error; error = bus_generic_detach(dev); if (error) return (error); if (sc->smbus) device_delete_child(dev, sc->smbus); if (sc->irq_hand) bus_teardown_intr(dev, sc->irq_res, sc->irq_hand); if (sc->irq_res) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); if (sc->io_res) bus_release_resource(dev, SYS_RES_IOPORT, PCI_BASE_ADDR_SMB, sc->io_res); lockuninit(&sc->lock); return (0); }
/* * Stop the OS-specific port helper thread and kill the per-port lock. */ void ahci_os_stop_port(struct ahci_port *ap) { if (ap->sysctl_tree) { sysctl_ctx_free(&ap->sysctl_ctx); ap->sysctl_tree = NULL; } if (ap->ap_thread) { ahci_os_signal_port_thread(ap, AP_SIGF_STOP); ahci_os_sleep(10); if (ap->ap_thread) { kprintf("%s: Waiting for thread to terminate\n", PORTNAME(ap)); while (ap->ap_thread) ahci_os_sleep(100); kprintf("%s: thread terminated\n", PORTNAME(ap)); } } lockuninit(&ap->ap_lock); }
/* * Function name: tw_osli_free_resources * Description: Performs clean-up at the time of going down. * * Input: sc -- ptr to OSL internal ctlr context * Output: None * Return value: None */ static TW_VOID tw_osli_free_resources(struct twa_softc *sc) { struct tw_osli_req_context *req; TW_INT32 error = 0; tw_osli_dbg_dprintf(3, sc, "entered"); /* Detach from CAM */ tw_osli_cam_detach(sc); if (sc->req_ctx_buf) while ((req = tw_osli_req_q_remove_head(sc, TW_OSLI_FREE_Q)) != NULL) { lockuninit(req->ioctl_wake_timeout_lock); if ((error = bus_dmamap_destroy(sc->dma_tag, req->dma_map))) tw_osli_dbg_dprintf(1, sc, "dmamap_destroy(dma) returned %d", error); } if ((sc->ioctl_tag) && (sc->ioctl_map)) if ((error = bus_dmamap_destroy(sc->ioctl_tag, sc->ioctl_map))) tw_osli_dbg_dprintf(1, sc, "dmamap_destroy(ioctl) returned %d", error); /* Free all memory allocated so far. */ if (sc->req_ctx_buf) kfree(sc->req_ctx_buf, TW_OSLI_MALLOC_CLASS); if (sc->non_dma_mem) kfree(sc->non_dma_mem, TW_OSLI_MALLOC_CLASS); if (sc->dma_mem) { bus_dmamap_unload(sc->cmd_tag, sc->cmd_map); bus_dmamem_free(sc->cmd_tag, sc->dma_mem, sc->cmd_map); } if (sc->cmd_tag) if ((error = bus_dma_tag_destroy(sc->cmd_tag))) tw_osli_dbg_dprintf(1, sc, "dma_tag_destroy(cmd) returned %d", error); if (sc->dma_tag) if ((error = bus_dma_tag_destroy(sc->dma_tag))) tw_osli_dbg_dprintf(1, sc, "dma_tag_destroy(dma) returned %d", error); if (sc->ioctl_tag) if ((error = bus_dma_tag_destroy(sc->ioctl_tag))) tw_osli_dbg_dprintf(1, sc, "dma_tag_destroy(ioctl) returned %d", error); if (sc->parent_tag) if ((error = bus_dma_tag_destroy(sc->parent_tag))) tw_osli_dbg_dprintf(1, sc, "dma_tag_destroy(parent) returned %d", error); /* Disconnect the interrupt handler. */ if ((error = twa_teardown_intr(sc))) tw_osli_dbg_dprintf(1, sc, "teardown_intr returned %d", error); if (sc->irq_res != NULL) if ((error = bus_release_resource(sc->bus_dev, SYS_RES_IRQ, sc->irq_res_id, sc->irq_res))) tw_osli_dbg_dprintf(1, sc, "release_resource(irq) returned %d", error); if (sc->irq_type == PCI_INTR_TYPE_MSI) pci_release_msi(sc->bus_dev); /* Release the register window mapping. */ if (sc->reg_res != NULL) if ((error = bus_release_resource(sc->bus_dev, SYS_RES_MEMORY, sc->reg_res_id, sc->reg_res))) tw_osli_dbg_dprintf(1, sc, "release_resource(io) returned %d", error); /* Destroy the control device. */ if (sc->ctrl_dev != NULL) destroy_dev(sc->ctrl_dev); dev_ops_remove_minor(&twa_ops, device_get_unit(sc->bus_dev)); }
static int tws_detach(device_t dev) { struct tws_softc *sc = device_get_softc(dev); int error, i; u_int32_t reg; TWS_TRACE_DEBUG(sc, "entry", 0, 0); lockmgr(&sc->gen_lock, LK_EXCLUSIVE); tws_send_event(sc, TWS_UNINIT_START); lockmgr(&sc->gen_lock, LK_RELEASE); /* needs to disable interrupt before detaching from cam */ tws_turn_off_interrupts(sc); /* clear door bell */ tws_write_reg(sc, TWS_I2O0_HOBDBC, ~0, 4); reg = tws_read_reg(sc, TWS_I2O0_HIMASK, 4); TWS_TRACE_DEBUG(sc, "turn-off-intr", reg, 0); sc->obfl_q_overrun = false; tws_init_connect(sc, 1); /* Teardown the state in our softc created in our attach routine. */ /* Disconnect the interrupt handler. */ for(i=0;i<sc->irqs;i++) { if (sc->intr_handle[i]) { if ((error = bus_teardown_intr(sc->tws_dev, sc->irq_res[i], sc->intr_handle[i]))) TWS_TRACE(sc, "bus teardown intr", 0, error); } } /* Release irq resource */ for(i=0;i<sc->irqs;i++) { if ( sc->irq_res[i] ){ if (bus_release_resource(sc->tws_dev, SYS_RES_IRQ, sc->irq_res_id[i], sc->irq_res[i])) TWS_TRACE(sc, "bus release irq resource", i, sc->irq_res_id[i]); } } if ( sc->intr_type == TWS_MSI ) { pci_release_msi(sc->tws_dev); } tws_cam_detach(sc); /* Release memory resource */ if ( sc->mfa_res ){ if (bus_release_resource(sc->tws_dev, SYS_RES_MEMORY, sc->mfa_res_id, sc->mfa_res)) TWS_TRACE(sc, "bus release mem resource", 0, sc->mfa_res_id); } if ( sc->reg_res ){ if (bus_release_resource(sc->tws_dev, SYS_RES_MEMORY, sc->reg_res_id, sc->reg_res)) TWS_TRACE(sc, "bus release mem resource", 0, sc->reg_res_id); } kfree(sc->reqs, M_TWS); kfree(sc->sense_bufs, M_TWS); kfree(sc->scan_ccb, M_TWS); kfree(sc->aen_q.q, M_TWS); kfree(sc->trace_q.q, M_TWS); lockuninit(&sc->q_lock); lockuninit(&sc->sim_lock); lockuninit(&sc->gen_lock); lockuninit(&sc->io_lock); destroy_dev(sc->tws_cdev); dev_ops_remove_minor(&tws_ops, device_get_unit(sc->tws_dev)); sysctl_ctx_free(&sc->tws_clist); return (0); }
static int tws_attach(device_t dev) { struct tws_softc *sc = device_get_softc(dev); u_int32_t cmd, bar; int error=0,i; /* no tracing yet */ /* Look up our softc and initialize its fields. */ sc->tws_dev = dev; sc->device_id = pci_get_device(dev); sc->subvendor_id = pci_get_subvendor(dev); sc->subdevice_id = pci_get_subdevice(dev); /* Intialize mutexes */ lockinit(&sc->q_lock, "tws_q_lock", 0, LK_CANRECURSE); lockinit(&sc->sim_lock, "tws_sim_lock", 0, LK_CANRECURSE); lockinit(&sc->gen_lock, "tws_gen_lock", 0, LK_CANRECURSE); lockinit(&sc->io_lock, "tws_io_lock", 0, LK_CANRECURSE); if ( tws_init_trace_q(sc) == FAILURE ) kprintf("trace init failure\n"); /* send init event */ lockmgr(&sc->gen_lock, LK_EXCLUSIVE); tws_send_event(sc, TWS_INIT_START); lockmgr(&sc->gen_lock, LK_RELEASE); #if _BYTE_ORDER == _BIG_ENDIAN TWS_TRACE(sc, "BIG endian", 0, 0); #endif /* sysctl context setup */ sysctl_ctx_init(&sc->tws_clist); sc->tws_oidp = SYSCTL_ADD_NODE(&sc->tws_clist, SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, device_get_nameunit(dev), CTLFLAG_RD, 0, ""); if ( sc->tws_oidp == NULL ) { tws_log(sc, SYSCTL_TREE_NODE_ADD); goto attach_fail_1; } SYSCTL_ADD_STRING(&sc->tws_clist, SYSCTL_CHILDREN(sc->tws_oidp), OID_AUTO, "driver_version", CTLFLAG_RD, TWS_DRIVER_VERSION_STRING, 0, "TWS driver version"); cmd = pci_read_config(dev, PCIR_COMMAND, 2); if ( (cmd & PCIM_CMD_PORTEN) == 0) { tws_log(sc, PCI_COMMAND_READ); goto attach_fail_1; } /* Force the busmaster enable bit on. */ cmd |= PCIM_CMD_BUSMASTEREN; pci_write_config(dev, PCIR_COMMAND, cmd, 2); bar = pci_read_config(dev, TWS_PCI_BAR0, 4); TWS_TRACE_DEBUG(sc, "bar0 ", bar, 0); bar = pci_read_config(dev, TWS_PCI_BAR1, 4); bar = bar & ~TWS_BIT2; TWS_TRACE_DEBUG(sc, "bar1 ", bar, 0); /* MFA base address is BAR2 register used for * push mode. Firmware will evatualy move to * pull mode during witch this needs to change */ #ifndef TWS_PULL_MODE_ENABLE sc->mfa_base = (u_int64_t)pci_read_config(dev, TWS_PCI_BAR2, 4); sc->mfa_base = sc->mfa_base & ~TWS_BIT2; TWS_TRACE_DEBUG(sc, "bar2 ", sc->mfa_base, 0); #endif /* allocate MMIO register space */ sc->reg_res_id = TWS_PCI_BAR1; /* BAR1 offset */ if ((sc->reg_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &(sc->reg_res_id), 0, ~0, 1, RF_ACTIVE)) == NULL) { tws_log(sc, ALLOC_MEMORY_RES); goto attach_fail_1; } sc->bus_tag = rman_get_bustag(sc->reg_res); sc->bus_handle = rman_get_bushandle(sc->reg_res); #ifndef TWS_PULL_MODE_ENABLE /* Allocate bus space for inbound mfa */ sc->mfa_res_id = TWS_PCI_BAR2; /* BAR2 offset */ if ((sc->mfa_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &(sc->mfa_res_id), 0, ~0, 0x100000, RF_ACTIVE)) == NULL) { tws_log(sc, ALLOC_MEMORY_RES); goto attach_fail_2; } sc->bus_mfa_tag = rman_get_bustag(sc->mfa_res); sc->bus_mfa_handle = rman_get_bushandle(sc->mfa_res); #endif /* Allocate and register our interrupt. */ sc->intr_type = TWS_INTx; /* default */ if ( tws_enable_msi ) sc->intr_type = TWS_MSI; if ( tws_setup_irq(sc) == FAILURE ) { tws_log(sc, ALLOC_MEMORY_RES); goto attach_fail_3; } /* Init callouts. */ callout_init(&sc->print_stats_handle); callout_init(&sc->reset_cb_handle); callout_init(&sc->reinit_handle); /* * Create a /dev entry for this device. The kernel will assign us * a major number automatically. We use the unit number of this * device as the minor number and name the character device * "tws<unit>". */ sc->tws_cdev = make_dev(&tws_ops, device_get_unit(dev), UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR, "tws%u", device_get_unit(dev)); sc->tws_cdev->si_drv1 = sc; if ( tws_init(sc) == FAILURE ) { tws_log(sc, TWS_INIT_FAILURE); goto attach_fail_4; } if ( tws_init_ctlr(sc) == FAILURE ) { tws_log(sc, TWS_CTLR_INIT_FAILURE); goto attach_fail_4; } if ((error = tws_cam_attach(sc))) { tws_log(sc, TWS_CAM_ATTACH); goto attach_fail_4; } /* send init complete event */ lockmgr(&sc->gen_lock, LK_EXCLUSIVE); tws_send_event(sc, TWS_INIT_COMPLETE); lockmgr(&sc->gen_lock, LK_RELEASE); TWS_TRACE_DEBUG(sc, "attached successfully", 0, sc->device_id); return(0); attach_fail_4: for(i=0;i<sc->irqs;i++) { if (sc->intr_handle[i]) { if ((error = bus_teardown_intr(sc->tws_dev, sc->irq_res[i], sc->intr_handle[i]))) TWS_TRACE(sc, "bus teardown intr", 0, error); } } destroy_dev(sc->tws_cdev); dev_ops_remove_minor(&tws_ops, device_get_unit(sc->tws_dev)); attach_fail_3: for(i=0;i<sc->irqs;i++) { if ( sc->irq_res[i] ){ if (bus_release_resource(sc->tws_dev, SYS_RES_IRQ, sc->irq_res_id[i], sc->irq_res[i])) TWS_TRACE(sc, "bus irq res", 0, 0); } } #ifndef TWS_PULL_MODE_ENABLE attach_fail_2: #endif if ( sc->mfa_res ){ if (bus_release_resource(sc->tws_dev, SYS_RES_MEMORY, sc->mfa_res_id, sc->mfa_res)) TWS_TRACE(sc, "bus release ", 0, sc->mfa_res_id); } if ( sc->reg_res ){ if (bus_release_resource(sc->tws_dev, SYS_RES_MEMORY, sc->reg_res_id, sc->reg_res)) TWS_TRACE(sc, "bus release2 ", 0, sc->reg_res_id); } attach_fail_1: lockuninit(&sc->q_lock); lockuninit(&sc->sim_lock); lockuninit(&sc->gen_lock); lockuninit(&sc->io_lock); sysctl_ctx_free(&sc->tws_clist); return (ENXIO); }
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); }