svn commit: r272254 - head/sys/dev/sound/usb

Hans Petter Selasky hselasky at FreeBSD.org
Sun Sep 28 12:55:14 UTC 2014


Author: hselasky
Date: Sun Sep 28 12:55:13 2014
New Revision: 272254
URL: http://svnweb.freebsd.org/changeset/base/272254

Log:
  Instead of creating the full range of possible ports, try to figure
  out the actual number of so-called "embedded jacks" which are present
  when a USB MIDI device is attaching.
  
  MFC after:	3 days

Modified:
  head/sys/dev/sound/usb/uaudio.c
  head/sys/dev/sound/usb/uaudioreg.h

Modified: head/sys/dev/sound/usb/uaudio.c
==============================================================================
--- head/sys/dev/sound/usb/uaudio.c	Sun Sep 28 12:41:48 2014	(r272253)
+++ head/sys/dev/sound/usb/uaudio.c	Sun Sep 28 12:55:13 2014	(r272254)
@@ -232,7 +232,7 @@ struct uaudio_chan {
 #define	UAUDIO_SYNC_LESS 2
 };
 
-#define	UMIDI_CABLES_MAX   16		/* units */
+#define	UMIDI_EMB_JACK_MAX   16		/* units */
 #define	UMIDI_TX_FRAMES	   256		/* units */
 #define	UMIDI_TX_BUFFER    (UMIDI_TX_FRAMES * 4)	/* bytes */
 
@@ -263,7 +263,7 @@ struct umidi_sub_chan {
 
 struct umidi_chan {
 
-	struct umidi_sub_chan sub[UMIDI_CABLES_MAX];
+	struct umidi_sub_chan sub[UMIDI_EMB_JACK_MAX];
 	struct mtx mtx;
 
 	struct usb_xfer *xfer[UMIDI_N_TRANSFER];
@@ -275,7 +275,7 @@ struct umidi_chan {
 	uint8_t	write_open_refcount;
 
 	uint8_t	curr_cable;
-	uint8_t	max_cable;
+	uint8_t	max_emb_jack;
 	uint8_t	valid;
 	uint8_t single_command;
 };
@@ -1481,6 +1481,7 @@ uaudio_chan_fill_info_sub(struct uaudio_
 	union uaudio_asid asid = { NULL };
 	union uaudio_asf1d asf1d = { NULL };
 	union uaudio_sed sed = { NULL };
+	struct usb_midi_streaming_endpoint_descriptor *msid = NULL;
 	usb_endpoint_descriptor_audio_t *ed1 = NULL;
 	const struct usb_audio_control_descriptor *acdp = NULL;
 	struct usb_config_descriptor *cd = usbd_get_config_descriptor(udev);
@@ -1498,6 +1499,7 @@ uaudio_chan_fill_info_sub(struct uaudio_
 	uint8_t bChannels;
 	uint8_t bBitResolution;
 	uint8_t audio_if = 0;
+	uint8_t midi_if = 0;
 	uint8_t uma_if_class;
 
 	while ((desc = usb_desc_foreach(cd, desc))) {
@@ -1533,7 +1535,8 @@ uaudio_chan_fill_info_sub(struct uaudio_
 			    ((id->bInterfaceClass == UICLASS_VENDOR) &&
 			    (sc->sc_uq_au_vendor_class != 0)));
 
-			if ((uma_if_class != 0) && (id->bInterfaceSubClass == UISUBCLASS_AUDIOSTREAM)) {
+			if ((uma_if_class != 0) &&
+			    (id->bInterfaceSubClass == UISUBCLASS_AUDIOSTREAM)) {
 				audio_if = 1;
 			} else {
 				audio_if = 0;
@@ -1545,13 +1548,16 @@ uaudio_chan_fill_info_sub(struct uaudio_
 				/*
 				 * XXX could allow multiple MIDI interfaces
 				 */
+				midi_if = 1;
 
 				if ((sc->sc_midi_chan.valid == 0) &&
-				    usbd_get_iface(udev, curidx)) {
+				    (usbd_get_iface(udev, curidx) != NULL)) {
 					sc->sc_midi_chan.iface_index = curidx;
 					sc->sc_midi_chan.iface_alt_index = alt_index;
 					sc->sc_midi_chan.valid = 1;
 				}
+			} else {
+				midi_if = 0;
 			}
 			asid.v1 = NULL;
 			asf1d.v1 = NULL;
@@ -1560,14 +1566,25 @@ uaudio_chan_fill_info_sub(struct uaudio_
 		}
 
 		if (audio_if == 0) {
-			if ((acdp == NULL) &&
-			    (desc->bDescriptorType == UDESC_CS_INTERFACE) &&
-			    (desc->bDescriptorSubtype == UDESCSUB_AC_HEADER) &&
-			    (desc->bLength >= sizeof(*acdp))) {
-				acdp = (void *)desc;
-				audio_rev = UGETW(acdp->bcdADC);
-			}
+			if (midi_if == 0) {
+				if ((acdp == NULL) &&
+				    (desc->bDescriptorType == UDESC_CS_INTERFACE) &&
+				    (desc->bDescriptorSubtype == UDESCSUB_AC_HEADER) &&
+				    (desc->bLength >= sizeof(*acdp))) {
+					acdp = (void *)desc;
+					audio_rev = UGETW(acdp->bcdADC);
+				}
+			} else {
+				msid = (void *)desc;
 
+				/* get the maximum number of embedded jacks in use, if any */
+				if (msid->bLength >= sizeof(*msid) &&
+				    msid->bDescriptorType == UDESC_CS_ENDPOINT &&
+				    msid->bDescriptorSubtype == MS_GENERAL &&
+				    msid->bNumEmbMIDIJack > sc->sc_midi_chan.max_emb_jack) {
+					sc->sc_midi_chan.max_emb_jack = msid->bNumEmbMIDIJack;
+				}
+			}
 			/*
 			 * Don't collect any USB audio descriptors if
 			 * this is not an USB audio stream interface.
@@ -5219,8 +5236,7 @@ umidi_bulk_read_callback(struct usb_xfer
 			 */
 			sub = &chan->sub[cn];
 
-			if ((cmd_len != 0) &&
-			    (cn < chan->max_cable) &&
+			if ((cmd_len != 0) && (cn < chan->max_emb_jack) &&
 			    (sub->read_open != 0)) {
 
 				/* Send data to the application */
@@ -5456,7 +5472,7 @@ tr_setup:
 			}
 
 			chan->curr_cable++;
-			if (chan->curr_cable >= chan->max_cable)
+			if (chan->curr_cable >= chan->max_emb_jack)
 				chan->curr_cable = 0;
 
 			if (chan->curr_cable == start_cable) {
@@ -5493,7 +5509,7 @@ umidi_sub_by_fifo(struct usb_fifo *fifo)
 	struct umidi_sub_chan *sub;
 	uint32_t n;
 
-	for (n = 0; n < UMIDI_CABLES_MAX; n++) {
+	for (n = 0; n < UMIDI_EMB_JACK_MAX; n++) {
 		sub = &chan->sub[n];
 		if ((sub->fifo.fp[USB_FIFO_RX] == fifo) ||
 		    (sub->fifo.fp[USB_FIFO_TX] == fifo)) {
@@ -5676,12 +5692,12 @@ umidi_probe(device_t dev)
 	if (chan->single_command != 0)
 		device_printf(dev, "Single command MIDI quirk enabled\n");
 
-	if ((chan->max_cable > UMIDI_CABLES_MAX) ||
-	    (chan->max_cable == 0)) {
-		chan->max_cable = UMIDI_CABLES_MAX;
+	if ((chan->max_emb_jack == 0) ||
+	    (chan->max_emb_jack > UMIDI_EMB_JACK_MAX)) {
+		chan->max_emb_jack = UMIDI_EMB_JACK_MAX;
 	}
 
-	for (n = 0; n < chan->max_cable; n++) {
+	for (n = 0; n < chan->max_emb_jack; n++) {
 
 		sub = &chan->sub[n];
 
@@ -5719,9 +5735,8 @@ umidi_detach(device_t dev)
 	struct umidi_chan *chan = &sc->sc_midi_chan;
 	uint32_t n;
 
-	for (n = 0; n < UMIDI_CABLES_MAX; n++) {
+	for (n = 0; n < UMIDI_EMB_JACK_MAX; n++)
 		usb_fifo_detach(&chan->sub[n].fifo);
-	}
 
 	mtx_lock(&chan->mtx);
 

Modified: head/sys/dev/sound/usb/uaudioreg.h
==============================================================================
--- head/sys/dev/sound/usb/uaudioreg.h	Sun Sep 28 12:41:48 2014	(r272253)
+++ head/sys/dev/sound/usb/uaudioreg.h	Sun Sep 28 12:55:13 2014	(r272254)
@@ -119,6 +119,13 @@ struct usb_audio_streaming_endpoint_desc
 	uWord	wLockDelay;
 } __packed;
 
+struct usb_midi_streaming_endpoint_descriptor {
+	uByte	bLength;
+	uByte	bDescriptorType;
+	uByte	bDescriptorSubtype;
+	uByte	bNumEmbMIDIJack;
+} __packed;
+
 struct usb_audio_streaming_type1_descriptor {
 	uByte	bLength;
 	uByte	bDescriptorType;
@@ -378,6 +385,7 @@ struct usb_audio_extension_unit_1 {
 
 #define	MASTER_CHAN	0
 
+#define	MS_GENERAL	1
 #define	AS_GENERAL	1
 #define	FORMAT_TYPE	2
 #define	FORMAT_SPECIFIC 3


More information about the svn-src-all mailing list