- 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.
This commit is contained in:
parent
d6811c6851
commit
05331bc6d4
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
||||
return (int)mpu_readport(scp, MPU_DATAPORT) & 0xff;
|
||||
*value = (u_int8_t)(mpu_readport(scp, MPU_DATAPORT) & 0xff);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Writes a byte of data. */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
||||
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((void *)&dbuf->tsleep_out, m, PRIBIO | PCATCH, "mbsqwt", 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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if (i == EINTR || i == ERESTART)
|
||||
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);
|
||||
}
|
||||
|
||||
/* The sequencer calls this function to undo dequeued data. */
|
||||
int
|
||||
midibuf_sequnread(midi_dbuf *dbuf, u_char* data, int len, 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;
|
||||
}
|
||||
}
|
||||
|
||||
return (lunread);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* The sequencer calls this function to copy data without dequeueing. */
|
||||
int
|
||||
midibuf_seqcopy(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, lread;
|
||||
int i, lrd;
|
||||
|
||||
if (m != NULL)
|
||||
mtx_assert(m, MA_OWNED);
|
||||
|
||||
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);
|
||||
copyrawdata(dbuf, 0, data, len);
|
||||
|
||||
/* 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);
|
||||
if (dbuf->sel.si_pid && dbuf->fl >= dbuf->blocksize)
|
||||
selwakeup(&dbuf->sel);
|
||||
}
|
||||
|
||||
/* Undo the last dequeue. */
|
||||
static void
|
||||
undequeuerawdata(midi_dbuf *dbuf, 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);
|
||||
|
||||
/* 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);
|
||||
/* Delete the data. */
|
||||
deleterawdata(dbuf, len);
|
||||
}
|
||||
|
||||
static void
|
||||
copyrawdata(midi_dbuf *dbuf, char *data, int len)
|
||||
copyrawdata(midi_dbuf *dbuf, int offset, char *data, int len)
|
||||
{
|
||||
int rp;
|
||||
|
||||
rp = (dbuf->rp + offset) % dbuf->bufsize;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user