svn commit: r223879 - in stable/8/sys/dev: sound/usb usb usb/quirk

Hans Petter Selasky hselasky at FreeBSD.org
Sat Jul 9 11:22:24 UTC 2011


Author: hselasky
Date: Sat Jul  9 11:22:23 2011
New Revision: 223879
URL: http://svn.freebsd.org/changeset/base/223879

Log:
  MFC r223727 and r223736:
  - Add quirk for non-compliant USB MIDI hardware.
  - Reduce MIDI TX buffer size to 512 bytes.

Modified:
  stable/8/sys/dev/sound/usb/uaudio.c
  stable/8/sys/dev/usb/quirk/usb_quirk.c
  stable/8/sys/dev/usb/quirk/usb_quirk.h
  stable/8/sys/dev/usb/usbdevs
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/dev/sound/usb/uaudio.c
==============================================================================
--- stable/8/sys/dev/sound/usb/uaudio.c	Sat Jul  9 08:42:23 2011	(r223878)
+++ stable/8/sys/dev/sound/usb/uaudio.c	Sat Jul  9 11:22:23 2011	(r223879)
@@ -192,7 +192,8 @@ struct uaudio_chan {
 };
 
 #define	UMIDI_CABLES_MAX   16		/* units */
-#define	UMIDI_BULK_SIZE  1024		/* bytes */
+#define	UMIDI_TX_FRAMES	   128		/* units */
+#define	UMIDI_TX_BUFFER    (UMIDI_TX_FRAMES * 4)	/* bytes */
 
 enum {
 	UMIDI_TX_TRANSFER,
@@ -235,6 +236,7 @@ struct umidi_chan {
 	uint8_t	curr_cable;
 	uint8_t	max_cable;
 	uint8_t	valid;
+	uint8_t single_command;
 };
 
 struct uaudio_softc {
@@ -497,8 +499,7 @@ static const struct usb_config
 		.type = UE_BULK,
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_OUT,
-		.bufsize = UMIDI_BULK_SIZE,
-		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
+		.bufsize = UMIDI_TX_BUFFER,
 		.callback = &umidi_bulk_write_callback,
 	},
 
@@ -507,7 +508,7 @@ static const struct usb_config
 		.endpoint = UE_ADDR_ANY,
 		.direction = UE_DIR_IN,
 		.bufsize = 4,	/* bytes */
-		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,.proxy_buffer = 1,},
+		.flags = {.short_xfer_ok = 1,.proxy_buffer = 1,},
 		.callback = &umidi_bulk_read_callback,
 	},
 };
@@ -3541,7 +3542,7 @@ umidi_bulk_write_callback(struct usb_xfe
 	struct umidi_sub_chan *sub;
 	struct usb_page_cache *pc;
 	uint32_t actlen;
-	uint16_t total_length;
+	uint16_t nframes;
 	uint8_t buf;
 	uint8_t start_cable;
 	uint8_t tr_any;
@@ -3549,6 +3550,10 @@ umidi_bulk_write_callback(struct usb_xfe
 
 	usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
 
+	/*
+	 * NOTE: Some MIDI devices only accept 4 bytes of data per
+	 * short terminated USB transfer.
+	 */
 	switch (USB_GET_STATE(xfer)) {
 	case USB_ST_TRANSFERRED:
 		DPRINTF("actlen=%d bytes\n", len);
@@ -3557,7 +3562,7 @@ umidi_bulk_write_callback(struct usb_xfe
 tr_setup:
 		DPRINTF("start\n");
 
-		total_length = 0;	/* reset */
+		nframes = 0;	/* reset */
 		start_cable = chan->curr_cable;
 		tr_any = 0;
 		pc = usbd_xfer_get_frame(xfer, 0);
@@ -3569,51 +3574,50 @@ tr_setup:
 			sub = &chan->sub[chan->curr_cable];
 
 			if (sub->write_open) {
-				usb_fifo_get_data(sub->fifo.fp[USB_FIFO_TX],
-				    pc, total_length, 1, &actlen, 0);
+				usb_fifo_get_data_linear(sub->fifo.fp[USB_FIFO_TX],
+				    &buf, 1, &actlen, 0);
 			} else {
 				actlen = 0;
 			}
 
 			if (actlen) {
-				usbd_copy_out(pc, total_length, &buf, 1);
 
 				tr_any = 1;
 
-				DPRINTF("byte=0x%02x\n", buf);
+				DPRINTF("byte=0x%02x from FIFO %u\n", buf,
+				    (unsigned int)chan->curr_cable);
 
 				if (umidi_convert_to_usb(sub, chan->curr_cable, buf)) {
 
-					DPRINTF("sub= %02x %02x %02x %02x\n",
+					DPRINTF("sub=0x%02x 0x%02x 0x%02x 0x%02x\n",
 					    sub->temp_cmd[0], sub->temp_cmd[1],
 					    sub->temp_cmd[2], sub->temp_cmd[3]);
 
-					usbd_copy_in(pc, total_length,
-					    sub->temp_cmd, 4);
+					usbd_copy_in(pc, nframes * 4, sub->temp_cmd, 4);
 
-					total_length += 4;
+					nframes++;
 
-					if (total_length >= UMIDI_BULK_SIZE) {
+					if ((nframes >= UMIDI_TX_FRAMES) || (chan->single_command != 0))
 						break;
-					}
 				} else {
 					continue;
 				}
 			}
+
 			chan->curr_cable++;
-			if (chan->curr_cable >= chan->max_cable) {
+			if (chan->curr_cable >= chan->max_cable)
 				chan->curr_cable = 0;
-			}
+
 			if (chan->curr_cable == start_cable) {
-				if (tr_any == 0) {
+				if (tr_any == 0)
 					break;
-				}
 				tr_any = 0;
 			}
 		}
 
-		if (total_length) {
-			usbd_xfer_set_frame_len(xfer, 0, total_length);
+		if (nframes != 0) {
+			DPRINTF("Transferring %d frames\n", (int)nframes);
+			usbd_xfer_set_frame_len(xfer, 0, 4 * nframes);
 			usbd_transfer_submit(xfer);
 		}
 		break;
@@ -3785,6 +3789,9 @@ umidi_probe(device_t dev)
 	int error;
 	uint32_t n;
 
+	if (usb_test_quirk(uaa, UQ_SINGLE_CMD_MIDI))
+		chan->single_command = 1;
+
 	if (usbd_set_alt_interface_index(sc->sc_udev, chan->iface_index,
 	    chan->iface_alt_index)) {
 		DPRINTF("setting of alternate index failed!\n");

Modified: stable/8/sys/dev/usb/quirk/usb_quirk.c
==============================================================================
--- stable/8/sys/dev/usb/quirk/usb_quirk.c	Sat Jul  9 08:42:23 2011	(r223878)
+++ stable/8/sys/dev/usb/quirk/usb_quirk.c	Sat Jul  9 11:22:23 2011	(r223879)
@@ -472,6 +472,7 @@ static struct usb_quirk_entry usb_quirks
 	USB_QUIRK(ROLAND, SD20, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS),
 	USB_QUIRK(ROLAND, SD80, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS),
 	USB_QUIRK(ROLAND, UA700, 0x0000, 0xffff, UQ_AU_VENDOR_CLASS),
+	USB_QUIRK(MEDELI, DD305, 0x0000, 0xffff, UQ_SINGLE_CMD_MIDI, UQ_MATCH_VENDOR_ONLY),
 };
 #undef USB_QUIRK_VP
 #undef USB_QUIRK
@@ -538,6 +539,7 @@ static const char *usb_quirk_str[USB_QUI
 	[UQ_MSC_EJECT_TCT]		= "UQ_MSC_EJECT_TCT",
 	[UQ_BAD_MIDI]			= "UQ_BAD_MIDI",
 	[UQ_AU_VENDOR_CLASS]		= "UQ_AU_VENDOR_CLASS",
+	[UQ_SINGLE_CMD_MIDI]		= "UQ_SINGLE_CMD_MIDI",
 };
 
 /*------------------------------------------------------------------------*

Modified: stable/8/sys/dev/usb/quirk/usb_quirk.h
==============================================================================
--- stable/8/sys/dev/usb/quirk/usb_quirk.h	Sat Jul  9 08:42:23 2011	(r223878)
+++ stable/8/sys/dev/usb/quirk/usb_quirk.h	Sat Jul  9 11:22:23 2011	(r223879)
@@ -102,6 +102,7 @@ enum {
 
 	UQ_BAD_MIDI,		/* device claims MIDI class, but isn't */
 	UQ_AU_VENDOR_CLASS,	/* audio device uses vendor and not audio class */
+	UQ_SINGLE_CMD_MIDI,	/* at most one command per USB packet */
 
 	USB_QUIRK_MAX
 };

Modified: stable/8/sys/dev/usb/usbdevs
==============================================================================
--- stable/8/sys/dev/usb/usbdevs	Sat Jul  9 08:42:23 2011	(r223878)
+++ stable/8/sys/dev/usb/usbdevs	Sat Jul  9 11:22:23 2011	(r223879)
@@ -484,6 +484,7 @@ vendor SHANTOU		0x0a46	ShanTou
 vendor MEDIAGEAR	0x0a48	MediaGear
 vendor BROADCOM		0x0a5c	Broadcom
 vendor GREENHOUSE	0x0a6b	GREENHOUSE
+vendor MEDELI		0x0a67	Medeli
 vendor GEOCAST		0x0a79	Geocast Network Systems
 vendor IDQUANTIQUE	0x0aba	id Quantique
 vendor ZYDAS		0x0ace	Zydas Technology Corporation
@@ -2129,6 +2130,9 @@ product MCT DU_H3SP_USB232	0x0200	D-Link
 product MCT USB232		0x0210	USB-232 Interface
 product MCT SITECOM_USB232	0x0230	Sitecom USB-232 Products
 
+/* Medeli */
+product MEDELI DD305		0x5011	DD305 Digital Drum Set
+
 /* MediaTek, Inc. */
 product MEDIATEK MTK3329	0x3329	MTK II GPS Receiver
 


More information about the svn-src-stable-8 mailing list