diff options
| author | Poul-Henning Kamp <phk@FreeBSD.org> | 2000-08-20 21:34:39 +0000 |
|---|---|---|
| committer | Poul-Henning Kamp <phk@FreeBSD.org> | 2000-08-20 21:34:39 +0000 |
| commit | 3f54a085a603b050163611ce23972ee8de7636f1 (patch) | |
| tree | 4a236ab334d49bc97f4741cc058e0ae301786c02 /sys/kern | |
| parent | e0faad6850ddd7593f869132fc7647c1576e0f6d (diff) | |
Notes
Diffstat (limited to 'sys/kern')
| -rw-r--r-- | sys/kern/init_main.c | 5 | ||||
| -rw-r--r-- | sys/kern/kern_conf.c | 69 | ||||
| -rw-r--r-- | sys/kern/subr_disk.c | 77 | ||||
| -rw-r--r-- | sys/kern/subr_diskslice.c | 108 | ||||
| -rw-r--r-- | sys/kern/tty_pty.c | 73 |
5 files changed, 198 insertions, 134 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 4ce964652f5c..0229c56a8b21 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -43,6 +43,7 @@ */ #include "opt_init_path.h" +#include "opt_devfs.h" #include <sys/param.h> #include <sys/file.h> @@ -498,6 +499,10 @@ start_init(void *dummy) (void)subyte(--ucp, 'C'); options = 1; #endif +#ifdef DEVFS + (void)subyte(--ucp, 'd'); + options = 1; +#endif if (options == 0) (void)subyte(--ucp, '-'); (void)subyte(--ucp, '-'); /* leading hyphen */ diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c index d6116f75513f..1e344e357450 100644 --- a/sys/kern/kern_conf.c +++ b/sys/kern/kern_conf.c @@ -195,13 +195,33 @@ makebdev(int x, int y) return (makedev(bmaj2cmaj[x], y)); } +static dev_t +allocdev(void) +{ + static int stashed; + struct specinfo *si; + + if (stashed >= DEVT_STASH) { + MALLOC(si, struct specinfo *, sizeof(*si), M_DEVT, + M_USE_RESERVE); + bzero(si, sizeof(*si)); + } else if (LIST_FIRST(&dev_free)) { + si = LIST_FIRST(&dev_free); + LIST_REMOVE(si, si_hash); + } else { + si = devt_stash + stashed++; + si->si_flags |= SI_STASHED; + } + LIST_INIT(&si->si_names); + return (si); +} + dev_t makedev(int x, int y) { struct specinfo *si; udev_t udev; int hash; - static int stashed; if (x == umajor(NOUDEV) && y == uminor(NOUDEV)) Debugger("makedev of NOUDEV"); @@ -211,17 +231,7 @@ makedev(int x, int y) if (si->si_udev == udev) return (si); } - if (stashed >= DEVT_STASH) { - MALLOC(si, struct specinfo *, sizeof(*si), M_DEVT, - M_USE_RESERVE); - bzero(si, sizeof(*si)); - } else if (LIST_FIRST(&dev_free)) { - si = LIST_FIRST(&dev_free); - LIST_REMOVE(si, si_hash); - } else { - si = devt_stash + stashed++; - si->si_flags |= SI_STASHED; - } + si = allocdev(); si->si_udev = udev; LIST_INSERT_HEAD(&dev_hash[hash], si, si_hash); return (si); @@ -230,7 +240,7 @@ makedev(int x, int y) void freedev(dev_t dev) { - int hash; + dev_t adev; if (!free_devt) return; @@ -238,7 +248,11 @@ freedev(dev_t dev) return; if (dev->si_devsw || dev->si_drv1 || dev->si_drv2) return; - hash = dev->si_udev % DEVT_HASH; + while (!LIST_EMPTY(&dev->si_names)) { + adev = LIST_FIRST(&dev->si_names); + adev->si_drv1 = NULL; + freedev(adev); + } LIST_REMOVE(dev, si_hash); if (dev->si_flags & SI_STASHED) { bzero(dev, sizeof(*dev)); @@ -304,9 +318,34 @@ make_dev(struct cdevsw *devsw, int minor, uid_t uid, gid_t gid, int perms, char dev->si_name[i] = '\0'; va_end(ap); dev->si_devsw = devsw; + dev->si_uid = uid; + dev->si_gid = gid; + dev->si_mode = perms; + + if (devfs_create_hook) + devfs_create_hook(dev); + return (dev); +} + +dev_t +make_dev_alias(dev_t pdev, char *fmt, ...) +{ + dev_t dev; + va_list ap; + int i; + + dev = allocdev(); + dev->si_flags |= SI_ALIAS; + dev->si_drv1 = pdev; + LIST_INSERT_HEAD(&pdev->si_names, dev, si_hash); + + va_start(ap, fmt); + i = kvprintf(fmt, NULL, dev->si_name, 32, ap); + dev->si_name[i] = '\0'; + va_end(ap); if (devfs_create_hook) - devfs_create_hook(dev, uid, gid, perms); + devfs_create_hook(dev); return (dev); } diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c index 8bb0c6da5d50..77fc4ee33628 100644 --- a/sys/kern/subr_disk.c +++ b/sys/kern/subr_disk.c @@ -10,6 +10,8 @@ * */ +#include "opt_devfs.h" + #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -21,6 +23,12 @@ #include <sys/sysctl.h> #include <machine/md_var.h> +#ifdef DEVFS +#include <sys/eventhandler.h> +#include <fs/devfs/devfs.h> +#include <sys/ctype.h> +#endif + MALLOC_DEFINE(M_DISK, "disk", "disk data"); static d_strategy_t diskstrategy; @@ -30,7 +38,65 @@ static d_ioctl_t diskioctl; static d_psize_t diskpsize; static LIST_HEAD(, disk) disklist = LIST_HEAD_INITIALIZER(&disklist); - + +#ifdef DEVFS +static void +disk_clone(void *arg, char *name, int namelen, dev_t *dev) +{ + struct disk *dp; + char const *d; + int i, u, s, p; + dev_t pdev; + + if (*dev != NODEV) + return; + + LIST_FOREACH(dp, &disklist, d_list) { + d = dp->d_devsw->d_name; + i = strlen(d); + if (bcmp(d, name, i) != 0) + continue; + u = 0; + if (!isdigit(name[i])) + continue; + while (isdigit(name[i])) { + u *= 10; + u += name[i++] - '0'; + } + p = RAW_PART; + s = WHOLE_DISK_SLICE; + pdev = makedev(dp->d_devsw->d_maj, dkmakeminor(u, s, p)); + if (pdev->si_disk == NULL) + continue; + if (name[i] != '\0') { + if (name[i] == 's') { + s = 0; + i++; + if (!isdigit(name[i])) + continue; + while (isdigit(name[i])) { + s *= 10; + s += name[i++] - '0'; + } + s += BASE_SLICE - 1; + } else { + s = COMPATIBILITY_SLICE; + } + if (name[i] == '\0') + ; + else if (name[i] < 'a' || name[i] > 'h') + continue; + else + p = name[i] - 'a'; + } + + *dev = make_dev(pdev->si_devsw, dkmakeminor(u, s, p), + UID_ROOT, GID_OPERATOR, 0640, name); + return; + } +} +#endif + static void inherit_raw(dev_t pdev, dev_t dev) { @@ -45,6 +111,7 @@ inherit_raw(dev_t pdev, dev_t dev) dev_t disk_create(int unit, struct disk *dp, int flags, struct cdevsw *cdevsw, struct cdevsw *proto) { + static int once; dev_t dev; bzero(dp, sizeof(*dp)); @@ -63,13 +130,19 @@ disk_create(int unit, struct disk *dp, int flags, struct cdevsw *cdevsw, struct if (bootverbose) printf("Creating DISK %s%d\n", cdevsw->d_name, unit); dev = make_dev(proto, dkmakeminor(unit, WHOLE_DISK_SLICE, RAW_PART), - 0, 0, 0, "%s%d", cdevsw->d_name, unit); + UID_ROOT, GID_OPERATOR, 0640, "%s%d", cdevsw->d_name, unit); dev->si_disk = dp; dp->d_dev = dev; dp->d_dsflags = flags; dp->d_devsw = cdevsw; LIST_INSERT_HEAD(&disklist, dp, d_list); + if (!once) { +#ifdef DEVFS + EVENTHANDLER_REGISTER(devfs_clone, disk_clone, 0, 1000); +#endif + once++; + } return (dev); } diff --git a/sys/kern/subr_diskslice.c b/sys/kern/subr_diskslice.c index 68df0db5905d..8d5d4ab03ebd 100644 --- a/sys/kern/subr_diskslice.c +++ b/sys/kern/subr_diskslice.c @@ -54,9 +54,6 @@ #include <sys/systm.h> #include <sys/bio.h> #include <sys/conf.h> -#ifdef DEVFS -#include <sys/devfsext.h> -#endif #include <sys/disklabel.h> #include <sys/diskslice.h> #include <sys/fcntl.h> @@ -78,17 +75,11 @@ static void dsiodone __P((struct bio *bp)); static char *fixlabel __P((char *sname, struct diskslice *sp, struct disklabel *lp, int writeflag)); static void free_ds_label __P((struct diskslices *ssp, int slice)); -#ifdef DEVFS -static void free_ds_labeldevs __P((struct diskslices *ssp, int slice)); -#endif static void partition_info __P((char *sname, int part, struct partition *pp)); static void slice_info __P((char *sname, struct diskslice *sp)); static void set_ds_label __P((struct diskslices *ssp, int slice, struct disklabel *lp)); static void set_ds_labeldevs __P((dev_t dev, struct diskslices *ssp)); -#ifdef DEVFS -static void set_ds_labeldevs_unaliased __P((dev_t dev, struct diskslices *ssp)); -#endif static void set_ds_wlabel __P((struct diskslices *ssp, int slice, int wlabel)); @@ -329,10 +320,6 @@ dsgone(sspp) for (slice = 0, ssp = *sspp; slice < ssp->dss_nslices; slice++) { sp = &ssp->dss_slices[slice]; -#ifdef DEVFS - if (sp->ds_dev != NULL) - devfs_remove_dev(sp->ds_dev); -#endif free_ds_label(ssp, slice); } free(ssp, M_DEVBUF); @@ -634,9 +621,6 @@ dsopen(dev, mode, flags, sspp, lp) struct disklabel *lp1; char *msg; u_char mask; -#ifdef DEVFS - int mynor; -#endif bool_t need_init; int part; char partname[2]; @@ -723,16 +707,6 @@ dsopen(dev, mode, flags, sspp, lp) continue; dev1 = dkmodslice(dkmodpart(dev, RAW_PART), slice); sname = dsname(dev, unit, slice, RAW_PART, partname); -#ifdef DEVFS - if (slice != COMPATIBILITY_SLICE && sp->ds_dev == NULL - && sp->ds_size != 0) { - mynor = minor(dev1); - sp->ds_dev = - devfs_add_devswf(devsw(dev1), mynor, DV_CHR, - UID_ROOT, GID_OPERATOR, 0640, - "r%s", sname); - } -#endif /* * XXX this should probably only be done for the need_init * case, but there may be a problem with DIOCSYNCSLICEINFO. @@ -818,39 +792,10 @@ free_ds_label(ssp, slice) lp = sp->ds_label; if (lp == NULL) return; -#ifdef DEVFS - free_ds_labeldevs(ssp, slice); - if (slice == COMPATIBILITY_SLICE) - free_ds_labeldevs(ssp, ssp->dss_first_bsd_slice); - else if (slice == ssp->dss_first_bsd_slice) - free_ds_labeldevs(ssp, COMPATIBILITY_SLICE); -#endif free(lp, M_DEVBUF); set_ds_label(ssp, slice, (struct disklabel *)NULL); } -#ifdef DEVFS -static void -free_ds_labeldevs(ssp, slice) - struct diskslices *ssp; - int slice; -{ - struct disklabel *lp; - int part; - struct diskslice *sp; - - sp = &ssp->dss_slices[slice]; - lp = sp->ds_label; - if (lp == NULL) - return; - for (part = 0; part < lp->d_npartitions; part++) { - if (sp->ds_devs[part] != NULL) { - devfs_remove_dev(sp->ds_devs[part]); - sp->ds_devs[part] = NULL; - } - } -} -#endif static char * fixlabel(sname, sp, lp, writeflag) @@ -976,61 +921,8 @@ set_ds_labeldevs(dev, ssp) dev_t dev; struct diskslices *ssp; { -#ifdef DEVFS - int slice; - - set_ds_labeldevs_unaliased(dev, ssp); - if (ssp->dss_first_bsd_slice == COMPATIBILITY_SLICE) - return; - slice = dkslice(dev); - if (slice == COMPATIBILITY_SLICE) - set_ds_labeldevs_unaliased( - dkmodslice(dev, ssp->dss_first_bsd_slice), ssp); - else if (slice == ssp->dss_first_bsd_slice) - set_ds_labeldevs_unaliased( - dkmodslice(dev, COMPATIBILITY_SLICE), ssp); -#endif /* DEVFS */ } -#ifdef DEVFS -static void -set_ds_labeldevs_unaliased(dev, ssp) - dev_t dev; - struct diskslices *ssp; -{ - struct disklabel *lp; - int mynor; - int part; - char partname[2]; - struct partition *pp; - int slice; - char *sname; - struct diskslice *sp; - - slice = dkslice(dev); - sp = &ssp->dss_slices[slice]; - if (sp->ds_size == 0) - return; - lp = sp->ds_label; - for (part = 0; part < lp->d_npartitions; part++) { - pp = &lp->d_partitions[part]; - if (pp->p_size == 0) - continue; - sname = dsname(dev, dkunit(dev), slice, part, partname); - if (part == RAW_PART && sp->ds_dev != NULL) { - sp->ds_devs[part] = - devfs_makelink(sp->ds_dev, - "r%s%s", sname, partname); - } else { - mynor = minor(dkmodpart(dev, part)); - sp->ds_devs[part] = - devfs_add_devswf(devsw(dev), mynor, DV_CHR, - UID_ROOT, GID_OPERATOR, 0640, - "r%s%s", sname, partname); - } - } -} -#endif /* DEVFS */ static void set_ds_wlabel(ssp, slice, wlabel) diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c index 6226e8cade6c..d4402cdd2498 100644 --- a/sys/kern/tty_pty.c +++ b/sys/kern/tty_pty.c @@ -39,6 +39,7 @@ * (Actually two drivers, requiring two entries in 'cdevsw') */ #include "opt_compat.h" +#include "opt_devfs.h" #include <sys/param.h> #include <sys/systm.h> #if defined(COMPAT_43) || defined(COMPAT_SUNOS) @@ -54,12 +55,17 @@ #include <sys/signalvar.h> #include <sys/malloc.h> +#ifdef DEVFS +#include <sys/eventhandler.h> +#include <fs/devfs/devfs.h> +#endif + MALLOC_DEFINE(M_PTY, "ptys", "pty data structures"); static void ptsstart __P((struct tty *tp)); static void ptsstop __P((struct tty *tp, int rw)); static void ptcwakeup __P((struct tty *tp, int flag)); -static void ptyinit __P((int n)); +static dev_t ptyinit __P((int n)); static d_open_t ptsopen; static d_close_t ptsclose; @@ -135,7 +141,7 @@ struct pt_ioctl { * XXX: define and add mapping of upper minor bits to allow more * than 256 ptys. */ -static void +static dev_t ptyinit(n) int n; { @@ -145,7 +151,7 @@ ptyinit(n) /* For now we only map the lower 8 bits of the minor */ if (n & ~0xff) - return; + return (NODEV); pt = malloc(sizeof(*pt), M_PTY, M_WAITOK); bzero(pt, sizeof(*pt)); @@ -157,6 +163,7 @@ ptyinit(n) devs->si_drv1 = devc->si_drv1 = pt; devs->si_tty = devc->si_tty = &pt->pt_tty; ttyregister(&pt->pt_tty); + return (devc); } /*ARGSUSED*/ @@ -168,24 +175,25 @@ ptsopen(dev, flag, devtype, p) { register struct tty *tp; int error; - int minr; - dev_t nextdev; struct pt_ioctl *pti; +#ifndef DEVFS + { + int minr = lminor(dev); /* - * XXX: Gross hack for DEVFS: * If we openned this device, ensure we have the * next one too, so people can open it. */ - minr = lminor(dev); if (minr < 255) { - nextdev = makedev(major(dev), minr + 1); + dev_t nextdev = makedev(major(dev), minr + 1); if (!nextdev->si_drv1) { ptyinit(minr + 1); } } if (!dev->si_drv1) ptyinit(minor(dev)); + } +#endif if (!dev->si_drv1) return(ENXIO); pti = dev->si_drv1; @@ -347,8 +355,10 @@ ptcopen(dev, flag, devtype, p) register struct tty *tp; struct pt_ioctl *pti; +#ifndef DEVFS if (!dev->si_drv1) ptyinit(minor(dev)); +#endif if (!dev->si_drv1) return(ENXIO); tp = dev->si_tty; @@ -816,14 +826,59 @@ ptyioctl(dev, cmd, data, flag, p) static void ptc_drvinit __P((void *unused)); +#ifdef DEVFS +static void pty_clone __P((void *arg, char *name, int namelen, dev_t *dev)); + +static void +pty_clone(arg, name, namelen, dev) + void *arg; + char *name; + int namelen; + dev_t *dev; +{ + int u; + + if (*dev != NODEV) + return; + if (bcmp(name, "pty", 3) != 0) + return; + if (name[5] != '\0') + return; + switch (name[3]) { + case 'p': u = 0; break; + case 'q': u = 32; break; + case 'r': u = 64; break; + case 's': u = 96; break; + case 'P': u = 128; break; + case 'Q': u = 160; break; + case 'R': u = 192; break; + case 'S': u = 224; break; + default: return; + } + if (name[4] >= '0' && name[4] <= '9') + u += name[4] - '0'; + else if (name[4] >= 'a' && name[4] <= 'v') + u += name[4] - 'a' + 10; + else + return; + *dev = ptyinit(u); + return; +} + + +#endif + static void ptc_drvinit(unused) void *unused; { +#ifdef DEVFS + EVENTHANDLER_REGISTER(devfs_clone, pty_clone, 0, 1000); +#else cdevsw_add(&pts_cdevsw); cdevsw_add(&ptc_cdevsw); - /* XXX: Gross hack for DEVFS */ ptyinit(0); +#endif } SYSINIT(ptcdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR_C,ptc_drvinit,NULL) |
