Module Name: src Committed By: nat Date: Sun Jul 2 13:32:51 UTC 2017
Modified Files: src/sys/dev/pad: pad.c Log Message: If a particular pad device is opened, ie pad1 then configure and use pad1 if it is not already configured. This improves scriptability as you will know the particular pad(4) device you have opened. pad(4) devices still have a cloning interface if pad device (minor number 254) is opened it will attach the next free device. This action can be repeated. XXX update MAKEDEV scripts to make /dev/pad the cloning device. Ok christos@. To generate a diff of this commit: cvs rdiff -u -r1.40 -r1.41 src/sys/dev/pad/pad.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pad/pad.c diff -u src/sys/dev/pad/pad.c:1.40 src/sys/dev/pad/pad.c:1.41 --- src/sys/dev/pad/pad.c:1.40 Sun Jul 2 05:59:27 2017 +++ src/sys/dev/pad/pad.c Sun Jul 2 13:32:50 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: pad.c,v 1.40 2017/07/02 05:59:27 nat Exp $ */ +/* $NetBSD: pad.c,v 1.41 2017/07/02 13:32:50 nat Exp $ */ /*- * Copyright (c) 2007 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.40 2017/07/02 05:59:27 nat Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.41 2017/07/02 13:32:50 nat Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -58,6 +58,7 @@ __KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.40 #include <dev/pad/padvar.h> #define MAXDEVS 128 +#define PADCLONER 254 #define PADUNIT(x) minor(x) #define PADFREQ 44100 @@ -110,8 +111,11 @@ static stream_filter_t *pad_swvol_filter const audio_params_t *, const audio_params_t *); static void pad_swvol_dtor(stream_filter_t *); -static int pad_close(struct file *); -static int pad_read(struct file *, off_t *, struct uio *, kauth_cred_t, int); +static int pad_close(struct pad_softc *); +static int pad_read(struct pad_softc *, off_t *, struct uio *, kauth_cred_t, int); + +static int fops_pad_close(struct file *); +static int fops_pad_read(struct file *, off_t *, struct uio *, kauth_cred_t, int); static int pad_write(struct file *, off_t *, struct uio *, kauth_cred_t, int); static int pad_ioctl(struct file *, u_long, void *); static int pad_kqfilter(struct file *, struct knote *); @@ -149,11 +153,13 @@ static int pad_add_block(pad_softc_t *, static int pad_get_block(pad_softc_t *, pad_block_t *, int); dev_type_open(pad_open); +dev_type_close(cdev_pad_close); +dev_type_read(cdev_pad_read); const struct cdevsw pad_cdevsw = { .d_open = pad_open, - .d_close = noclose, - .d_read = noread, + .d_close = cdev_pad_close, + .d_read = cdev_pad_read, .d_write = nowrite, .d_ioctl = noioctl, .d_stop = nostop, @@ -166,13 +172,13 @@ const struct cdevsw pad_cdevsw = { }; const struct fileops pad_fileops = { - .fo_read = pad_read, + .fo_read = fops_pad_read, .fo_write = pad_write, .fo_ioctl = pad_ioctl, .fo_fcntl = fnullop_fcntl, .fo_stat = pad_stat, .fo_poll = pad_poll, - .fo_close = pad_close, + .fo_close = fops_pad_close, .fo_mmap = pad_mmap, .fo_kqfilter = pad_kqfilter, .fo_restart = fnullop_restart @@ -308,7 +314,7 @@ pad_detach(device_t self, int flags) auconv_delete_encodings(sc->sc_encodings); - return rc; + return 0; } int @@ -320,12 +326,18 @@ pad_open(dev_t dev, int flags, int fmt, cfdata_t cf; int error, fd, i; - for (i = 0; i < MAXDEVS; i++) { - if (device_lookup(&pad_cd, i) == NULL) - break; + if (PADUNIT(dev) == PADCLONER) { + for (i = 0; i < MAXDEVS; i++) { + if (device_lookup(&pad_cd, i) == NULL) + break; + } + if (i == MAXDEVS) + return ENXIO; + } else { + if (PADUNIT(dev) >= MAXDEVS) + return ENXIO; + i = PADUNIT(dev); } - if (i == MAXDEVS) - return ENXIO; cf = kmem_alloc(sizeof(struct cfdata), KM_SLEEP); cf->cf_name = pad_cd.cd_name; @@ -333,18 +345,27 @@ pad_open(dev_t dev, int flags, int fmt, cf->cf_unit = i; cf->cf_fstate = FSTATE_STAR; - paddev = config_attach_pseudo(cf); + if (device_lookup(&pad_cd, minor(dev)) == NULL) + paddev = config_attach_pseudo(cf); + else + paddev = device_lookup(&pad_cd, minor(dev)); + sc = device_private(paddev); - sc->sc_dev = paddev; - sc->sc_dying = false; + if (sc == NULL) + return ENXIO; if (sc->sc_open == 1) return EBUSY; - error = fd_allocfile(&fp, &fd); - if (error) { - config_detach(sc->sc_dev, 0); - return error; + sc->sc_dev = paddev; + sc->sc_dying = false; + + if (PADUNIT(dev) == PADCLONER) { + error = fd_allocfile(&fp, &fd); + if (error) { + config_detach(sc->sc_dev, 0); + return error; + } } if (auconv_create_encodings(pad_formats, PAD_NFORMATS, @@ -366,28 +387,47 @@ pad_open(dev_t dev, int flags, int fmt, if (!pmf_device_register(sc->sc_dev, NULL, NULL)) aprint_error_dev(sc->sc_dev, "couldn't establish power handler\n"); - error = fd_clone(fp, fd, flags, &pad_fileops, sc); - KASSERT(error == EMOVEFD); - + if (PADUNIT(dev) == PADCLONER) { + error = fd_clone(fp, fd, flags, &pad_fileops, sc); + KASSERT(error == EMOVEFD); + } sc->sc_open = 1; return error; } static int -pad_close(struct file *fp) +pad_close(struct pad_softc *sc) +{ + if (sc == NULL) + return ENXIO; + + return config_detach(sc->sc_dev, DETACH_FORCE); +} + +static int +fops_pad_close(struct file *fp) { pad_softc_t *sc; + int error; sc = fp->f_pad; - if (sc == NULL) - return ENXIO; - config_detach(sc->sc_dev, DETACH_FORCE); + error = pad_close(sc); - fp->f_pad = NULL; + if (error == 0) + fp->f_pad = NULL; - return 0; + return error; +} + +int +cdev_pad_close(dev_t dev, int flags, int ifmt, struct lwp *l) +{ + pad_softc_t *sc; + sc = device_private(device_lookup(&pad_cd, PADUNIT(dev))); + + return pad_close(sc); } static int @@ -448,22 +488,41 @@ pad_mmap(struct file *fp, off_t *offp, s #define BYTESTOSLEEP (int64_t)(PAD_BLKSIZE) #define TIMENEXTREAD (int64_t)(BYTESTOSLEEP * 1000000 / PAD_BYTES_PER_SEC) +int +cdev_pad_read(dev_t dev, struct uio *uio, int ioflag) +{ + pad_softc_t *sc; + sc = device_private(device_lookup(&pad_cd, PADUNIT(dev))); + if (sc == NULL) + return ENXIO; + + return pad_read(sc, NULL, uio, NULL, ioflag); +} + static int -pad_read(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred, +fops_pad_read(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred, + int ioflag) +{ + pad_softc_t *sc; + + sc = fp->f_pad; + if (sc == NULL) + return ENXIO; + + return pad_read(sc, offp, uio, cred, ioflag); +} + +static int +pad_read(struct pad_softc *sc, off_t *offp, struct uio *uio, kauth_cred_t cred, int ioflag) { struct timeval now; uint64_t nowusec, lastusec; - pad_softc_t *sc; pad_block_t pb; void (*intr)(void *); void *intrarg; int err, wait_ticks; - sc = fp->f_pad; - if (sc == NULL) - return ENXIO; - err = 0; while (uio->uio_resid > 0 && !err) {