summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authortanimura <tanimura@FreeBSD.org>2002-01-01 17:36:26 +0000
committertanimura <tanimura@FreeBSD.org>2002-01-01 17:36:26 +0000
commita46d1d7f893729bbd95a207f15da7cf72690209c (patch)
tree2bf9e44e75f8effab6b654ff7122f77f882aeee0 /sys
parentcfe419eb213db0b2937a261122224454d75db7a4 (diff)
downloadFreeBSD-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.c20
-rw-r--r--sys/dev/sound/isa/gusmidi.c14
-rw-r--r--sys/dev/sound/isa/mpu.c34
-rw-r--r--sys/dev/sound/isa/opl.c19
-rw-r--r--sys/dev/sound/isa/uartsio.c13
-rw-r--r--sys/dev/sound/midi/midi.c71
-rw-r--r--sys/dev/sound/midi/midi.h1
-rw-r--r--sys/dev/sound/midi/midibuf.c350
-rw-r--r--sys/dev/sound/midi/midibuf.h32
-rw-r--r--sys/dev/sound/midi/midisynth.c88
-rw-r--r--sys/dev/sound/midi/midisynth.h4
-rw-r--r--sys/dev/sound/midi/miditypes.h2
-rw-r--r--sys/dev/sound/midi/sequencer.c130
-rw-r--r--sys/dev/sound/midi/sequencer.h6
-rw-r--r--sys/dev/sound/pci/csamidi.c28
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. */
OpenPOWER on IntegriCloud