alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
From: Daniel Mack <zonque@gmail.com>
To: alsa-devel@alsa-project.org
Cc: tiwai@suse.de, clemens@ladisch.de, linuxaudio@showlabor.de,
	Daniel Mack <zonque@gmail.com>,
	"[v3.5+]"@mail.zonque.de, linux@romal.de, stable@kernel.org
Subject: [PATCH 2/3] ALSA: snd-usb: fix calls to next_packet_size
Date: Thu, 30 Aug 2012 18:52:30 +0200	[thread overview]
Message-ID: <1346345551-8956-3-git-send-email-zonque@gmail.com> (raw)
In-Reply-To: <1346345551-8956-1-git-send-email-zonque@gmail.com>

In order to support devices with implicit feedback streaming models,
packet sizes are now stored with each individual urb, and the PCM
handling code which fills the buffers purely relies on the size fields
now.

However, calling snd_usb_audio_next_packet_size() for all possible
packets in an URB at once, prior to letting the PCM code do its job
does in fact not lead to the same behaviour than what the old code did:
The PCM code will break its loop once a period boundary is reached,
consequently using up less packets that it really could.

As snd_usb_audio_next_packet_size() implements a feedback mechanism to
the endpoints phase accumulator, the number of calls to that function
matters, and when called too often, the data rate runs out of bounds.

Fix this by making the next_packet function public, and call it from the
PCM code as before if the packet data sizes are not defined.

Signed-off-by: Daniel Mack <zonque@gmail.com>
Cc: stable@kernel.org [v3.5+]
---
 sound/usb/endpoint.c | 13 +------------
 sound/usb/endpoint.h |  1 +
 sound/usb/pcm.c      |  7 ++++++-
 3 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index b896c55..d6e2bb4 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -141,7 +141,7 @@ int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep)
  *
  * For implicit feedback, next_packet_size() is unused.
  */
-static int next_packet_size(struct snd_usb_endpoint *ep)
+int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep)
 {
 	unsigned long flags;
 	int ret;
@@ -177,15 +177,6 @@ static void retire_inbound_urb(struct snd_usb_endpoint *ep,
 		ep->retire_data_urb(ep->data_subs, urb);
 }
 
-static void prepare_outbound_urb_sizes(struct snd_usb_endpoint *ep,
-				       struct snd_urb_ctx *ctx)
-{
-	int i;
-
-	for (i = 0; i < ctx->packets; ++i)
-		ctx->packet_size[i] = next_packet_size(ep);
-}
-
 /*
  * Prepare a PLAYBACK urb for submission to the bus.
  */
@@ -370,7 +361,6 @@ static void snd_complete_urb(struct urb *urb)
 			goto exit_clear;
 		}
 
-		prepare_outbound_urb_sizes(ep, ctx);
 		prepare_outbound_urb(ep, ctx);
 	} else {
 		retire_inbound_urb(ep, ctx);
@@ -857,7 +847,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep)
 			goto __error;
 
 		if (usb_pipeout(ep->pipe)) {
-			prepare_outbound_urb_sizes(ep, urb->context);
 			prepare_outbound_urb(ep, urb->context);
 		} else {
 			prepare_inbound_urb(ep, urb->context);
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
index a8e60c1..cbbbdf2 100644
--- a/sound/usb/endpoint.h
+++ b/sound/usb/endpoint.h
@@ -21,6 +21,7 @@ int  snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep);
 void snd_usb_endpoint_free(struct list_head *head);
 
 int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep);
+int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep);
 
 void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep,
 			     struct snd_usb_endpoint *sender,
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 5ceb8f1..e80b668 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -1029,6 +1029,7 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
 				 struct urb *urb)
 {
 	struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
+	struct snd_usb_endpoint *ep = subs->data_endpoint;
 	struct snd_urb_ctx *ctx = urb->context;
 	unsigned int counts, frames, bytes;
 	int i, stride, period_elapsed = 0;
@@ -1040,7 +1041,11 @@ static void prepare_playback_urb(struct snd_usb_substream *subs,
 	urb->number_of_packets = 0;
 	spin_lock_irqsave(&subs->lock, flags);
 	for (i = 0; i < ctx->packets; i++) {
-		counts = ctx->packet_size[i];
+		if (ctx->packet_size[i])
+			counts = ctx->packet_size[i];
+		else
+			counts = snd_usb_endpoint_next_packet_size(ep);
+
 		/* set up descriptor */
 		urb->iso_frame_desc[i].offset = frames * stride;
 		urb->iso_frame_desc[i].length = counts * stride;
-- 
1.7.11.4

  parent reply	other threads:[~2012-08-30 16:52 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-30 16:52 [PATCH 0/3] ALSA: snd-usb: Regression fixes for 3.5 Daniel Mack
2012-08-30 16:52 ` [PATCH 1/3] ALSA: snd-usb: restore delay information Daniel Mack
2012-08-30 16:52 ` Daniel Mack [this message]
2012-08-30 16:52 ` [PATCH 3/3] ALSA: snd-usb: fix cross-interface streaming devices Daniel Mack
2012-08-30 16:54   ` Daniel Mack
2012-08-31 16:26 ` [PATCH 0/3] ALSA: snd-usb: Regression fixes for 3.5 Takashi Iwai
2012-08-31 16:30   ` Daniel Mack
2012-08-31 23:37     ` Felix Homann
2012-09-04 14:33     ` Takashi Iwai

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=1346345551-8956-3-git-send-email-zonque@gmail.com \
    --to=zonque@gmail.com \
    --cc="[v3.5+]"@mail.zonque.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=clemens@ladisch.de \
    --cc=linux@romal.de \
    --cc=linuxaudio@showlabor.de \
    --cc=stable@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).