Date: Thu, 17 Feb 2011 22:54:35 +0100 From: Hans Petter Selasky <hselasky@c2i.net> To: freebsd-multimedia@freebsd.org Subject: Re: USB MIDI patch for FreeBSD 8/9 Message-ID: <201102172254.35501.hselasky@c2i.net> In-Reply-To: <20110217211213.F1DC8A6284@smtp3-g21.free.fr> References: <20110217211213.F1DC8A6284@smtp3-g21.free.fr>
next in thread | previous in thread | raw e-mail | index | archive | help
--Boundary-00=_bkZXNBbphpH84ED Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable On Thursday 17 February 2011 22:12:16 Raoul M=EF=BF=BDg=EF=BF=BDlas wrote: > on Thu, 17 Feb 2011 11:18:40 +0100 > Hans Petter Selasky <hselasky@c2i.net> wrote: >=20 > ... >=20 > > cd /usr/src/sys/dev/sound/usb/ > > cat umidi_patch_001.txt | patch > >=20 > > A short summary of what the changes are about: > >=20 > > - Make the USB MIDI driver more OSS compliant by implementing the > > correct data format for the /dev/umidiX.Y character devices. Also > > implement some missing OSS MIDI ioctls. > > - Use the USB stack's builtin clear-stall feature. > > - Wrap some long lines. > > - Use memcpy() instead of bcopy(). > >=20 > > --HPS > >=20 > > Some demo tunes: > >=20 > > fluidsynth + zynaddsubfx + audacity + midipp: > >=20 > > http://www.selasky.org/hans_petter/synth_test_new.mp3 > >=20 > > zynaddsubfx + midipp: > >=20 > > http://www.selasky.org/hans_petter/synth_test.mp3 > >=20 > > --HPS > >=20 > > --Boundary-00=3D_AYPXNgVCRizMd8n > > Content-Type: text/plain; > >=20 > > charset=3D"us-ascii"; > > name=3D"umidi_patch_001.txt" > >=20 > > Content-Transfer-Encoding: 7bit > > Content-Disposition: inline; > >=20 > > filename=3D"umidi_patch_001.txt" > >=20 > > =3D=3D=3D uaudio.c > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > --- uaudio.c (revision 218769) > > +++ uaudio.c (local) > > @@ -191,10 +191,15 @@ > >=20 > > uint8_t iface_alt_index; > > =20 > > }; > >=20 > > -#define UMIDI_N_TRANSFER 4 /* units */ > >=20 > > #define UMIDI_CABLES_MAX 16 /* units */ > > #define UMIDI_BULK_SIZE 1024 /* bytes */ > >=20 > > +enum { > > + UMIDI_TX_TRANSFER, > > + UMIDI_RX_TRANSFER, > > + UMIDI_N_TRANSFER, > > +}; > > + > >=20 > > struct umidi_sub_chan { > > =20 > > struct usb_fifo_sc fifo; > > uint8_t *temp_cmd; > >=20 > > @@ -224,10 +229,6 @@ > >=20 > > uint8_t iface_index; > > uint8_t iface_alt_index; > >=20 > > - uint8_t flags; > > -#define UMIDI_FLAG_READ_STALL 0x01 > > -#define UMIDI_FLAG_WRITE_STALL 0x02 > > - > >=20 > > uint8_t read_open_refcount; > > uint8_t write_open_refcount; > >=20 > > @@ -336,9 +337,7 @@ > >=20 > > static usb_callback_t uaudio_chan_play_callback; > > static usb_callback_t uaudio_chan_record_callback; > > static usb_callback_t uaudio_mixer_write_cfg_callback; > >=20 > > -static usb_callback_t umidi_read_clear_stall_callback; > >=20 > > static usb_callback_t umidi_bulk_read_callback; > >=20 > > -static usb_callback_t umidi_write_clear_stall_callback; > >=20 > > static usb_callback_t umidi_bulk_write_callback; > > =20 > > static void uaudio_chan_fill_info_sub(struct uaudio_softc *, > >=20 > > @@ -493,7 +492,7 @@ > >=20 > > static const struct usb_config > > =20 > > umidi_config[UMIDI_N_TRANSFER] =3D { > >=20 > > - [0] =3D { > > + [UMIDI_TX_TRANSFER] =3D { > >=20 > > .type =3D UE_BULK, > > .endpoint =3D UE_ADDR_ANY, > > .direction =3D UE_DIR_OUT, > >=20 > > @@ -502,7 +501,7 @@ > >=20 > > .callback =3D &umidi_bulk_write_callback, > > =09 > > }, > >=20 > > - [1] =3D { > > + [UMIDI_RX_TRANSFER] =3D { > >=20 > > .type =3D UE_BULK, > > .endpoint =3D UE_ADDR_ANY, > > .direction =3D UE_DIR_IN, > >=20 > > @@ -510,26 +509,6 @@ > >=20 > > .flags =3D {.pipe_bof =3D 1,.short_xfer_ok =3D 1,.proxy_buffer =3D 1= ,}, > > .callback =3D &umidi_bulk_read_callback, > > =09 > > }, > >=20 > > - > > - [2] =3D { > > - .type =3D UE_CONTROL, > > - .endpoint =3D 0x00, /* Control pipe */ > > - .direction =3D UE_DIR_ANY, > > - .bufsize =3D sizeof(struct usb_device_request), > > - .callback =3D &umidi_write_clear_stall_callback, > > - .timeout =3D 1000, /* 1 second */ > > - .interval =3D 50, /* 50ms */ > > - }, > > - > > - [3] =3D { > > - .type =3D UE_CONTROL, > > - .endpoint =3D 0x00, /* Control pipe */ > > - .direction =3D UE_DIR_ANY, > > - .bufsize =3D sizeof(struct usb_device_request), > > - .callback =3D &umidi_read_clear_stall_callback, > > - .timeout =3D 1000, /* 1 second */ > > - .interval =3D 50, /* 50ms */ > > - }, > >=20 > > }; > > =20 > > static devclass_t uaudio_devclass; > >=20 > > @@ -1577,10 +1556,10 @@ > >=20 > > uaudio_mixer_add_ctl_sub(struct uaudio_softc *sc, struct > > uaudio_mixer_node *mc) { > > =20 > > struct uaudio_mixer_node *p_mc_new =3D > >=20 > > - malloc(sizeof(*p_mc_new), M_USBDEV, M_WAITOK); > > + malloc(sizeof(*p_mc_new), M_USBDEV, M_WAITOK); > >=20 > > - if (p_mc_new) { > > - bcopy(mc, p_mc_new, sizeof(*p_mc_new)); > > + if (p_mc_new !=3D NULL) { > > + memcpy(p_mc_new, mc, sizeof(*p_mc_new)); > >=20 > > p_mc_new->next =3D sc->sc_mixer_root; > > sc->sc_mixer_root =3D p_mc_new; > > sc->sc_mixer_count++; > >=20 > > @@ -1722,7 +1701,7 @@ > >=20 > > DPRINTFN(3, "ichs=3D%d ochs=3D%d\n", ichs, ochs); > >=20 > > - bzero(&mix, sizeof(mix)); > > + memset(&mix, 0, sizeof(mix)); > >=20 > > mix.wIndex =3D MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no); > > uaudio_mixer_determine_class(&iot[id], &mix); > >=20 > > @@ -1782,7 +1761,7 @@ > >=20 > > if (d->bNrInPins =3D=3D 0) { > > =09 > > return; > > =09 > > } > >=20 > > - bzero(&mix, sizeof(mix)); > > + memset(&mix, 0, sizeof(mix)); > >=20 > > mix.wIndex =3D MAKE_WORD(d->bUnitId, sc->sc_mixer_iface_no); > > mix.wValue[0] =3D MAKE_WORD(0, 0); > >=20 > > @@ -1852,7 +1831,7 @@ > >=20 > > if (d->bControlSize =3D=3D 0) { > > =09 > > return; > > =09 > > } > >=20 > > - bzero(&mix, sizeof(mix)); > > + memset(&mix, 0, sizeof(mix)); > >=20 > > nchan =3D (d->bLength - 7) / d->bControlSize; > > mmask =3D uaudio_mixer_feature_get_bmaControls(d, 0); > >=20 > > @@ -1986,7 +1965,7 @@ > >=20 > > DPRINTF("no mode select\n"); > > return; > > =09 > > } > >=20 > > - bzero(&mix, sizeof(mix)); > > + memset(&mix, 0, sizeof(mix)); > >=20 > > mix.wIndex =3D MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no); > > mix.nchan =3D 1; > >=20 > > @@ -2012,7 +1991,7 @@ > >=20 > > struct uaudio_mixer_node mix; > > uint16_t ptype; > >=20 > > - bzero(&mix, sizeof(mix)); > > + memset(&mix, 0, sizeof(mix)); > >=20 > > ptype =3D UGETW(d0->wProcessType); > >=20 > > @@ -2067,7 +2046,7 @@ > >=20 > > } > > if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) { > >=20 > > - bzero(&mix, sizeof(mix)); > > + memset(&mix, 0, sizeof(mix)); > >=20 > > mix.wIndex =3D MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no); > > mix.nchan =3D 1; > >=20 > > @@ -2294,7 +2273,7 @@ > >=20 > > } > > =20 > > error: > > DPRINTF("bad data\n"); > >=20 > > - bzero(&r, sizeof(r)); > > + memset(&r, 0, sizeof(r)); > >=20 > > done: > > return (r); > > =20 > > } > >=20 > > @@ -3284,25 +3263,12 @@ > >=20 > > *=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > =3D=3D*/ > > =20 > > static void > >=20 > > -umidi_read_clear_stall_callback(struct usb_xfer *xfer, usb_error_t > > error) -{ > > - struct umidi_chan *chan =3D usbd_xfer_softc(xfer); > > - struct usb_xfer *xfer_other =3D chan->xfer[1]; > > - > > - if (usbd_clear_stall_callback(xfer, xfer_other)) { > > - DPRINTF("stall cleared\n"); > > - chan->flags &=3D ~UMIDI_FLAG_READ_STALL; > > - usbd_transfer_start(xfer_other); > > - } > > -} > > - > > -static void > >=20 > > umidi_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) > > { > > =20 > > struct umidi_chan *chan =3D usbd_xfer_softc(xfer); > > struct umidi_sub_chan *sub; > > struct usb_page_cache *pc; > >=20 > > - uint8_t buf[1]; > > + uint8_t buf[5]; > >=20 > > uint8_t cmd_len; > > uint8_t cn; > > uint16_t pos; > >=20 > > @@ -3320,60 +3286,66 @@ > >=20 > > while (actlen >=3D 4) { > >=20 > > - usbd_copy_out(pc, pos, buf, 1); > > - > > - cmd_len =3D umidi_cmd_to_len[buf[0] & 0xF]; /* command length=20 */ > > - cn =3D buf[0] >> 4; /* cable number */ > > + /* copy out the MIDI data */ > > + usbd_copy_out(pc, pos, buf, 4); > > + /* command length */ > > + cmd_len =3D umidi_cmd_to_len[buf[0] & 0xF]; > > + /* cable number */ > > + cn =3D buf[0] >> 4; > > + /* > > + * Lookup sub-channel. The index is range > > + * checked below. > > + */ > >=20 > > sub =3D &chan->sub[cn]; > >=20 > > - if (cmd_len && (cn < chan->max_cable) && sub->read_open) { > > - usb_fifo_put_data(sub->fifo.fp[USB_FIFO_RX], pc, > > - pos + 1, cmd_len, 1); > > - } else { > > - /* ignore the command */ > > - } > > + if ((cmd_len !=3D 0) && > > + (cn < chan->max_cable) && > > + (sub->read_open !=3D 0)) { > >=20 > > + /* re-pack into a 4-byte array */ > > + /* zero unused bytes */ > > + if (cmd_len =3D=3D 1) { > > + buf[2] =3D 0; > > + buf[3] =3D 0; > > + buf[4] =3D 0; > > + } else if (cmd_len =3D=3D 2) { > > + buf[3] =3D 0; > > + buf[4] =3D 0; > > + } else { > > + buf[4] =3D 0; > > + } > > + > > + /* > > + * Send data in 4-byte chunks to the > > + * application: > > + */ > > + usb_fifo_put_data_linear( > > + sub->fifo.fp[USB_FIFO_RX], > > + buf + 1, 4, 1); > > + } > >=20 > > actlen -=3D 4; > > pos +=3D 4; > > =09 > > } > > =09 > > case USB_ST_SETUP: > > DPRINTF("start\n"); > >=20 > > - > > - if (chan->flags & UMIDI_FLAG_READ_STALL) { > > - usbd_transfer_start(chan->xfer[3]); > > - return; > > - } > >=20 > > +tr_setup: > > usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); > > usbd_transfer_submit(xfer); > >=20 > > - return; > > + break; > >=20 > > default: > > DPRINTF("error=3D%s\n", usbd_errstr(error)); > > =09 > > if (error !=3D USB_ERR_CANCELLED) { > > =09 > > /* try to clear stall first */ > >=20 > > - chan->flags |=3D UMIDI_FLAG_READ_STALL; > > - usbd_transfer_start(chan->xfer[3]); > > + usbd_xfer_set_stall(xfer); > > + goto tr_setup; > >=20 > > } > >=20 > > - return; > > - > > + break; > >=20 > > } > > =20 > > } > >=20 > > -static void > > -umidi_write_clear_stall_callback(struct usb_xfer *xfer, usb_error_t > > error) -{ > > - struct umidi_chan *chan =3D usbd_xfer_softc(xfer); > > - struct usb_xfer *xfer_other =3D chan->xfer[0]; > > - > > - if (usbd_clear_stall_callback(xfer, xfer_other)) { > > - DPRINTF("stall cleared\n"); > > - chan->flags &=3D ~UMIDI_FLAG_WRITE_STALL; > > - usbd_transfer_start(xfer_other); > > - } > > -} > > - > >=20 > > /* > > =20 > > * The following statemachine, that converts MIDI commands to > > * USB MIDI packets, derives from Linux's usbmidi.c, which > >=20 > > @@ -3502,6 +3474,8 @@ > >=20 > > sub->temp_cmd =3D sub->temp_1; > > sub->state =3D UMIDI_ST_SYSEX_0; > > return (1); > >=20 > > + default: > > + break; > >=20 > > } > > =09 > > } > > return (0); > >=20 > > @@ -3527,13 +3501,9 @@ > >=20 > > DPRINTF("actlen=3D%d bytes\n", len); > > =09 > > case USB_ST_SETUP: > > - > >=20 > > +tr_setup: > > DPRINTF("start\n"); > >=20 > > - if (chan->flags & UMIDI_FLAG_WRITE_STALL) { > > - usbd_transfer_start(chan->xfer[2]); > > - return; > > - } > >=20 > > total_length =3D 0; /* reset */ > > start_cable =3D chan->curr_cable; > > tr_any =3D 0; > >=20 > > @@ -3593,7 +3563,7 @@ > >=20 > > usbd_xfer_set_frame_len(xfer, 0, total_length); > > usbd_transfer_submit(xfer); > > =09 > > } > >=20 > > - return; > > + break; > >=20 > > default: /* Error */ > >=20 > > @@ -3601,11 +3571,10 @@ > >=20 > > if (error !=3D USB_ERR_CANCELLED) { > > =09 > > /* try to clear stall first */ > >=20 > > - chan->flags |=3D UMIDI_FLAG_WRITE_STALL; > > - usbd_transfer_start(chan->xfer[2]); > > + usbd_xfer_set_stall(xfer); > > + goto tr_setup; > >=20 > > } > >=20 > > - return; > > - > > + break; > >=20 > > } > > =20 > > } > >=20 > > @@ -3635,7 +3604,7 @@ > >=20 > > { > > =20 > > struct umidi_chan *chan =3D usb_fifo_softc(fifo); > >=20 > > - usbd_transfer_start(chan->xfer[1]); > > + usbd_transfer_start(chan->xfer[UMIDI_RX_TRANSFER]); > >=20 > > } > > =20 > > static void > >=20 > > @@ -3662,7 +3631,7 @@ > >=20 > > { > > =20 > > struct umidi_chan *chan =3D usb_fifo_softc(fifo); > >=20 > > - usbd_transfer_start(chan->xfer[0]); > > + usbd_transfer_start(chan->xfer[UMIDI_TX_TRANSFER]); > >=20 > > } > > =20 > > static void > >=20 > > @@ -3677,8 +3646,7 @@ > >=20 > > if (--(chan->write_open_refcount) =3D=3D 0) { > > =09 > > DPRINTF("(stopping write transfer)\n"); > >=20 > > - usbd_transfer_stop(chan->xfer[2]); > > - usbd_transfer_stop(chan->xfer[0]); > > + usbd_transfer_stop(chan->xfer[UMIDI_TX_TRANSFER]); > >=20 > > } > > =20 > > } > >=20 > > @@ -3703,7 +3671,7 @@ > >=20 > > } > > /* clear stall first */ > > mtx_lock(&chan->mtx); > >=20 > > - chan->flags |=3D UMIDI_FLAG_WRITE_STALL; > > + usbd_xfer_set_stall(chan->xfer[UMIDI_TX_TRANSFER]); > >=20 > > chan->write_open_refcount++; > > sub->write_open =3D 1; > >=20 > > @@ -3769,7 +3737,8 @@ > >=20 > > DPRINTF("setting of alternate index failed!\n"); > > goto detach; > > =09 > > } > >=20 > > - usbd_set_parent_iface(sc->sc_udev, chan->iface_index, > > sc->sc_mixer_iface_index); + usbd_set_parent_iface(sc->sc_udev, > > chan->iface_index, > > + sc->sc_mixer_iface_index); > >=20 > > error =3D usbd_transfer_setup(uaa->device, &chan->iface_index, > > =09 > > chan->xfer, umidi_config, UMIDI_N_TRANSFER, > >=20 > > @@ -3799,13 +3768,15 @@ > >=20 > > mtx_lock(&chan->mtx); > > =09 > > /* clear stall first */ > >=20 > > - chan->flags |=3D UMIDI_FLAG_READ_STALL; > > + usbd_xfer_set_stall(chan->xfer[UMIDI_RX_TRANSFER]); > >=20 > > /* > >=20 > > - * NOTE: at least one device will not work properly unless > > - * the BULK pipe is open all the time. > > + * NOTE: At least one device will not work properly unless the > > + * BULK IN pipe is open all the time. This might have to do > > + * about that the internal queues of the device overflow if we > > + * don't read them regularly. > >=20 > > */ > >=20 > > - usbd_transfer_start(chan->xfer[1]); > > + usbd_transfer_start(chan->xfer[UMIDI_RX_TRANSFER]); > >=20 > > mtx_unlock(&chan->mtx); > >=20 > > @@ -3828,8 +3799,7 @@ > >=20 > > mtx_lock(&chan->mtx); > >=20 > > - usbd_transfer_stop(chan->xfer[3]); > > - usbd_transfer_stop(chan->xfer[1]); > > + usbd_transfer_stop(chan->xfer[UMIDI_RX_TRANSFER]); > >=20 > > mtx_unlock(&chan->mtx); >=20 > Hi Hans Peter, >=20 > On my laptop The first patch coredump, but not the second. > without the patch, my little soft runs fine, > i.e. using the mutexes part of code from ssynth. > With the second patch: > in the same conditions of testing, all notes stick, and make some jam. > It seems that the performances are degraded here. > what i do is simple: > the master keyboard sends the notes, the soft does some transformations a= nd > resends the notes to the two modules. >=20 > Do you need something else? > feel free to ask, of course. Could you try this third patch? =2D-HPS --Boundary-00=_bkZXNBbphpH84ED Content-Type: text/plain; charset="iso-8859-15"; name="umidi_patch_003.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="umidi_patch_003.txt" === uaudio.c ================================================================== --- uaudio.c (revision 218769) +++ uaudio.c (local) @@ -191,10 +191,15 @@ uint8_t iface_alt_index; }; -#define UMIDI_N_TRANSFER 4 /* units */ #define UMIDI_CABLES_MAX 16 /* units */ #define UMIDI_BULK_SIZE 1024 /* bytes */ +enum { + UMIDI_TX_TRANSFER, + UMIDI_RX_TRANSFER, + UMIDI_N_TRANSFER, +}; + struct umidi_sub_chan { struct usb_fifo_sc fifo; uint8_t *temp_cmd; @@ -224,10 +229,6 @@ uint8_t iface_index; uint8_t iface_alt_index; - uint8_t flags; -#define UMIDI_FLAG_READ_STALL 0x01 -#define UMIDI_FLAG_WRITE_STALL 0x02 - uint8_t read_open_refcount; uint8_t write_open_refcount; @@ -336,9 +337,7 @@ static usb_callback_t uaudio_chan_play_callback; static usb_callback_t uaudio_chan_record_callback; static usb_callback_t uaudio_mixer_write_cfg_callback; -static usb_callback_t umidi_read_clear_stall_callback; static usb_callback_t umidi_bulk_read_callback; -static usb_callback_t umidi_write_clear_stall_callback; static usb_callback_t umidi_bulk_write_callback; static void uaudio_chan_fill_info_sub(struct uaudio_softc *, @@ -493,7 +492,7 @@ static const struct usb_config umidi_config[UMIDI_N_TRANSFER] = { - [0] = { + [UMIDI_TX_TRANSFER] = { .type = UE_BULK, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, @@ -502,7 +501,7 @@ .callback = &umidi_bulk_write_callback, }, - [1] = { + [UMIDI_RX_TRANSFER] = { .type = UE_BULK, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, @@ -510,26 +509,6 @@ .flags = {.pipe_bof = 1,.short_xfer_ok = 1,.proxy_buffer = 1,}, .callback = &umidi_bulk_read_callback, }, - - [2] = { - .type = UE_CONTROL, - .endpoint = 0x00, /* Control pipe */ - .direction = UE_DIR_ANY, - .bufsize = sizeof(struct usb_device_request), - .callback = &umidi_write_clear_stall_callback, - .timeout = 1000, /* 1 second */ - .interval = 50, /* 50ms */ - }, - - [3] = { - .type = UE_CONTROL, - .endpoint = 0x00, /* Control pipe */ - .direction = UE_DIR_ANY, - .bufsize = sizeof(struct usb_device_request), - .callback = &umidi_read_clear_stall_callback, - .timeout = 1000, /* 1 second */ - .interval = 50, /* 50ms */ - }, }; static devclass_t uaudio_devclass; @@ -1577,10 +1556,10 @@ uaudio_mixer_add_ctl_sub(struct uaudio_softc *sc, struct uaudio_mixer_node *mc) { struct uaudio_mixer_node *p_mc_new = - malloc(sizeof(*p_mc_new), M_USBDEV, M_WAITOK); + malloc(sizeof(*p_mc_new), M_USBDEV, M_WAITOK); - if (p_mc_new) { - bcopy(mc, p_mc_new, sizeof(*p_mc_new)); + if (p_mc_new != NULL) { + memcpy(p_mc_new, mc, sizeof(*p_mc_new)); p_mc_new->next = sc->sc_mixer_root; sc->sc_mixer_root = p_mc_new; sc->sc_mixer_count++; @@ -1722,7 +1701,7 @@ DPRINTFN(3, "ichs=%d ochs=%d\n", ichs, ochs); - bzero(&mix, sizeof(mix)); + memset(&mix, 0, sizeof(mix)); mix.wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no); uaudio_mixer_determine_class(&iot[id], &mix); @@ -1782,7 +1761,7 @@ if (d->bNrInPins == 0) { return; } - bzero(&mix, sizeof(mix)); + memset(&mix, 0, sizeof(mix)); mix.wIndex = MAKE_WORD(d->bUnitId, sc->sc_mixer_iface_no); mix.wValue[0] = MAKE_WORD(0, 0); @@ -1852,7 +1831,7 @@ if (d->bControlSize == 0) { return; } - bzero(&mix, sizeof(mix)); + memset(&mix, 0, sizeof(mix)); nchan = (d->bLength - 7) / d->bControlSize; mmask = uaudio_mixer_feature_get_bmaControls(d, 0); @@ -1986,7 +1965,7 @@ DPRINTF("no mode select\n"); return; } - bzero(&mix, sizeof(mix)); + memset(&mix, 0, sizeof(mix)); mix.wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no); mix.nchan = 1; @@ -2012,7 +1991,7 @@ struct uaudio_mixer_node mix; uint16_t ptype; - bzero(&mix, sizeof(mix)); + memset(&mix, 0, sizeof(mix)); ptype = UGETW(d0->wProcessType); @@ -2067,7 +2046,7 @@ } if (d1->bmControls[0] & UA_EXT_ENABLE_MASK) { - bzero(&mix, sizeof(mix)); + memset(&mix, 0, sizeof(mix)); mix.wIndex = MAKE_WORD(d0->bUnitId, sc->sc_mixer_iface_no); mix.nchan = 1; @@ -2294,7 +2273,7 @@ } error: DPRINTF("bad data\n"); - bzero(&r, sizeof(r)); + memset(&r, 0, sizeof(r)); done: return (r); } @@ -3284,25 +3263,12 @@ *========================================================================*/ static void -umidi_read_clear_stall_callback(struct usb_xfer *xfer, usb_error_t error) -{ - struct umidi_chan *chan = usbd_xfer_softc(xfer); - struct usb_xfer *xfer_other = chan->xfer[1]; - - if (usbd_clear_stall_callback(xfer, xfer_other)) { - DPRINTF("stall cleared\n"); - chan->flags &= ~UMIDI_FLAG_READ_STALL; - usbd_transfer_start(xfer_other); - } -} - -static void umidi_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error) { struct umidi_chan *chan = usbd_xfer_softc(xfer); struct umidi_sub_chan *sub; struct usb_page_cache *pc; - uint8_t buf[1]; + uint8_t buf[4]; uint8_t cmd_len; uint8_t cn; uint16_t pos; @@ -3320,60 +3286,50 @@ while (actlen >= 4) { - usbd_copy_out(pc, pos, buf, 1); - - cmd_len = umidi_cmd_to_len[buf[0] & 0xF]; /* command length */ - cn = buf[0] >> 4; /* cable number */ + /* copy out the MIDI data */ + usbd_copy_out(pc, pos, buf, 4); + /* command length */ + cmd_len = umidi_cmd_to_len[buf[0] & 0xF]; + /* cable number */ + cn = buf[0] >> 4; + /* + * Lookup sub-channel. The index is range + * checked below. + */ sub = &chan->sub[cn]; - if (cmd_len && (cn < chan->max_cable) && sub->read_open) { - usb_fifo_put_data(sub->fifo.fp[USB_FIFO_RX], pc, - pos + 1, cmd_len, 1); - } else { - /* ignore the command */ - } + if ((cmd_len != 0) && + (cn < chan->max_cable) && + (sub->read_open != 0)) { + /* Send data to the application */ + usb_fifo_put_data_linear( + sub->fifo.fp[USB_FIFO_RX], + buf + 1, cmd_len, 1); + } actlen -= 4; pos += 4; } case USB_ST_SETUP: DPRINTF("start\n"); - - if (chan->flags & UMIDI_FLAG_READ_STALL) { - usbd_transfer_start(chan->xfer[3]); - return; - } +tr_setup: usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); usbd_transfer_submit(xfer); - return; + break; default: DPRINTF("error=%s\n", usbd_errstr(error)); if (error != USB_ERR_CANCELLED) { /* try to clear stall first */ - chan->flags |= UMIDI_FLAG_READ_STALL; - usbd_transfer_start(chan->xfer[3]); + usbd_xfer_set_stall(xfer); + goto tr_setup; } - return; - + break; } } -static void -umidi_write_clear_stall_callback(struct usb_xfer *xfer, usb_error_t error) -{ - struct umidi_chan *chan = usbd_xfer_softc(xfer); - struct usb_xfer *xfer_other = chan->xfer[0]; - - if (usbd_clear_stall_callback(xfer, xfer_other)) { - DPRINTF("stall cleared\n"); - chan->flags &= ~UMIDI_FLAG_WRITE_STALL; - usbd_transfer_start(xfer_other); - } -} - /* * The following statemachine, that converts MIDI commands to * USB MIDI packets, derives from Linux's usbmidi.c, which @@ -3502,6 +3458,8 @@ sub->temp_cmd = sub->temp_1; sub->state = UMIDI_ST_SYSEX_0; return (1); + default: + break; } } return (0); @@ -3527,13 +3485,9 @@ DPRINTF("actlen=%d bytes\n", len); case USB_ST_SETUP: - +tr_setup: DPRINTF("start\n"); - if (chan->flags & UMIDI_FLAG_WRITE_STALL) { - usbd_transfer_start(chan->xfer[2]); - return; - } total_length = 0; /* reset */ start_cable = chan->curr_cable; tr_any = 0; @@ -3593,7 +3547,7 @@ usbd_xfer_set_frame_len(xfer, 0, total_length); usbd_transfer_submit(xfer); } - return; + break; default: /* Error */ @@ -3601,11 +3555,10 @@ if (error != USB_ERR_CANCELLED) { /* try to clear stall first */ - chan->flags |= UMIDI_FLAG_WRITE_STALL; - usbd_transfer_start(chan->xfer[2]); + usbd_xfer_set_stall(xfer); + goto tr_setup; } - return; - + break; } } @@ -3635,7 +3588,7 @@ { struct umidi_chan *chan = usb_fifo_softc(fifo); - usbd_transfer_start(chan->xfer[1]); + usbd_transfer_start(chan->xfer[UMIDI_RX_TRANSFER]); } static void @@ -3662,7 +3615,7 @@ { struct umidi_chan *chan = usb_fifo_softc(fifo); - usbd_transfer_start(chan->xfer[0]); + usbd_transfer_start(chan->xfer[UMIDI_TX_TRANSFER]); } static void @@ -3677,8 +3630,7 @@ if (--(chan->write_open_refcount) == 0) { DPRINTF("(stopping write transfer)\n"); - usbd_transfer_stop(chan->xfer[2]); - usbd_transfer_stop(chan->xfer[0]); + usbd_transfer_stop(chan->xfer[UMIDI_TX_TRANSFER]); } } @@ -3703,7 +3655,7 @@ } /* clear stall first */ mtx_lock(&chan->mtx); - chan->flags |= UMIDI_FLAG_WRITE_STALL; + usbd_xfer_set_stall(chan->xfer[UMIDI_TX_TRANSFER]); chan->write_open_refcount++; sub->write_open = 1; @@ -3769,7 +3721,8 @@ DPRINTF("setting of alternate index failed!\n"); goto detach; } - usbd_set_parent_iface(sc->sc_udev, chan->iface_index, sc->sc_mixer_iface_index); + usbd_set_parent_iface(sc->sc_udev, chan->iface_index, + sc->sc_mixer_iface_index); error = usbd_transfer_setup(uaa->device, &chan->iface_index, chan->xfer, umidi_config, UMIDI_N_TRANSFER, @@ -3799,13 +3752,15 @@ mtx_lock(&chan->mtx); /* clear stall first */ - chan->flags |= UMIDI_FLAG_READ_STALL; + usbd_xfer_set_stall(chan->xfer[UMIDI_RX_TRANSFER]); /* - * NOTE: at least one device will not work properly unless - * the BULK pipe is open all the time. + * NOTE: At least one device will not work properly unless the + * BULK IN pipe is open all the time. This might have to do + * about that the internal queues of the device overflow if we + * don't read them regularly. */ - usbd_transfer_start(chan->xfer[1]); + usbd_transfer_start(chan->xfer[UMIDI_RX_TRANSFER]); mtx_unlock(&chan->mtx); @@ -3828,8 +3783,7 @@ mtx_lock(&chan->mtx); - usbd_transfer_stop(chan->xfer[3]); - usbd_transfer_stop(chan->xfer[1]); + usbd_transfer_stop(chan->xfer[UMIDI_RX_TRANSFER]); mtx_unlock(&chan->mtx); --Boundary-00=_bkZXNBbphpH84ED--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201102172254.35501.hselasky>