> > It avoids a lot of effort in the disconnect methods of the network
> > drivers which would have to check and wait for an ongoing asynchronous
> > unlinking.
>
> Now I'm really not following you -- at all.
>
> Are you implying that there's some difference in the synchronous
> and asynchronous calls _other_ than the fact that in one case
> the unlink is guaranteed to be completed when the call returns,
> and in the other it isn't? If so, what's that difference?
There's no difference in function. There is a difference in consequences.
An asynchronous unlink due to being asynchronous allows other
things to happen while it is underway. Therefore the need to do
a synchronous unlink while an asynchronous unlink is happening
may arise.
>From pegasus.c::pegasus_tx_timeout
pegasus->tx_urb->transfer_flags |= USB_ASYNC_UNLINK;
usb_unlink_urb( pegasus->tx_urb );
In pegasus_disconnect this URB is supposed to be unlinked
synchronously however. You cannot however simply reset
the flag. The method would have to check for an ongoing
asynchronous unlink and wait for it to complete.
This would be vastly simnplified and could be pushed into the hcd layer
if the functions had seperate names.
[..]
> > > > >> void usb_wait_completion(struct urb *urb);
> > >
> > > I still haven't seen a description of what this is supposed to do,
> > > and would want to see one before a discussion about whether
> > > the API should be included ...
> >
> > if (urb->status != -EINPROGRESS) {
> > retval = 0;
> > goto done;
>
> No device driver is allowed to test urb->status except within the
> completion handler -- otherwise they're racing with the host
> controller driver. Yes?
Yes, of course. This is code from hcd.c where it is legitimate in principle.
> > Correct me if I am wrong, but it seems to me that a completion handler
> > may be running after a synchronous unlink returns.
>
> OK -- you're wrong! See above, for starters. Though I could believe
> that some of the 2.4 host controller drivers have bugs in that area,
> at least on MP systems. I seem to recall pushing that into the HCD
> layer so that related problems could be _structurally_ removed,
> rather than only by (excessive) debugging.
In usb_hcd_giveback_urb() urb->complete (urb) is called without
any locks held, yes ?
Now suppose that while urb->complete is running somebody calls
usb_unlink_urb on that urb. Then you'll get ENODEV.
This well and good and shows you that a completion handler
may be running and you need to wait for it to finish.
But there's no generic function to do so.
Any driver can include this on its own, but is really common
functionality and could be achieved by adding
urb->completion_finished = 1;
if (urb->completion_waiters)
wake_up(&urb->completion_handlers);
> > In most disconnect methods we want to free memory completion handlers
> > may want to access. Thus a method to wait for them to finish would be
> > handy.
>
> Could you explain why it's hard to actually let the completion
> handlers (each driver knows when they're called :) flag that it's
> OK to free such memory?
Inconvinient. People will get it wrong. Having gone through a lot
of disconnect methods I've been convinced that what can go wrong
will go wrong.
Knowing that it's OK to free after two function calls is simple.
Setting a flag in a completion handler is too hard.
Regards
Oliver
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel