PERFORCE change 170001 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sat Oct 31 15:40:45 UTC 2009
http://p4web.freebsd.org/chv.cgi?CH=170001
Change 170001 by hselasky at hselasky_laptop001 on 2009/10/31 15:39:49
USB CORE:
- Fix a corner case where usbd_transfer_drain() can return
too early. This fixes some rare panics at USB device detach.
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb/usb_core.h#28 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#170 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb/usb_core.h#28 (text+ko) ====
@@ -112,6 +112,7 @@
uint8_t curr_dma_set:1; /* used by USB HC/DC driver */
uint8_t can_cancel_immed:1; /* set if USB transfer can be
* cancelled immediately */
+ uint8_t doing_callback:1; /* set if executing the callback */
};
/*
==== //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#170 (text+ko) ====
@@ -1797,8 +1797,18 @@
usbd_transfer_stop(xfer);
- while (usbd_transfer_pending(xfer)) {
+ while (usbd_transfer_pending(xfer) ||
+ xfer->flags_int.doing_callback) {
+
+ /*
+ * It is allowed that the callback can drop its
+ * transfer mutex. In that case checking only
+ * "usbd_transfer_pending()" is not enough to tell if
+ * the USB transfer is fully drained. We also need to
+ * check the internal "doing_callback" flag.
+ */
xfer->flags_int.draining = 1;
+
/*
* Wait until the current outstanding USB
* transfer is complete !
@@ -2043,6 +2053,9 @@
/* get next USB transfer in the queue */
info->done_q.curr = NULL;
+ /* set flag in case of drain */
+ xfer->flags_int.doing_callback = 1;
+
USB_BUS_UNLOCK(info->bus);
USB_BUS_LOCK_ASSERT(info->bus, MA_NOTOWNED);
@@ -2095,12 +2108,17 @@
if ((!xfer->flags_int.open) &&
(xfer->flags_int.started) &&
(xfer->usb_state == USB_ST_ERROR)) {
+ /* clear flag in case of drain */
+ xfer->flags_int.doing_callback = 0;
/* try to loop, but not recursivly */
usb_command_wrapper(&info->done_q, xfer);
return;
}
done:
+ /* clear flag in case of drain */
+ xfer->flags_int.doing_callback = 0;
+
/*
* Check if we are draining.
*/
More information about the p4-projects
mailing list