[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

patch: umidi(4) improvement



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;
 		}



Visit your host, monkey.org