diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/nmdm/nmdm.c | 169 | ||||
-rw-r--r-- | sys/dev/snp/snp.c | 30 |
2 files changed, 97 insertions, 102 deletions
diff --git a/sys/dev/nmdm/nmdm.c b/sys/dev/nmdm/nmdm.c index 3227b11..f3440dd 100644 --- a/sys/dev/nmdm/nmdm.c +++ b/sys/dev/nmdm/nmdm.c @@ -63,8 +63,7 @@ MALLOC_DEFINE(M_NLMDM, "nullmodem", "nullmodem data structures"); static void nmdmstart(struct tty *tp); static void nmdmstop(struct tty *tp, int rw); static void wakeup_other(struct tty *tp, int flag); -static void nmdminit(int); -static int nmdmshutdown(void); +static void nmdminit(dev_t dev); static d_open_t nmdmopen; static d_close_t nmdmclose; @@ -72,7 +71,6 @@ static d_read_t nmdmread; static d_write_t nmdmwrite; static d_ioctl_t nmdmioctl; -#define CDEV_MAJOR 18 static struct cdevsw nmdm_cdevsw = { .d_open = nmdmopen, .d_close = nmdmclose, @@ -80,14 +78,14 @@ static struct cdevsw nmdm_cdevsw = { .d_write = nmdmwrite, .d_ioctl = nmdmioctl, .d_poll = ttypoll, - .d_name = "pts", - .d_maj = CDEV_MAJOR, - .d_flags = D_TTY, + .d_name = "nmdm", + .d_flags = D_TTY | D_PSEUDO, }; #define BUFSIZ 100 /* Chunk size iomoved to/from user */ #define NMDM_MAX_NUM 128 /* Artificially limit # devices. */ #define PF_STOPPED 0x10 /* user told stopped */ +#define BFLAG CLONE_FLAG0 struct softpart { struct tty nm_tty; @@ -97,11 +95,61 @@ struct softpart { }; struct nm_softc { - int pt_flags; - struct softpart part1, part2; - struct prison *pt_prison; + TAILQ_ENTRY(nm_softc) pt_list; + int pt_flags; + struct softpart part1, part2; + struct prison *pt_prison; }; +static struct clonedevs *nmdmclones; +static TAILQ_HEAD(,nm_softc) nmdmhead = TAILQ_HEAD_INITIALIZER(nmdmhead); + +static void +nmdm_clone(void *arg, char *name, int nameen, dev_t *dev) +{ + int i, unit; + char *p; + dev_t d1, d2; + + if (*dev != NODEV) + return; + if (strcmp(name, "nmdm") == 0) { + p = NULL; + unit = -1; + } else { + i = dev_stdclone(name, &p, "nmdm", &unit); + if (i == 0) + return; + if (p[0] != '\0' && p[0] != 'A' && p[0] != 'B') + return; + else if (p[0] != '\0' && p[1] != '\0') + return; + } + i = clone_create(&nmdmclones, &nmdm_cdevsw, &unit, &d1, 0); + if (i) { + d1 = make_dev(&nmdm_cdevsw, unit2minor(unit), + 0, 0, 0666, "nmdm%dA", unit); + if (d1 == NULL) + return; + d2 = make_dev(&nmdm_cdevsw, unit2minor(unit) | BFLAG, + 0, 0, 0666, "nmdm%dB", unit); + if (d2 == NULL) { + destroy_dev(d1); + return; + } + d2->si_drv2 = d1; + d1->si_drv2 = d2; + dev_depends(d1, d2); + dev_depends(d2, d1); + d1->si_flags |= SI_CHEAPCLONE; + d2->si_flags |= SI_CHEAPCLONE; + } + if (p != NULL && p[0] == 'B') + *dev = d1->si_drv2; + else + *dev = d1; +} + static void nmdm_crossover(struct nm_softc *pti, struct softpart *ourpart, @@ -123,24 +171,22 @@ do { \ * This function creates and initializes a pair of ttys. */ static void -nmdminit(n) - int n; +nmdminit(dev_t dev1) { - dev_t dev1, dev2; + dev_t dev2; struct nm_softc *pt; - /* For now we only map the lower 8 bits of the minor */ - if (n & ~0xff) - return; + dev2 = dev1->si_drv2; - pt = malloc(sizeof(*pt), M_NLMDM, M_WAITOK); - bzero(pt, sizeof(*pt)); - pt->part1.dev = dev1 = make_dev(&nmdm_cdevsw, n+n, - 0, 0, 0666, "nmdm%dA", n); - pt->part2.dev = dev2 = make_dev(&nmdm_cdevsw, n+n+1, - 0, 0, 0666, "nmdm%dB", n); + dev1->si_flags &= ~SI_CHEAPCLONE; + dev2->si_flags &= ~SI_CHEAPCLONE; + pt = malloc(sizeof(*pt), M_NLMDM, M_WAITOK | M_ZERO); + TAILQ_INSERT_TAIL(&nmdmhead, pt, pt_list); dev1->si_drv1 = dev2->si_drv1 = pt; + + pt->part1.dev = dev1; + pt->part2.dev = dev2; dev1->si_tty = &pt->part1.nm_tty; dev2->si_tty = &pt->part2.nm_tty; ttyregister(&pt->part1.nm_tty); @@ -148,9 +194,9 @@ nmdminit(n) pt->part1.nm_tty.t_oproc = nmdmstart; pt->part2.nm_tty.t_oproc = nmdmstart; pt->part1.nm_tty.t_stop = nmdmstop; + pt->part2.nm_tty.t_stop = nmdmstop; pt->part2.nm_tty.t_dev = dev1; pt->part1.nm_tty.t_dev = dev2; - pt->part2.nm_tty.t_stop = nmdmstop; } /* @@ -161,39 +207,14 @@ nmdmopen(dev_t dev, int flag, int devtype, struct thread *td) { register struct tty *tp, *tp2; int error; - int minr; - dev_t nextdev; struct nm_softc *pti; - int is_b; - int pair; struct softpart *ourpart, *otherpart; - /* - * XXX: Gross hack for DEVFS: - * If we openned this device, ensure we have the - * next one too, so people can open it. - */ - minr = dev2unit(dev); - pair = minr >> 1; - is_b = minr & 1; - - if (pair < (NMDM_MAX_NUM - 1)) { - nextdev = makedev(major(dev), minr + 2); - if (!nextdev->si_drv1) { - nmdminit(pair + 1); - } - } else { /* Limit ourselves to 128 of them for now */ - if (pair > (NMDM_MAX_NUM - 1)) - return (ENXIO); - } - if (!dev->si_drv1) - nmdminit(pair); - - if (!dev->si_drv1) - return(ENXIO); - + if (dev->si_drv1 == NULL) + nmdminit(dev); pti = dev->si_drv1; - if (is_b) + + if (minor(dev) & BFLAG) tp = &pti->part2.nm_tty; else tp = &pti->part1.nm_tty; @@ -567,20 +588,27 @@ nmdm_crossover(struct nm_softc *pti, struct softpart *ourpart, static int nmdm_modevent(module_t mod, int type, void *data) { + static eventhandler_tag tag; + struct nm_softc *pt, *tpt; int error = 0; switch(type) { - case MOD_LOAD: /* start with 4 of them */ - nmdminit(0); - nmdminit(1); - nmdminit(2); - nmdminit(3); + case MOD_LOAD: + tag = EVENTHANDLER_REGISTER(dev_clone, nmdm_clone, 0, 1000); + if (tag == NULL) + return (ENOMEM); break; case MOD_SHUTDOWN: /* FALLTHROUGH */ case MOD_UNLOAD: - nmdmshutdown(); + EVENTHANDLER_DEREGISTER(dev_clone, tag); + TAILQ_FOREACH_SAFE(pt, &nmdmhead, pt_list, tpt) { + destroy_dev(pt->part1.dev); + TAILQ_REMOVE(&nmdmhead, pt, pt_list); + free(pt, M_NLMDM); + } + clone_cleanup(&nmdmclones); break; default: error = EOPNOTSUPP; @@ -588,31 +616,4 @@ nmdm_modevent(module_t mod, int type, void *data) return (error); } -/* - * Handle teardown of device - */ -static int -nmdmshutdown(void) -{ - int i; - dev_t nextdev1; - dev_t nextdev2; - void * ptr1; - - for(i = 0;( i < NMDM_MAX_NUM) ;i++) { - nextdev1 = makedev(CDEV_MAJOR, (i+i) ); - nextdev2 = makedev(CDEV_MAJOR, (i+i) + 1); - ptr1 = nextdev1->si_drv1; - if (ptr1) { - destroy_dev(nextdev1); - destroy_dev(nextdev2); - free(ptr1, M_NLMDM); - } else { - freedev(nextdev1); - freedev(nextdev2); - } - } - return(0); -} - DEV_MODULE(nmdm, nmdm_modevent, NULL); diff --git a/sys/dev/snp/snp.c b/sys/dev/snp/snp.c index 4c4115d..2c1c3c6 100644 --- a/sys/dev/snp/snp.c +++ b/sys/dev/snp/snp.c @@ -38,7 +38,6 @@ static d_write_t snpwrite; static d_ioctl_t snpioctl; static d_poll_t snppoll; -#define CDEV_MAJOR 53 static struct cdevsw snp_cdevsw = { .d_open = snpopen, .d_close = snpclose, @@ -47,7 +46,7 @@ static struct cdevsw snp_cdevsw = { .d_ioctl = snpioctl, .d_poll = snppoll, .d_name = "snp", - .d_maj = CDEV_MAJOR, + .d_flags = D_PSEUDO, }; static struct linesw snpdisc = { @@ -101,10 +100,9 @@ static MALLOC_DEFINE(M_SNP, "snp", "Snoop device data"); * module load time. */ static int snooplinedisc; -static udev_t snpbasedev = NOUDEV; - static LIST_HEAD(, snoop) snp_sclist = LIST_HEAD_INITIALIZER(&snp_sclist); +static struct clonedevs *snpclones; static struct tty *snpdevtotty(dev_t dev); static void snp_clone(void *arg, char *name, @@ -384,9 +382,7 @@ snpopen(dev, flag, mode, td) struct snoop *snp; if (dev->si_drv1 == NULL) { - if (!(dev->si_flags & SI_NAMED)) - make_dev(&snp_cdevsw, minor(dev), UID_ROOT, GID_WHEEL, - 0600, "snp%d", dev2unit(dev)); + dev->si_flags &= ~SI_CHEAPCLONE; dev->si_drv1 = snp = malloc(sizeof(*snp), M_SNP, M_WAITOK | M_ZERO); snp->snp_unit = dev2unit(dev); @@ -466,6 +462,7 @@ snpclose(dev, flags, fmt, td) free(snp->snp_buf, M_SNP); snp->snp_flags &= ~SNOOP_OPEN; dev->si_drv1 = NULL; + destroy_dev(dev); return (snp_detach(snp)); } @@ -608,20 +605,18 @@ snp_clone(arg, name, namelen, dev) int namelen; dev_t *dev; { - int u; + int u, i; if (*dev != NODEV) return; if (dev_stdclone(name, NULL, "snp", &u) != 1) return; - *dev = make_dev(&snp_cdevsw, unit2minor(u), UID_ROOT, GID_WHEEL, 0600, - "snp%d", u); - if (snpbasedev == NOUDEV) - snpbasedev = (*dev)->si_udev; - else { + i = clone_create(&snpclones, &snp_cdevsw, &u, dev, 0); + if (i) + *dev = make_dev(&snp_cdevsw, unit2minor(u), + UID_ROOT, GID_WHEEL, 0600, "snp%d", u); + if (*dev != NULL) (*dev)->si_flags |= SI_CHEAPCLONE; - dev_depends(udev2dev(snpbasedev, 0), *dev); - } } static int @@ -642,8 +637,7 @@ snp_modevent(mod, type, data) if (!LIST_EMPTY(&snp_sclist)) return (EBUSY); EVENTHANDLER_DEREGISTER(dev_clone, eh_tag); - if (snpbasedev != NOUDEV) - destroy_dev(udev2dev(snpbasedev, 0)); + clone_cleanup(&snpclones); ldisc_deregister(snooplinedisc); break; default: @@ -657,4 +651,4 @@ static moduledata_t snp_mod = { snp_modevent, NULL }; -DECLARE_MODULE(snp, snp_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE + CDEV_MAJOR); +DECLARE_MODULE(snp, snp_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); |