Ejemplo n.º 1
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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);
}
Ejemplo n.º 5
0
/* 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);
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
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);
}
Ejemplo n.º 10
0
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;
}