Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pad pad(4) mixer has only 1 channel, so return EINVA...



details:   https://anonhg.NetBSD.org/src/rev/8a08c142e686
branches:  trunk
changeset: 993662:8a08c142e686
user:      nakayama <nakayama%NetBSD.org@localhost>
date:      Sun Sep 23 21:18:30 2018 +0000

description:
pad(4) mixer has only 1 channel, so return EINVAL in the case other than 1.

This fixes the following strange output of mixerctl(1):

        outputs.master=255,0
        inputs.dac=255,0

diffstat:

 sys/dev/pad/pad.c |  492 +++++++++++++++++------------------------------------
 1 files changed, 158 insertions(+), 334 deletions(-)

diffs (truncated from 699 to 300 lines):

diff -r 03ef5eadf90f -r 8a08c142e686 sys/dev/pad/pad.c
--- a/sys/dev/pad/pad.c Sun Sep 23 19:32:03 2018 +0000
+++ b/sys/dev/pad/pad.c Sun Sep 23 21:18:30 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pad.c,v 1.53 2018/09/03 16:29:32 riastradh Exp $ */
+/* $NetBSD: pad.c,v 1.54 2018/09/23 21:18:30 nakayama Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,23 +27,18 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.53 2018/09/03 16:29:32 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.54 2018/09/23 21:18:30 nakayama Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/conf.h>
 #include <sys/buf.h>
-#include <sys/file.h>
-#include <sys/filedesc.h>
-#include <sys/vnode.h>
-#include <sys/kauth.h>
 #include <sys/kmem.h>
 #include <sys/kernel.h>
 #include <sys/device.h>
 #include <sys/proc.h>
 #include <sys/condvar.h>
 #include <sys/select.h>
-#include <sys/stat.h>
 #include <sys/audioio.h>
 #include <sys/vnode.h>
 #include <sys/module.h>
@@ -57,17 +52,9 @@
 
 #include <dev/pad/padvar.h>
 
-#define MAXDEVS                128
-#define PADCLONER      254
 #define PADUNIT(x)     minor(x)
 
-#define PADFREQ                44100
-#define PADCHAN                2
-#define PADPREC                16
-#define PADENC         AUDIO_ENCODING_SLINEAR_LE
-
 extern struct cfdriver pad_cd;
-kmutex_t padconfig;
 
 typedef struct pad_block {
        uint8_t         *pb_ptr;
@@ -112,18 +99,7 @@
     const audio_params_t *, const audio_params_t *);
 static void    pad_swvol_dtor(stream_filter_t *);
 
-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 *);
-static int pad_poll(struct file *, int);
-static int pad_stat(struct file *, struct stat *);
-static int pad_mmap(struct file *, off_t *, size_t, int, int *, int *,
-                          struct uvm_object **, int *);
+static bool    pad_is_attached;        /* Do we have an audio* child? */
 
 static const struct audio_hw_if pad_hw_if = {
        .open = pad_audio_open,
@@ -144,8 +120,8 @@
 
 #define PAD_NFORMATS   1
 static const struct audio_format pad_formats[PAD_NFORMATS] = {
-       { NULL, AUMODE_PLAY|AUMODE_RECORD, PADENC, PADPREC, PADPREC,
-         PADCHAN, AUFMT_STEREO, 1, { PADFREQ } },
+       { NULL, AUMODE_PLAY|AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16,
+         2, AUFMT_STEREO, 1, { 44100 } },
 };
 
 extern void    padattach(int);
@@ -154,13 +130,13 @@
 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);
+dev_type_close(pad_close);
+dev_type_read(pad_read);
 
 const struct cdevsw pad_cdevsw = {
        .d_open = pad_open,
-       .d_close = cdev_pad_close,
-       .d_read = cdev_pad_read,
+       .d_close = pad_close,
+       .d_read = pad_read,
        .d_write = nowrite,
        .d_ioctl = noioctl,
        .d_stop = nostop,
@@ -172,36 +148,34 @@
        .d_flag = D_OTHER | D_MPSAFE,
 };
 
-const struct fileops pad_fileops = {
-       .fo_name = "pad",
-       .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 = fops_pad_close,
-       .fo_mmap = pad_mmap,
-       .fo_kqfilter = pad_kqfilter,
-       .fo_restart = fnullop_restart
-};
-
 CFATTACH_DECL2_NEW(pad, sizeof(pad_softc_t), pad_match, pad_attach, pad_detach,
     NULL, NULL, pad_childdet);
 
 void
 padattach(int n)
 {
-       int error;
+       int i, err;
+       cfdata_t cf;
+
+       aprint_debug("pad: requested %d units\n", n);
 
-       error = config_cfattach_attach(pad_cd.cd_name, &pad_ca);
-       if (error) {
+       err = config_cfattach_attach(pad_cd.cd_name, &pad_ca);
+       if (err) {
                aprint_error("%s: couldn't register cfattach: %d\n",
-                   pad_cd.cd_name, error);
+                   pad_cd.cd_name, err);
                config_cfdriver_detach(&pad_cd);
                return;
        }
-       mutex_init(&padconfig, MUTEX_DEFAULT, IPL_NONE);
+
+       for (i = 0; i < n; i++) {
+               cf = kmem_alloc(sizeof(struct cfdata), KM_SLEEP);
+               cf->cf_name = pad_cd.cd_name;
+               cf->cf_atname = pad_cd.cd_name;
+               cf->cf_unit = i;
+               cf->cf_fstate = FSTATE_STAR;
+
+               (void)config_attach_pseudo(cf);
+       }
 
        return;
 }
@@ -244,7 +218,7 @@
        KASSERT(mutex_owned(&sc->sc_lock));
        KASSERT(pb != NULL);
 
-       if (sc->sc_buflen < (uint)blksize)
+       if (sc->sc_buflen < blksize)
                return ERESTART;
 
        pb->pb_ptr = (sc->sc_audiobuf + sc->sc_rpos);
@@ -279,23 +253,59 @@
 static void
 pad_attach(device_t parent, device_t self, void *opaque)
 {
+       pad_softc_t *sc = device_private(self);
+
        aprint_normal_dev(self, "outputs: 44100Hz, 16-bit, stereo\n");
 
+       sc->sc_dev = self;
+       sc->sc_open = 0;
+       if (auconv_create_encodings(pad_formats, PAD_NFORMATS,
+           &sc->sc_encodings) != 0) {
+               aprint_error_dev(self, "couldn't create encodings\n");
+               return;
+       }
+
+       cv_init(&sc->sc_condvar, device_xname(self));
+       mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
+       mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_NONE);
+
+       sc->sc_swvol = 255;
+       sc->sc_buflen = 0;
+       sc->sc_rpos = sc->sc_wpos = 0;
+       sc->sc_audiodev = (void *)audio_attach_mi(&pad_hw_if, sc, sc->sc_dev);
+
+       if (!pmf_device_register(self, NULL, NULL))
+               aprint_error_dev(self, "couldn't establish power handler\n");
+
+       pad_is_attached = true;
        return;
 }
 
 static int
 pad_detach(device_t self, int flags)
 {
-       pad_softc_t *sc;
-       int cmaj, mn;
+       pad_softc_t *sc = device_private(self);
+       int cmaj, mn, rc;
 
-       sc = device_private(self);
+       if (!pad_is_attached)
+               return ENXIO;
+
        cmaj = cdevsw_lookup_major(&pad_cdevsw);
-       mn = device_unit(sc->sc_dev);
-       if (!sc->sc_dying)
-               vdevgone(cmaj, mn, mn, VCHR);
+       mn = device_unit(self);
+       vdevgone(cmaj, mn, mn, VCHR);
+
+       if ((rc = config_detach_children(self, flags)) != 0)
+               return rc;
+
+       pmf_device_deregister(self);
 
+       mutex_destroy(&sc->sc_lock);
+       mutex_destroy(&sc->sc_intr_lock);
+       cv_destroy(&sc->sc_condvar);
+
+       auconv_delete_encodings(sc->sc_encodings);
+
+       pad_is_attached = false;
        return 0;
 }
 
@@ -303,264 +313,56 @@
 pad_open(dev_t dev, int flags, int fmt, struct lwp *l)
 {
        pad_softc_t *sc;
-       struct file *fp;
-       device_t paddev;
-       cfdata_t cf;
-       int error, fd, i;
 
-       error = 0;
-
-       mutex_enter(&padconfig);
-       if (PADUNIT(dev) == PADCLONER) {
-               for (i = 0; i < MAXDEVS; i++) {
-                       if (device_lookup(&pad_cd, i) == NULL)
-                               break;
-               }
-               if (i == MAXDEVS)
-                       goto bad;
-       } else {
-               if (PADUNIT(dev) >= MAXDEVS)
-                       goto bad;
-               i = PADUNIT(dev);
-       }
-
-       cf = kmem_alloc(sizeof(struct cfdata), KM_SLEEP);
-       cf->cf_name = pad_cd.cd_name;
-       cf->cf_atname = pad_cd.cd_name;
-       cf->cf_unit = i;
-       cf->cf_fstate = FSTATE_STAR;
-
-       bool existing = false;
-       paddev = device_lookup(&pad_cd, minor(dev));
-       if (paddev == NULL)
-               paddev = config_attach_pseudo(cf);
-       else
-               existing = true;
-       if (paddev == NULL)
-               goto bad;
-
-       sc = device_private(paddev);
-       if (sc == NULL)
-               goto bad;
-
-       if (sc->sc_open == 1) {
-               mutex_exit(&padconfig);
-               return EBUSY;
-       }
-
-       sc->sc_dev = paddev;
-       sc->sc_dying = false;
-
-       if (PADUNIT(dev) == PADCLONER) {
-               error = fd_allocfile(&fp, &fd);
-               if (error) {
-                       if (existing == false)
-                               config_detach(sc->sc_dev, 0);
-                       mutex_exit(&padconfig);
-                       return error;
-               }
-       }
-
-       if (auconv_create_encodings(pad_formats, PAD_NFORMATS,
-           &sc->sc_encodings) != 0) {
-               aprint_error_dev(sc->sc_dev, "couldn't create encodings\n");
-               if (existing == false)
-                       config_detach(sc->sc_dev, 0);
-               mutex_exit(&padconfig);
-               return EINVAL;
-       }



Home | Main Index | Thread Index | Old Index