예제 #1
0
/* Create single-use devices for /dev/apm and /dev/apmctl. */
static void
apm_clone(void *arg, struct ucred *cred, char *name, int namelen,
    struct cdev **dev)
{
	int ctl_dev, unit;

	if (*dev != NULL)
		return;
	if (strcmp(name, "apmctl") == 0)
		ctl_dev = TRUE;
	else if (strcmp(name, "apm") == 0)
		ctl_dev = FALSE;
	else
		return;

	/* Always create a new device and unit number. */
	unit = -1;
	if (clone_create(&apm_clones, &apm_cdevsw, &unit, dev, 0)) {
		if (ctl_dev) {
			*dev = make_dev(&apm_cdevsw, unit,
			    UID_ROOT, GID_OPERATOR, 0660, "apmctl%d", unit);
		} else {
			*dev = make_dev(&apm_cdevsw, unit,
			    UID_ROOT, GID_OPERATOR, 0664, "apm%d", unit);
		}
		if (*dev != NULL) {
			dev_ref(*dev);
			(*dev)->si_flags |= SI_CHEAPCLONE;
		}
	}
}
예제 #2
0
파일: if_tun.c 프로젝트: MarginC/kame
static void
tunclone(void *arg, char *name, int namelen, struct cdev **dev)
{
	int u, i;

	if (*dev != NULL)
		return;

	if (strcmp(name, TUNNAME) == 0) {
		u = -1;
	} else if (dev_stdclone(name, NULL, TUNNAME, &u) != 1)
		return;	/* Don't recognise the name */
	if (u != -1 && u > IF_MAXUNIT)
		return;	/* Unit number too high */

	/* find any existing device, or allocate new unit number */
	i = clone_create(&tunclones, &tun_cdevsw, &u, dev, 0);
	if (i) {
		/* No preexisting struct cdev *, create one */
		*dev = make_dev(&tun_cdevsw, unit2minor(u),
		    UID_UUCP, GID_DIALER, 0600, "tun%d", u);
		if (*dev != NULL)
			(*dev)->si_flags |= SI_CHEAPCLONE;
	}
}
예제 #3
0
static void
dtrace_clone(void *arg, struct ucred *cred, char *name, int namelen, struct cdev **dev)
{
	int u = -1;
	size_t len;

	if (*dev != NULL)
		return;

	len = strlen(name);

	if (len != 6 && len != 13)
		return;

	if (bcmp(name,"dtrace",6) != 0)
		return;

	if (len == 13 && bcmp(name,"dtrace/dtrace",13) != 0)
		return;

	/* Clone the device to the new minor number. */
	if (clone_create(&dtrace_clones, &dtrace_cdevsw, &u, dev, 0) != 0)
		/* Create the /dev/dtrace/dtraceNN entry. */
		*dev = make_dev_cred(&dtrace_cdevsw, u, cred,
		     UID_ROOT, GID_WHEEL, 0600, "dtrace/dtrace%d", u);
	if (*dev != NULL) {
		dev_ref(*dev);
		(*dev)->si_flags |= SI_CHEAPCLONE;
	}
}
예제 #4
0
static void
sms1xxx_demux_clone(void *arg, struct ucred *cred, char *name,
    int namelen, struct cdev **dev)
{
    char buf[40];
    int filtnr = 0;
    int unit;
    struct sms1xxx_softc *sc = arg;

    TRACE(TRACE_OPEN,"name=%s\n",name);

    if (*dev != NULL || sc == NULL)
        return;

    snprintf(buf,39,"dvb/adapter%d/demux0",device_get_unit(sc->sc_dev));
    if(strcmp(name,buf) != 0)
        return;

    for(filtnr = 0; filtnr < MAX_FILTERS; ++filtnr) {
        if(sc->filter[filtnr].pid == PIDFREE)
            break;
    }

    if(filtnr >= MAX_FILTERS) {
        ERR("no more filter free\n");
        return;
    }

    if(sc->filter[filtnr].dev != NULL) {
        ERR("filter %d not free\n", filtnr);
        return;
    }

    /* Clones are shared among devices, so handle unit numbers
       manually by reserving a range of MAX_FILTERS units per-device
       (clone_create will fail setting unit number automatically :
       unit number assignment is done by crawling sc's (only) clones
       and will not detect clones created for other devices, resulting
       in trying to set twice the same unit number). */
    unit = device_get_unit(sc->sc_dev) * MAX_FILTERS + filtnr;

    if(clone_create(&sc->demux_clones, &sms1xxx_demux_cdevsw, &unit, dev, 0)) {
        *dev = make_dev_credf(MAKEDEV_REF, &sms1xxx_demux_cdevsw,
            unit, NULL, UID_ROOT, GID_WHEEL,
            0666, "dvb/adapter%d/demux0.%d",
            device_get_unit(sc->sc_dev), filtnr);
        if(*dev != NULL) {
            TRACE(TRACE_MODULE,"created demux0.%d device, addr=%p\n",
                filtnr, *dev);
            (*dev)->si_flags |= SI_CHEAPCLONE;
            (*dev)->si_drv1 = sc;
            (*dev)->si_drv2 = &sc->filter[filtnr];  /* map filter to device */
            sc->filter[filtnr].dev = *dev;          /* map device to filter */
            sc->filter[filtnr].pid = PIDCLONED;
        }
    }
}
예제 #5
0
/**
 * DEVFS event handler.
 */
static void vgdrvFreeBSDClone(void *pvArg, struct ucred *pCred, char *pszName, int cchName, struct cdev **ppDev)
{
    int iUnit;
    int rc;

    Log(("vgdrvFreeBSDClone: pszName=%s ppDev=%p\n", pszName, ppDev));

    /*
     * One device node per user, si_drv1 points to the session.
     * /dev/vboxguest<N> where N = {0...255}.
     */
    if (!ppDev)
        return;
    if (strcmp(pszName, "vboxguest") == 0)
        iUnit =  -1;
    else if (dev_stdclone(pszName, NULL, "vboxguest", &iUnit) != 1)
        return;
    if (iUnit >= 256)
    {
        Log(("vgdrvFreeBSDClone: iUnit=%d >= 256 - rejected\n", iUnit));
        return;
    }

    Log(("vgdrvFreeBSDClone: pszName=%s iUnit=%d\n", pszName, iUnit));

    rc = clone_create(&g_pvgdrvFreeBSDClones, &g_vgdrvFreeBSDChrDevSW, &iUnit, ppDev, 0);
    Log(("vgdrvFreeBSDClone: clone_create -> %d; iUnit=%d\n", rc, iUnit));
    if (rc)
    {
        *ppDev = make_dev(&g_vgdrvFreeBSDChrDevSW,
                          iUnit,
                          UID_ROOT,
                          GID_WHEEL,
                          0664,
                          "vboxguest%d", iUnit);
        if (*ppDev)
        {
            dev_ref(*ppDev);
            (*ppDev)->si_flags |= SI_CHEAPCLONE;
            Log(("vgdrvFreeBSDClone: Created *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n",
                     *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2));
            (*ppDev)->si_drv1 = (*ppDev)->si_drv2 = NULL;
        }
        else
            Log(("vgdrvFreeBSDClone: make_dev iUnit=%d failed\n", iUnit));
    }
    else
        Log(("vgdrvFreeBSDClone: Existing *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n",
             *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2));
}
예제 #6
0
/**
 * DEVFS event handler.
 */
static void VBoxDrvFreeBSDClone(void *pvArg, struct ucred *pCred, char *pszName, int cchName, struct cdev **ppDev)
{
    int iUnit;
    int rc;

    Log(("VBoxDrvFreeBSDClone: pszName=%s ppDev=%p\n", pszName, ppDev));

    /*
     * One device node per user, si_drv1 points to the session.
     * /dev/vboxdrv<N> where N = {0...255}.
     */
    if (!ppDev)
        return;
    if (dev_stdclone(pszName, NULL, "vboxdrv", &iUnit) != 1)
        return;
    if (iUnit >= 256 || iUnit < 0)
    {
        Log(("VBoxDrvFreeBSDClone: iUnit=%d >= 256 - rejected\n", iUnit));
        return;
    }

    Log(("VBoxDrvFreeBSDClone: pszName=%s iUnit=%d\n", pszName, iUnit));

    rc = clone_create(&g_pVBoxDrvFreeBSDClones, &g_VBoxDrvFreeBSDChrDevSW, &iUnit, ppDev, 0);
    Log(("VBoxDrvFreeBSDClone: clone_create -> %d; iUnit=%d\n", rc, iUnit));
    if (rc)
    {
#if __FreeBSD_version > 800061
        *ppDev = make_dev(&g_VBoxDrvFreeBSDChrDevSW, iUnit, UID_ROOT, GID_WHEEL, VBOXDRV_PERM, "vboxdrv%d", iUnit);
#else
        *ppDev = make_dev(&g_VBoxDrvFreeBSDChrDevSW, unit2minor(iUnit), UID_ROOT, GID_WHEEL, VBOXDRV_PERM, "vboxdrv%d", iUnit);
#endif
        if (*ppDev)
        {
            dev_ref(*ppDev);
            (*ppDev)->si_flags |= SI_CHEAPCLONE;
            Log(("VBoxDrvFreeBSDClone: Created *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n",
                 *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2));
            (*ppDev)->si_drv1 = (*ppDev)->si_drv2 = NULL;
        }
        else
            OSDBGPRINT(("VBoxDrvFreeBSDClone: make_dev iUnit=%d failed\n", iUnit));
    }
    else
        Log(("VBoxDrvFreeBSDClone: Existing *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n",
             *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2));
}
예제 #7
0
static void
nsmb_dev_clone(void *arg, struct ucred *cred, char *name, int namelen,
    struct cdev **dev)
{
	int i, u;

	if (*dev != NULL)
		return;

	if (strcmp(name, NSMB_NAME) == 0)
		u = -1;
	else if (dev_stdclone(name, NULL, NSMB_NAME, &u) != 1)
		return;
	i = clone_create(&nsmb_clones, &nsmb_cdevsw, &u, dev, 0);
	if (i)
		*dev = make_dev_credf(MAKEDEV_REF, &nsmb_cdevsw, u, cred,
		    UID_ROOT, GID_WHEEL, 0600, "%s%d", NSMB_NAME, u);
}
예제 #8
0
static void
nsmb_dev_clone(void *arg, struct ucred *cred, char *name, int namelen,
    struct cdev **dev)
{
	int i, u;

	if (*dev != NULL)
		return;

	if (strcmp(name, NSMB_NAME) == 0)
		u = -1;
	else if (dev_stdclone(name, NULL, NSMB_NAME, &u) != 1)
		return;
	i = clone_create(&nsmb_clones, &nsmb_cdevsw, &u, dev, 0);
	if (i) {
		*dev = make_dev(&nsmb_cdevsw, u, UID_ROOT, GID_WHEEL, 0600,
		    "%s%d", NSMB_NAME, u);
		if (*dev != NULL) {
			dev_ref(*dev);
			(*dev)->si_flags |= SI_CHEAPCLONE;
		}
	}
}