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 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; }
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; }
static void fuse_bringdown(eventhandler_tag eh_tag) { EVENTHANDLER_DEREGISTER(dev_clone, eh_tag); fuse_ipc_destroy(); clone_cleanup(&fuseclones); mtx_destroy(&fuse_mtx); }
/* 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 VBoxDrvFreeBSDLoad(void) { g_cUsers = 0; /* * Initialize the runtime. */ int rc = RTR0Init(0); if (RT_SUCCESS(rc)) { Log(("VBoxDrvFreeBSDLoad:\n")); /* * Initialize the device extension. */ rc = supdrvInitDevExt(&g_VBoxDrvFreeBSDDevExt, sizeof(SUPDRVSESSION)); if (RT_SUCCESS(rc)) { /* * Configure device cloning. */ clone_setup(&g_pVBoxDrvFreeBSDClones); g_VBoxDrvFreeBSDEHTag = EVENTHANDLER_REGISTER(dev_clone, VBoxDrvFreeBSDClone, 0, 1000); if (g_VBoxDrvFreeBSDEHTag) { Log(("VBoxDrvFreeBSDLoad: returns successfully\n")); return VINF_SUCCESS; } printf("vboxdrv: EVENTHANDLER_REGISTER(dev_clone,,,) failed\n"); clone_cleanup(&g_pVBoxDrvFreeBSDClones); rc = VERR_ALREADY_LOADED; supdrvDeleteDevExt(&g_VBoxDrvFreeBSDDevExt); } else printf("vboxdrv: supdrvInitDevExt failed, rc=%d\n", rc); RTR0Term(); } else printf("vboxdrv: RTR0Init failed, rc=%d\n", rc); return rc; }
static int fuse_loader(struct module *m, int what, void *arg) { static eventhandler_tag eh_tag = NULL; int err = 0; switch (what) { case MOD_LOAD: /* kldload */ fuse_pbuf_freecnt = nswbuf / 2 + 1; clone_setup(&fuseclones); mtx_init(&fuse_mtx, "fuse_mtx", NULL, MTX_DEF); eh_tag = EVENTHANDLER_REGISTER(dev_clone, fuse_device_clone, 0, 1000); if (eh_tag == NULL) { clone_cleanup(&fuseclones); mtx_destroy(&fuse_mtx); return (ENOMEM); } fuse_ipc_init(); /* vfs_modevent ignores its first arg */ if ((err = vfs_modevent(NULL, what, &fuse_vfsconf))) fuse_bringdown(eh_tag); else printf("fuse-freebsd: version %s, FUSE ABI %d.%d\n", FUSE_FREEBSD_VERSION, FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION); break; case MOD_UNLOAD: if ((err = vfs_modevent(NULL, what, &fuse_vfsconf))) return (err); fuse_bringdown(eh_tag); break; default: return (EINVAL); } return (err); }
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 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); }
static int vgdrvFreeBSDAttach(device_t pDevice) { int rc; int iResId; struct VBoxGuestDeviceState *pState; cUsers = 0; /* * Initialize IPRT R0 driver, which internally calls OS-specific r0 init. */ rc = RTR0Init(0); if (RT_FAILURE(rc)) { LogFunc(("RTR0Init failed.\n")); return ENXIO; } pState = device_get_softc(pDevice); /* * Allocate I/O port resource. */ iResId = PCIR_BAR(0); pState->pIOPortRes = bus_alloc_resource_any(pDevice, SYS_RES_IOPORT, &iResId, RF_ACTIVE); pState->uIOPortBase = rman_get_start(pState->pIOPortRes); pState->iIOPortResId = iResId; if (pState->uIOPortBase) { /* * Map the MMIO region. */ iResId = PCIR_BAR(1); pState->pVMMDevMemRes = bus_alloc_resource_any(pDevice, SYS_RES_MEMORY, &iResId, RF_ACTIVE); pState->VMMDevMemHandle = rman_get_bushandle(pState->pVMMDevMemRes); pState->VMMDevMemSize = rman_get_size(pState->pVMMDevMemRes); pState->pMMIOBase = rman_get_virtual(pState->pVMMDevMemRes); pState->iVMMDevMemResId = iResId; if (pState->pMMIOBase) { /* * Call the common device extension initializer. */ rc = VGDrvCommonInitDevExt(&g_DevExt, pState->uIOPortBase, pState->pMMIOBase, pState->VMMDevMemSize, #if ARCH_BITS == 64 VBOXOSTYPE_FreeBSD_x64, #else VBOXOSTYPE_FreeBSD, #endif VMMDEV_EVENT_MOUSE_POSITION_CHANGED); if (RT_SUCCESS(rc)) { /* * Add IRQ of VMMDev. */ rc = vgdrvFreeBSDAddIRQ(pDevice, pState); if (RT_SUCCESS(rc)) { /* * Read host configuration. */ VGDrvCommonProcessOptionsFromHost(&g_DevExt); /* * Configure device cloning. */ clone_setup(&g_pvgdrvFreeBSDClones); g_vgdrvFreeBSDEHTag = EVENTHANDLER_REGISTER(dev_clone, vgdrvFreeBSDClone, 0, 1000); if (g_vgdrvFreeBSDEHTag) { printf(DEVICE_NAME ": loaded successfully\n"); return 0; } printf(DEVICE_NAME ": EVENTHANDLER_REGISTER(dev_clone,,,) failed\n"); clone_cleanup(&g_pvgdrvFreeBSDClones); vgdrvFreeBSDRemoveIRQ(pDevice, pState); } else printf((DEVICE_NAME ": VGDrvCommonInitDevExt failed.\n")); VGDrvCommonDeleteDevExt(&g_DevExt); } else printf((DEVICE_NAME ": vgdrvFreeBSDAddIRQ failed.\n")); } else printf((DEVICE_NAME ": MMIO region setup failed.\n")); } else printf((DEVICE_NAME ": IOport setup failed.\n")); RTR0Term(); return ENXIO; }