patch: umidi(4) improvement

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

patch: umidi(4) improvement

Alexandre Ratchov-2
Hello,

As pointed recently by Chapman Flank, the current umidi(4) driver sends
every usb-midi event to the umidi device in a separate usb transfer.

The following patch improves this by allowing multiple events to be
transfered in a single usb transfer. Also multiple midi devices that have to
use the same usb endpoint will share the same usb transfer when possible.

I've had to add a new "optional" flush() method to the midi hardware
interface (struct midi_hw_if, see sys/dev/midi_if.h), this change doesn't
affect old mpu(4)-like drivers (testers can confirm this?).

I've tested the patch on -current, with the following umidi hardware:
        - Edirol UM2 2in/2out interface (fixed endpoints)
        - Roland XV-2020 sound module (class-compliant)
        - M-Audio 61es keyboard (class-compliant)

The patch also fixes a bug preventing two midi(4) devices attached to the
same endpoint of an umidi(4) device to work reliably.

Feedback appreciated, especially from midi(4) users.

--
Alexandre
Index: midi.c
===================================================================
RCS file: /cvs/src/sys/dev/midi.c,v
retrieving revision 1.12
diff -u -r1.12 midi.c
--- midi.c 22 Sep 2004 22:17:44 -0000 1.12
+++ midi.c 25 Mar 2006 10:56:45 -0000
@@ -48,6 +48,7 @@
 #include <dev/audio_if.h>
 #include <dev/midivar.h>
 
+
 int     midiopen(dev_t, int, int, struct proc *);
 int     midiclose(dev_t, int, int, struct proc *);
 int     midiread(dev_t, struct uio *, int);
@@ -223,34 +224,53 @@
 {
  struct midi_buffer *mb = &sc->outbuf;
  unsigned    i, max;
- unsigned    data;
  int    error;
 
  /*
  * If output interrupts are not supported then we write MIDI_MAXWRITE
  * bytes instead of 1, and then we wait sc->wait
- */
-
+ */
+
  max = sc->props & MIDI_PROP_OUT_INTR ? 1 : MIDI_MAXWRITE;
  for (i = max; i != 0;) {
  if (mb->used == 0)
  break;
-
- MIDIBUF_READ(mb, data);
- error = sc->hw_if->output(sc->hw_hdl, data);
+ error = sc->hw_if->output(sc->hw_hdl, mb->data[mb->start]);
  /*
- * EINPROGRESS means that data has been handled,
- * but will not be sent immediately and thus will
- * not generate interrupt, in this case we can
- * send another byte
+ * 0 means that data is being sent, an interrupt will
+ * be generated when the interface becomes ready again
+ *
+ * EINPROGRESS means that data has been queued, but
+ * will not be sent immediately and thus will not
+ * generate interrupt, in this case we can send
+ * another byte. The flush() method can be called
+ * to force the tranfer.
+ *
+ * EAGAIN means that data cannot be queued or sent;
+ * because the interface isn't ready. An interrupt
+ * will be generated once the interface is ready again
+ *
+ * any other (fatal) error code means that data couldn't
+ * be sent and was lost, interrupt will not be generated
  */
  if (error == EINPROGRESS) {
+ MIDIBUF_REMOVE(mb, 1);
  if (MIDIBUF_ISEMPTY(mb)) {
+ if (sc->hw_if->flush != NULL)
+ sc->hw_if->flush(sc->hw_hdl);
  midi_out_stop(sc);
  return;
  }
- } else
+ } else if (error == 0) {
+ MIDIBUF_REMOVE(mb, 1);
  i--;
+ } else if (error == EAGAIN) {
+ break;
+ } else {
+ MIDIBUF_INIT(mb);
+ midi_out_stop(sc);
+ return;
+ }
  }
 
  if (!(sc->props & MIDI_PROP_OUT_INTR)) {
Index: midi_if.h
===================================================================
RCS file: /cvs/src/sys/dev/midi_if.h,v
retrieving revision 1.5
diff -u -r1.5 midi_if.h
--- midi_if.h 15 Mar 2002 01:20:04 -0000 1.5
+++ midi_if.h 25 Mar 2006 10:56:46 -0000
@@ -56,6 +56,7 @@
  void *);
  void (*close)(void *); /* close hardware */
  int (*output)(void *, int); /* output a byte */
+ void (*flush)(void *); /* flush the output */
  void (*getinfo)(void *, struct midi_info *);
  int (*ioctl)(void *, u_long, caddr_t, int, struct proc *);
 };
Index: midisyn.c
===================================================================
RCS file: /cvs/src/sys/dev/midisyn.c,v
retrieving revision 1.5
diff -u -r1.5 midisyn.c
--- midisyn.c 21 Nov 2005 18:16:38 -0000 1.5
+++ midisyn.c 25 Mar 2006 10:56:46 -0000
@@ -84,6 +84,7 @@
  midisyn_open,
  midisyn_close,
  midisyn_output,
+ NULL, /* flush */
  midisyn_getinfo,
  midisyn_ioctl,
 };
Index: isa/mpu401.c
===================================================================
RCS file: /cvs/src/sys/dev/isa/mpu401.c,v
retrieving revision 1.9
diff -u -r1.9 mpu401.c
--- isa/mpu401.c 9 Jan 2004 21:32:24 -0000 1.9
+++ isa/mpu401.c 25 Mar 2006 10:56:48 -0000
@@ -84,6 +84,7 @@
  mpu_open,
  mpu_close,
  mpu_output,
+ 0, /* flush */
  mpu_getinfo,
  0,                      /* ioctl */
 };
Index: isa/sb.c
===================================================================
RCS file: /cvs/src/sys/dev/isa/sb.c,v
retrieving revision 1.23
diff -u -r1.23 sb.c
--- isa/sb.c 27 Apr 2003 11:22:53 -0000 1.23
+++ isa/sb.c 25 Mar 2006 10:56:49 -0000
@@ -75,6 +75,7 @@
  sbdsp_midi_open,
  sbdsp_midi_close,
  sbdsp_midi_output,
+ 0, /* flush */
  sbdsp_midi_getinfo,
  0, /* ioctl */
 };
@@ -83,6 +84,7 @@
  sb_mpu401_open,
  sb_mpu401_close,
  sb_mpu401_output,
+ 0, /* flush */
  sb_mpu401_getinfo,
  0, /* ioctl */
 };
Index: isa/ym.c
===================================================================
RCS file: /cvs/src/sys/dev/isa/ym.c,v
retrieving revision 1.12
diff -u -r1.12 ym.c
--- isa/ym.c 27 Apr 2003 11:22:53 -0000 1.12
+++ isa/ym.c 25 Mar 2006 10:56:51 -0000
@@ -121,6 +121,7 @@
  ym_mpu401_open,
  ym_mpu401_close,
  ym_mpu401_output,
+ 0, /* flush */
  ym_mpu401_getinfo,
  0, /* ioctl */
 };
Index: pci/autri.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/autri.c,v
retrieving revision 1.17
diff -u -r1.17 autri.c
--- pci/autri.c 22 Feb 2006 18:12:24 -0000 1.17
+++ pci/autri.c 25 Mar 2006 10:56:54 -0000
@@ -184,6 +184,7 @@
  autri_midi_open,
  autri_midi_close,
  autri_midi_output,
+ NULL, /* flush */
  autri_midi_getinfo,
  NULL, /* ioctl */
 };
Index: pci/cs4280.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/cs4280.c,v
retrieving revision 1.24
diff -u -r1.24 cs4280.c
--- pci/cs4280.c 29 Nov 2005 05:42:17 -0000 1.24
+++ pci/cs4280.c 25 Mar 2006 10:56:57 -0000
@@ -277,8 +277,9 @@
  cs4280_midi_open,
  cs4280_midi_close,
  cs4280_midi_output,
+ 0, /* flush */
  cs4280_midi_getinfo,
- 0,
+ 0, /* ioctl */
 };
 #endif
 
Index: pci/eap.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/eap.c,v
retrieving revision 1.28
diff -u -r1.28 eap.c
--- pci/eap.c 9 Aug 2005 04:10:11 -0000 1.28
+++ pci/eap.c 25 Mar 2006 10:57:01 -0000
@@ -272,6 +272,7 @@
  eap_midi_open,
  eap_midi_close,
  eap_midi_output,
+ 0, /* flush */
  eap_midi_getinfo,
  0, /* ioctl */
 };
Index: usb/umidi.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/umidi.c,v
retrieving revision 1.14
diff -u -r1.14 umidi.c
--- usb/umidi.c 21 Nov 2005 18:16:44 -0000 1.14
+++ usb/umidi.c 25 Mar 2006 10:57:10 -0000
@@ -76,6 +76,7 @@
       void (*)(void *, int), void (*)(void *), void *);
 static void umidi_close(void *);
 static int umidi_output(void *, int);
+static void umidi_flush(void *);
 static void umidi_getinfo(void *, struct midi_info *);
 
 static usbd_status alloc_pipe(struct umidi_endpoint *);
@@ -121,15 +122,17 @@
 static usbd_status start_input_transfer(struct umidi_endpoint *);
 static usbd_status start_output_transfer(struct umidi_endpoint *);
 static int out_jack_output(struct umidi_jack *, int);
+static void out_jack_flush(struct umidi_jack *);
 static void in_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
 static void out_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
-static int out_build_packet(int, struct umidi_packet *, uByte);
+static int out_build_packet(int, struct umidi_packet *, uByte, u_char *);
 
 
 struct midi_hw_if umidi_hw_if = {
  umidi_open,
  umidi_close,
  umidi_output,
+ umidi_flush, /* flush */
  umidi_getinfo,
  0, /* ioctl */
 };
@@ -323,6 +326,17 @@
 }
 
 void
+umidi_flush(void *addr)
+{
+ struct umidi_mididev *mididev = addr;
+
+ if (!mididev->out_jack || !mididev->opened)
+ return;
+
+ return out_jack_flush(mididev->out_jack);
+}
+
+void
 umidi_getinfo(void *addr, struct midi_info *mi)
 {
  struct umidi_mididev *mididev = addr;
@@ -346,7 +360,9 @@
  usbd_status err;
 
  DPRINTF(("%s: alloc_pipe %p\n", USBDEVNAME(sc->sc_dev), ep));
- TAILQ_INIT(&ep->queue_head);
+ ep->istart = ep->iused = 0;
+ ep->busy = 0;
+ ep->used = 0;
  ep->xfer = usbd_alloc_xfer(sc->sc_udev);
  if (ep->xfer == NULL) {
  return USBD_NOMEM;
@@ -477,7 +493,6 @@
  sc->sc_out_num_jacks += fp->out_ep[i].num_jacks;
  ep->num_open = 0;
  memset(ep->jacks, 0, sizeof(ep->jacks));
- TAILQ_INIT(&ep->queue_head);
  ep++;
  }
  ep = &sc->sc_in_ep[0];
@@ -594,7 +609,7 @@
  sc->sc_out_ep = sc->sc_endpoints;
  sc->sc_out_ep->sc = sc;
  sc->sc_out_ep->addr = out_addr;
- sc->sc_out_ep->packetsize = UMIDI_PACKET_SIZE;
+ sc->sc_out_ep->packetsize = UGETW(epd->wMaxPacketSize);
  sc->sc_out_ep->num_jacks = sc->sc_out_num_jacks;
  sc->sc_out_ep->num_open = 0;
  memset(sc->sc_out_ep->jacks, 0, sizeof(sc->sc_out_ep->jacks));
@@ -736,6 +751,9 @@
  jack->binded = 0;
  jack->arg = NULL;
  jack->u.out.intr = NULL;
+#ifdef UMIDI_DEBUG
+ jack->wait = 0;
+#endif
  jack->cable_number = i;
  jack++;
  }
@@ -897,11 +915,6 @@
 close_out_jack(struct umidi_jack *jack)
 {
  if (jack->opened) {
-#ifdef UMIDI_DEBUG
- if (!TAILQ_EMPTY(&jack->endpoint->queue_head)) {
- printf("close_out_jack: queue_head still not empty\n");
- }
-#endif
  jack->opened = 0;
  jack->endpoint->num_open--;
  }
@@ -1125,7 +1138,7 @@
  usbd_status err;
  usbd_setup_xfer(ep->xfer, ep->pipe,
  (usbd_private_handle)ep,
- ep->buffer, UMIDI_PACKET_SIZE,
+ ep->buffer, ep->used,
  USBD_NO_COPY, USBD_NO_TIMEOUT, out_intr);
  err = usbd_transfer(ep->xfer);
  if (err != USBD_NORMAL_COMPLETION && err != USBD_IN_PROGRESS) {
@@ -1133,9 +1146,11 @@
  USBDEVNAME(ep->sc->sc_dev), usbd_errstr(err)));
  return err;
  }
+ ep->used = ep->packetsize;
  return USBD_NORMAL_COMPLETION;
 }
 
+
 #ifdef UMIDI_DEBUG
 #define DPR_PACKET(dir, sc, p) \
  DPRINTFN(500, \
@@ -1150,39 +1165,80 @@
 #endif
 
 static int
-out_jack_output(struct umidi_jack *out_jack, int d)
+out_jack_output(struct umidi_jack *j, int d)
 {
- struct umidi_endpoint *ep = out_jack->endpoint;
+ struct umidi_endpoint *ep = j->endpoint;
  struct umidi_softc *sc = ep->sc;
  int s;
 
  if (sc->sc_dying)
  return EIO;
-
- if (!out_jack->opened) {
+ if (!j->opened)
  return ENODEV;
- }
-
- if (out_build_packet(out_jack->cable_number, &out_jack->packet, d)) {
- DPR_PACKET(out, sc, &out_jack->packet);
- s = splusb();
- if (TAILQ_EMPTY(&ep->queue_head)) {
- memcpy(ep->buffer,
-       out_jack->packet.buffer,
-       UMIDI_PACKET_SIZE);
- TAILQ_INSERT_TAIL(&ep->queue_head,
- out_jack, u.out.queue_entry);
- start_output_transfer(ep);
+
+ s = splusb();
+ if (ep->used == ep->packetsize) {
+#ifdef UMIDI_DEBUG
+ if (j->wait == 0) {
+ j->wait = 1;
+#endif
+ ep->ibuf[(ep->istart + ep->iused) & UMIDI_IBUF_MASK] = j;
+ ep->iused++;
+#if UMIDI_DEBUG
  } else {
- DPRINTF(("%s: out_jack_output: packet ignored\n", USBDEVNAME(sc->sc_dev)));
+ printf("out_jack_output: (again) %d: already on ibuf\n", j->cable_number);
  }
+#endif
  splx(s);
- return 0;
+ return EAGAIN;
  }
 
- return EINPROGRESS;
+ if (!out_build_packet(j->cable_number, &j->packet, d, ep->buffer + ep->used)) {
+ splx(s);
+ return EINPROGRESS;
+ }
+ ep->used += UMIDI_PACKET_SIZE;
+ if (ep->used < ep->packetsize) {
+ splx(s);
+ return EINPROGRESS;
+ }
+#ifdef UMIDI_DEBUG
+ if (j->wait == 0) {
+ j->wait = 1;
+#endif
+ ep->ibuf[(ep->istart + ep->iused) & UMIDI_IBUF_MASK] = j;
+ ep->iused++;
+#ifdef UMIDI_DEBUG
+ } else {
+ printf("out_jack_output: (ok) %d: already on ibuf\n", j->cable_number);
+ }
+#endif
+ if (!ep->busy) {
+ ep->busy = 1;
+ start_output_transfer(ep);
+ }
+ splx(s);
+ return 0;
+}
+
+static void
+out_jack_flush(struct umidi_jack *j)
+{
+ struct umidi_endpoint *ep = j->endpoint;
+ int s;
+
+ if (ep->sc->sc_dying || !j->opened)
+ return;
+
+ s = splusb();
+ if (ep->used != 0 && !ep->busy) {
+ ep->busy = 1;
+ start_output_transfer(ep);
+ }
+ splx(s);
 }
 
+
 static void
 in_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 {
@@ -1196,9 +1252,9 @@
 
  usbd_get_xfer_status(xfer, NULL, NULL, &remain, NULL);
  if (status != USBD_NORMAL_COMPLETION) {
- DPRINTF(("umidi: in_intr: abnormal status: %s\n", usbd_errstr(status)));
- goto quit;
- }
+ DPRINTF(("in_intr: abnormal status: %s\n", usbd_errstr(status)));
+ return;
+ }
  buf = ep->buffer;
  while (remain >= UMIDI_PACKET_SIZE) {
  cn = GET_CN(buf[0]);
@@ -1207,21 +1263,10 @@
      evlen = packet_length[GET_CIN(buf[0])];
  for (i=0; i<evlen; i++)
  (*jack->u.in.intr)(jack->arg, buf[i+1]);
- } else
- DPRINTFN(10, ("in_intr: unused packet %02x %02x %02x %02x\n",
- buf[0], buf[1], buf[2], buf[3]));
-
+ }
  buf += UMIDI_PACKET_SIZE;
  remain -= UMIDI_PACKET_SIZE;
  }
-
-#ifdef UMIDI_DEBUG
- if (remain != 0) {
- DPRINTF(("umidi: in_intr: remain != 0\n"));
- }
-#endif
-
-quit:
  (void)start_input_transfer(ep);
 }
 
@@ -1230,26 +1275,35 @@
 {
  struct umidi_endpoint *ep = (struct umidi_endpoint *)priv;
  struct umidi_softc *sc = ep->sc;
- struct umidi_jack *jack;
- int s;
+ struct umidi_jack *j;
+ unsigned pending;
 
  if (sc->sc_dying)
  return;
 
- s = splusb();
- jack = TAILQ_FIRST(&ep->queue_head);
- if (jack) {
- TAILQ_REMOVE(&ep->queue_head, jack, u.out.queue_entry);
- if (!TAILQ_EMPTY(&ep->queue_head)) {
- memcpy(ep->buffer,
-       TAILQ_FIRST(&ep->queue_head)->packet.buffer,
-       UMIDI_PACKET_SIZE);
- (void)start_output_transfer(ep);
+ ep->used = 0;
+ for (pending = ep->iused; pending > 0; pending--) {
+ j = ep->ibuf[ep->istart++];
+ ep->istart &= UMIDI_IBUF_MASK;
+ ep->iused--;
+#ifdef UMIDI_DEBUG
+ if (j->wait) {
+ j->wait = 0;
+#endif
+ if (j->opened && j->u.out.intr)
+ (*j->u.out.intr)(j->arg);
+#ifdef UMIDI_DEBUG
+ } else {
+ DPRINTF(("out_intr: %d: notify flag not raised\n", j->cable_number));
  }
- if (jack->opened && jack->u.out.intr)
- (*jack->u.out.intr)(jack->arg);
+#endif
+ }
+
+ if (ep->used == 0) {
+ ep->busy = 0;
+ } else {
+ start_output_transfer(ep);
  }
- splx(s);
 }
 
 #define UMIDI_VOICELEN(status) (umidi_evlen[((status) >> 4) & 7])
@@ -1263,20 +1317,20 @@
 #define EV_SYSEX_STOP 0xf7
 
 static int
-out_build_packet(int cable_number, struct umidi_packet *packet, uByte data)
+out_build_packet(int cable_number, struct umidi_packet *packet,
+    uByte data, u_char *obuf)
 {
  if (data >= 0xf8) { /* is it a realtime message ? */
- packet->buffer_rt[0] = data >> 4 | cable_number << 4;
- packet->buffer_rt[1] = data;
- packet->buffer_rt[2] = 0;
- packet->buffer_rt[3] = 0;
- packet->buffer = packet->buffer_rt;
+ obuf[0] = data >> 4 | cable_number << 4;
+ obuf[1] = data;
+ obuf[2] = 0;
+ obuf[3] = 0;
  return 1;
  }
  if (data >= 0xf0) { /* is it a common message ? */
  switch(data) {
  case EV_SYSEX:
- packet->buffer_com[1] = packet->status = data;
+ packet->buf[1] = packet->status = data;
  packet->index = 2;
  break;
  case EV_SYSEX_STOP:
@@ -1284,12 +1338,12 @@
  if (packet->index == 0)
  packet->index = 1;
  packet->status = data;
- packet->buffer_com[packet->index++] = data;
- packet->buffer_com[0] = (0x4 - 1 + packet->index) | cable_number << 4;
+ packet->buf[packet->index++] = data;
+ packet->buf[0] = (0x4 - 1 + packet->index) | cable_number << 4;
  goto packetready;
  case EV_TUNE_REQ:
  packet->status = data;
- packet->buffer_com[0] = 0x5 | cable_number << 4;
+ packet->buf[0] = 0x5 | cable_number << 4;
  packet->index = 1;
  goto packetready;
  default:
@@ -1311,27 +1365,27 @@
  if (packet->index == 0)
  packet->index = 1;
 
- packet->buffer_com[packet->index++] = data;
+ packet->buf[packet->index++] = data;
  if (packet->index >= UMIDI_PACKET_SIZE) {
- packet->buffer_com[0] = 0x4 | cable_number << 4;
+ packet->buf[0] = 0x4 | cable_number << 4;
  goto packetready;
  }
  break;
  case EV_MTC: /* messages with 1 data byte */
  case EV_SONGSEL:
- packet->buffer_com[0] = 0x2 | cable_number << 4;
- packet->buffer_com[1] = packet->status;
- packet->buffer_com[2] = data;
+ packet->buf[0] = 0x2 | cable_number << 4;
+ packet->buf[1] = packet->status;
+ packet->buf[2] = data;
  packet->index = 3;
  goto packetready;
  case EV_SPP: /* messages with 2 data bytes */
  if (packet->index == 0) {
- packet->buffer_com[0] = 0x3 | cable_number << 4;
+ packet->buf[0] = 0x3 | cable_number << 4;
  packet->index = 1;
  }
- packet->buffer_com[packet->index++] = data;
+ packet->buf[packet->index++] = data;
  if (packet->index >= UMIDI_PACKET_SIZE) {
- packet->buffer_com[1] = packet->status;
+ packet->buf[1] = packet->status;
  goto packetready;
  }
  break;
@@ -1342,11 +1396,11 @@
  }
  if (packet->status >= 0x80) { /* is it a voice message ? */
  if (packet->index == 0) {
- packet->buffer_com[0] = packet->status >> 4 | cable_number << 4;
- packet->buffer_com[1] = packet->status;
+ packet->buf[0] = packet->status >> 4 | cable_number << 4;
+ packet->buf[1] = packet->status;
  packet->index = 2;
  }
- packet->buffer_com[packet->index++] = data;
+ packet->buf[packet->index++] = data;
  if (packet->index >= UMIDI_VOICELEN(packet->status))
  goto packetready;
  }
@@ -1355,9 +1409,8 @@
 
 packetready:
  while (packet->index < UMIDI_PACKET_SIZE)
- packet->buffer_com[packet->index++] = 0;
-
+ packet->buf[packet->index++] = 0;
  packet->index = 0;
- packet->buffer = packet->buffer_com;
+ memcpy(obuf, packet->buf, UMIDI_PACKET_SIZE);
  return 1;
 }
Index: usb/umidivar.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/umidivar.h,v
retrieving revision 1.9
diff -u -r1.9 umidivar.h
--- usb/umidivar.h 7 Sep 2005 06:57:09 -0000 1.9
+++ usb/umidivar.h 25 Mar 2006 10:57:12 -0000
@@ -40,9 +40,7 @@
 struct umidi_packet {
  unsigned status;
  unsigned index;
- unsigned char buffer_rt[UMIDI_PACKET_SIZE]; /* real time packet */
- unsigned char buffer_com[UMIDI_PACKET_SIZE]; /* common/voice packet */
- unsigned char  *buffer;
+ unsigned char buf[UMIDI_PACKET_SIZE]; /* common/voice packet */
 };
 
 /*
@@ -76,13 +74,15 @@
  void *arg;
  int binded;
  int opened;
+#ifdef UMIDI_DEBUG
+ unsigned wait;
+#endif
  union {
  struct {
- void (*intr)(void *);
- TAILQ_ENTRY(umidi_jack) queue_entry;
+ void (*intr)(void *);
  } out;
  struct {
- void (*intr)(void *, int);
+ void (*intr)(void *, int);
  } in;
  } u;
 };
@@ -100,7 +100,13 @@
  int num_open;
  int num_jacks;
  struct umidi_jack *jacks[UMIDI_MAX_EPJACKS];
- TAILQ_HEAD(, umidi_jack) queue_head;
+ unsigned used;
+ unsigned busy;
+ /* pending interrupts list, at least 2 * UMIDI_MAX_EPJACKS */
+#define UMIDI_IBUF_SIZE (1 << 5)
+#define UMIDI_IBUF_MASK (UMIDI_IBUF_SIZE - 1)
+ struct umidi_jack *ibuf[UMIDI_IBUF_SIZE];
+ unsigned istart, iused;
 };
 
 /* software context */
Index: usb/uvisor.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uvisor.c,v
retrieving revision 1.24
diff -u -r1.24 uvisor.c
--- usb/uvisor.c 14 Mar 2006 10:18:10 -0000 1.24
+++ usb/uvisor.c 25 Mar 2006 10:57:12 -0000
@@ -440,7 +440,7 @@
  * switch them over to using visor. dont do free space
  * checks on them since they dont like them either.
  */
- DPRINTF(("switching role for CLIE probe\n"))
+ DPRINTF(("switching role for CLIE probe\n"));
  sc->sc_flags = CLIE4;
  err = 0;
  }