Dave and everyone else:

The meaning of the return value from usb_unlink_urb() is not as clear
as it should be.  The value is used in only a handful of drivers,
mostly for debugging output.  David's code uses it for warnings and
error messages, but not for altering the control flow.

The real question is this:

        Under what conditions does it make sense to say that
        usb_unlink_urb() has failed?

Since the call races against URB completion, I think it never really
makes sense.  Here's a more detailed examination of the possibilities.  
Consider what happens when an URB is submitted:

        0. Initially the URB is unlinked and idle.

        1. The URB gets submitted and linked.

        2. The URB is passed to the HCD, which enqueues it.

        3. The URB completes and is dequeued by the HCD.

        4. The URB is unlinked and passed to the completion routine.

        5. The URB is once again idle (or it may be resubmitted).

Now consider what happens if usb_unlink_urb() is called just after each
step above:

        0. Nothing happens since the URB is idle.  (Error)

        1. This is the tricky part.  We want the submission to fail
           but it hasn't finished yet.  The URB is marked so that the 
           HCD will recognize it has already been unlinked, and the
           enqueue call will fail.  (Error?)

        2. The HCD's dequeue routine works in the usual way.  (Success)

        3. The HCD's dequeue routine fails since the URB has already
           been dequeued.  (Error?)

        4. The unlink call fails since the URB is no longer linked.
           (Error?)

        5. Same as 0.

0 is clearly an error and 2 is clearly a success.  The others aren't so 
clear.  In particular, in 1 can we say that the URB was unlinked when 
strictly speaking it never got fully submitted to begin with?  But if 
the unlink call hadn't been made then the submission would have 
succeeded!  Part of the confusion results from the somewhat artificial 
difference between being linked and being enqueued.

IMO the fine distinctions above simply don't matter.  Drivers don't
care anyway, since they can't know what stage the URB is at when they
try to unlink it.

The only possible place where this might matter is in usbtest, which 
specifically intends to test the unlink code paths.  Even there, 
I'm not sure that usb_unlink_urb needs to return a meaningful value; 
the URB's final status code ought to be sufficient.

So -- is there any objection if I change usb_unlink_urb to return void?

If there is, then consider that steps 0, 1, 3, and 4 ought to return
distinct error codes, which they currently don't do.  (Or maybe 1
should count as a success?)  In practice this would just make more work
for drivers, since they would have to test more possible codes.

Alan Stern


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to