[alsa-devel] [PATCH] usb: add USB_QUIRK_RESET_RESUME for M-Audio 49

Takashi Iwai tiwai at suse.de
Mon Nov 26 14:04:46 CET 2012


At Mon, 26 Nov 2012 13:35:31 +0100,
Clemens Ladisch wrote:
> 
> Takashi Iwai wrote:> At Sun, 25 Nov 2012 23:01:27 +0100,
> > Clemens Ladisch wrote:
> >>
> >> Jonathan Nieder wrote:
> >>> Some USB MIDI keyboards fail to operate after a USB autosuspend.
> >>
> >> Make that *all* USB MIDI devices with input ports.
> >>
> >> This is not a bug in the device, but one of the many bugs introduced
> >> with the autosuspend code in <http://git.kernel.org/linus/88a8516a2128>.
> >>
> >> That patch does not handle input at all, i.e., when the driver wants to
> >> read from the device, it just doesn't take it out of suspend mode.
> >>
> >>> A workaround is to disable USB autosuspend for these devices by
> >>> putting AUTOSUSPEND_USBID_BLACKLIST="0763:2027" (resp. 0763:019b) in
> >>> /etc/laptop-mode/conf.d/usb-autosuspend.conf.  In the spirit of commit
> >>> 166cb70e97bd ("usb: add USB_QUIRK_RESET_RESUME for M-Audio 88es"),
> >>> reset the device on resume so this workaround is not needed any more.
> >>
> >> It is not feasible to add the IDs of all USB MIDI devices.
> >>
> >> I'm working on a fix that adds proper power management for input ports,
> >> but this requires the driver to be reorganized a little ...
> >
> > Doesn't a simple patch like below work?
> 
> > +static int substream_open(struct snd_rawmidi_substream *substream, int open)
> >  {
> > +	if (open && umidi->opened++ == 0) {
> > +		err = usb_autopm_get_interface(umidi->iface);
> >
> >  static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream)
> >  {
> > +	return substream_open(substream, 1);
> 
> No, because the input URBs are submitted before the userspace device is
> opened.  (And usb_autopm_get_interface() cannot be called from the USB
> probe callback.)

Ah, right.  What's the reason of submitting input urbs for the all
time from the beginning?  For loopback?

If it has to be running, the easiest fix would be the patch like
below.  This will turn off the autopm essentially, but better than
breakage.


Takashi

---
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index eeefbce..66acccb 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -175,6 +175,7 @@ struct snd_usb_midi_in_endpoint {
 	u8 seen_f5;
 	u8 error_resubmit;
 	int current_port;
+	bool autopm_reference;
 };
 
 static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep);
@@ -2065,6 +2066,8 @@ void snd_usbmidi_input_stop(struct list_head* p)
 		if (ep->in)
 			for (j = 0; j < INPUT_URBS; ++j)
 				usb_kill_urb(ep->in->urbs[j]);
+		if (ep->autopm_reference)
+			usb_autopm_put_interface(umidi->iface);
 	}
 }
 
@@ -2074,6 +2077,8 @@ static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep)
 
 	if (!ep)
 		return;
+	ep->autopm_reference =
+		usb_autopm_get_interface(ep->umidi->iface) >= 0;
 	for (i = 0; i < INPUT_URBS; ++i) {
 		struct urb* urb = ep->urbs[i];
 		urb->dev = ep->umidi->dev;


More information about the Alsa-devel mailing list