--- /dev/null
+From stable-bounces@linux.kernel.org Thu Jan 12 00:48:57 2006
+Date: Thu, 12 Jan 2006 09:44:29 +0100
+Message-id: <20060112084429.GA18332@turing.informatik.uni-halle.de>
+From: Clemens Ladisch <clemens@ladisch.de>
+To: stable@kernel.org
+Cc: Takashi Iwai <tiwai@suse.de>, alsa-devel@lists.sourceforge.net
+Subject: [PATCH] usb-audio: don't use empty packets at start of playback
+
+Some widespread USB interface chips with adaptive iso endpoints hang
+after receiving a series of empty packets when they expect data. This
+completely disables audio playback on those devices. To avoid this, we
+have to send packets containing silence (zero samples) instead.
+
+ALSA bug: http://bugtrack.alsa-project.org/alsa-bug/view.php?id=1585
+
+Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+
+ sound/usb/usbaudio.c | 26 +++++++++++++++++++++-----
+ 1 files changed, 21 insertions(+), 5 deletions(-)
+
+--- linux-2.6.15.y.orig/sound/usb/usbaudio.c
++++ linux-2.6.15.y/sound/usb/usbaudio.c
+@@ -480,22 +480,38 @@ static int retire_playback_sync_urb_hs(s
+ /*
+ * Prepare urb for streaming before playback starts.
+ *
+- * We don't care about (or have) any data, so we just send a transfer delimiter.
++ * We don't yet have data, so we send a frame of silence.
+ */
+ static int prepare_startup_playback_urb(snd_usb_substream_t *subs,
+ snd_pcm_runtime_t *runtime,
+ struct urb *urb)
+ {
+- unsigned int i;
++ unsigned int i, offs, counts;
+ snd_urb_ctx_t *ctx = urb->context;
++ int stride = runtime->frame_bits >> 3;
+
++ offs = 0;
+ urb->dev = ctx->subs->dev;
+ urb->number_of_packets = subs->packs_per_ms;
+ for (i = 0; i < subs->packs_per_ms; ++i) {
+- urb->iso_frame_desc[i].offset = 0;
+- urb->iso_frame_desc[i].length = 0;
++ /* calculate the size of a packet */
++ if (subs->fill_max)
++ counts = subs->maxframesize; /* fixed */
++ else {
++ subs->phase = (subs->phase & 0xffff)
++ + (subs->freqm << subs->datainterval);
++ counts = subs->phase >> 16;
++ if (counts > subs->maxframesize)
++ counts = subs->maxframesize;
++ }
++ urb->iso_frame_desc[i].offset = offs * stride;
++ urb->iso_frame_desc[i].length = counts * stride;
++ offs += counts;
+ }
+- urb->transfer_buffer_length = 0;
++ urb->transfer_buffer_length = offs * stride;
++ memset(urb->transfer_buffer,
++ subs->cur_audiofmt->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0,
++ offs * stride);
+ return 0;
+ }
+