struct snd_usX2Y_substream *subs = usX2Y->subs[s];
if (subs) {
if (atomic_read(&subs->state) >= state_PRERUNNING) {
- unsigned long flags;
-
- snd_pcm_stream_lock_irqsave(subs->pcm_substream, flags);
snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
- snd_pcm_stream_unlock_irqrestore(subs->pcm_substream, flags);
}
for (u = 0; u < NRURBS; u++) {
struct urb *urb = subs->urb[u];
usX2Y_clients_stop(usX2Y);
}
+static void usX2Y_error_sequence(struct usX2Ydev *usX2Y,
+ struct snd_usX2Y_substream *subs, struct urb *urb)
+{
+ snd_printk(KERN_ERR
+"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
+"Most probably some urb of usb-frame %i is still missing.\n"
+"Cause could be too long delays in usb-hcd interrupt handling.\n",
+ usb_get_current_frame_number(usX2Y->dev),
+ subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
+ usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
+ usX2Y_clients_stop(usX2Y);
+}
+
static void i_usX2Y_urb_complete(struct urb *urb)
{
struct snd_usX2Y_substream *subs = urb->context;
usX2Y_error_urb_status(usX2Y, subs, urb);
return;
}
-
- subs->completed_urb = urb;
-
+ if (likely((urb->start_frame & 0xFFFF) == (usX2Y->wait_iso_frame & 0xFFFF)))
+ subs->completed_urb = urb;
+ else {
+ usX2Y_error_sequence(usX2Y, subs, urb);
+ return;
+ }
{
struct snd_usX2Y_substream *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE],
*playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];