Index: usbdi.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/dev/usb/usbdi.c,v retrieving revision 1.86.2.4 diff -u -r1.86.2.4 usbdi.c --- usbdi.c 3 Mar 2005 01:54:58 -0000 1.86.2.4 +++ usbdi.c 12 Apr 2005 00:44:00 -0000 @@ -847,17 +847,21 @@ 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);