1
0
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:
Ian Dowse 2005-12-08 03:08:17 +00:00
parent 200bc1f049
commit 2b58bea7c0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=153224

View File

@ -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);