From f167e1d073278fe231bbdd5d6c24fb9d091aa544 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 15 Feb 2010 08:55:28 +0100 Subject: [PATCH 1/2] ALSA: usb-audio: reduce MIDI packet size to work around broken firmware Extend the list of devices whose firmware does not expect more than one USB MIDI packet in one USB packet. bug report: https://bugtrack.alsa-project.org/alsa-bug/view.php?id=3752 Signed-off-by: Clemens Ladisch Cc: Signed-off-by: Jaroslav Kysela --- sound/usb/usbmidi.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 6e89b8368d9a..aae50df06232 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c @@ -1162,10 +1162,22 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi, pipe = usb_sndintpipe(umidi->dev, ep_info->out_ep); else pipe = usb_sndbulkpipe(umidi->dev, ep_info->out_ep); - if (umidi->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */ - ep->max_transfer = 4; - else + switch (umidi->usb_id) { + default: ep->max_transfer = usb_maxpacket(umidi->dev, pipe, 1); + break; + /* + * Various chips declare a packet size larger than 4 bytes, but + * do not actually work with larger packets: + */ + case USB_ID(0x0a92, 0x1020): /* ESI M4U */ + case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */ + case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */ + case USB_ID(0x15ca, 0x1806): /* Textech USB Midi Cable */ + case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */ + ep->max_transfer = 4; + break; + } for (i = 0; i < OUTPUT_URBS; ++i) { buffer = usb_buffer_alloc(umidi->dev, ep->max_transfer, GFP_KERNEL, From 3be522a9514f58e0596db34898a514df206cadc5 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 16 Feb 2010 11:55:43 +0100 Subject: [PATCH 2/2] ALSA: pcm core - fix fifo_size channels interval check Signed-off-by: Jaroslav Kysela Cc: --- sound/core/pcm_native.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 25b0641e6b8c..f7e1c9f0d3ed 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -315,10 +315,10 @@ int snd_pcm_hw_refine(struct snd_pcm_substream *substream, if (!params->info) params->info = hw->info & ~SNDRV_PCM_INFO_FIFO_IN_FRAMES; if (!params->fifo_size) { - if (snd_mask_min(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT]) == - snd_mask_max(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT]) && - snd_mask_min(¶ms->masks[SNDRV_PCM_HW_PARAM_CHANNELS]) == - snd_mask_max(¶ms->masks[SNDRV_PCM_HW_PARAM_CHANNELS])) { + m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); + if (snd_mask_min(m) == snd_mask_max(m) && + snd_interval_min(i) == snd_interval_max(i)) { changed = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_FIFO_SIZE, params); if (changed < 0)