static int linux_common_modevent(module_t mod, int type, void *data) { struct linux_device_handler **ldhp; switch(type) { case MOD_LOAD: linux_osd_jail_register(); linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit, NULL, 1000); linux_exec_tag = EVENTHANDLER_REGISTER(process_exec, linux_proc_exec, NULL, 1000); linux_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor, linux_thread_dtor, NULL, EVENTHANDLER_PRI_ANY); SET_FOREACH(ldhp, linux_device_handler_set) linux_device_register_handler(*ldhp); break; case MOD_UNLOAD: linux_osd_jail_deregister(); SET_FOREACH(ldhp, linux_device_handler_set) linux_device_unregister_handler(*ldhp); EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag); EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag); EVENTHANDLER_DEREGISTER(thread_dtor, linux_thread_dtor_tag); break; default: return (EOPNOTSUPP); } return (0); }
static int nsmb_dev_load(module_t mod, int cmd, void *arg) { int error = 0; switch (cmd) { case MOD_LOAD: error = smb_sm_init(); if (error) break; error = smb_iod_init(); if (error) { smb_sm_done(); break; } clone_setup(&nsmb_clones); nsmb_dev_tag = EVENTHANDLER_REGISTER(dev_clone, nsmb_dev_clone, 0, 1000); break; case MOD_UNLOAD: smb_iod_done(); error = smb_sm_done(); if (error) break; EVENTHANDLER_DEREGISTER(dev_clone, nsmb_dev_tag); drain_dev_clone_events(); clone_cleanup(&nsmb_clones); destroy_dev_drain(&nsmb_cdevsw); break; default: error = EINVAL; break; } return error; }
/* * Module handling */ static int nmdm_modevent(module_t mod, int type, void *data) { static eventhandler_tag tag; switch(type) { case MOD_LOAD: tag = EVENTHANDLER_REGISTER(dev_clone, nmdm_clone, 0, 1000); if (tag == NULL) return (ENOMEM); break; case MOD_SHUTDOWN: break; case MOD_UNLOAD: if (nmdm_count != 0) return (EBUSY); EVENTHANDLER_DEREGISTER(dev_clone, tag); break; default: return (EOPNOTSUPP); } return (0); }
static int tunmodevent(module_t mod, int type, void *data) { static eventhandler_tag tag; struct tun_softc *tp; switch (type) { case MOD_LOAD: mtx_init(&tunmtx, "tunmtx", NULL, MTX_DEF); clone_setup(&tunclones); tag = EVENTHANDLER_REGISTER(dev_clone, tunclone, 0, 1000); if (tag == NULL) return (ENOMEM); break; case MOD_UNLOAD: EVENTHANDLER_DEREGISTER(dev_clone, tag); mtx_lock(&tunmtx); while ((tp = TAILQ_FIRST(&tunhead)) != NULL) { TAILQ_REMOVE(&tunhead, tp, tun_list); mtx_unlock(&tunmtx); tun_destroy(tp); mtx_lock(&tunmtx); } mtx_unlock(&tunmtx); clone_cleanup(&tunclones); mtx_destroy(&tunmtx); break; default: return EOPNOTSUPP; } return 0; }
void ipfw3_log_modevent(int type){ struct ifnet *tmpif; int i; switch (type) { case MOD_LOAD: LOGIF_LOCK_INIT(); log_if_count = 0; if_clone_attach(&ipfw_log_cloner); ipfw_log_ifdetach_cookie = EVENTHANDLER_REGISTER(ifnet_detach_event, ipfw_log_clone_destroy, &ipfw_log_cloner, EVENTHANDLER_PRI_ANY); break; case MOD_UNLOAD: EVENTHANDLER_DEREGISTER(ifnet_detach_event, ipfw_log_ifdetach_cookie); if_clone_detach(&ipfw_log_cloner); for(i = 0; log_if_count > 0 && i < LOG_IF_MAX; i++){ tmpif = log_if_table[i]; if (tmpif != NULL) { ipfw_log_clone_destroy(tmpif); } } LOGIF_LOCK_DESTROY(); break; default: break; } }
static int mfi_pci_detach(device_t dev) { struct mfi_softc *sc; int error, devcount, i; device_t *devlist; sc = device_get_softc(dev); sx_xlock(&sc->mfi_config_lock); mtx_lock(&sc->mfi_io_lock); if ((sc->mfi_flags & MFI_FLAGS_OPEN) != 0) { mtx_unlock(&sc->mfi_io_lock); sx_xunlock(&sc->mfi_config_lock); return (EBUSY); } sc->mfi_detaching = 1; mtx_unlock(&sc->mfi_io_lock); if ((error = device_get_children(sc->mfi_dev, &devlist, &devcount)) != 0) { sx_xunlock(&sc->mfi_config_lock); return error; } for (i = 0; i < devcount; i++) device_delete_child(sc->mfi_dev, devlist[i]); free(devlist, M_TEMP); sx_xunlock(&sc->mfi_config_lock); EVENTHANDLER_DEREGISTER(shutdown_final, sc->mfi_eh); mfi_shutdown(sc); mfi_free(sc); mfi_pci_free(sc); return (0); }
static int vgdrvFreeBSDDetach(device_t pDevice) { struct VBoxGuestDeviceState *pState = device_get_softc(pDevice); if (cUsers > 0) return EBUSY; /* * Reverse what we did in vgdrvFreeBSDAttach. */ if (g_vgdrvFreeBSDEHTag != NULL) EVENTHANDLER_DEREGISTER(dev_clone, g_vgdrvFreeBSDEHTag); clone_cleanup(&g_pvgdrvFreeBSDClones); vgdrvFreeBSDRemoveIRQ(pDevice, pState); if (pState->pVMMDevMemRes) bus_release_resource(pDevice, SYS_RES_MEMORY, pState->iVMMDevMemResId, pState->pVMMDevMemRes); if (pState->pIOPortRes) bus_release_resource(pDevice, SYS_RES_IOPORT, pState->iIOPortResId, pState->pIOPortRes); VGDrvCommonDeleteDevExt(&g_DevExt); RTR0Term(); return 0; }
static int ichwd_detach(device_t dev) { struct ichwd_softc *sc; device_t ich = NULL; sc = device_get_softc(dev); /* halt the watchdog timer */ if (sc->active) ichwd_tmr_disable(sc); /* enable the SMI handler */ if (sc->smi_enabled != 0) ichwd_smi_enable(sc); /* deregister event handler */ if (sc->ev_tag != NULL) EVENTHANDLER_DEREGISTER(watchdog_list, sc->ev_tag); sc->ev_tag = NULL; /* reset the watchdog status registers */ ichwd_sts_reset(sc); /* deallocate I/O register space */ bus_release_resource(dev, SYS_RES_IOPORT, sc->tco_rid, sc->tco_res); bus_release_resource(dev, SYS_RES_IOPORT, sc->smi_rid, sc->smi_res); /* deallocate memory resource */ ich = ichwd_find_ich_lpc_bridge(NULL); if (sc->gcs_res && ich) bus_release_resource(ich, SYS_RES_MEMORY, sc->gcs_rid, sc->gcs_res); return (0); }
static int nsmb_dev_load(module_t mod, int cmd, void *arg) { int error = 0; switch (cmd) { case MOD_LOAD: error = smb_sm_init(); if (error) break; error = smb_iod_init(); if (error) { smb_sm_done(); break; } cdevsw_add(&nsmb_cdevsw); nsmb_dev_tag = EVENTHANDLER_REGISTER(dev_clone, nsmb_dev_clone, 0, 1000); printf("netsmb_dev: loaded\n"); break; case MOD_UNLOAD: smb_iod_done(); error = smb_sm_done(); error = 0; EVENTHANDLER_DEREGISTER(dev_clone, nsmb_dev_tag); cdevsw_remove(&nsmb_cdevsw); printf("netsmb_dev: unloaded\n"); break; default: error = EINVAL; break; } return error; }
static int mfi_pci_detach(device_t dev) { struct mfi_softc *sc; struct mfi_disk *ld; int error; sc = device_get_softc(dev); sx_xlock(&sc->mfi_config_lock); mtx_lock(&sc->mfi_io_lock); if ((sc->mfi_flags & MFI_FLAGS_OPEN) != 0) { mtx_unlock(&sc->mfi_io_lock); sx_xunlock(&sc->mfi_config_lock); return (EBUSY); } sc->mfi_detaching = 1; mtx_unlock(&sc->mfi_io_lock); while ((ld = TAILQ_FIRST(&sc->mfi_ld_tqh)) != NULL) { if ((error = device_delete_child(dev, ld->ld_dev)) != 0) { sc->mfi_detaching = 0; sx_xunlock(&sc->mfi_config_lock); return (error); } } sx_xunlock(&sc->mfi_config_lock); EVENTHANDLER_DEREGISTER(shutdown_final, sc->mfi_eh); mfi_shutdown(sc); mfi_free(sc); mfi_pci_free(sc); return (0); }
static void acpi_timer_suspend_handler(struct timecounter *newtc) { struct timecounter *tc; /* Deregister existing resume event handler. */ if (acpi_timer_eh != NULL) { EVENTHANDLER_DEREGISTER(power_resume, acpi_timer_eh); acpi_timer_eh = NULL; } if ((timecounter->tc_flags & TC_FLAGS_SUSPEND_SAFE) != 0) { /* * If we are using a suspend safe timecounter, don't * save/restore it across suspend/resume. */ return; } KASSERT(newtc == &acpi_timer_timecounter, ("acpi_timer_suspend_handler: wrong timecounter")); tc = timecounter; if (tc != newtc) { if (bootverbose) device_printf(acpi_timer_dev, "switching timecounter, %s -> %s\n", tc->tc_name, newtc->tc_name); (void)acpi_timer_read(); (void)acpi_timer_read(); timecounter = newtc; acpi_timer_eh = EVENTHANDLER_REGISTER(power_resume, acpi_timer_resume_handler, tc, EVENTHANDLER_PRI_LAST); } }
static void fuse_bringdown(eventhandler_tag eh_tag) { EVENTHANDLER_DEREGISTER(dev_clone, eh_tag); fuse_ipc_destroy(); clone_cleanup(&fuseclones); mtx_destroy(&fuse_mtx); }
/* * Tear down vnode cache */ void pfs_vncache_unload(void) { mtx_assert(&Giant, MA_OWNED); EVENTHANDLER_DEREGISTER(process_exit, pfs_exit_tag); KASSERT(pfs_vncache_entries == 0, ("%d vncache entries remaining", pfs_vncache_entries)); mtx_destroy(&pfs_vncache_mutex); }
static int canbepm_detach(device_t dev) { struct canbepm_softc *sc = device_get_softc(dev); /* eventhandler deregist */ EVENTHANDLER_DEREGISTER(shutdown_final, sc->canbepm_tag); BUS_CHILD_DETACHED(device_get_parent(dev), dev); return (0); }
/* * * Detach interface event handlers on last VNET instance * detach. */ static void iface_khandler_deregister() { int destroy; destroy = 0; mtx_lock(&vnet_mtx); if (num_vnets == 1) destroy = 1; num_vnets--; mtx_unlock(&vnet_mtx); if (destroy == 0) return; EVENTHANDLER_DEREGISTER(ifnet_arrival_event, ipfw_ifattach_event); EVENTHANDLER_DEREGISTER(ifnet_departure_event, ipfw_ifdetach_event); }
/* * Tear down vnode cache */ void pfs_vncache_unload(void) { EVENTHANDLER_DEREGISTER(process_exit, pfs_exit_tag); mtx_lock(&pfs_vncache_mutex); pfs_purge_locked(NULL, true); mtx_unlock(&pfs_vncache_mutex); KASSERT(pfs_vncache_entries == 0, ("%d vncache entries remaining", pfs_vncache_entries)); mtx_destroy(&pfs_vncache_mutex); }
/* Called from detach */ void sms1xxx_demux_exit(struct sms1xxx_softc *sc) { /* Wake up readers ! */ if(sc->dvr.state & DVR_SLEEP) { wakeup(&sc->dvr); } if(sc->dvr.state & DVR_POLL) { sc->dvr.state &= ~DVR_POLL; selwakeuppri(&sc->dvr.rsel,PZERO); } /* Devices */ if(sc->dvr.dev != NULL) { TRACE(TRACE_MODULE,"destroying dvr0, addr=%p\n",sc->dvr.dev); destroy_dev(sc->dvr.dev); sc->dvr.dev = NULL; } if(sc->clonetag != NULL) { EVENTHANDLER_DEREGISTER(dev_clone,sc->clonetag); sc->clonetag = NULL; } /* Destroy remaining clones */ for(int i = 0; i < MAX_FILTERS; ++i) { if((sc->filter[i].pid != PIDFREE) && (sc->filter[i].dev != NULL)) { TRACE(TRACE_MODULE,"destroying demux0.%d device, addr=%p\n", i,sc->filter[i].dev); destroy_dev_sched_cb(sc->filter[i].dev, sms1xxx_demux_filter_reset, &sc->filter[i]); } } if(sc->demux_clones != NULL) { drain_dev_clone_events(); clone_cleanup(&sc->demux_clones); destroy_dev_drain(&sms1xxx_demux_cdevsw); sc->demux_clones = NULL; } /* DVR */ sc->dvr.state = 0; sms1xxx_demux_pesbuf_reset(sc, 0, "exit"); if(sc->dvr.buf != NULL) { free(sc->dvr.buf, M_USBDEV); sc->dvr.buf = NULL; } /* Mutexes */ mtx_destroy(&sc->filterlock); mtx_destroy(&sc->dvr.lock); }
static int cdce_driver_loaded(struct module *mod, int what, void *arg) { switch (what) { case MOD_LOAD: /* register our autoinstall handler */ cdce_etag = EVENTHANDLER_REGISTER(usb_dev_configured, cdce_test_autoinst, NULL, EVENTHANDLER_PRI_ANY); return (0); case MOD_UNLOAD: EVENTHANDLER_DEREGISTER(usb_dev_configured, cdce_etag); return (0); default: return (EOPNOTSUPP); } }
static int pmc_isa_detach(device_t dev) { struct pmc_isa_softc *sc = device_get_softc(dev); if (bootverbose) { device_printf(dev, "pmc_isa_detach called\n"); } if (sc->evt != NULL) { EVENTHANDLER_DEREGISTER(shutdown_final, sc->evt); } sc->evt = NULL; pmc_isa_release_resources(dev); return 0; }
/* * The function called at load/unload. */ static int fsyscall_modevent(struct module *_, int cmd, void *__) { int error = 0; switch (cmd) { case MOD_LOAD : fsyscall_exit_tag = EVENTHANDLER_REGISTER(process_exit, process_exit, NULL, EVENTHANDLER_PRI_ANY); break; case MOD_UNLOAD : EVENTHANDLER_DEREGISTER(process_exit, fsyscall_exit_tag); break; default : error = EOPNOTSUPP; break; } return (error); }
static int ti_wdt_detach(device_t dev) { struct ti_wdt_softc *sc; sc = device_get_softc(dev); if (sc->sc_ev_tag) EVENTHANDLER_DEREGISTER(watchdog_list, sc->sc_ev_tag); if (sc->sc_intr) bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intr); if (sc->sc_irq_res) bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->sc_irq_res), sc->sc_irq_res); if (sc->sc_mem_res) bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(sc->sc_mem_res), sc->sc_mem_res); return (0); }
static int acpi_panasonic_detach(device_t dev) { struct acpi_panasonic_softc *sc; sc = device_get_softc(dev); /* Remove power profile event handler */ EVENTHANDLER_DEREGISTER(power_profile_change, sc->power_evh); /* Remove notify handler */ AcpiRemoveNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY, acpi_panasonic_notify); /* Free sysctl tree */ sysctl_ctx_free(&sc->sysctl_ctx); return (0); }
static int uhso_driver_loaded(struct module *mod, int what, void *arg) { switch (what) { case MOD_LOAD: /* register our autoinstall handler */ uhso_etag = EVENTHANDLER_REGISTER(usb_dev_configured, uhso_test_autoinst, NULL, EVENTHANDLER_PRI_ANY); /* create our unit allocator for inet devs */ uhso_ifnet_unit = new_unrhdr(0, INT_MAX, NULL); break; case MOD_UNLOAD: EVENTHANDLER_DEREGISTER(usb_dev_configured, uhso_etag); delete_unrhdr(uhso_ifnet_unit); break; default: return (EOPNOTSUPP); } return (0); }
/* * Disconnect ourselves from the system. */ static int mpt_pci_detach(device_t dev) { struct mpt_softc *mpt; mpt = (struct mpt_softc*)device_get_softc(dev); if (mpt) { mpt_disable_ints(mpt); mpt_detach(mpt); mpt_reset(mpt, /*reinit*/FALSE); mpt_dma_mem_free(mpt); mpt_free_bus_resources(mpt); mpt_raid_free_mem(mpt); if (mpt->eh != NULL) { EVENTHANDLER_DEREGISTER(shutdown_post_sync, mpt->eh); } } return(0); }
static int alq_load_handler(module_t mod, int what, void *arg) { int ret; ret = 0; switch (what) { case MOD_LOAD: case MOD_SHUTDOWN: break; case MOD_QUIESCE: ALD_LOCK(); /* Only allow unload if there are no open queues. */ if (BSD_LIST_FIRST(&ald_queues) == NULL) { ald_shutingdown = 1; ALD_UNLOCK(); EVENTHANDLER_DEREGISTER(shutdown_pre_sync, alq_eventhandler_tag); ald_shutdown(NULL, 0); mtx_destroy(&ald_mtx); } else { ALD_UNLOCK(); ret = EBUSY; } break; case MOD_UNLOAD: /* If MOD_QUIESCE failed we must fail here too. */ if (ald_shutingdown == 0) ret = EBUSY; break; default: ret = EINVAL; break; } return (ret); }
static int dcons_crom_detach(device_t dev) { struct dcons_crom_softc *sc; sc = (struct dcons_crom_softc *) device_get_softc(dev); sc->fd.post_busreset = NULL; if (sc->ehand) EVENTHANDLER_DEREGISTER(dcons_poll, sc->ehand); /* XXX */ if (dcons_conf->dma_tag == sc->dma_tag) dcons_conf->dma_tag = NULL; bus_dmamap_unload(sc->dma_tag, sc->dma_map); bus_dmamap_destroy(sc->dma_tag, sc->dma_map); bus_dma_tag_destroy(sc->dma_tag); return 0; }
static int amdsbwd_detach(device_t dev) { struct amdsbwd_softc *sc; sc = device_get_softc(dev); if (sc->ev_tag != NULL) EVENTHANDLER_DEREGISTER(watchdog_list, sc->ev_tag); if (sc->active) amdsbwd_tmr_disable(sc); if (sc->res_ctrl != NULL) bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_ctrl, sc->res_ctrl); if (sc->res_count != NULL) bus_release_resource(dev, SYS_RES_MEMORY, sc->rid_count, sc->res_count); return (0); }
static int VBoxDrvFreeBSDUnload(void) { Log(("VBoxDrvFreeBSDUnload:\n")); if (g_cUsers > 0) return EBUSY; /* * Reserve what we did in VBoxDrvFreeBSDInit. */ EVENTHANDLER_DEREGISTER(dev_clone, g_VBoxDrvFreeBSDEHTag); clone_cleanup(&g_pVBoxDrvFreeBSDClones); supdrvDeleteDevExt(&g_VBoxDrvFreeBSDDevExt); RTR0Term(); memset(&g_VBoxDrvFreeBSDDevExt, 0, sizeof(g_VBoxDrvFreeBSDDevExt)); Log(("VBoxDrvFreeBSDUnload: returns\n")); return VINF_SUCCESS; }
static int ixl_detach(device_t dev) { struct ixl_pf *pf = device_get_softc(dev); struct i40e_hw *hw = &pf->hw; struct ixl_vsi *vsi = &pf->vsi; enum i40e_status_code status; #if defined(PCI_IOV) || defined(IXL_IW) int error; #endif INIT_DEBUGOUT("ixl_detach: begin"); /* Make sure VLANS are not using driver */ if (vsi->ifp->if_vlantrunk != NULL) { device_printf(dev, "Vlan in use, detach first\n"); return (EBUSY); } #ifdef PCI_IOV error = pci_iov_detach(dev); if (error != 0) { device_printf(dev, "SR-IOV in use; detach first.\n"); return (error); } #endif /* Remove all previously allocated media types */ ifmedia_removeall(&vsi->media); ether_ifdetach(vsi->ifp); if (vsi->ifp->if_drv_flags & IFF_DRV_RUNNING) ixl_stop(pf); /* Shutdown LAN HMC */ status = i40e_shutdown_lan_hmc(hw); if (status) device_printf(dev, "Shutdown LAN HMC failed with code %d\n", status); /* Teardown LAN queue resources */ ixl_teardown_queue_msix(vsi); ixl_free_queue_tqs(vsi); /* Shutdown admin queue */ ixl_disable_intr0(hw); ixl_teardown_adminq_msix(pf); ixl_free_adminq_tq(pf); status = i40e_shutdown_adminq(hw); if (status) device_printf(dev, "Shutdown Admin queue failed with code %d\n", status); /* Unregister VLAN events */ if (vsi->vlan_attach != NULL) EVENTHANDLER_DEREGISTER(vlan_config, vsi->vlan_attach); if (vsi->vlan_detach != NULL) EVENTHANDLER_DEREGISTER(vlan_unconfig, vsi->vlan_detach); callout_drain(&pf->timer); #ifdef IXL_IW if (ixl_enable_iwarp && pf->iw_enabled) { error = ixl_iw_pf_detach(pf); if (error == EBUSY) { device_printf(dev, "iwarp in use; stop it first.\n"); return (error); } } #endif #ifdef DEV_NETMAP netmap_detach(vsi->ifp); #endif /* DEV_NETMAP */ ixl_pf_qmgr_destroy(&pf->qmgr); ixl_free_pci_resources(pf); bus_generic_detach(dev); if_free(vsi->ifp); ixl_free_vsi(vsi); IXL_PF_LOCK_DESTROY(pf); return (0); }
static int dtrace_unload() { dtrace_state_t *state; int error = 0; #if __FreeBSD_version < 800039 /* * Check if there is still an event handler callback * registered. */ if (eh_tag != 0) { /* De-register the device cloning event handler. */ EVENTHANDLER_DEREGISTER(dev_clone, eh_tag); eh_tag = 0; /* Stop device cloning. */ clone_cleanup(&dtrace_clones); } #else destroy_dev(dtrace_dev); destroy_dev(helper_dev); #endif mutex_enter(&dtrace_provider_lock); mutex_enter(&dtrace_lock); mutex_enter(&cpu_lock); ASSERT(dtrace_opens == 0); if (dtrace_helpers > 0) { mutex_exit(&cpu_lock); mutex_exit(&dtrace_lock); mutex_exit(&dtrace_provider_lock); return (EBUSY); } if (dtrace_unregister((dtrace_provider_id_t)dtrace_provider) != 0) { mutex_exit(&cpu_lock); mutex_exit(&dtrace_lock); mutex_exit(&dtrace_provider_lock); return (EBUSY); } dtrace_provider = NULL; if ((state = dtrace_anon_grab()) != NULL) { /* * If there were ECBs on this state, the provider should * have not been allowed to detach; assert that there is * none. */ ASSERT(state->dts_necbs == 0); dtrace_state_destroy(state); } bzero(&dtrace_anon, sizeof (dtrace_anon_t)); mutex_exit(&cpu_lock); if (dtrace_helptrace_enabled) { kmem_free(dtrace_helptrace_buffer, 0); dtrace_helptrace_buffer = NULL; } if (dtrace_probes != NULL) { kmem_free(dtrace_probes, 0); dtrace_probes = NULL; dtrace_nprobes = 0; } dtrace_hash_destroy(dtrace_bymod); dtrace_hash_destroy(dtrace_byfunc); dtrace_hash_destroy(dtrace_byname); dtrace_bymod = NULL; dtrace_byfunc = NULL; dtrace_byname = NULL; kmem_cache_destroy(dtrace_state_cache); delete_unrhdr(dtrace_arena); if (dtrace_toxrange != NULL) { kmem_free(dtrace_toxrange, 0); dtrace_toxrange = NULL; dtrace_toxranges = 0; dtrace_toxranges_max = 0; } ASSERT(dtrace_vtime_references == 0); ASSERT(dtrace_opens == 0); ASSERT(dtrace_retained == NULL); mutex_exit(&dtrace_lock); mutex_exit(&dtrace_provider_lock); mutex_destroy(&dtrace_meta_lock); mutex_destroy(&dtrace_provider_lock); mutex_destroy(&dtrace_lock); mutex_destroy(&dtrace_errlock); /* XXX Hack */ mutex_destroy(&mod_lock); /* Reset our hook for exceptions. */ dtrace_invop_uninit(); /* * Reset our hook for thread switches, but ensure that vtime isn't * active first. */ dtrace_vtime_active = 0; dtrace_vtime_switch_func = NULL; /* Unhook from the trap handler. */ dtrace_trap_func = NULL; return (error); }