From patchwork Mon Nov 26 09:35:05 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takashi Iwai X-Patchwork-Id: 1801261 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 81F5E3FC54 for ; Mon, 26 Nov 2012 09:35:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754753Ab2KZJfM (ORCPT ); Mon, 26 Nov 2012 04:35:12 -0500 Received: from cantor2.suse.de ([195.135.220.15]:60311 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754485Ab2KZJfH (ORCPT ); Mon, 26 Nov 2012 04:35:07 -0500 Received: from relay1.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id EFA25A4479; Mon, 26 Nov 2012 10:35:05 +0100 (CET) Date: Mon, 26 Nov 2012 10:35:05 +0100 Message-ID: From: Takashi Iwai To: Clemens Ladisch Cc: Jonathan Nieder , Steffen =?UTF-8?B?TcO8bGxlcg==?= , alsa-devel@alsa-project.org, Olivier MATZ , linux-pm@vger.kernel.org, linux-usb@vger.kernel.org, Oliver Neukum , stable@vger.kernel.org, David Banks , Ralf Lang Subject: Re: [alsa-devel] [PATCH] usb: add USB_QUIRK_RESET_RESUME for M-Audio 49 In-Reply-To: <50B29537.7060007@ladisch.de> References: <4FA2D481.4070304@droids-corp.org> <4FA2DB9D.1040303@droids-corp.org> <20120604110608.GG8248@droids-corp.org> <20120605232432.GE3619@burratino> <4FD06563.7050605@droids-corp.org> <20121125094110.GA21387@elie.Belkin> <50B2815E.2090105@droids-corp.org> <20121125212100.GE24024@elie.Belkin> <50B29537.7060007@ladisch.de> User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI/1.14.6 (Maruoka) FLIM/1.14.9 (=?UTF-8?B?R29qxY0=?=) APEL/10.8 Emacs/24.2 (x86_64-suse-linux-gnu) MULE/6.0 (HANACHIRUSATO) MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org 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 . > > 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? (It even reduces more lines! :) Takashi --- -- To unsubscribe from this list: send the line "unsubscribe linux-pm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/sound/usb/midi.c b/sound/usb/midi.c index eeefbce..2e0fabc 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -148,7 +148,6 @@ struct snd_usb_midi_out_endpoint { struct snd_usb_midi_out_endpoint* ep; struct snd_rawmidi_substream *substream; int active; - bool autopm_reference; uint8_t cable; /* cable number << 4 */ uint8_t state; #define STATE_UNKNOWN 0 @@ -1033,29 +1032,35 @@ static void update_roland_altsetting(struct snd_usb_midi* umidi) snd_usbmidi_input_start(&umidi->list); } -static void substream_open(struct snd_rawmidi_substream *substream, int open) +static int substream_open(struct snd_rawmidi_substream *substream, int open) { struct snd_usb_midi* umidi = substream->rmidi->private_data; struct snd_kcontrol *ctl; + int err = 0; mutex_lock(&umidi->mutex); - if (open) { - if (umidi->opened++ == 0 && umidi->roland_load_ctl) { + if (open && umidi->opened++ == 0) { + err = usb_autopm_get_interface(umidi->iface); + if (err == -EACCES) + err = 0; + if (!err && umidi->roland_load_ctl) { ctl = umidi->roland_load_ctl; ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(umidi->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); update_roland_altsetting(umidi); } - } else { - if (--umidi->opened == 0 && umidi->roland_load_ctl) { + } else if (!open && --umidi->opened == 0) { + if (umidi->roland_load_ctl) { ctl = umidi->roland_load_ctl; ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(umidi->card, SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); } + usb_autopm_put_interface(umidi->iface); } mutex_unlock(&umidi->mutex); + return err; } static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) @@ -1076,25 +1081,17 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) snd_BUG(); return -ENXIO; } - err = usb_autopm_get_interface(umidi->iface); - port->autopm_reference = err >= 0; - if (err < 0 && err != -EACCES) - return -EIO; + err = substream_open(substream, 1); + if (err < 0) + return err; substream->runtime->private_data = port; port->state = STATE_UNKNOWN; - substream_open(substream, 1); return 0; } static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) { - struct snd_usb_midi* umidi = substream->rmidi->private_data; - struct usbmidi_out_port *port = substream->runtime->private_data; - - substream_open(substream, 0); - if (port->autopm_reference) - usb_autopm_put_interface(umidi->iface); - return 0; + return substream_open(substream, 0); } static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream, int up) @@ -1147,14 +1144,12 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream) static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream) { - substream_open(substream, 1); - return 0; + return substream_open(substream, 1); } static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream) { - substream_open(substream, 0); - return 0; + return substream_open(substream, 0); } static void snd_usbmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)