summaryrefslogtreecommitdiffstats
path: root/sys/dev/sound
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2014-10-02 16:57:44 +0000
committerhselasky <hselasky@FreeBSD.org>2014-10-02 16:57:44 +0000
commitf0d6c23c18f8099c5faf939bea89160c2326adfe (patch)
tree4fe6db39daa5e29675c00230c6b3b6c7c08eeec6 /sys/dev/sound
parenta6d8870502afabc99c377d86c3bb7bb3c9a64a61 (diff)
downloadFreeBSD-src-f0d6c23c18f8099c5faf939bea89160c2326adfe.zip
FreeBSD-src-f0d6c23c18f8099c5faf939bea89160c2326adfe.tar.gz
MFC r272254:
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. Approved by: re, gjb
Diffstat (limited to 'sys/dev/sound')
-rw-r--r--sys/dev/sound/usb/uaudio.c59
-rw-r--r--sys/dev/sound/usb/uaudioreg.h8
2 files changed, 45 insertions, 22 deletions
diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c
index 51e6b3e..daedbbc 100644
--- a/sys/dev/sound/usb/uaudio.c
+++ b/sys/dev/sound/usb/uaudio.c
@@ -238,7 +238,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 */
@@ -269,7 +269,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];
@@ -281,7 +281,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;
};
@@ -1487,6 +1487,7 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
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);
@@ -1504,6 +1505,7 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
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))) {
@@ -1539,7 +1541,8 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
((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;
@@ -1551,13 +1554,16 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
/*
* 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;
@@ -1566,14 +1572,25 @@ uaudio_chan_fill_info_sub(struct uaudio_softc *sc, struct usb_device *udev,
}
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.
@@ -5225,8 +5242,7 @@ umidi_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
*/
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 */
@@ -5462,7 +5478,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) {
@@ -5499,7 +5515,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)) {
@@ -5682,12 +5698,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];
@@ -5725,9 +5741,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);
diff --git a/sys/dev/sound/usb/uaudioreg.h b/sys/dev/sound/usb/uaudioreg.h
index c2c1ad4..637b5b1 100644
--- a/sys/dev/sound/usb/uaudioreg.h
+++ b/sys/dev/sound/usb/uaudioreg.h
@@ -119,6 +119,13 @@ struct usb_audio_streaming_endpoint_descriptor {
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
OpenPOWER on IntegriCloud