mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-20 11:11:24 +00:00
Reorder the calling of the completion callback and the transfer
"done" method so that for non-repeat operations we have completely finished with the transfer by the time the callback is invoked. This makes it possible to recycle a transfer from within the callback routine for the same transfer. Previously this almost worked, but with OHCI controllers calling the "done" method after the callback would zero out some important fields needed by the recycled transfer. Only some usb peripheral drivers such as ucom appear to rely on the ability to reuse a transfer from its callback. MFC after: 1 week
This commit is contained in:
parent
200bc1f049
commit
2b58bea7c0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=153224
@ -847,17 +847,21 @@ usb_transfer_complete(usbd_xfer_handle xfer)
|
||||
xfer->status = USBD_SHORT_XFER;
|
||||
}
|
||||
|
||||
if (xfer->callback)
|
||||
xfer->callback(xfer, xfer->priv, xfer->status);
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (pipe->methods->done != NULL)
|
||||
/*
|
||||
* For repeat operations, call the callback first, as the xfer
|
||||
* will not go away and the "done" method may modify it. Otherwise
|
||||
* reverse the order in case the callback wants to free or reuse
|
||||
* the xfer.
|
||||
*/
|
||||
if (repeat) {
|
||||
if (xfer->callback)
|
||||
xfer->callback(xfer, xfer->priv, xfer->status);
|
||||
pipe->methods->done(xfer);
|
||||
else
|
||||
printf("usb_transfer_complete: pipe->methods->done == NULL\n");
|
||||
#else
|
||||
pipe->methods->done(xfer);
|
||||
#endif
|
||||
} else {
|
||||
pipe->methods->done(xfer);
|
||||
if (xfer->callback)
|
||||
xfer->callback(xfer, xfer->priv, xfer->status);
|
||||
}
|
||||
|
||||
if (sync && !polling)
|
||||
wakeup(xfer);
|
||||
|
Loading…
Reference in New Issue
Block a user