summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Boyer <jwboyer@redhat.com>2012-08-29 17:26:05 -0400
committerJosh Boyer <jwboyer@redhat.com>2012-08-29 17:26:21 -0400
commita3b7bc1c152ea359f9db676c0b85ada895db07a9 (patch)
treeefe3a2ed3fe982de6e6af60fa71a9bc8ac800f5f
parent9745498bee1046f55a97ee19edf48c07c9a3f4fe (diff)
downloadkernel-a3b7bc1c152ea359f9db676c0b85ada895db07a9.tar.gz
kernel-a3b7bc1c152ea359f9db676c0b85ada895db07a9.tar.xz
kernel-a3b7bc1c152ea359f9db676c0b85ada895db07a9.zip
Add patch to fix USB audio regression (rhbz 851619)
-rw-r--r--0001-ALSA-snd-usb-Fix-URB-cancellation-at-stream-start.patch131
-rw-r--r--kernel.spec9
2 files changed, 139 insertions, 1 deletions
diff --git a/0001-ALSA-snd-usb-Fix-URB-cancellation-at-stream-start.patch b/0001-ALSA-snd-usb-Fix-URB-cancellation-at-stream-start.patch
new file mode 100644
index 000000000..031888c3c
--- /dev/null
+++ b/0001-ALSA-snd-usb-Fix-URB-cancellation-at-stream-start.patch
@@ -0,0 +1,131 @@
+From 42ff3e2d34427dc4c6faa09052a2531f2e71d7d6 Mon Sep 17 00:00:00 2001
+From: Daniel Mack <zonque@gmail.com>
+Date: Wed, 29 Aug 2012 13:17:05 +0200
+Subject: [PATCH] ALSA: snd-usb: Fix URB cancellation at stream start
+
+Commit e9ba389c5 ("ALSA: usb-audio: Fix scheduling-while-atomic bug in
+PCM capture stream") fixed a scheduling-while-atomic bug that happened
+when snd_usb_endpoint_start was called from the trigger callback, which
+is an atmic context. However, the patch breaks the idea of the endpoints
+reference counting, which is the reason why the driver has been
+refactored lately.
+
+Revert that commit and let snd_usb_endpoint_start() take care of the URB
+cancellation again. As this function is called from both atomic and
+non-atomic context, add a flag to denote whether the function may sleep.
+
+Signed-off-by: Daniel Mack <zonque@gmail.com>
+Cc: stable@kernel.org [3.5+]
+---
+ sound/usb/endpoint.c | 11 +++++++++--
+ sound/usb/endpoint.h | 2 +-
+ sound/usb/pcm.c | 13 +++++--------
+ 3 files changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
+index c411812..b896c55 100644
+--- a/sound/usb/endpoint.c
++++ b/sound/usb/endpoint.c
+@@ -799,7 +799,9 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
+ /**
+ * snd_usb_endpoint_start: start an snd_usb_endpoint
+ *
+- * @ep: the endpoint to start
++ * @ep: the endpoint to start
++ * @can_sleep: flag indicating whether the operation is executed in
++ * non-atomic context
+ *
+ * A call to this function will increment the use count of the endpoint.
+ * In case it is not already running, the URBs for this endpoint will be
+@@ -809,7 +811,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
+ *
+ * Returns an error if the URB submission failed, 0 in all other cases.
+ */
+-int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
++int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep)
+ {
+ int err;
+ unsigned int i;
+@@ -821,6 +823,11 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep)
+ if (++ep->use_count != 1)
+ return 0;
+
++ /* just to be sure */
++ deactivate_urbs(ep, 0, can_sleep);
++ if (can_sleep)
++ wait_clear_urbs(ep);
++
+ ep->active_mask = 0;
+ ep->unlink_mask = 0;
+ ep->phase = 0;
+diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
+index ee2723f..a8e60c1 100644
+--- a/sound/usb/endpoint.h
++++ b/sound/usb/endpoint.h
+@@ -13,7 +13,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
+ struct audioformat *fmt,
+ struct snd_usb_endpoint *sync_ep);
+
+-int snd_usb_endpoint_start(struct snd_usb_endpoint *ep);
++int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep);
+ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep,
+ int force, int can_sleep, int wait);
+ int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep);
+diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
+index 62ec808..1546577 100644
+--- a/sound/usb/pcm.c
++++ b/sound/usb/pcm.c
+@@ -212,7 +212,7 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
+ }
+ }
+
+-static int start_endpoints(struct snd_usb_substream *subs)
++static int start_endpoints(struct snd_usb_substream *subs, int can_sleep)
+ {
+ int err;
+
+@@ -225,7 +225,7 @@ static int start_endpoints(struct snd_usb_substream *subs)
+ snd_printdd(KERN_DEBUG "Starting data EP @%p\n", ep);
+
+ ep->data_subs = subs;
+- err = snd_usb_endpoint_start(ep);
++ err = snd_usb_endpoint_start(ep, can_sleep);
+ if (err < 0) {
+ clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags);
+ return err;
+@@ -239,7 +239,7 @@ static int start_endpoints(struct snd_usb_substream *subs)
+ snd_printdd(KERN_DEBUG "Starting sync EP @%p\n", ep);
+
+ ep->sync_slave = subs->data_endpoint;
+- err = snd_usb_endpoint_start(ep);
++ err = snd_usb_endpoint_start(ep, can_sleep);
+ if (err < 0) {
+ clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags);
+ return err;
+@@ -544,13 +544,10 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
+ subs->last_frame_number = 0;
+ runtime->delay = 0;
+
+- /* clear the pending deactivation on the target EPs */
+- deactivate_endpoints(subs);
+-
+ /* for playback, submit the URBs now; otherwise, the first hwptr_done
+ * updates for all URBs would happen at the same time when starting */
+ if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK)
+- return start_endpoints(subs);
++ return start_endpoints(subs, 1);
+
+ return 0;
+ }
+@@ -1175,7 +1172,7 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+- err = start_endpoints(subs);
++ err = start_endpoints(subs, 0);
+ if (err < 0)
+ return err;
+
+--
+1.7.11.4
+
diff --git a/kernel.spec b/kernel.spec
index d7a4c1aa3..187e2e2cb 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -62,7 +62,7 @@ Summary: The Linux kernel
# For non-released -rc kernels, this will be appended after the rcX and
# gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
#
-%global baserelease 1
+%global baserelease 2
%global fedora_build %{baserelease}
# base_sublevel is the kernel version we're starting with and patching
@@ -753,6 +753,8 @@ Patch22066: virtio-scsi-Initialize-scatterlist-structure.patch
#rhbz 846037
Patch22067: selinux-Fix-sel_netnode_insert-suspicious-rcu-dereference.patch
+Patch30000: 0001-ALSA-snd-usb-Fix-URB-cancellation-at-stream-start.patch
+
# END OF PATCH DEFINITIONS
%endif
@@ -1449,6 +1451,8 @@ ApplyPatch virtio-scsi-Initialize-scatterlist-structure.patch
#rhbz 846037
ApplyPatch selinux-Fix-sel_netnode_insert-suspicious-rcu-dereference.patch
+ApplyPatch 0001-ALSA-snd-usb-Fix-URB-cancellation-at-stream-start.patch
+
# END OF PATCH APPLICATIONS
%endif
@@ -2311,6 +2315,9 @@ fi
# ||----w |
# || ||
%changelog
+* Wed Aug 29 2012 Josh Boyer <jwboyer@redhat.com> - 3.6.0-0.rc3.git3.2
+- Add patch to fix USB audio regression (rhbz 851619)
+
* Wed Aug 29 2012 Josh Boyer <jwboyer@redhat.com> - 3.6.0-0.rc3.git3.1
- Linux v3.6-rc3-207-g318e151