summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorPoul-Henning Kamp <phk@FreeBSD.org>2000-08-20 21:34:39 +0000
committerPoul-Henning Kamp <phk@FreeBSD.org>2000-08-20 21:34:39 +0000
commit3f54a085a603b050163611ce23972ee8de7636f1 (patch)
tree4a236ab334d49bc97f4741cc058e0ae301786c02 /sys/kern
parente0faad6850ddd7593f869132fc7647c1576e0f6d (diff)
Notes
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/init_main.c5
-rw-r--r--sys/kern/kern_conf.c69
-rw-r--r--sys/kern/subr_disk.c77
-rw-r--r--sys/kern/subr_diskslice.c108
-rw-r--r--sys/kern/tty_pty.c73
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)