From ffcdaf144d1beb9591d4020aa44839c9192bb4b6 Mon Sep 17 00:00:00 2001 From: augustss Date: Sat, 6 Sep 1997 01:14:48 +0000 Subject: [PATCH] Move around splaudio() to (hopefully) get rid of some rare race conditions. Add a missing call to round_blocksize. Add some MIDI stuff that will be used in the future. --- sys/dev/audio.c | 80 ++++++++++++++++++++++++++-------------------- sys/dev/audio_if.h | 26 +++++++++++++-- 2 files changed, 70 insertions(+), 36 deletions(-) diff --git a/sys/dev/audio.c b/sys/dev/audio.c index 0c18fa14bdf4..9e51f24a667e 100644 --- a/sys/dev/audio.c +++ b/sys/dev/audio.c @@ -1,4 +1,4 @@ -/* $NetBSD: audio.c,v 1.70 1997/08/27 18:54:28 thorpej Exp $ */ +/* $NetBSD: audio.c,v 1.71 1997/09/06 01:14:48 augustss Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -161,12 +161,6 @@ struct cfdriver audio_cd = { NULL, "audio", DV_DULL }; -struct audio_attach_args { - struct audio_hw_if *ahw; - struct midi_hw_if *mhw; - void *hdl; -}; - int audioprobe(parent, match, aux) struct device *parent; @@ -179,6 +173,10 @@ audioprobe(parent, match, aux) { struct audio_attach_args *sa = aux; + DPRINTF(("audioprobe: done=%d sa=%p hw=%p\n", + sa->audiodone, sa, sa->ahw)); + if (sa->audiodone) + return 0; return sa->ahw != 0; } @@ -195,6 +193,8 @@ audioattach(parent, self, aux) printf("\n"); + sa->audiodone++; + #ifdef DIAGNOSTIC if (hwp == 0 || hwp->open == 0 || @@ -255,7 +255,7 @@ audioattach(parent, self, aux) /* * Called from hardware driver. This is where the MI audio driver gets - * probed/attached to the hardare driver. + * probed/attached to the hardware driver. */ void audio_attach_mi(ahwp, mhwp, hdlp, dev) @@ -269,7 +269,9 @@ audio_attach_mi(ahwp, mhwp, hdlp, dev) arg.ahw = ahwp; arg.mhw = mhwp; arg.hdl = hdlp; - (void)config_found(dev, &arg, 0); + arg.audiodone = arg.mididone = 0; + while(config_found(dev, &arg, 0)) + ; } #ifdef AUDIO_DEBUG @@ -573,7 +575,7 @@ audio_sleep_timo(chan, label, timo) if (!label) label = "audio"; - + *chan = 1; st = tsleep(chan, PWAIT | PCATCH, label, timo); *chan = 0; @@ -592,6 +594,7 @@ audio_sleep(chan, label) return audio_sleep_timo(chan, label, 0); } +/* call at splaudio() */ static __inline void audio_wakeup(chan) int *chan; @@ -746,6 +749,7 @@ audio_drain(sc) { int error, drops; struct audio_ringbuffer *cb = &sc->sc_pr; + int s; if (sc->sc_pr.mmapped || sc->sc_pr.used <= 0) return 0; @@ -753,7 +757,7 @@ audio_drain(sc) /* We've never started playing, probably because the * block was too short. Pad it and start now. */ - int s, cc; + int cc; u_char *inp = cb->inp; cc = cb->blksize - (inp - cb->start) % cb->blksize; @@ -782,17 +786,18 @@ audio_drain(sc) } #endif drops = cb->drops; - while (cb->drops == drops) { + error = 0; + s = splaudio(); + while (cb->drops == drops && !error) { DPRINTF(("audio_drain: used=%d, drops=%ld\n", sc->sc_pr.used, cb->drops)); /* * When the process is exiting, it ignores all signals and * we can't interrupt this sleep, so we set a timeout just in case. */ error = audio_sleep_timo(&sc->sc_wchan, "aud dr", 30*hz); - if (error) - return (error); } - return (0); + splx(s); + return error; } /* @@ -879,12 +884,12 @@ audio_read(dev, uio, ioflag) sc->sc_pr.stamp, sc->sc_wstamp)); if (ioflag & IO_NDELAY) { splx(s); - return (EWOULDBLOCK); + return EWOULDBLOCK; } error = audio_sleep(&sc->sc_rchan, "aud hr"); if (error) { splx(s); - return (error); + return error; } } splx(s); @@ -901,27 +906,29 @@ audio_read(dev, uio, ioflag) return (error); } while (uio->uio_resid > 0 && !error) { + s = splaudio(); while (cb->used <= 0) { if (ioflag & IO_NDELAY) { - error = EWOULDBLOCK; - return (error); + splx(s); + return EWOULDBLOCK; } - s = splaudio(); if (!sc->sc_rbus) { error = audiostartr(sc); - if (error) goto err; + if (error) { + splx(s); + return error; + } } #ifdef AUDIO_DEBUG if (audiodebug > 2) printf("audio_read: sleep used=%d\n", cb->used); #endif error = audio_sleep(&sc->sc_rchan, "aud rd"); - err: - splx(s); - if (error) - return (error); + if (error) { + splx(s); + return error; + } } - s = splaudio(); used = cb->used; outp = cb->outp; cb->copying = 1; @@ -1133,16 +1140,20 @@ audio_write(dev, uio, ioflag) error = 0; while (uio->uio_resid > 0 && !error) { + s = splaudio(); while (cb->used >= cb->usedhigh) { DPRINTF(("audio_write: sleep used=%d lowat=%d hiwat=%d\n", cb->used, cb->usedlow, cb->usedhigh)); - if (ioflag & IO_NDELAY) + if (ioflag & IO_NDELAY) { + splx(s); return (EWOULDBLOCK); + } error = audio_sleep(&sc->sc_wchan, "aud wr"); - if (error) - return (error); + if (error) { + splx(s); + return error; + } } - s = splaudio(); used = cb->used; inp = cb->inp; cb->copying = 1; @@ -1226,7 +1237,7 @@ audio_write(dev, uio, ioflag) cb->needfill = 0; cb->copying = 0; if (!sc->sc_pbus && !cb->pause) - error = audiostartp(sc); + error = audiostartp(sc); /* XXX should not clobber error */ splx(s); if (cc) { #ifdef AUDIO_DEBUG @@ -2090,14 +2101,15 @@ audiosetinfo(sc, ai) audio_clear(sc); cleared = 1; - /* No need to check the blocksize, audio_initbufs() does that. */ if (ai->blocksize == 0) { audio_calc_blksize(sc, AUMODE_RECORD); audio_calc_blksize(sc, AUMODE_PLAY); sc->sc_blkset = 0; } else { - sc->sc_pr.blksize = ai->blocksize; - sc->sc_rr.blksize = ai->blocksize; + int bs = ai->blocksize; + if (hw->round_blocksize) + bs = hw->round_blocksize(sc->hw_hdl, bs); + sc->sc_pr.blksize = sc->sc_rr.blksize = bs; sc->sc_blkset = 1; } } diff --git a/sys/dev/audio_if.h b/sys/dev/audio_if.h index 6f9638dc6a57..385ae70ba533 100644 --- a/sys/dev/audio_if.h +++ b/sys/dev/audio_if.h @@ -1,4 +1,4 @@ -/* $NetBSD: audio_if.h,v 1.20 1997/08/24 22:31:30 augustss Exp $ */ +/* $NetBSD: audio_if.h,v 1.21 1997/09/06 01:14:49 augustss Exp $ */ /* * Copyright (c) 1994 Havard Eidnes. @@ -123,7 +123,29 @@ struct audio_hw_if { int (*get_props)__P((void *)); /* device properties */ }; -struct midi_hw_if; +struct midi_info { + char *name; /* Name of MIDI hardware */ + int props; +}; +#define MIDI_PROP_OUT_INTR 1 + +struct midi_hw_if { + int (*open)__P((void *, int, /* open hardware */ + void (*)__P((void *, int)), + void (*)__P((void *)), + void *)); + void (*close)__P((void *)); /* close hardware */ + int (*output)__P((void *, int)); /* output a byte */ + void (*getinfo)__P((void *, struct midi_info *)); + int (*ioctl)__P((u_long, caddr_t, int, struct proc *)); +}; + +struct audio_attach_args { + struct audio_hw_if *ahw; + struct midi_hw_if *mhw; + void *hdl; + char audiodone, mididone; +}; /* Attach the MI driver(s) to the MD driver. */ extern void audio_attach_mi __P((struct audio_hw_if *, struct midi_hw_if *, void *, struct device *));