Source-Changes-HG archive

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

[src/trunk]: src/sys/dev Add support for detaching audio devices.



details:   https://anonhg.NetBSD.org/src/rev/00470fb801be
branches:  trunk
changeset: 476194:00470fb801be
user:      augustss <augustss%NetBSD.org@localhost>
date:      Thu Sep 09 10:24:39 1999 +0000

description:
Add support for detaching audio devices.

diffstat:

 sys/dev/audio.c    |  330 +++++++++++++++++++++++++++++++++++++---------------
 sys/dev/audio_if.h |    5 +-
 sys/dev/audiovar.h |    5 +-
 sys/dev/midi.c     |    8 +-
 sys/dev/midi_if.h  |    5 +-
 5 files changed, 248 insertions(+), 105 deletions(-)

diffs (truncated from 735 to 300 lines):

diff -r 38237bb6b8a4 -r 00470fb801be sys/dev/audio.c
--- a/sys/dev/audio.c   Thu Sep 09 09:54:08 1999 +0000
+++ b/sys/dev/audio.c   Thu Sep 09 10:24:39 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: audio.c,v 1.115 1999/06/07 19:24:38 thorpej Exp $      */
+/*     $NetBSD: audio.c,v 1.116 1999/09/09 10:24:39 augustss Exp $     */
 
 /*
  * Copyright (c) 1991-1993 Regents of the University of California.
@@ -103,17 +103,17 @@
 int    audiosetinfo __P((struct audio_softc *, struct audio_info *));
 int    audiogetinfo __P((struct audio_softc *, struct audio_info *));
 
-int    audio_open __P((dev_t, int, int, struct proc *));
-int    audio_close __P((dev_t, int, int, struct proc *));
-int    audio_read __P((dev_t, struct uio *, int));
-int    audio_write __P((dev_t, struct uio *, int));
-int    audio_ioctl __P((dev_t, int, caddr_t, int, struct proc *));
-int    audio_poll __P((dev_t, int, struct proc *));
-int    audio_mmap __P((dev_t, int, int));
+int    audio_open __P((dev_t, struct audio_softc *, int, int, struct proc *));
+int    audio_close __P((struct audio_softc *, int, int, struct proc *));
+int    audio_read __P((struct audio_softc *, struct uio *, int));
+int    audio_write __P((struct audio_softc *, struct uio *, int));
+int    audio_ioctl __P((struct audio_softc *, int, caddr_t, int, struct proc *));
+int    audio_poll __P((struct audio_softc *, int, struct proc *));
+int    audio_mmap __P((struct audio_softc *, int, int));
 
-int    mixer_open __P((dev_t, int, int, struct proc *));
-int    mixer_close __P((dev_t, int, int, struct proc *));
-int    mixer_ioctl __P((dev_t, int, caddr_t, int, struct proc *));
+int    mixer_open __P((dev_t, struct audio_softc *, int, int, struct proc *));
+int    mixer_close __P((struct audio_softc *, int, int, struct proc *));
+int    mixer_ioctl __P((struct audio_softc *, int, caddr_t, int, struct proc *));
 static void mixer_remove __P((struct audio_softc *, struct proc *p));
 static void mixer_signal __P((struct audio_softc *));
     
@@ -146,6 +146,8 @@
 
 int    audioprobe __P((struct device *, struct cfdata *, void *));
 void   audioattach __P((struct device *, struct device *, void *));
+int    audiodetach __P((struct device *, int));
+int    audioactivate __P((struct device *, enum devact));
 
 struct portname {
        char    *name;
@@ -185,7 +187,8 @@
        { 8000, AUDIO_ENCODING_ULAW, 8, 1, 0, 1 };
 
 struct cfattach audio_ca = {
-       sizeof(struct audio_softc), audioprobe, audioattach
+       sizeof(struct audio_softc), audioprobe, audioattach, 
+       audiodetach, audioactivate
 };
 
 extern struct cfdriver audio_cd;
@@ -312,6 +315,64 @@
 }
 
 int
+audioactivate(self, act)
+       struct device *self;
+       enum devact act;
+{
+       struct audio_softc *sc = (struct audio_softc *)self;
+
+       switch (act) {
+       case DVACT_ACTIVATE:
+               return (EOPNOTSUPP);
+               break;
+
+       case DVACT_DEACTIVATE:
+               sc->sc_dying = 1;
+               break;
+       }
+       return (0);
+}
+
+int
+audiodetach(self, flags)
+       struct device *self;
+       int flags;
+{
+       struct audio_softc *sc = (struct audio_softc *)self;
+       int maj, mn;
+       int s;
+
+       DPRINTF(("audio_detach: sc=%p flags=%d\n", sc, flags));
+
+       sc->sc_dying = 1;
+
+       wakeup(&sc->sc_wchan);
+       wakeup(&sc->sc_rchan);
+       s = splaudio();
+       if (--sc->sc_refcnt >= 0) {
+               if (tsleep(&sc->sc_refcnt, PZERO, "auddet", hz * 120))
+                       printf("audiodetach: %s didn't detach\n",
+                              sc->dev.dv_xname);
+       }
+       splx(s);
+
+       /* free resources */
+       audio_free_ring(sc, &sc->sc_pr);
+       audio_free_ring(sc, &sc->sc_rr);
+
+       /* locate the major number */
+       for (maj = 0; maj < nchrdev; maj++)
+               if (cdevsw[maj].d_open == audioopen)
+                       break;
+
+       /* Nuke the vnodes for any open instances (calls close). */
+       mn = self->dv_unit;
+       vdevgone(maj, mn, mn, VCHR);
+
+       return (0);
+}
+
+int
 au_portof(sc, name)
        struct  audio_softc *sc;
        char    *name;
@@ -382,7 +443,7 @@
  * Called from hardware driver.  This is where the MI audio driver gets
  * probed/attached to the hardware driver.
  */
-void
+struct device *
 audio_attach_mi(ahwp, hdlp, dev)
        struct audio_hw_if *ahwp;
        void *hdlp;
@@ -393,13 +454,13 @@
 #ifdef DIAGNOSTIC
        if (ahwp == NULL) {
                printf("audio_attach_mi: NULL\n");
-               return;
+               return (0);
        }
 #endif
        arg.type = AUDIODEV_TYPE_AUDIO;
        arg.hwif = ahwp;
        arg.hdl = hdlp;
-       (void)config_found(dev, &arg, audioprint);
+       return (config_found(dev, &arg, audioprint));
 }
 
 #ifdef AUDIO_DEBUG
@@ -476,17 +537,36 @@
        int flags, ifmt;
        struct proc *p;
 {
+       int unit = AUDIOUNIT(dev);
+       struct audio_softc *sc;
+       int error;
 
+       if (unit >= audio_cd.cd_ndevs ||
+           (sc = audio_cd.cd_devs[unit]) == NULL)
+               return (ENXIO);
+
+       if (sc->sc_dying)
+               return (EIO);
+
+       sc->sc_refcnt++;
        switch (AUDIODEV(dev)) {
        case SOUND_DEVICE:
        case AUDIO_DEVICE:
+               error = audio_open(dev, sc, flags, ifmt, p);
+               break;
        case AUDIOCTL_DEVICE:
-               return (audio_open(dev, flags, ifmt, p));
+               error = 0;
+               break;
        case MIXER_DEVICE:
-               return (mixer_open(dev, flags, ifmt, p));
+               error = mixer_open(dev, sc, flags, ifmt, p);
+               break;
        default:
-               return (ENXIO);
+               error = ENXIO;
+               break;
        }
+       if (--sc->sc_refcnt < 0)
+               wakeup(&sc->sc_refcnt);
+       return (error);
 }
 
 int
@@ -495,18 +575,26 @@
        int flags, ifmt;
        struct proc *p;
 {
+       int unit = AUDIOUNIT(dev);
+       struct audio_softc *sc = audio_cd.cd_devs[unit];
+       int error;
 
        switch (AUDIODEV(dev)) {
        case SOUND_DEVICE:
        case AUDIO_DEVICE:
-               return (audio_close(dev, flags, ifmt, p));
+               error = audio_close(sc, flags, ifmt, p);
+               break;
        case MIXER_DEVICE:
-               return (mixer_close(dev, flags, ifmt, p));
+               error = mixer_close(sc, flags, ifmt, p);
+               break;
        case AUDIOCTL_DEVICE:
-               return 0;
+               error = 0;
+               break;
        default:
-               return (ENXIO);
+               error = ENXIO;
+               break;
        }
+       return (error);
 }
 
 int
@@ -515,17 +603,34 @@
        struct uio *uio;
        int ioflag;
 {
+       int unit = AUDIOUNIT(dev);
+       struct audio_softc *sc;
+       int error;
 
+       if (unit >= audio_cd.cd_ndevs ||
+           (sc = audio_cd.cd_devs[unit]) == NULL)
+               return ENXIO;
+
+       if (sc->sc_dying)
+               return (EIO);
+
+       sc->sc_refcnt++;
        switch (AUDIODEV(dev)) {
        case SOUND_DEVICE:
        case AUDIO_DEVICE:
-               return (audio_read(dev, uio, ioflag));
+               error = audio_read(sc, uio, ioflag);
+               break;
        case AUDIOCTL_DEVICE:
        case MIXER_DEVICE:
-               return (ENODEV);
+               error = ENODEV;
+               break;
        default:
-               return (ENXIO);
+               error = ENXIO;
+               break;
        }
+       if (--sc->sc_refcnt < 0)
+               wakeup(&sc->sc_refcnt);
+       return (error);
 }
 
 int
@@ -534,17 +639,34 @@
        struct uio *uio;
        int ioflag;
 {
+       int unit = AUDIOUNIT(dev);
+       struct audio_softc *sc;
+       int error;
 
+       if (unit >= audio_cd.cd_ndevs ||
+           (sc = audio_cd.cd_devs[unit]) == NULL)
+               return ENXIO;
+
+       if (sc->sc_dying)
+               return (EIO);
+
+       sc->sc_refcnt++;
        switch (AUDIODEV(dev)) {
        case SOUND_DEVICE:
        case AUDIO_DEVICE:
-               return (audio_write(dev, uio, ioflag));
+               error = audio_write(sc, uio, ioflag);
+               break;
        case AUDIOCTL_DEVICE:
        case MIXER_DEVICE:
-               return (ENODEV);
+               error = ENODEV;
+               break;
        default:
-               return (ENXIO);
+               error = ENXIO;
+               break;
        }
+       if (--sc->sc_refcnt < 0)
+               wakeup(&sc->sc_refcnt);
+       return (error);
 }
 
 int
@@ -555,17 +677,30 @@
        int flag;
        struct proc *p;
 {
+       int unit = AUDIOUNIT(dev);
+       struct audio_softc *sc = audio_cd.cd_devs[unit];
+       int error;



Home | Main Index | Thread Index | Old Index