At Wed, 7 Nov 2012 15:37:17 -0500 (EST), Alan Stern wrote: > > On Wed, 7 Nov 2012, Takashi Iwai wrote: > > > > What is the right solution for this problem? > > > > How about the patch below? (It's for 3.6, and won't be applied cleanly > > to 3.7, but easy to adapt.) > > I simplified your patch a little.
You can't drop the check of stopping endpoint. As Daniel pointed, endpoints might be still running when it's called. I already did a similar failure in the past, so this patch is a revised version with the check for pending operations. > This is for 3.7, not 3.6. I > verified that it does fix the problem raised by the test program. > > If you think this is okay, I'll submit it officially. Don't worry, my patch is also based on 3.7, too :) 3.6 patch was provided just for convenience, testers seemed to have 3.6 systems. thanks, Takashi > > Alan Stern > > > > Index: usb-3.7/sound/usb/endpoint.h > =================================================================== > --- usb-3.7.orig/sound/usb/endpoint.h > +++ usb-3.7/sound/usb/endpoint.h > @@ -19,6 +19,7 @@ int snd_usb_endpoint_set_params(struct s > 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); > +void snd_usb_endpoint_sync_stop(struct snd_usb_endpoint *ep); > int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); > int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); > void snd_usb_endpoint_free(struct list_head *head); > Index: usb-3.7/sound/usb/pcm.c > =================================================================== > --- usb-3.7.orig/sound/usb/pcm.c > +++ usb-3.7/sound/usb/pcm.c > @@ -576,6 +576,11 @@ static int snd_usb_pcm_prepare(struct sn > subs->need_setup_ep = false; > } > > + if (subs->sync_endpoint) > + snd_usb_endpoint_sync_stop(subs->sync_endpoint); > + if (subs->data_endpoint) > + snd_usb_endpoint_sync_stop(subs->data_endpoint); > + > /* some unit conversions in runtime */ > subs->data_endpoint->maxframesize = > bytes_to_frames(runtime, subs->data_endpoint->maxpacksize); > Index: usb-3.7/sound/usb/endpoint.c > =================================================================== > --- usb-3.7.orig/sound/usb/endpoint.c > +++ usb-3.7/sound/usb/endpoint.c > @@ -481,7 +481,7 @@ __exit_unlock: > /* > * wait until all urbs are processed. > */ > -static int wait_clear_urbs(struct snd_usb_endpoint *ep) > +void snd_usb_endpoint_sync_stop(struct snd_usb_endpoint *ep) > { > unsigned long end_time = jiffies + msecs_to_jiffies(1000); > unsigned int i; > @@ -502,8 +502,6 @@ static int wait_clear_urbs(struct snd_us > if (alive) > snd_printk(KERN_ERR "timeout: still %d active urbs on EP #%x\n", > alive, ep->ep_num); > - > - return 0; > } > > /* > @@ -556,7 +554,7 @@ static void release_urbs(struct snd_usb_ > > /* stop urbs */ > deactivate_urbs(ep, force, 1); > - wait_clear_urbs(ep); > + snd_usb_endpoint_sync_stop(ep); > > for (i = 0; i < ep->nurbs; i++) > release_urb_ctx(&ep->urb[i]); > @@ -833,7 +831,7 @@ int snd_usb_endpoint_start(struct snd_us > /* just to be sure */ > deactivate_urbs(ep, 0, can_sleep); > if (can_sleep) > - wait_clear_urbs(ep); > + snd_usb_endpoint_sync_stop(ep); > > ep->active_mask = 0; > ep->unlink_mask = 0; > @@ -917,7 +915,7 @@ void snd_usb_endpoint_stop(struct snd_us > ep->prepare_data_urb = NULL; > > if (wait) > - wait_clear_urbs(ep); > + snd_usb_endpoint_sync_stop(ep); > } > } > > @@ -940,7 +938,7 @@ int snd_usb_endpoint_deactivate(struct s > return -EINVAL; > > deactivate_urbs(ep, 1, 1); > - wait_clear_urbs(ep); > + snd_usb_endpoint_sync_stop(ep); > > if (ep->use_count != 0) > return 0; > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html