diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-10-07 15:10:20 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-01-10 09:53:31 +0100 |
commit | c40e45b75eb76d79a05c7fa85c1fa9b5c728a12f (patch) | |
tree | ad4f2519067709f00ab98b3c591186c26dc3a21f /freebsd/sys/kern/kern_conf.c | |
parent | userspace-header-gen.py: Simplify program ports (diff) | |
download | rtems-libbsd-c40e45b75eb76d79a05c7fa85c1fa9b5c728a12f.tar.bz2 |
Update to FreeBSD head 2016-08-23
Git mirror commit 9fe7c416e6abb28b1398fd3e5687099846800cfd.
Diffstat (limited to 'freebsd/sys/kern/kern_conf.c')
-rw-r--r-- | freebsd/sys/kern/kern_conf.c | 146 |
1 files changed, 96 insertions, 50 deletions
diff --git a/freebsd/sys/kern/kern_conf.c b/freebsd/sys/kern/kern_conf.c index 589e5941..fb43c243 100644 --- a/freebsd/sys/kern/kern_conf.c +++ b/freebsd/sys/kern/kern_conf.c @@ -62,6 +62,7 @@ static void destroy_devl(struct cdev *dev); #ifndef __rtems__ static int destroy_dev_sched_cbl(struct cdev *dev, void (*cb)(void *), void *arg); +static void destroy_dev_tq(void *ctx, int pending); #endif /* __rtems__ */ static int make_dev_credv(int flags, struct cdev **dres, struct cdevsw *devsw, int unit, struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt, @@ -206,7 +207,7 @@ dev_refthread(struct cdev *dev, int *ref) if (csw != NULL) { cdp = cdev2priv(dev); if ((cdp->cdp_flags & CDP_SCHED_DTR) == 0) - dev->si_threadcount++; + atomic_add_long(&dev->si_threadcount, 1); else csw = NULL; } @@ -248,7 +249,7 @@ devvn_refthread(struct vnode *vp, struct cdev **devp, int *ref) if ((cdp->cdp_flags & CDP_SCHED_DTR) == 0) { csw = dev->si_devsw; if (csw != NULL) - dev->si_threadcount++; + atomic_add_long(&dev->si_threadcount, 1); } dev_unlock(); if (csw != NULL) { @@ -266,11 +267,9 @@ dev_relthread(struct cdev *dev, int ref) mtx_assert(&devmtx, MA_NOTOWNED); if (!ref) return; - dev_lock(); KASSERT(dev->si_threadcount > 0, ("%s threadcount is wrong", dev->si_name)); - dev->si_threadcount--; - dev_unlock(); + atomic_subtract_rel_long(&dev->si_threadcount, 1); } int @@ -597,22 +596,26 @@ notify_destroy(struct cdev *dev) } static struct cdev * -newdev(struct cdevsw *csw, int unit, struct cdev *si) +newdev(struct make_dev_args *args, struct cdev *si) { struct cdev *si2; + struct cdevsw *csw; mtx_assert(&devmtx, MA_OWNED); + csw = args->mda_devsw; if (csw->d_flags & D_NEEDMINOR) { /* We may want to return an existing device */ LIST_FOREACH(si2, &csw->d_devs, si_list) { - if (dev2unit(si2) == unit) { + if (dev2unit(si2) == args->mda_unit) { dev_free_devlocked(si); return (si2); } } } - si->si_drv0 = unit; + si->si_drv0 = args->mda_unit; si->si_devsw = csw; + si->si_drv1 = args->mda_si_drv1; + si->si_drv2 = args->mda_si_drv2; LIST_INSERT_HEAD(&csw->d_devs, si, si_list); return (si); } @@ -728,16 +731,22 @@ prep_devname(struct cdev *dev, const char *fmt, va_list ap) mtx_assert(&devmtx, MA_OWNED); - len = vsnrprintf(dev->__si_namebuf, sizeof(dev->__si_namebuf), 32, - fmt, ap); - if (len > sizeof(dev->__si_namebuf) - 1) + len = vsnrprintf(dev->si_name, sizeof(dev->si_name), 32, fmt, ap); + if (len > sizeof(dev->si_name) - 1) return (ENAMETOOLONG); /* Strip leading slashes. */ - for (from = dev->__si_namebuf; *from == '/'; from++) + for (from = dev->si_name; *from == '/'; from++) ; - for (to = dev->__si_namebuf; *from != '\0'; from++, to++) { + for (to = dev->si_name; *from != '\0'; from++, to++) { + /* + * Spaces and double quotation marks cause + * problems for the devctl(4) protocol. + * Reject names containing those characters. + */ + if (isspace(*from) || *from == '"') + return (EINVAL); /* Treat multiple sequential slashes as single. */ while (from[0] == '/' && from[1] == '/') from++; @@ -748,11 +757,11 @@ prep_devname(struct cdev *dev, const char *fmt, va_list ap) } *to = '\0'; - if (dev->__si_namebuf[0] == '\0') + if (dev->si_name[0] == '\0') return (EINVAL); /* Disallow "." and ".." components. */ - for (s = dev->__si_namebuf;;) { + for (s = dev->si_name;;) { for (q = s; *q != '/' && *q != '\0'; q++) ; if (q - s == 1 && s[0] == '.') @@ -764,39 +773,52 @@ prep_devname(struct cdev *dev, const char *fmt, va_list ap) s = q + 1; } - if (devfs_dev_exists(dev->__si_namebuf) != 0) + if (devfs_dev_exists(dev->si_name) != 0) return (EEXIST); return (0); } +void +make_dev_args_init_impl(struct make_dev_args *args, size_t sz) +{ + + bzero(args, sz); + args->mda_size = sz; +} + static int -make_dev_credv(int flags, struct cdev **dres, struct cdevsw *devsw, int unit, - struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt, - va_list ap) +make_dev_sv(struct make_dev_args *args1, struct cdev **dres, + const char *fmt, va_list ap) { struct cdev *dev, *dev_new; + struct make_dev_args args; int res; - KASSERT((flags & MAKEDEV_WAITOK) == 0 || (flags & MAKEDEV_NOWAIT) == 0, - ("make_dev_credv: both WAITOK and NOWAIT specified")); - dev_new = devfs_alloc(flags); + bzero(&args, sizeof(args)); + if (sizeof(args) < args1->mda_size) + return (EINVAL); + bcopy(args1, &args, args1->mda_size); + KASSERT((args.mda_flags & MAKEDEV_WAITOK) == 0 || + (args.mda_flags & MAKEDEV_NOWAIT) == 0, + ("make_dev_sv: both WAITOK and NOWAIT specified")); + dev_new = devfs_alloc(args.mda_flags); if (dev_new == NULL) return (ENOMEM); dev_lock(); - res = prep_cdevsw(devsw, flags); + res = prep_cdevsw(args.mda_devsw, args.mda_flags); if (res != 0) { dev_unlock(); devfs_free(dev_new); return (res); } - dev = newdev(devsw, unit, dev_new); + dev = newdev(&args, dev_new); if ((dev->si_flags & SI_NAMED) == 0) { res = prep_devname(dev, fmt, ap); if (res != 0) { - if ((flags & MAKEDEV_CHECKNAME) == 0) { + if ((args.mda_flags & MAKEDEV_CHECKNAME) == 0) { panic( - "make_dev_credv: bad si_name (error=%d, si_name=%s)", + "make_dev_sv: bad si_name (error=%d, si_name=%s)", res, dev->si_name); } if (dev == dev_new) { @@ -808,9 +830,9 @@ make_dev_credv(int flags, struct cdev **dres, struct cdevsw *devsw, int unit, return (res); } } - if (flags & MAKEDEV_REF) + if ((args.mda_flags & MAKEDEV_REF) != 0) dev_refl(dev); - if (flags & MAKEDEV_ETERNAL) + if ((args.mda_flags & MAKEDEV_ETERNAL) != 0) dev->si_flags |= SI_ETERNAL; if (dev->si_flags & SI_CHEAPCLONE && dev->si_flags & SI_NAMED) { @@ -825,14 +847,14 @@ make_dev_credv(int flags, struct cdev **dres, struct cdevsw *devsw, int unit, } KASSERT(!(dev->si_flags & SI_NAMED), ("make_dev() by driver %s on pre-existing device (min=%x, name=%s)", - devsw->d_name, dev2unit(dev), devtoname(dev))); + args.mda_devsw->d_name, dev2unit(dev), devtoname(dev))); dev->si_flags |= SI_NAMED; #ifndef __rtems__ - if (cr != NULL) - dev->si_cred = crhold(cr); - dev->si_uid = uid; - dev->si_gid = gid; - dev->si_mode = mode; + if (args.mda_cr != NULL) + dev->si_cred = crhold(args.mda_cr); + dev->si_uid = args.mda_uid; + dev->si_gid = args.mda_gid; + dev->si_mode = args.mda_mode; #endif /* __rtems__ */ devfs_create(dev); @@ -841,12 +863,43 @@ make_dev_credv(int flags, struct cdev **dres, struct cdevsw *devsw, int unit, #endif /* __rtems__ */ dev_unlock_and_free(); - notify_create(dev, flags); + notify_create(dev, args.mda_flags); *dres = dev; return (0); } +int +make_dev_s(struct make_dev_args *args, struct cdev **dres, + const char *fmt, ...) +{ + va_list ap; + int res; + + va_start(ap, fmt); + res = make_dev_sv(args, dres, fmt, ap); + va_end(ap); + return (res); +} + +static int +make_dev_credv(int flags, struct cdev **dres, struct cdevsw *devsw, int unit, + struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt, + va_list ap) +{ + struct make_dev_args args; + + make_dev_args_init(&args); + args.mda_flags = flags; + args.mda_devsw = devsw; + args.mda_cr = cr; + args.mda_uid = uid; + args.mda_gid = gid; + args.mda_mode = mode; + args.mda_unit = unit; + return (make_dev_sv(&args, dres, fmt, ap)); +} + struct cdev * make_dev(struct cdevsw *devsw, int unit, uid_t uid, gid_t gid, int mode, const char *fmt, ...) @@ -1299,6 +1352,7 @@ clone_create(struct clonedevs **cdp, struct cdevsw *csw, int *up, { struct clonedevs *cd; struct cdev *dev, *ndev, *dl, *de; + struct make_dev_args args; int unit, low, u; KASSERT(*cdp != NULL, @@ -1350,7 +1404,10 @@ clone_create(struct clonedevs **cdp, struct cdevsw *csw, int *up, } if (unit == -1) unit = low & CLONE_UNITMASK; - dev = newdev(csw, unit | extra, ndev); + make_dev_args_init(&args); + args.mda_unit = unit | extra; + args.mda_devsw = csw; + dev = newdev(&args, ndev); if (dev->si_flags & SI_CLONELIST) { printf("dev %p (%s) is on clonelist\n", dev, dev->si_name); printf("unit=%d, low=%d, extra=0x%x\n", unit, low, extra); @@ -1398,7 +1455,8 @@ clone_cleanup(struct clonedevs **cdp) if (!(cp->cdp_flags & CDP_SCHED_DTR)) { cp->cdp_flags |= CDP_SCHED_DTR; KASSERT(dev->si_flags & SI_NAMED, - ("Driver has goofed in cloning underways udev %x unit %x", dev2udev(dev), dev2unit(dev))); + ("Driver has goofed in cloning underways udev %jx unit %x", + (uintmax_t)dev2udev(dev), dev2unit(dev))); destroy_devl(dev); } } @@ -1409,7 +1467,7 @@ clone_cleanup(struct clonedevs **cdp) static TAILQ_HEAD(, cdev_priv) dev_ddtr = TAILQ_HEAD_INITIALIZER(dev_ddtr); -static struct task dev_dtr_task; +static struct task dev_dtr_task = TASK_INITIALIZER(0, destroy_dev_tq, NULL); static void destroy_dev_tq(void *ctx, int pending) @@ -1497,15 +1555,6 @@ drain_dev_clone_events(void) sx_xunlock(&clone_drain_lock); } -static void -devdtr_init(void *dummy __unused) -{ - - TASK_INIT(&dev_dtr_task, 0, destroy_dev_tq, NULL); -} - -SYSINIT(devdtr, SI_SUB_DEVFS, SI_ORDER_SECOND, devdtr_init, NULL); - #include <rtems/bsd/local/opt_ddb.h> #ifdef DDB #include <sys/kernel.h> @@ -1551,10 +1600,7 @@ DB_SHOW_COMMAND(cdev, db_show_cdev) SI_FLAG(SI_NAMED); SI_FLAG(SI_CHEAPCLONE); SI_FLAG(SI_CHILD); - SI_FLAG(SI_DEVOPEN); - SI_FLAG(SI_CONSOPEN); SI_FLAG(SI_DUMPDEV); - SI_FLAG(SI_CANDELETE); SI_FLAG(SI_CLONELIST); db_printf("si_flags %s\n", buf); |