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