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/dev/sound/midi/midi.c | |
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/dev/sound/midi/midi.c')
-rw-r--r-- | sys/dev/sound/midi/midi.c | 71 |
1 files changed, 46 insertions, 25 deletions
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); |