[ Since Greg KH and Duncan Sands haven't contributed directly to this discussion, I'm removing their names from the CC: above -- they can read this via the regular mailing list. ]
On Wed, 15 Jan 2003, Oliver Neukum wrote: > I take it back, there's a need for a TERMINATING state. > Your argument is right. But it's somewhat different still. > > usb_hcd_giveback_urb() must be able to tell apart > between usb_unlink_urb() called in state SUBMITTED > and COMPLETING because the transitions are different. > > SUBMITTED - usb_unlink_urb() -> CANCELED > COMPLETING - usb_unlink_urb() -> TERMINATING > > before handler after handler new state > CANCELED * IDLE > SUBMITTED COMPLETING IDLE > SUBMITTED CANCELED CANCELED > SUBMITTED TERMINATING IDLE I think your code is right, but it is more complicated than it needs to be. usb_hcd_giveback_urb() can already detect this difference because unlink called in state SUBMITTED means that upon entry to giveback_urb() the state is CANCELED, whereas unlink called in state COMPLETING means that upon entry to giveback_urb() the state is SUBMITTED. So in my proposal, at the start of giveback_urb() if state is SUBMITTED it gets set to COMPLETING; if state is CANCELED it gets set to TERMINATING. This eliminates the need for your old_state variable in giveback_urb(). When the handler returns, if the current state is COMPLETING or TERMINATING then it gets set to IDLE, otherwise (SUBMITTED or CANCELED) it doesn't change. In the end, this does the same thing as your code; it's just a little simpler. > This means that lock order must be handler_lock before lock. Yes. In fact, I would change the code in giveback_urb() so that handler_lock is _unlocked_ at the end, just before usb_put_urb(). That way, when a synchronous unlink stops spinning, all the state changes have taken place. By the same token, we should make sure that when a normal (i.e., not during the handler) synchronous call to usb_unlink_urb() returns, all the state changes have taken place. That can be accomplished by adding a spin_lock(&urb->handler_lock); spin_unlock(&urb->handler_lock); pair in usb_unlink_urb() just after wait_for_completion(&splice_done). Maybe that code path can be merged with the err_out_waiting path. > How do you like this version? Aside from the things mentioned above, it looks fine. Alan Stern ------------------------------------------------------- This SF.NET email is sponsored by: Thawte.com Understand how to protect your customers personal information by implementing SSL on your Apache Web Server. Click here to get our FREE Thawte Apache Guide: http://ads.sourceforge.net/cgi-bin/redirect.pl?thaw0029en _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel