diff options
author | tanimura <tanimura@FreeBSD.org> | 2002-01-01 17:36:26 +0000 |
---|---|---|
committer | tanimura <tanimura@FreeBSD.org> | 2002-01-01 17:36:26 +0000 |
commit | a46d1d7f893729bbd95a207f15da7cf72690209c (patch) | |
tree | 2bf9e44e75f8effab6b654ff7122f77f882aeee0 /sys | |
parent | cfe419eb213db0b2937a261122224454d75db7a4 (diff) | |
download | FreeBSD-src-a46d1d7f893729bbd95a207f15da7cf72690209c.zip FreeBSD-src-a46d1d7f893729bbd95a207f15da7cf72690209c.tar.gz |
- Do not uiomove with a mutex locked.
- Move from msleep/wakeup to condvar.
- Return either zero or a positive errno value from a function.
Return additional result via references.
- Unify the typedef of callback functions.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/sound/isa/emu8000.c | 20 | ||||
-rw-r--r-- | sys/dev/sound/isa/gusmidi.c | 14 | ||||
-rw-r--r-- | sys/dev/sound/isa/mpu.c | 34 | ||||
-rw-r--r-- | sys/dev/sound/isa/opl.c | 19 | ||||
-rw-r--r-- | sys/dev/sound/isa/uartsio.c | 13 | ||||
-rw-r--r-- | sys/dev/sound/midi/midi.c | 71 | ||||
-rw-r--r-- | sys/dev/sound/midi/midi.h | 1 | ||||
-rw-r--r-- | sys/dev/sound/midi/midibuf.c | 350 | ||||
-rw-r--r-- | sys/dev/sound/midi/midibuf.h | 32 | ||||
-rw-r--r-- | sys/dev/sound/midi/midisynth.c | 88 | ||||
-rw-r--r-- | sys/dev/sound/midi/midisynth.h | 4 | ||||
-rw-r--r-- | sys/dev/sound/midi/miditypes.h | 2 | ||||
-rw-r--r-- | sys/dev/sound/midi/sequencer.c | 130 | ||||
-rw-r--r-- | sys/dev/sound/midi/sequencer.h | 6 | ||||
-rw-r--r-- | sys/dev/sound/pci/csamidi.c | 28 |
15 files changed, 387 insertions, 425 deletions
diff --git a/sys/dev/sound/isa/emu8000.c b/sys/dev/sound/isa/emu8000.c index ea434e6..af9e3b2 100644 --- a/sys/dev/sound/isa/emu8000.c +++ b/sys/dev/sound/isa/emu8000.c @@ -803,21 +803,28 @@ emu_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td) } static int -emu_callback(mididev_info *devinfo, int reason) +emu_callback(void *d, int reason) { + mididev_info *devinfo; + + devinfo = (mididev_info *)d; + mtx_assert(&devinfo->flagqueue_mtx, MA_OWNED); return (0); } static int -emu_readraw(mididev_info *md, u_char *buf, int len, int nonblock) +emu_readraw(mididev_info *md, u_char *buf, int len, int *lenr, int nonblock) { sc_p scp; int unit; if (md == NULL) return (ENXIO); + if (lenr == NULL) + return (EINVAL); + unit = md->unit; scp = md->softc; if ((md->fflags & FREAD) == 0) { @@ -826,17 +833,22 @@ emu_readraw(mididev_info *md, u_char *buf, int len, int nonblock) } /* NOP. */ + *lenr = 0; + return (0); } static int -emu_writeraw(mididev_info *md, u_char *buf, int len, int nonblock) +emu_writeraw(mididev_info *md, u_char *buf, int len, int *lenw, int nonblock) { sc_p scp; int unit; if (md == NULL) return (ENXIO); + if (lenw == NULL) + return (EINVAL); + unit = md->unit; scp = md->softc; if ((md->fflags & FWRITE) == 0) { @@ -845,6 +857,8 @@ emu_writeraw(mididev_info *md, u_char *buf, int len, int nonblock) } /* NOP. */ + *lenw = 0; + return (0); } diff --git a/sys/dev/sound/isa/gusmidi.c b/sys/dev/sound/isa/gusmidi.c index 797d168..e5ff9cf 100644 --- a/sys/dev/sound/isa/gusmidi.c +++ b/sys/dev/sound/isa/gusmidi.c @@ -289,7 +289,7 @@ gusmidi_intr(void *arg) sc_p scp; u_char c; mididev_info *devinfo; - int stat, did_something; + int stat, did_something, leni; scp = (sc_p)arg; devinfo = scp->devinfo; @@ -308,13 +308,13 @@ gusmidi_intr(void *arg) (!(devinfo->flags & MIDI_F_BUSY) || !(devinfo->fflags & FWRITE))) { midibuf_input_intr(&devinfo->midi_dbuf_passthru, - &c, sizeof c); + &c, sizeof c, &leni); devinfo->callback(devinfo, MIDI_CB_START | MIDI_CB_WR); } if ((devinfo->flags & MIDI_F_READING) && c != 0xfe) { midibuf_input_intr(&devinfo->midi_dbuf_in, - &c, sizeof c); + &c, sizeof c, &leni); } did_something = 1; } else @@ -342,10 +342,13 @@ gusmidi_intr(void *arg) } static int -gusmidi_callback(mididev_info *d, int reason) +gusmidi_callback(void *di, int reason) { int unit; sc_p scp; + mididev_info *d; + + d = (mididev_info *)di; mtx_assert(&d->flagqueue_mtx, MA_OWNED); @@ -424,6 +427,7 @@ gusmidi_xmit(sc_p scp) register mididev_info *devinfo; register midi_dbuf *dbuf; u_char c; + int leno; devinfo = scp->devinfo; @@ -450,7 +454,7 @@ gusmidi_xmit(sc_p scp) mtx_lock(&scp->mtx); if (gusmidi_readport(scp, PORT_ST) & MIDIST_TXDONE) { /* Send the data. */ - midibuf_output_intr(dbuf, &c, sizeof(c)); + midibuf_output_intr(dbuf, &c, sizeof(c), &leno); gusmidi_writeport(scp, PORT_TX, c); /* We are playing now. */ } else { diff --git a/sys/dev/sound/isa/mpu.c b/sys/dev/sound/isa/mpu.c index ed9b746..b79a3dd 100644 --- a/sys/dev/sound/isa/mpu.c +++ b/sys/dev/sound/isa/mpu.c @@ -148,7 +148,7 @@ static int mpu_uartmode(sc_p scp); static int mpu_waitack(sc_p scp); static int mpu_status(sc_p scp); static int mpu_command(sc_p scp, u_int8_t value); -static int mpu_readdata(sc_p scp); +static int mpu_readdata(sc_p scp, u_int8_t *value); static int mpu_writedata(sc_p scp, u_int8_t value); static u_int mpu_readport(sc_p scp, int off); static void mpu_writeport(sc_p scp, int off, u_int8_t value); @@ -454,6 +454,7 @@ mpu_intr(void *arg) sc_p scp; u_char c; mididev_info *devinfo; + int leni; scp = (sc_p)arg; devinfo = scp->devinfo; @@ -464,16 +465,16 @@ mpu_intr(void *arg) /* Read the received data. */ while ((mpu_status(scp) & MPU_INPUTBUSY) == 0) { /* Receive the data. */ - c = mpu_readdata(scp); + mpu_readdata(scp, &c); mtx_unlock(&scp->mtx); /* Queue into the passthru buffer and start transmitting if we can. */ if ((devinfo->flags & MIDI_F_PASSTHRU) != 0 && ((devinfo->flags & MIDI_F_BUSY) == 0 || (devinfo->fflags & FWRITE) == 0)) { - midibuf_input_intr(&devinfo->midi_dbuf_passthru, &c, sizeof(c)); + midibuf_input_intr(&devinfo->midi_dbuf_passthru, &c, sizeof(c), &leni); devinfo->callback(devinfo, MIDI_CB_START | MIDI_CB_WR); } /* Queue if we are reading. Discard an active sensing. */ if ((devinfo->flags & MIDI_F_READING) != 0 && c != 0xfe) { - midibuf_input_intr(&devinfo->midi_dbuf_in, &c, sizeof(c)); + midibuf_input_intr(&devinfo->midi_dbuf_in, &c, sizeof(c), &leni); } mtx_lock(&scp->mtx); } @@ -485,10 +486,13 @@ mpu_intr(void *arg) } static int -mpu_callback(mididev_info *d, int reason) +mpu_callback(void *di, int reason) { int unit; sc_p scp; + mididev_info *d; + + d = (mididev_info *)di; mtx_assert(&d->flagqueue_mtx, MA_OWNED); @@ -553,6 +557,7 @@ mpu_xmit(sc_p scp) register mididev_info *devinfo; register midi_dbuf *dbuf; u_char c; + int leno; devinfo = scp->devinfo; @@ -573,7 +578,7 @@ mpu_xmit(sc_p scp) /* XXX Wait until we can write the data. */ if ((mpu_status(scp) & MPU_OUTPUTBUSY) == 0) { /* Send the data. */ - midibuf_output_intr(dbuf, &c, sizeof(c)); + midibuf_output_intr(dbuf, &c, sizeof(c), &leno); mpu_writedata(scp, c); /* We are playing now. */ devinfo->flags |= MIDI_F_WRITING; @@ -639,12 +644,12 @@ mpu_uartmode(sc_p scp) static int mpu_waitack(sc_p scp) { - int i, resp; + int i; + u_int8_t resp; resp = 0; for (i = 0 ; i < MPU_TRYDATA ; i++) { - resp = mpu_readdata(scp); - if (resp >= 0) + if (mpu_readdata(scp, &resp) == 0) break; } if (resp != MPU_ACK) @@ -680,17 +685,22 @@ mpu_command(sc_p scp, u_int8_t value) /* Reads a byte of data. */ static int -mpu_readdata(sc_p scp) +mpu_readdata(sc_p scp, u_int8_t *value) { u_int status; + if (value == NULL) + return (EINVAL); + /* Is the interface ready to write? */ status = mpu_status(scp); if ((status & MPU_INPUTBUSY) != 0) /* The interface is busy. */ - return (-EAGAIN); + return (EAGAIN); + + *value = (u_int8_t)(mpu_readport(scp, MPU_DATAPORT) & 0xff); - return (int)mpu_readport(scp, MPU_DATAPORT) & 0xff; + return (0); } /* Writes a byte of data. */ diff --git a/sys/dev/sound/isa/opl.c b/sys/dev/sound/isa/opl.c index 5ebf974..345bebb 100644 --- a/sys/dev/sound/isa/opl.c +++ b/sys/dev/sound/isa/opl.c @@ -907,10 +907,13 @@ opl_ioctl(dev_t i_dev, u_long cmd, caddr_t arg, int mode, struct thread *td) } static int -opl_callback(mididev_info *devinfo, int reason) +opl_callback(void *d, int reason) { int unit; sc_p scp; + mididev_info *devinfo; + + devinfo = (mididev_info *)d; mtx_assert(&devinfo->flagqueue_mtx, MA_OWNED); @@ -948,13 +951,16 @@ opl_callback(mididev_info *devinfo, int reason) } static int -opl_readraw(mididev_info *md, u_char *buf, int len, int nonblock) +opl_readraw(mididev_info *md, u_char *buf, int len, int *lenr, int nonblock) { sc_p scp; int unit; if (md == NULL) return (ENXIO); + if (lenr == NULL) + return (EINVAL); + unit = md->unit; scp = md->softc; if ((md->fflags & FREAD) == 0) { @@ -963,17 +969,22 @@ opl_readraw(mididev_info *md, u_char *buf, int len, int nonblock) } /* NOP. */ + *lenr = 0; + return (0); } static int -opl_writeraw(mididev_info *md, u_char *buf, int len, int nonblock) +opl_writeraw(mididev_info *md, u_char *buf, int len, int *lenw, int nonblock) { sc_p scp; int unit; if (md == NULL) return (ENXIO); + if (lenw == NULL) + return (EINVAL); + unit = md->unit; scp = md->softc; if ((md->fflags & FWRITE) == 0) { @@ -982,6 +993,8 @@ opl_writeraw(mididev_info *md, u_char *buf, int len, int nonblock) } /* NOP. */ + *lenw = 0; + return (0); } diff --git a/sys/dev/sound/isa/uartsio.c b/sys/dev/sound/isa/uartsio.c index 07c9be3..f81f787 100644 --- a/sys/dev/sound/isa/uartsio.c +++ b/sys/dev/sound/isa/uartsio.c @@ -320,10 +320,13 @@ uartsio_intr(void *arg) } static int -uartsio_callback(mididev_info *d, int reason) +uartsio_callback(void *di, int reason) { int unit; sc_p scp; + mididev_info *d; + + d = (mididev_info *)di; mtx_assert(&d->flagqueue_mtx, MA_OWNED); @@ -386,7 +389,7 @@ uartsio_xmit(sc_p scp) { mididev_info *devinfo; midi_dbuf *dbuf; - int lsr, msr, iir, i, txsize; + int lsr, msr, iir, i, txsize, leni, leno; u_char c[TX_FIFO_SIZE]; devinfo = scp->devinfo; @@ -406,12 +409,12 @@ uartsio_xmit(sc_p scp) mtx_unlock(&scp->mtx); /* Queue into the passthru buffer and start transmitting if we can. */ if ((devinfo->flags & MIDI_F_PASSTHRU) != 0 && ((devinfo->flags & MIDI_F_BUSY) == 0 || (devinfo->fflags & FWRITE) == 0)) { - midibuf_input_intr(&devinfo->midi_dbuf_passthru, &c[0], sizeof(c[0])); + midibuf_input_intr(&devinfo->midi_dbuf_passthru, &c[0], sizeof(c[0]), &leni); devinfo->flags |= MIDI_F_WRITING; } /* Queue if we are reading. Discard an active sensing. */ if ((devinfo->flags & MIDI_F_READING) != 0 && c[0] != 0xfe) - midibuf_input_intr(&devinfo->midi_dbuf_in, &c[0], sizeof(c[0])); + midibuf_input_intr(&devinfo->midi_dbuf_in, &c[0], sizeof(c[0]), &leni); mtx_lock(&scp->mtx); } } @@ -440,7 +443,7 @@ uartsio_xmit(sc_p scp) txsize = scp->tx_size; if (dbuf->rl < txsize) txsize = dbuf->rl; - midibuf_output_intr(dbuf, c, txsize); + midibuf_output_intr(dbuf, c, txsize, &leno); for (i = 0 ; i < txsize ; i++) uartsio_writeport(scp, com_data, c[i]); /* We are playing now. */ diff --git a/sys/dev/sound/midi/midi.c b/sys/dev/sound/midi/midi.c index e577398..2db4d65 100644 --- a/sys/dev/sound/midi/midi.c +++ b/sys/dev/sound/midi/midi.c @@ -476,8 +476,9 @@ midi_close(dev_t i_dev, int flags, int mode, struct thread *td) int midi_read(dev_t i_dev, struct uio * buf, int flag) { - int dev, unit, len, ret; + int dev, unit, len, lenr, ret; mididev_info *d ; + u_char *uiobuf; dev = minor(i_dev); @@ -489,35 +490,42 @@ midi_read(dev_t i_dev, struct uio * buf, int flag) ret = 0; + len = buf->uio_resid; + lenr = 0; + + uiobuf = (u_char *)malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); + if (uiobuf == NULL) + return (ENOMEM); + mtx_lock(&d->flagqueue_mtx); /* Begin recording. */ d->callback(d, MIDI_CB_START | MIDI_CB_RD); - len = 0; - /* Have we got the data to read? */ if ((d->flags & MIDI_F_NBIO) != 0 && d->midi_dbuf_in.rl == 0) ret = EAGAIN; - else { - len = buf->uio_resid; - ret = midibuf_uioread(&d->midi_dbuf_in, buf, len, &d->flagqueue_mtx); - if (ret < 0) - ret = -ret; - else - ret = 0; - } + else + ret = midibuf_seqread(&d->midi_dbuf_in, uiobuf, len, &lenr, + d->callback, d, MIDI_CB_START | MIDI_CB_RD, + &d->flagqueue_mtx); mtx_unlock(&d->flagqueue_mtx); + if (lenr > 0) + ret = uiomove(uiobuf, lenr, buf); + + free(uiobuf, M_DEVBUF); + return (ret); } int midi_write(dev_t i_dev, struct uio * buf, int flag) { - int dev, unit, len, ret; + int dev, unit, len, len2, lenw, ret; mididev_info *d; + u_char *uiobuf; dev = minor(i_dev); d = get_mididev_info(i_dev, &unit); @@ -529,6 +537,19 @@ midi_write(dev_t i_dev, struct uio * buf, int flag) ret = 0; + len = buf->uio_resid; + lenw = 0; + + uiobuf = (u_char *)malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); + if (uiobuf == NULL) + return (ENOMEM); + + ret = uiomove(uiobuf, len, buf); + if (ret != 0) { + free(uiobuf, M_DEVBUF); + return (ret); + } + mtx_lock(&d->flagqueue_mtx); /* Have we got the data to write? */ @@ -537,22 +558,19 @@ midi_write(dev_t i_dev, struct uio * buf, int flag) d->callback(d, MIDI_CB_START | MIDI_CB_WR); ret = EAGAIN; } else { - len = buf->uio_resid; - if (len > d->midi_dbuf_out.fl && - (d->flags & MIDI_F_NBIO)) - len = d->midi_dbuf_out.fl; - ret = midibuf_uiowrite(&d->midi_dbuf_out, buf, len, &d->flagqueue_mtx); - if (ret < 0) - ret = -ret; - else { - /* Begin playing. */ - d->callback(d, MIDI_CB_START | MIDI_CB_WR); - ret = 0; - } + len2 = len; + if ((d->flags & MIDI_F_NBIO) != 0 && len2 > d->midi_dbuf_out.fl) + len2 = d->midi_dbuf_out.fl; + ret = midibuf_seqwrite(&d->midi_dbuf_out, uiobuf, len2, &lenw, + d->callback, d, MIDI_CB_START | MIDI_CB_WR, + &d->flagqueue_mtx); } mtx_unlock(&d->flagqueue_mtx); + free(uiobuf, M_DEVBUF); + buf->uio_resid = len - lenw; + return (ret); } @@ -789,7 +807,10 @@ midi_sync(mididev_info *d) if ((d->flags & MIDI_F_WRITING) == 0) d->callback(d, MIDI_CB_START | MIDI_CB_WR); rl = d->midi_dbuf_out.rl; - i = msleep(&d->midi_dbuf_out.tsleep_out, &d->flagqueue_mtx, PRIBIO | PCATCH, "midsnc", (d->midi_dbuf_out.bufsize * 10 * hz / 38400) + MIDI_SYNC_TIMEOUT * hz); + i = cv_timedwait_sig(&d->midi_dbuf_out.cv_out, + &d->flagqueue_mtx, + (d->midi_dbuf_out.bufsize * 10 * hz / 38400) + + MIDI_SYNC_TIMEOUT * hz); if (i == EINTR || i == ERESTART) { if (i == EINTR) d->callback(d, MIDI_CB_STOP | MIDI_CB_WR); diff --git a/sys/dev/sound/midi/midi.h b/sys/dev/sound/midi/midi.h index ca13d51..9302b56 100644 --- a/sys/dev/sound/midi/midi.h +++ b/sys/dev/sound/midi/midi.h @@ -67,6 +67,7 @@ #include <sys/mman.h> #include <sys/poll.h> #include <sys/mutex.h> +#include <sys/condvar.h> #include <dev/sound/midi/miditypes.h> #include <dev/sound/midi/midibuf.h> diff --git a/sys/dev/sound/midi/midibuf.c b/sys/dev/sound/midi/midibuf.c index e1f15c7..7e75471 100644 --- a/sys/dev/sound/midi/midibuf.c +++ b/sys/dev/sound/midi/midibuf.c @@ -42,11 +42,9 @@ #define SPACE_AVAIL(dbuf) ((dbuf)->fl) static void queuerawdata(midi_dbuf *dbuf, char *data, int len); -static void queueuiodata(midi_dbuf *dbuf, struct uio *buf, int len); static void dequeuerawdata(midi_dbuf *dbuf, char *data, int len); -static void undequeuerawdata(midi_dbuf *dbuf, char *data, int len); -static void copyrawdata(midi_dbuf *dbuf, char *data, int len); -static void dequeueuiodata(midi_dbuf *dbuf, struct uio *buf, int len); +static void copyrawdata(midi_dbuf *dbuf, int offset, char *data, int len); +static void deleterawdata(midi_dbuf *dbuf, int len); /* * Here are the functions to interact to the midi device drivers. @@ -56,9 +54,11 @@ static void dequeueuiodata(midi_dbuf *dbuf, struct uio *buf, int len); int midibuf_init(midi_dbuf *dbuf) { - if (dbuf->buf != NULL) - free(dbuf->buf, M_DEVBUF); - dbuf->buf = malloc(MIDI_BUFFSIZE, M_DEVBUF, M_WAITOK | M_ZERO); + if (dbuf->buf == NULL) { + dbuf->buf = malloc(MIDI_BUFFSIZE, M_DEVBUF, M_WAITOK | M_ZERO); + cv_init(&dbuf->cv_in, "midi queue in"); + cv_init(&dbuf->cv_out, "midi queue out"); + } return (midibuf_clear(dbuf)); } @@ -66,8 +66,11 @@ midibuf_init(midi_dbuf *dbuf) int midibuf_destroy(midi_dbuf *dbuf) { - if (dbuf->buf != NULL) + if (dbuf->buf != NULL) { free(dbuf->buf, M_DEVBUF); + cv_destroy(&dbuf->cv_in); + cv_destroy(&dbuf->cv_out); + } return (0); } @@ -94,15 +97,21 @@ midibuf_clear(midi_dbuf *dbuf) /* The sequencer calls this function to queue data. */ int -midibuf_seqwrite(midi_dbuf *dbuf, u_char* data, int len, struct mtx *m) +midibuf_seqwrite(midi_dbuf *dbuf, u_char* data, int len, int *lenw, midi_callback_t *cb, void *d, int reason, struct mtx *m) { - int i, lwrt, lwritten; + int i, lwrt; + + if (m != NULL) + mtx_assert(m, MA_OWNED); + + if (lenw == NULL) + return (EINVAL); + *lenw = 0; /* Is this a real queue? */ if (dbuf == (midi_dbuf *)NULL) - return (0); + return (EINVAL); - lwritten = 0; /* Write down every single byte. */ while (len > 0) { /* Find out the number of bytes to write. */ @@ -113,131 +122,103 @@ midibuf_seqwrite(midi_dbuf *dbuf, u_char* data, int len, struct mtx *m) /* We can write some now. Queue the data. */ queuerawdata(dbuf, data, lwrt); - lwritten += lwrt; + *lenw += lwrt; len -= lwrt; data += lwrt; - } - - /* Have we got still more data to write? */ - if (len > 0) { - /* Yes, sleep until we have enough space. */ - i = msleep((void *)&dbuf->tsleep_out, m, PRIBIO | PCATCH, "mbsqwt", 0); - if (i == EINTR || i == ERESTART) - return (-i); - } - } - - return (lwritten); -} - -/* sndwrite calls this function to queue data. */ -int -midibuf_uiowrite(midi_dbuf *dbuf, struct uio *buf, int len, struct mtx *m) -{ - int i, lwrt, lwritten; - - /* Is this a real queue? */ - if (dbuf == (midi_dbuf *)NULL) - return (0); - - lwritten = 0; - /* Write down every single byte. */ - while (len > 0) { - /* Find out the number of bytes to write. */ - lwrt = SPACE_AVAIL(dbuf); - if (lwrt > len) - lwrt = len; - if (lwrt > 0) { - /* We can write some now. Queue the data. */ - queueuiodata(dbuf, buf, lwrt); - lwritten += lwrt; - len -= lwrt; + if (cb != NULL) + (*cb)(d, reason); } /* Have we got still more data to write? */ if (len > 0) { - /* Yes, sleep until we have enough space. */ - i = msleep(&dbuf->tsleep_out, m, PRIBIO | PCATCH, "mbuiwt", 0); + /* Sleep until we have enough space. */ + i = cv_wait_sig(&dbuf->cv_out, m); if (i == EINTR || i == ERESTART) - return (-i); + return (i); } } - return (lwritten); + return (0); } int -midibuf_output_intr(midi_dbuf *dbuf, u_char *data, int len) +midibuf_output_intr(midi_dbuf *dbuf, u_char *data, int len, int *leno) { - int lrd; + if (leno == NULL) + return (EINVAL); + *leno = 0; /* Is this a real queue? */ if (dbuf == (midi_dbuf *)NULL) - return (0); + return (EINVAL); /* Have we got any data in the queue? */ - if ((lrd = DATA_AVAIL(dbuf)) == 0) - return (0); + *leno = DATA_AVAIL(dbuf); + if (*leno == 0) + return (EAGAIN); /* Dequeue the data. */ - if (lrd > len) - lrd = len; - dequeuerawdata(dbuf, data, lrd); + if (*leno > len) + *leno = len; + dequeuerawdata(dbuf, data, *leno); - return (lrd); + return (0); } int -midibuf_input_intr(midi_dbuf *dbuf, u_char *data, int len) +midibuf_input_intr(midi_dbuf *dbuf, u_char *data, int len, int *leni) { - int lwritten; + if (leni == NULL) + return (EINVAL); + *leni = 0; /* Is this a real queue? */ if (dbuf == (midi_dbuf *)NULL) - return (0); - - lwritten = 0; + return (EINVAL); /* Have we got any data to write? */ if (len == 0) return (0); /* Can we write now? */ if (SPACE_AVAIL(dbuf) < len) - return (-EAGAIN); + return (EAGAIN); /* We can write some now. Queue the data. */ queuerawdata(dbuf, data, len); - lwritten = len; + *leni = len; - /* Have we managed to write the whole data? */ - if (lwritten < len) - printf("midibuf_input_intr: queue did not have enough space, discarded %d bytes out of %d bytes.\n", len - lwritten, len); - - return (lwritten); + return (0); } /* The sequencer calls this function to dequeue data. */ int -midibuf_seqread(midi_dbuf *dbuf, u_char* data, int len, struct mtx *m) +midibuf_seqread(midi_dbuf *dbuf, u_char* data, int len, int *lenr, midi_callback_t *cb, void *d, int reason, struct mtx *m) { - int i, lrd, lread; + int i, lrd; + + if (m != NULL) + mtx_assert(m, MA_OWNED); + + if (lenr == NULL) + return (EINVAL); + *lenr = 0; /* Is this a real queue? */ if (dbuf == (midi_dbuf *)NULL) - return (0); + return (EINVAL); - lread = 0; /* Write down every single byte. */ while (len > 0) { + if (cb != NULL) + (*cb)(d, reason); + /* Have we got data to read? */ if ((lrd = DATA_AVAIL(dbuf)) == 0) { - /* No, sleep until we have data ready to read. */ - i = msleep(&dbuf->tsleep_in, m, PRIBIO | PCATCH, "mbsqrd", 0); + /* Sleep until we have data ready to read. */ + i = cv_wait_sig(&dbuf->cv_in, m); if (i == EINTR || i == ERESTART) - return (-i); - if (i == EWOULDBLOCK) - continue; + return (i); /* Find out the number of bytes to read. */ lrd = DATA_AVAIL(dbuf); } @@ -248,76 +229,43 @@ midibuf_seqread(midi_dbuf *dbuf, u_char* data, int len, struct mtx *m) /* We can read some data now. Dequeue the data. */ dequeuerawdata(dbuf, data, lrd); - lread += lrd; + *lenr += lrd; len -= lrd; data += lrd; } } - return (lread); + return (0); } -/* The sequencer calls this function to undo dequeued data. */ +/* The sequencer calls this function to copy data without dequeueing. */ int -midibuf_sequnread(midi_dbuf *dbuf, u_char* data, int len, struct mtx *m) +midibuf_seqcopy(midi_dbuf *dbuf, u_char* data, int len, int *lenc, midi_callback_t *cb, void *d, int reason, struct mtx *m) { - int i, lrd, lunread; - - /* Is this a real queue? */ - if (dbuf == (midi_dbuf *)NULL) - return (0); - - lunread = 0; - /* Write down every single byte. */ - while (len > 0) { - /* Have we got data to read? */ - if ((lrd = SPACE_AVAIL(dbuf)) == 0) { - /* No, sleep until we have data ready to read. */ - i = msleep(&dbuf->tsleep_in, m, PRIBIO | PCATCH, "mbsqur", 0); - if (i == EINTR || i == ERESTART) - return (-i); - if (i == EWOULDBLOCK) - continue; - /* Find out the number of bytes to unread. */ - lrd = SPACE_AVAIL(dbuf); - } - - if (lrd > len) - lrd = len; - if (lrd > 0) { - /* We can read some data now. Dequeue the data. */ - undequeuerawdata(dbuf, data, lrd); - - lunread += lrd; - len -= lrd; - data += lrd; - } - } + int i, lrd; - return (lunread); -} + if (m != NULL) + mtx_assert(m, MA_OWNED); -/* The sequencer calls this function to copy data without dequeueing. */ -int -midibuf_seqcopy(midi_dbuf *dbuf, u_char* data, int len, struct mtx *m) -{ - int i, lrd, lread; + if (lenc == NULL) + return (EINVAL); + *lenc = 0; /* Is this a real queue? */ if (dbuf == (midi_dbuf *)NULL) - return (0); + return (EINVAL); - lread = 0; /* Write down every single byte. */ while (len > 0) { + if (cb != NULL) + (*cb)(d, reason); + /* Have we got data to read? */ if ((lrd = DATA_AVAIL(dbuf)) == 0) { - /* No, sleep until we have data ready to read. */ - i = msleep(&dbuf->tsleep_in, m, PRIBIO | PCATCH, "mbsqrd", 0); + /* Sleep until we have data ready to read. */ + i = cv_wait_sig(&dbuf->cv_in, m); if (i == EINTR || i == ERESTART) - return (-i); - if (i == EWOULDBLOCK) - continue; + return (i); /* Find out the number of bytes to read. */ lrd = DATA_AVAIL(dbuf); } @@ -326,37 +274,48 @@ midibuf_seqcopy(midi_dbuf *dbuf, u_char* data, int len, struct mtx *m) lrd = len; if (lrd > 0) { /* We can read some data now. Copy the data. */ - copyrawdata(dbuf, data, lrd); + copyrawdata(dbuf, *lenc, data, lrd); - lread += lrd; + *lenc += lrd; len -= lrd; data += lrd; } } - return (lread); + return (0); } -/* sndread calls this function to dequeue data. */ +/* + * The sequencer calls this function to delete the data + * that the sequencer has already read. + */ int -midibuf_uioread(midi_dbuf *dbuf, struct uio *buf, int len, struct mtx *m) +midibuf_seqdelete(midi_dbuf *dbuf, int len, int *lenr, midi_callback_t *cb, void *d, int reason, struct mtx *m) { - int i, lrd, lread; + int i, lrd; + + if (m != NULL) + mtx_assert(m, MA_OWNED); + + if (lenr == NULL) + return (EINVAL); + *lenr = 0; /* Is this a real queue? */ if (dbuf == (midi_dbuf *)NULL) - return (0); + return (EINVAL); + + /* Write down every single byte. */ + while (len > 0) { + if (cb != NULL) + (*cb)(d, reason); - lread = 0; - while (len > 0 && lread == 0) { /* Have we got data to read? */ if ((lrd = DATA_AVAIL(dbuf)) == 0) { - /* No, sleep until we have data ready to read. */ - i = msleep(&dbuf->tsleep_in, m, PRIBIO | PCATCH, "mbuird", 0); + /* Sleep until we have data ready to read. */ + i = cv_wait_sig(&dbuf->cv_in, m); if (i == EINTR || i == ERESTART) - return (-i); - if (i == EWOULDBLOCK) - continue; + return (i); /* Find out the number of bytes to read. */ lrd = DATA_AVAIL(dbuf); } @@ -364,15 +323,15 @@ midibuf_uioread(midi_dbuf *dbuf, struct uio *buf, int len, struct mtx *m) if (lrd > len) lrd = len; if (lrd > 0) { - /* We can read some data now. Dequeue the data. */ - dequeueuiodata(dbuf, buf, lrd); + /* We can read some data now. Delete the data. */ + deleterawdata(dbuf, lrd); - lread += lrd; + *lenr += lrd; len -= lrd; } } - return (lread); + return (0); } /* @@ -385,11 +344,11 @@ queuerawdata(midi_dbuf *dbuf, char *data, int len) /* dbuf->fp might wrap around dbuf->bufsize. */ if (dbuf->bufsize - dbuf->fp < len) { /* The new data wraps, copy them twice. */ - memcpy(dbuf->buf + dbuf->fp, data, dbuf->bufsize - dbuf->fp); - memcpy(dbuf->buf, data + dbuf->bufsize - dbuf->fp, len - (dbuf->bufsize - dbuf->fp)); + bcopy(data, dbuf->buf + dbuf->fp, dbuf->bufsize - dbuf->fp); + bcopy(data + dbuf->bufsize - dbuf->fp, dbuf->buf, len - (dbuf->bufsize - dbuf->fp)); } else /* The new data do not wrap, once is enough. */ - memcpy(dbuf->buf + dbuf->fp, data, len); + bcopy(data, dbuf->buf + dbuf->fp, len); /* Adjust the pointer and the length counters. */ dbuf->fp = (dbuf->fp + len) % dbuf->bufsize; @@ -397,30 +356,7 @@ queuerawdata(midi_dbuf *dbuf, char *data, int len) dbuf->rl += len; /* Wake up the processes sleeping on input data. */ - wakeup(&dbuf->tsleep_in); - if (dbuf->sel.si_pid && dbuf->rl >= dbuf->blocksize) - selwakeup(&dbuf->sel); -} - -static void -queueuiodata(midi_dbuf *dbuf, struct uio *buf, int len) -{ - /* dbuf->fp might wrap around dbuf->bufsize. */ - if (dbuf->bufsize - dbuf->fp < len) { - /* The new data wraps, copy them twice. */ - uiomove((caddr_t)(dbuf->buf + dbuf->fp), dbuf->bufsize - dbuf->fp, buf); - uiomove((caddr_t)(dbuf->buf), len - (dbuf->bufsize - dbuf->fp), buf); - } else - /* The new data do not wrap, once is enough. */ - uiomove((caddr_t)(dbuf->buf + dbuf->fp), len, buf); - - /* Adjust the pointer and the length counters. */ - dbuf->fp = (dbuf->fp + len) % dbuf->bufsize; - dbuf->fl -= len; - dbuf->rl += len; - - /* Wake up the processes sleeping on queueing. */ - wakeup(&dbuf->tsleep_in); + cv_broadcast(&dbuf->cv_in); if (dbuf->sel.si_pid && dbuf->rl >= dbuf->blocksize) selwakeup(&dbuf->sel); } @@ -429,73 +365,39 @@ static void dequeuerawdata(midi_dbuf *dbuf, char *data, int len) { /* Copy the data. */ - copyrawdata(dbuf, data, len); - - /* Adjust the pointer and the length counters. */ - dbuf->rp = (dbuf->rp + len) % dbuf->bufsize; - dbuf->rl -= len; - dbuf->fl += len; + copyrawdata(dbuf, 0, data, len); - /* Wake up the processes sleeping on queueing. */ - wakeup(&dbuf->tsleep_out); - if (dbuf->sel.si_pid && dbuf->fl >= dbuf->blocksize) - selwakeup(&dbuf->sel); + /* Delete the data. */ + deleterawdata(dbuf, len); } -/* Undo the last dequeue. */ static void -undequeuerawdata(midi_dbuf *dbuf, char *data, int len) +copyrawdata(midi_dbuf *dbuf, int offset, char *data, int len) { - /* Copy the data. */ - if (dbuf->rp < len) { - memcpy(dbuf->buf, data + (len - dbuf->rp), dbuf->rp); - memcpy(dbuf->buf + (dbuf->bufsize - (len - dbuf->rp)), data, len - dbuf->rp); - } else - memcpy(dbuf->buf + (dbuf->rp - len), data, len); + int rp; - /* Adjust the pointer and the length counters. */ - dbuf->rp = (dbuf->rp - len + dbuf->bufsize) % dbuf->bufsize; - dbuf->rl += len; - dbuf->fl -= len; - - /* Wake up the processes sleeping on queueing. */ - wakeup(&dbuf->tsleep_in); - if (dbuf->sel.si_pid && dbuf->rl >= dbuf->blocksize) - selwakeup(&dbuf->sel); -} + rp = (dbuf->rp + offset) % dbuf->bufsize; -static void -copyrawdata(midi_dbuf *dbuf, char *data, int len) -{ /* dbuf->rp might wrap around dbuf->bufsize. */ - if (dbuf->bufsize - dbuf->rp < len) { + if (dbuf->bufsize - rp < len) { /* The data to be read wraps, copy them twice. */ - memcpy(data, dbuf->buf + dbuf->rp, dbuf->bufsize - dbuf->rp); - memcpy(data + dbuf->bufsize - dbuf->rp, dbuf->buf, len - (dbuf->bufsize - dbuf->rp)); + bcopy(dbuf->buf + rp, data, dbuf->bufsize - rp); + bcopy(dbuf->buf, data + dbuf->bufsize - rp, len - (dbuf->bufsize - rp)); } else /* The new data do not wrap, once is enough. */ - memcpy(data, dbuf->buf + dbuf->rp, len); + bcopy(dbuf->buf + rp, data, len); } static void -dequeueuiodata(midi_dbuf *dbuf, struct uio *buf, int len) +deleterawdata(midi_dbuf *dbuf, int len) { - /* dbuf->rp might wrap around dbuf->bufsize. */ - if (dbuf->bufsize - dbuf->rp < len) { - /* The new data wraps, copy them twice. */ - uiomove((caddr_t)(dbuf->buf + dbuf->rp), dbuf->bufsize - dbuf->rp, buf); - uiomove((caddr_t)(dbuf->buf), len - (dbuf->bufsize - dbuf->rp), buf); - } else - /* The new data do not wrap, once is enough. */ - uiomove((caddr_t)(dbuf->buf + dbuf->rp), len, buf); - /* Adjust the pointer and the length counters. */ dbuf->rp = (dbuf->rp + len) % dbuf->bufsize; dbuf->rl -= len; dbuf->fl += len; /* Wake up the processes sleeping on queueing. */ - wakeup(&dbuf->tsleep_out); + cv_broadcast(&dbuf->cv_out); if (dbuf->sel.si_pid && dbuf->fl >= dbuf->blocksize) selwakeup(&dbuf->sel); } diff --git a/sys/dev/sound/midi/midibuf.h b/sys/dev/sound/midi/midibuf.h index 68a7a37..a25c1cc 100644 --- a/sys/dev/sound/midi/midibuf.h +++ b/sys/dev/sound/midi/midibuf.h @@ -38,17 +38,17 @@ typedef struct _midi_dbuf { char *buf; int bufsize ; - volatile int rp, fp; /* pointers to the ready and free area */ - volatile int dl; /* transfer size */ - volatile int rl, fl; /* length of ready and free areas. */ + volatile int rp, fp; /* pointers to the ready and free area */ + volatile int dl; /* transfer size */ + volatile int rl, fl; /* length of ready and free areas. */ int int_count; - int chan; /* dma channel */ - int unit_size ; /* unit size */ + int chan; /* dma channel */ + int unit_size ; /* unit size */ struct selinfo sel; - u_long total; /* total bytes processed */ - u_long prev_total; /* copy of the above when GETxPTR called */ - int tsleep_in, tsleep_out; /* pillows to tsleep on */ - int blocksize; /* block size */ + u_long total; /* total bytes processed */ + u_long prev_total; /* copy of the above when GETxPTR called */ + struct cv cv_in, cv_out; /* condvars */ + int blocksize; /* block size */ } midi_dbuf ; /* @@ -57,11 +57,9 @@ typedef struct _midi_dbuf { int midibuf_init(midi_dbuf *dbuf); int midibuf_destroy(midi_dbuf *dbuf); int midibuf_clear(midi_dbuf *dbuf); -int midibuf_seqwrite(midi_dbuf *dbuf, u_char* data, int len, struct mtx *m); -int midibuf_uiowrite(midi_dbuf *dbuf, struct uio *buf, int len, struct mtx *m); -int midibuf_output_intr(midi_dbuf *dbuf, u_char *data, int len); -int midibuf_input_intr(midi_dbuf *dbuf, u_char *data, int len); -int midibuf_seqread(midi_dbuf *dbuf, u_char* data, int len, struct mtx *m); -int midibuf_sequnread(midi_dbuf *dbuf, u_char* data, int len, struct mtx *m); -int midibuf_seqcopy(midi_dbuf *dbuf, u_char* data, int len, struct mtx *m); -int midibuf_uioread(midi_dbuf *dbuf, struct uio *buf, int len, struct mtx *m); +int midibuf_seqwrite(midi_dbuf *dbuf, u_char* data, int len, int *lenw, midi_callback_t *cb, void *d, int reason, struct mtx *m); +int midibuf_output_intr(midi_dbuf *dbuf, u_char *data, int len, int *leno); +int midibuf_input_intr(midi_dbuf *dbuf, u_char *data, int len, int *leni); +int midibuf_seqread(midi_dbuf *dbuf, u_char* data, int len, int *lenr, midi_callback_t *cb, void *d, int reason, struct mtx *m); +int midibuf_seqcopy(midi_dbuf *dbuf, u_char* data, int len, int *lenc, midi_callback_t *cb, void *d, int reason, struct mtx *m); +int midibuf_seqdelete(midi_dbuf *dbuf, int len, int *lend, midi_callback_t *cb, void *d, int reason, struct mtx *m); diff --git a/sys/dev/sound/midi/midisynth.c b/sys/dev/sound/midi/midisynth.c index 63b4423..9f99d35 100644 --- a/sys/dev/sound/midi/midisynth.c +++ b/sys/dev/sound/midi/midisynth.c @@ -101,13 +101,13 @@ static int synth_leavesysex(mididev_info *md); /* * Here are the main functions to interact to the midi sequencer. - * These are called from the sequencer functions in sys/i386/isa/snd/sequencer.c. + * These are called from the sequencer functions in sequencer.c. */ static int synth_killnote(mididev_info *md, int chn, int note, int vel) { - int unit; + int unit, lenw; synthdev_info *sd; u_char c[3]; @@ -132,16 +132,14 @@ synth_killnote(mididev_info *md, int chn, int note, int vel) if (synth_prefixcmd(md, c[0])) return (0); - if (md->synth.writeraw(md, c, 3, 1) == EAGAIN) - return EAGAIN; - return (0); + return (md->synth.writeraw(md, c, 3, &lenw, 1)); } static int synth_setinstr(mididev_info *md, int chn, int instr) { - int unit; + int unit, lenw; synthdev_info *sd; u_char c[2]; @@ -156,16 +154,14 @@ synth_setinstr(mididev_info *md, int chn, int instr) c[0] = 0xc0 | (chn & 0x0f); /* Progamme change. */ c[1] = (u_char)instr; - if (md->synth.writeraw(md, c, 3, 1) == EAGAIN) - return (EAGAIN); - return (0); + return (md->synth.writeraw(md, c, 3, &lenw, 1)); } static int synth_startnote(mididev_info *md, int chn, int note, int vel) { - int unit; + int unit, lenw; synthdev_info *sd; u_char c[3]; @@ -183,10 +179,8 @@ synth_startnote(mididev_info *md, int chn, int note, int vel) c[2] = (u_char)vel; if (synth_prefixcmd(md, c[0])) return (0); - if (md->synth.writeraw(md, c, 3, 1) == EAGAIN) - return (EAGAIN); - return (0); + return (md->synth.writeraw(md, c, 3, &lenw, 1)); } static int @@ -208,7 +202,7 @@ synth_loadpatch(mididev_info *md, int format, struct uio *buf, int offs, int cou { struct sysex_info sysex; synthdev_info *sd; - int unit, i, eox_seen, first_byte, left, src_offs, hdr_size; + int unit, i, eox_seen, first_byte, left, src_offs, hdr_size, lenw; u_char c[count]; unit = md->unit; @@ -254,7 +248,7 @@ synth_loadpatch(mididev_info *md, int format, struct uio *buf, int offs, int cou return (EINVAL); } if (!first_byte && (c[i] & 0x80) != 0) { - md->synth.writeraw(md, c, i + 1, 0); + md->synth.writeraw(md, c, i + 1, &lenw, 0); return (0); } first_byte = 0; @@ -262,7 +256,7 @@ synth_loadpatch(mididev_info *md, int format, struct uio *buf, int offs, int cou if (!eox_seen) { c[0] = 0xf7; - md->synth.writeraw(md, c, 1, 0); + md->synth.writeraw(md, c, 1, &lenw, 0); } return (0); @@ -278,7 +272,7 @@ synth_panning(mididev_info *md, int chn, int pan) static int synth_aftertouch(mididev_info *md, int chn, int press) { - int unit; + int unit, lenw; synthdev_info *sd; u_char c[2]; @@ -294,16 +288,14 @@ synth_aftertouch(mididev_info *md, int chn, int press) c[1] = (u_char)press; if (synth_prefixcmd(md, c[0])) return (0); - if (md->synth.writeraw(md, c, 2, 1) == EAGAIN) - return (EAGAIN); - return (0); + return (md->synth.writeraw(md, c, 2, &lenw, 1)); } static int synth_controller(mididev_info *md, int chn, int ctrlnum, int val) { - int unit; + int unit, lenw; synthdev_info *sd; u_char c[3]; @@ -319,10 +311,8 @@ synth_controller(mididev_info *md, int chn, int ctrlnum, int val) c[1] = (u_char)ctrlnum; if (synth_prefixcmd(md, c[0])) return (0); - if (md->synth.writeraw(md, c, 3, 1) == EAGAIN) - return (EAGAIN); - return (0); + return (md->synth.writeraw(md, c, 3, &lenw, 1)); } static int @@ -334,7 +324,7 @@ synth_patchmgr(mididev_info *md, struct patmgr_info *rec) static int synth_bender(mididev_info *md, int chn, int val) { - int unit; + int unit, lenw; synthdev_info *sd; u_char c[3]; @@ -351,10 +341,8 @@ synth_bender(mididev_info *md, int chn, int val) c[2] = (u_char)(val >> 7) & 0x7f; if (synth_prefixcmd(md, c[0])) return (0); - if (md->synth.writeraw(md, c, 3, 1) == EAGAIN) - return (EAGAIN); - return (0); + return (md->synth.writeraw(md, c, 3, &lenw, 1)); } static int @@ -374,7 +362,7 @@ synth_setupvoice(mididev_info *md, int voice, int chn) static int synth_sendsysex(mididev_info *md, u_char *sysex, int len) { - int unit, i; + int unit, i, lenw; synthdev_info *sd; u_char c[len]; @@ -417,10 +405,8 @@ synth_sendsysex(mididev_info *md, u_char *sysex, int len) break; } mtx_unlock(&sd->status_mtx); - if (md->synth.writeraw(md, c, i, 1) == EAGAIN) - return (EAGAIN); - return (0); + return (md->synth.writeraw(md, c, i, &lenw, 1)); } static int @@ -438,16 +424,20 @@ synth_volumemethod(mididev_info *md, int mode) } static int -synth_readraw(mididev_info *md, u_char *buf, int len, int nonblock) +synth_readraw(mididev_info *md, u_char *buf, int len, int *lenr, int nonblock) { int unit, ret; if (md == NULL) return (ENXIO); + if (lenr == NULL) + return (EINVAL); + *lenr = 0; unit = md->unit; + if ((md->fflags & FREAD) == 0) { - DEB(printf("mpu_readraw: unit %d is not for reading.\n", unit)); + DEB(printf("synth_readraw: unit %d is not for reading.\n", unit)); return (EIO); } @@ -465,26 +455,26 @@ synth_readraw(mididev_info *md, u_char *buf, int len, int nonblock) } } - ret = midibuf_seqread(&md->midi_dbuf_in, buf, len, &md->flagqueue_mtx); + ret = midibuf_seqread(&md->midi_dbuf_in, buf, len, lenr, + md->callback, md, MIDI_CB_START | MIDI_CB_RD, + &md->flagqueue_mtx); mtx_unlock(&md->flagqueue_mtx); - if (ret < 0) - ret = -ret; - else - ret = 0; - return (ret); } static int -synth_writeraw(mididev_info *md, u_char *buf, int len, int nonblock) +synth_writeraw(mididev_info *md, u_char *buf, int len, int *lenw, int nonblock) { int unit, ret; if (md == NULL) return (ENXIO); + if (lenw == NULL) + return (EINVAL); + *lenw = 0; unit = md->unit; if ((md->fflags & FWRITE) == 0) { @@ -501,15 +491,13 @@ synth_writeraw(mididev_info *md, u_char *buf, int len, int nonblock) return (EAGAIN); } - ret = midibuf_seqwrite(&md->midi_dbuf_out, buf, len, &md->flagqueue_mtx); + ret = midibuf_seqwrite(&md->midi_dbuf_out, buf, len, lenw, + md->callback, md, MIDI_CB_START | MIDI_CB_WR, + &md->flagqueue_mtx); - if (ret < 0) - ret = -ret; - else { + if (ret == 0) /* Begin playing. */ md->callback(md, MIDI_CB_START | MIDI_CB_WR); - ret = 0; - } mtx_unlock(&md->flagqueue_mtx); @@ -523,7 +511,7 @@ synth_writeraw(mididev_info *md, u_char *buf, int len, int nonblock) static int synth_leavesysex(mididev_info *md) { - int unit; + int unit, lenw; synthdev_info *sd; u_char c; @@ -539,8 +527,6 @@ synth_leavesysex(mididev_info *md) sd->sysex_state = 0; mtx_unlock(&sd->status_mtx); c = 0xf7; - if (md->synth.writeraw(md, &c, sizeof(c), 1) == EAGAIN) - return (EAGAIN); - return (0); + return (md->synth.writeraw(md, &c, sizeof(c), &lenw, 1)); } diff --git a/sys/dev/sound/midi/midisynth.h b/sys/dev/sound/midi/midisynth.h index db43354..356be89 100644 --- a/sys/dev/sound/midi/midisynth.h +++ b/sys/dev/sound/midi/midisynth.h @@ -64,8 +64,8 @@ typedef int (mdsy_setupvoice_t)(mididev_info *md, int voice, int chn); typedef int (mdsy_sendsysex_t)(mididev_info *md, u_char *sysex, int len); typedef int (mdsy_prefixcmd_t)(mididev_info *md, int status); typedef int (mdsy_volumemethod_t)(mididev_info *md, int mode); -typedef int (mdsy_readraw_t)(mididev_info *md, u_char *buf, int len, int nonblock); -typedef int (mdsy_writeraw_t)(mididev_info *md, u_char *buf, int len, int nonblock); +typedef int (mdsy_readraw_t)(mididev_info *md, u_char *buf, int len, int *lenr, int nonblock); +typedef int (mdsy_writeraw_t)(mididev_info *md, u_char *buf, int len, int *lenw, int nonblock); /* * The order of mutex lock (from the first to the last) diff --git a/sys/dev/sound/midi/miditypes.h b/sys/dev/sound/midi/miditypes.h index c0dfdf6..0657342 100644 --- a/sys/dev/sound/midi/miditypes.h +++ b/sys/dev/sound/midi/miditypes.h @@ -30,5 +30,5 @@ typedef struct _mididev_info mididev_info; -typedef int (midi_callback_t)(mididev_info *d, int reason); +typedef int (midi_callback_t)(void *d, int reason); typedef void (midi_intr_t)(void *p, mididev_info *md); diff --git a/sys/dev/sound/midi/sequencer.c b/sys/dev/sound/midi/sequencer.c index ab35f81..3677c76 100644 --- a/sys/dev/sound/midi/sequencer.c +++ b/sys/dev/sound/midi/sequencer.c @@ -69,7 +69,7 @@ enum { */ static midi_intr_t seq_intr; -static seq_callback_t seq_callback; +static midi_callback_t seq_callback; /* These are the entries to the sequencer driver. */ static d_open_t seq_open; @@ -372,9 +372,10 @@ seq_close(dev_t i_dev, int flags, int mode, struct thread *td) int seq_read(dev_t i_dev, struct uio *buf, int flag) { - int unit, ret, len; + int unit, ret, len, lenr; sc_p scp; seqdev_info *sd; + u_char *uiobuf; unit = MIDIUNIT(i_dev); @@ -396,27 +397,34 @@ seq_read(dev_t i_dev, struct uio *buf, int flag) return (EIO); } + len = buf->uio_resid; + lenr = 0; + + uiobuf = (u_char *)malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); + if (uiobuf == NULL) + return (ENOMEM); + mtx_lock(&sd->flagqueue_mtx); /* Begin recording. */ if ((sd->flags & SEQ_F_READING) == 0) sd->callback(sd, SEQ_CB_START | SEQ_CB_RD); - len = 0; - /* Have we got the data to read? */ if ((sd->flags & SEQ_F_NBIO) != 0 && sd->midi_dbuf_in.rl == 0) ret = EAGAIN; - else { - len = buf->uio_resid; - ret = midibuf_uioread(&sd->midi_dbuf_in, buf, len, &sd->flagqueue_mtx); - if (ret < 0) - ret = -ret; - else - ret = 0; - } + else + ret = midibuf_seqread(&sd->midi_dbuf_in, uiobuf, len, &lenr, + sd->callback, sd, SEQ_CB_START | SEQ_CB_RD, + &sd->flagqueue_mtx); + mtx_unlock(&sd->flagqueue_mtx); + if (ret == 0 && lenr > 0) + ret = uiomove(uiobuf, lenr, buf); + + free(uiobuf, M_DEVBUF); + return (ret); } @@ -965,10 +973,13 @@ seq_intr(void *p, mididev_info *md) } static int -seq_callback(seqdev_info *sd, int reason) +seq_callback(void *d, int reason) { int unit; sc_p scp; + seqdev_info *sd; + + sd = (seqdev_info *)d; /*DEB(printf("seq_callback: reason 0x%x.\n", reason));*/ @@ -1020,7 +1031,7 @@ seq_callback(seqdev_info *sd, int reason) static int seq_queue(sc_p scp, u_char *note) { - int unit, err; + int unit, err, lenw; seqdev_info *sd; sd = scp->devinfo; @@ -1030,10 +1041,8 @@ seq_queue(sc_p scp, u_char *note) /*DEB(printf("seq%d: queueing.\n", unit));*/ - if ((sd->flags & SEQ_F_INSYNC) != 0) { + if ((sd->flags & SEQ_F_INSYNC) != 0) cv_wait(&sd->insync_cv, &sd->flagqueue_mtx); - cv_signal(&sd->insync_cv); - } if (sd->midi_dbuf_out.fl < EV_SZ) { /* We have no space. Start playing if not yet. */ @@ -1042,26 +1051,14 @@ seq_queue(sc_p scp, u_char *note) if ((sd->flags & SEQ_F_NBIO) != 0 && sd->midi_dbuf_out.fl < EV_SZ) /* We would block. */ return (EAGAIN); - else { - while (sd->midi_dbuf_out.fl < EV_SZ) { - /* We have no space. Good night. */ - err = msleep(&sd->midi_dbuf_out.tsleep_out, &sd->flagqueue_mtx, PRIBIO | PCATCH, "seqque", 0); - if (err == EINTR || err == ERESTART) { - if (err == EINTR) - sd->callback(sd, SEQ_CB_STOP | SEQ_CB_WR); - return (err); - } - } - } } - /* We now have enough space to write. */ - err = midibuf_seqwrite(&sd->midi_dbuf_out, note, EV_SZ, &sd->flagqueue_mtx); + /* Write to the queue. */ + err = midibuf_seqwrite(&sd->midi_dbuf_out, note, EV_SZ, &lenw, + sd->callback, sd, SEQ_CB_START | SEQ_CB_WR, + &sd->flagqueue_mtx); - if (err < 0) - err = -err; - else { - err = 0; + if (err == 0) { /* Start playing if we have some data in the queue. */ if (sd->midi_dbuf_out.rl >= EV_SZ && ((sd->flags & SEQ_F_WRITING) == 0)) sd->callback(sd, SEQ_CB_START | SEQ_CB_WR); @@ -1073,7 +1070,7 @@ seq_queue(sc_p scp, u_char *note) static void seq_startplay(sc_p scp) { - int unit; + int unit, lenr; u_char event[EV_SZ]; seqdev_info *sd; @@ -1082,19 +1079,28 @@ seq_startplay(sc_p scp) mtx_assert(&sd->flagqueue_mtx, MA_OWNED); + sd->flags |= SEQ_F_WRITING; + /* Dequeue the events to play. */ while (sd->midi_dbuf_out.rl >= EV_SZ) { - midibuf_seqread(&sd->midi_dbuf_out, event, EV_SZ, &sd->flagqueue_mtx); + midibuf_seqcopy(&sd->midi_dbuf_out, event, EV_SZ, &lenr, + NULL, NULL, 0, + &sd->flagqueue_mtx); switch (seq_playevent(scp, event)) { case TIMERARMED: + midibuf_seqdelete(&sd->midi_dbuf_out, EV_SZ, &lenr, + NULL, NULL, 0, + &sd->flagqueue_mtx); return; case QUEUEFULL: /* We cannot play any further. */ - midibuf_sequnread(&sd->midi_dbuf_out, event, EV_SZ, &sd->flagqueue_mtx); return; case MORE: + midibuf_seqdelete(&sd->midi_dbuf_out, EV_SZ, &lenr, + NULL, NULL, 0, + &sd->flagqueue_mtx); break; } } @@ -1106,7 +1112,7 @@ seq_startplay(sc_p scp) static int seq_playevent(sc_p scp, u_char *event) { - int unit, ret; + int unit, ret, lenw; long *delay; seqdev_info *sd; mididev_info *md; @@ -1182,14 +1188,12 @@ seq_playevent(sc_p scp, u_char *event) break; } mtx_unlock(&sd->flagqueue_mtx); - if (md->synth.writeraw(md, &event[1], sizeof(event[1]), 1) == EAGAIN) { - mtx_lock(&sd->flagqueue_mtx); + if (md->synth.writeraw(md, &event[1], sizeof(event[1]), &lenw, 1) == EAGAIN) /* The queue was full. Try again later. */ ret = QUEUEFULL; - break; - } + else + ret = MORE; mtx_lock(&sd->flagqueue_mtx); - ret = MORE; break; case SEQ_ECHO: /* Echo this event back. */ @@ -1325,7 +1329,7 @@ seq_stoptimer(sc_p scp) static void seq_midiinput(sc_p scp, mididev_info *md) { - int unit, midiunit; + int unit, midiunit, lenr; u_long tstamp; u_char event[4]; seqdev_info *sd; @@ -1342,7 +1346,7 @@ seq_midiinput(sc_p scp, mididev_info *md) if ((md->flags & MIDI_F_READING) != 0 && md->intrarg == sd) { /* Read the input data. */ - while (md->synth.readraw(md, &event[1], sizeof(event[1]), 1) == 0) { + while (md->synth.readraw(md, &event[1], sizeof(event[1]), &lenr, 1) == 0) { tstamp = seq_gettime() - scp->seq_time; if (tstamp != scp->prev_input_time) { /* Insert a wait between events. */ @@ -1361,16 +1365,16 @@ seq_midiinput(sc_p scp, mididev_info *md) static int seq_copytoinput(sc_p scp, u_char *event, int len) { + int ret, leni; seqdev_info *sd; sd = scp->devinfo; mtx_assert(&sd->flagqueue_mtx, MA_OWNED); - if (midibuf_input_intr(&sd->midi_dbuf_in, event, len) == -EAGAIN) - return (EAGAIN); + ret = midibuf_input_intr(&sd->midi_dbuf_in, event, len, &leni); - return (0); + return (ret); } static int @@ -1482,7 +1486,7 @@ seq_chnvoice(sc_p scp, u_char *event) #if notyet if (voice == -1 && scp->seq_mode == SEQ_2 && md->synth.allocvoice) /* This is an internal synthesizer. (FM, GUS, etc) */ - if ((voice = seq_allocvoice(scp, md, chn, note)) == -EAGAIN) + if ((voice = seq_allocvoice(scp, md, chn, note)) == EAGAIN) return (QUEUEFULL); #endif /* notyet */ if (voice == -1) @@ -1572,9 +1576,9 @@ seq_allocvoice(sc_p scp, mididev_info *md, int chn, int note) key = (chn << 8) | (note + 1); mtx_unlock(&scp->devinfo->flagqueue_mtx); - if ((voice = md->synth.allocvoice(md, chn, note, &md->synth.alloc)) == -EAGAIN) { + if ((voice = md->synth.allocvoice(md, chn, note, &md->synth.alloc)) == EAGAIN) { mtx_lock(&scp->devinfo->flagqueue_mtx); - return (-EAGAIN); + return (EAGAIN); } mtx_lock(&scp->devinfo->flagqueue_mtx); @@ -1737,9 +1741,9 @@ seq_timing(sc_p scp, u_char *event) #endif /* notyet */ switch (event[1]) { case TMR_WAIT_REL: + parm += scp->prev_event_time; + /* FALLTHRU */ case TMR_WAIT_ABS: - if (event[1] == TMR_WAIT_REL) - parm += scp->prev_event_time; if (parm > 0) { sd->flags |= SEQ_F_WRITING; if (seq_requesttimer(scp, parm)) @@ -1881,7 +1885,7 @@ seq_openmidi(sc_p scp, mididev_info *md, int flags, int mode, struct thread *td) TAILQ_INSERT_TAIL(&scp->midi_open, md, md_linkseq); if (insync) - cv_signal(&scp->devinfo->insync_cv); + cv_broadcast(&scp->devinfo->insync_cv); return (0); } @@ -1916,7 +1920,7 @@ seq_closemidi(sc_p scp, mididev_info *md, int flags, int mode, struct thread *td TAILQ_REMOVE(&scp->midi_open, md, md_linkseq); if (insync) - cv_signal(&scp->devinfo->insync_cv); + cv_broadcast(&scp->devinfo->insync_cv); return (0); } @@ -1932,7 +1936,7 @@ seq_panic(sc_p scp) static int seq_reset(sc_p scp) { - int unit, chn; + int unit, chn, lenw; seqdev_info *sd; mididev_info *md; u_char c[3]; @@ -1942,10 +1946,8 @@ seq_reset(sc_p scp) mtx_assert(&sd->flagqueue_mtx, MA_OWNED); - if ((sd->flags & SEQ_F_INSYNC) != 0) { + if ((sd->flags & SEQ_F_INSYNC) != 0) cv_wait(&sd->insync_cv, &sd->flagqueue_mtx); - cv_signal(&sd->insync_cv); - } /* Stop reading and writing. */ sd->callback(sd, SEQ_CB_ABORT | SEQ_CB_RD | SEQ_CB_WR); @@ -1977,11 +1979,11 @@ seq_reset(sc_p scp) c[0] = 0xb0 | (chn & 0x0f); c[1] = (u_char)0x78; /* All sound off */ c[2] = (u_char)0; - md->synth.writeraw(md, c, 3, 0); + md->synth.writeraw(md, c, 3, &lenw, 0); c[1] = (u_char)0x7b; /* All note off */ - md->synth.writeraw(md, c, 3, 0); + md->synth.writeraw(md, c, 3, &lenw, 0); c[1] = (u_char)0x79; /* Reset all controller */ - md->synth.writeraw(md, c, 3, 0); + md->synth.writeraw(md, c, 3, &lenw, 0); } } seq_sync(scp); @@ -2012,7 +2014,7 @@ seq_sync(sc_p scp) if ((sd->flags & SEQ_F_WRITING) == 0) sd->callback(sd, SEQ_CB_START | SEQ_CB_WR); rl = sd->midi_dbuf_out.rl; - i = msleep(&sd->midi_dbuf_out.tsleep_out, &sd->flagqueue_mtx, PRIBIO | PCATCH, "seqsnc", SEQ_SYNC_TIMEOUT * hz); + i = cv_timedwait_sig(&sd->midi_dbuf_out.cv_out, &sd->flagqueue_mtx, SEQ_SYNC_TIMEOUT * hz); if (i == EINTR || i == ERESTART) { if (i == EINTR) sd->callback(sd, SEQ_CB_STOP | SEQ_CB_WR); @@ -2048,7 +2050,7 @@ seq_sync(sc_p scp) mtx_lock(&sd->flagqueue_mtx); sd->flags &= ~SEQ_F_INSYNC; - cv_signal(&sd->insync_cv); + cv_broadcast(&sd->insync_cv); return (0); } diff --git a/sys/dev/sound/midi/sequencer.h b/sys/dev/sound/midi/sequencer.h index a81e041..ea75a36 100644 --- a/sys/dev/sound/midi/sequencer.h +++ b/sys/dev/sound/midi/sequencer.h @@ -68,8 +68,6 @@ typedef struct _seqdev_info seqdev_info; -typedef int (seq_callback_t)(seqdev_info *sd, int reason); - /* * The order of mutex lock (from the first to the last) * @@ -101,7 +99,7 @@ struct _seqdev_info { d_write_t *write; d_ioctl_t *ioctl; d_poll_t *poll; - seq_callback_t *callback; + midi_callback_t *callback; /* * combinations of the following flags are used as second argument in @@ -234,7 +232,7 @@ struct _seqdev_info { /* * finally, all default parameters */ -#define SEQ_BUFFSIZE (4 * 1024) /* XXX */ +#define SEQ_BUFFSIZE (1024) /* XXX */ /* * some macros for debugging purposes diff --git a/sys/dev/sound/pci/csamidi.c b/sys/dev/sound/pci/csamidi.c index 74810aa..ace03d1 100644 --- a/sys/dev/sound/pci/csamidi.c +++ b/sys/dev/sound/pci/csamidi.c @@ -113,7 +113,7 @@ static void csamidi_xmit(sc_p scp); static int csamidi_reset(sc_p scp); static int csamidi_status(sc_p scp); static int csamidi_command(sc_p scp, u_int32_t value); -static int csamidi_readdata(sc_p scp); +static int csamidi_readdata(sc_p scp, u_int8_t *value); static int csamidi_writedata(sc_p scp, u_int32_t value); static u_int32_t csamidi_readio(sc_p scp, u_long offset); static void csamidi_writeio(sc_p scp, u_long offset, u_int32_t data); @@ -261,6 +261,7 @@ csamidi_intr(void *arg) sc_p scp; u_char c; mididev_info *devinfo; + int leni; scp = (sc_p)arg; devinfo = scp->devinfo; @@ -271,17 +272,17 @@ csamidi_intr(void *arg) /* Read the received data. */ while ((csamidi_status(scp) & MIDSR_RBE) == 0) { /* Receive the data. */ - c = (u_char)csamidi_readdata(scp); + csamidi_readdata(scp, &c); mtx_unlock(&scp->mtx); /* Queue into the passthru buffer and start transmitting if we can. */ if ((devinfo->flags & MIDI_F_PASSTHRU) != 0 && ((devinfo->flags & MIDI_F_BUSY) == 0 || (devinfo->fflags & FWRITE) == 0)) { - midibuf_input_intr(&devinfo->midi_dbuf_passthru, &c, sizeof(c)); + midibuf_input_intr(&devinfo->midi_dbuf_passthru, &c, sizeof(c), &leni); devinfo->callback(devinfo, MIDI_CB_START | MIDI_CB_WR); } /* Queue if we are reading. Discard an active sensing. */ if ((devinfo->flags & MIDI_F_READING) != 0 && c != 0xfe) { - midibuf_input_intr(&devinfo->midi_dbuf_in, &c, sizeof(c)); + midibuf_input_intr(&devinfo->midi_dbuf_in, &c, sizeof(c), &leni); } mtx_lock(&scp->mtx); } @@ -298,10 +299,13 @@ csamidi_intr(void *arg) } static int -csamidi_callback(mididev_info *d, int reason) +csamidi_callback(void *di, int reason) { int unit; sc_p scp; + mididev_info *d; + + d = (mididev_info *)di; mtx_assert(&d->flagqueue_mtx, MA_OWNED); @@ -366,6 +370,7 @@ csamidi_xmit(sc_p scp) register mididev_info *devinfo; register midi_dbuf *dbuf; u_char c; + int leno; devinfo = scp->devinfo; @@ -391,7 +396,7 @@ csamidi_xmit(sc_p scp) break; } /* Send the data. */ - midibuf_output_intr(dbuf, &c, sizeof(c)); + midibuf_output_intr(dbuf, &c, sizeof(c), &leno); csamidi_writedata(scp, c); /* We are playing now. */ devinfo->flags |= MIDI_F_WRITING; @@ -452,17 +457,22 @@ csamidi_command(sc_p scp, u_int32_t value) /* Reads a byte of data. */ static int -csamidi_readdata(sc_p scp) +csamidi_readdata(sc_p scp, u_int8_t *value) { u_int status; + if (value == NULL) + return (EINVAL); + /* Is the interface ready to read? */ status = csamidi_status(scp); if ((status & MIDSR_RBE) != 0) /* The interface is busy. */ - return (-EAGAIN); + return (EAGAIN); - return (int)csamidi_readio(scp, BA0_MIDRP) & 0xff; + *value = (u_int8_t)(csamidi_readio(scp, BA0_MIDRP) & 0xff); + + return (0); } /* Writes a byte of data. */ |