From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
alan@lxorguk.ukuu.org.uk, Clemens Ladisch <clemens@ladisch.de>,
Takashi Iwai <tiwai@suse.de>
Subject: [ 15/47] ALSA: usb-audio: Fix missing autopm for MIDI input
Date: Wed, 9 Jan 2013 12:35:10 -0800 [thread overview]
Message-ID: <20130109201731.225460134@linuxfoundation.org> (raw)
In-Reply-To: <20130109201729.435233560@linuxfoundation.org>
3.0-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
commit f5f165418cabf2218eb466c0e94693b8b1aee88b upstream.
The commit [88a8516a: ALSA: usbaudio: implement USB autosuspend] added
the support of autopm for USB MIDI output, but it didn't take the MIDI
input into account.
This patch adds the following for fixing the autopm:
- Manage the URB start at the first MIDI input stream open, instead of
the time of instance creation
- Move autopm code to the common substream_open()
- Make snd_usbmidi_input_start/_stop() more robust and add the running
state check
Reviewd-by: Clemens Ladisch <clemens@ladisch.de>
Tested-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/usb/midi.c | 88 ++++++++++++++++++++++++++++---------------------------
1 file changed, 46 insertions(+), 42 deletions(-)
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -125,8 +125,10 @@ struct snd_usb_midi {
struct snd_usb_midi_in_endpoint *in;
} endpoints[MIDI_MAX_ENDPOINTS];
unsigned long input_triggered;
- unsigned int opened;
+ bool autopm_reference;
+ unsigned int opened[2];
unsigned char disconnected;
+ unsigned char input_running;
struct snd_kcontrol *roland_load_ctl;
};
@@ -148,7 +150,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
@@ -1017,36 +1018,58 @@ static void update_roland_altsetting(str
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 dir,
+ int open)
{
struct snd_usb_midi* umidi = substream->rmidi->private_data;
struct snd_kcontrol *ctl;
+ int err;
down_read(&umidi->disc_rwsem);
if (umidi->disconnected) {
up_read(&umidi->disc_rwsem);
- return;
+ return open ? -ENODEV : 0;
}
mutex_lock(&umidi->mutex);
if (open) {
- if (umidi->opened++ == 0 && umidi->roland_load_ctl) {
- ctl = umidi->roland_load_ctl;
- ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(umidi->card,
+ if (!umidi->opened[0] && !umidi->opened[1]) {
+ err = usb_autopm_get_interface(umidi->iface);
+ umidi->autopm_reference = err >= 0;
+ if (err < 0 && err != -EACCES) {
+ mutex_unlock(&umidi->mutex);
+ up_read(&umidi->disc_rwsem);
+ return -EIO;
+ }
+ 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);
- update_roland_altsetting(umidi);
+ update_roland_altsetting(umidi);
+ }
}
+ umidi->opened[dir]++;
+ if (umidi->opened[1])
+ snd_usbmidi_input_start(&umidi->list);
} else {
- if (--umidi->opened == 0 && umidi->roland_load_ctl) {
- ctl = umidi->roland_load_ctl;
- ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(umidi->card,
+ umidi->opened[dir]--;
+ if (!umidi->opened[1])
+ snd_usbmidi_input_stop(&umidi->list);
+ if (!umidi->opened[0] && !umidi->opened[1]) {
+ 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);
+ }
+ if (umidi->autopm_reference)
+ usb_autopm_put_interface(umidi->iface);
}
}
mutex_unlock(&umidi->mutex);
up_read(&umidi->disc_rwsem);
+ return 0;
}
static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
@@ -1054,7 +1077,6 @@ static int snd_usbmidi_output_open(struc
struct snd_usb_midi* umidi = substream->rmidi->private_data;
struct usbmidi_out_port* port = NULL;
int i, j;
- int err;
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
if (umidi->endpoints[i].out)
@@ -1068,33 +1090,14 @@ static int snd_usbmidi_output_open(struc
return -ENXIO;
}
- down_read(&umidi->disc_rwsem);
- if (umidi->disconnected) {
- up_read(&umidi->disc_rwsem);
- return -ENODEV;
- }
- err = usb_autopm_get_interface(umidi->iface);
- port->autopm_reference = err >= 0;
- up_read(&umidi->disc_rwsem);
- if (err < 0 && err != -EACCES)
- return -EIO;
substream->runtime->private_data = port;
port->state = STATE_UNKNOWN;
- substream_open(substream, 1);
- return 0;
+ return substream_open(substream, 0, 1);
}
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);
- down_read(&umidi->disc_rwsem);
- if (!umidi->disconnected && port->autopm_reference)
- usb_autopm_put_interface(umidi->iface);
- up_read(&umidi->disc_rwsem);
- return 0;
+ return substream_open(substream, 0, 0);
}
static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream, int up)
@@ -1147,14 +1150,12 @@ static void snd_usbmidi_output_drain(str
static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream)
{
- substream_open(substream, 1);
- return 0;
+ return substream_open(substream, 1, 1);
}
static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream)
{
- substream_open(substream, 0);
- return 0;
+ return substream_open(substream, 1, 0);
}
static void snd_usbmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
@@ -2063,12 +2064,15 @@ void snd_usbmidi_input_stop(struct list_
unsigned int i, j;
umidi = list_entry(p, struct snd_usb_midi, list);
+ if (!umidi->input_running)
+ return;
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i];
if (ep->in)
for (j = 0; j < INPUT_URBS; ++j)
usb_kill_urb(ep->in->urbs[j]);
}
+ umidi->input_running = 0;
}
static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep)
@@ -2093,8 +2097,11 @@ void snd_usbmidi_input_start(struct list
int i;
umidi = list_entry(p, struct snd_usb_midi, list);
+ if (umidi->input_running || !umidi->opened[1])
+ return;
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
snd_usbmidi_input_start_ep(umidi->endpoints[i].in);
+ umidi->input_running = 1;
}
/*
@@ -2222,9 +2229,6 @@ int snd_usbmidi_create(struct snd_card *
}
list_add_tail(&umidi->list, midi_list);
-
- for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
- snd_usbmidi_input_start_ep(umidi->endpoints[i].in);
return 0;
}
next prev parent reply other threads:[~2013-01-09 20:35 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-09 20:34 [ 00/47] 3.0.58-stable review Greg Kroah-Hartman
2013-01-09 20:34 ` [ 01/47] bonding: Bonding driver does not consider the gso_max_size/gso_max_segs setting of slave devices Greg Kroah-Hartman
2013-01-09 20:34 ` [ 02/47] bonding: fix race condition in bonding_store_slaves_active Greg Kroah-Hartman
2013-01-09 20:34 ` [ 03/47] sctp: fix memory leak in sctp_datamsg_from_user() when copy from user space fails Greg Kroah-Hartman
2013-01-09 20:34 ` [ 04/47] sctp: fix -ENOMEM result with invalid user space pointer in sendto() syscall Greg Kroah-Hartman
2013-01-09 20:35 ` [ 05/47] ne2000: add the right platform device Greg Kroah-Hartman
2013-01-09 20:35 ` [ 06/47] irda: sir_dev: Fix copy/paste typo Greg Kroah-Hartman
2013-01-09 20:35 ` [ 07/47] usb/ipheth: Add iPhone 5 support Greg Kroah-Hartman
2013-01-09 20:35 ` [ 08/47] pnpacpi: fix incorrect TEST_ALPHA() test Greg Kroah-Hartman
2013-01-09 20:35 ` [ 09/47] exec: do not leave bprm->interp on stack Greg Kroah-Hartman
2013-01-09 20:35 ` [ 10/47] x86, 8042: Enable A20 using KBC to fix S3 resume on some MSI laptops Greg Kroah-Hartman
2013-01-09 20:35 ` [ 11/47] virtio: force vring descriptors to be allocated from lowmem Greg Kroah-Hartman
2013-01-09 20:35 ` [ 12/47] mm: Fix PageHead when !CONFIG_PAGEFLAGS_EXTENDED Greg Kroah-Hartman
2013-01-09 20:35 ` [ 13/47] tmpfs mempolicy: fix /proc/mounts corrupting memory Greg Kroah-Hartman
2013-01-09 20:35 ` [ 14/47] ALSA: usb-audio: Avoid autopm calls after disconnection Greg Kroah-Hartman
2013-01-09 20:35 ` Greg Kroah-Hartman [this message]
2013-01-09 20:35 ` [ 16/47] p54usb: add USB ID for T-Com Sinus 154 data II Greg Kroah-Hartman
2013-01-09 20:35 ` [ 17/47] p54usb: add USBIDs for two more p54usb devices Greg Kroah-Hartman
2013-01-09 20:35 ` [ 18/47] usb: gadget: phonet: free requests in pn_bind()s error path Greg Kroah-Hartman
2013-01-09 20:35 ` [ 19/47] ACPI / scan: Do not use dummy HID for system bus ACPI nodes Greg Kroah-Hartman
2013-01-09 20:35 ` [ 20/47] NFS: avoid NULL dereference in nfs_destroy_server Greg Kroah-Hartman
2013-01-09 20:35 ` [ 21/47] NFS: Fix calls to drop_nlink() Greg Kroah-Hartman
2013-01-09 20:35 ` [ 22/47] nfsd4: fix oops on unusual readlike compound Greg Kroah-Hartman
2013-01-09 20:35 ` [ 23/47] nfs: fix null checking in nfs_get_option_str() Greg Kroah-Hartman
2013-01-09 20:35 ` [ 24/47] Input: walkera0701 - fix crash on startup Greg Kroah-Hartman
2013-01-09 20:35 ` [ 25/47] genirq: Always force thread affinity Greg Kroah-Hartman
2013-01-09 20:35 ` [ 26/47] xhci: Add Lynx Point LP to list of Intel switchable hosts Greg Kroah-Hartman
2013-01-09 20:35 ` [ 27/47] cgroup: remove incorrect dget/dput() pair in cgroup_create_dir() Greg Kroah-Hartman
2013-01-09 20:35 ` [ 28/47] x86, amd: Disable way access filter on Piledriver CPUs Greg Kroah-Hartman
2013-01-09 20:35 ` [ 29/47] ftrace: Do not function trace inlined functions Greg Kroah-Hartman
2013-01-09 20:35 ` [ 30/47] sparc: huge_ptep_set_* functions need to call set_huge_pte_at() Greg Kroah-Hartman
2013-01-09 20:35 ` [ 31/47] net: sched: integer overflow fix Greg Kroah-Hartman
2013-01-09 20:35 ` [ 32/47] tcp: implement RFC 5961 3.2 Greg Kroah-Hartman
2013-01-09 20:35 ` [ 33/47] tcp: implement RFC 5961 4.2 Greg Kroah-Hartman
2013-01-09 20:35 ` [ 34/47] tcp: refine SYN handling in tcp_validate_incoming Greg Kroah-Hartman
2013-01-09 20:35 ` [ 35/47] tcp: tcp_replace_ts_recent() should not be called from tcp_validate_incoming() Greg Kroah-Hartman
2013-01-09 20:35 ` [ 36/47] tcp: RFC 5961 5.2 Blind Data Injection Attack Mitigation Greg Kroah-Hartman
2013-01-09 20:35 ` [ 37/47] ARM: mm: use pteval_t to represent page protection values Greg Kroah-Hartman
2013-01-09 20:35 ` [ 38/47] ARM: missing ->mmap_sem around find_vma() in swp_emulate.c Greg Kroah-Hartman
2013-01-09 20:35 ` [ 39/47] solos-pci: fix double-free of TX skb in DMA mode Greg Kroah-Hartman
2013-01-09 20:35 ` [ 40/47] PCI: Reduce Ricoh 0xe822 SD card reader base clock frequency to 50MHz Greg Kroah-Hartman
2013-01-09 20:35 ` [ 41/47] Bluetooth: ath3k: Add support for VAIO VPCEH [0489:e027] Greg Kroah-Hartman
2013-01-09 20:35 ` [ 42/47] Bluetooth: cancel power_on work when unregistering the device Greg Kroah-Hartman
2013-01-09 20:35 ` [ 43/47] CRIS: fix I/O macros Greg Kroah-Hartman
2013-01-09 20:35 ` [ 44/47] drivers/rtc/rtc-vt8500.c: correct handling of CR_24H bitfield Greg Kroah-Hartman
2013-01-09 20:35 ` [ 45/47] drivers/rtc/rtc-vt8500.c: fix handling of data passed in struct rtc_time Greg Kroah-Hartman
2013-01-09 20:35 ` [ 46/47] mm: limit mmu_gather batching to fix soft lockups on !CONFIG_PREEMPT Greg Kroah-Hartman
2013-01-09 20:35 ` [ 47/47] can: Do not call dev_put if restart timer is running upon close Greg Kroah-Hartman
2013-01-10 18:01 ` [ 00/47] 3.0.58-stable review Shuah Khan
2013-01-11 14:47 ` Satoru Takeuchi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130109201731.225460134@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=clemens@ladisch.de \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=tiwai@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).