From f32bdd677b387916be3c936ab73d053a3d3ae812 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Mon, 8 Jun 2009 11:49:05 -0700 Subject: [PATCH] USB - Add support for xfer-restart-before-callback Interrupt pipes restart their xfers. When used for a USB keyboard the xfer must be restarted before the callback, even though there may be state data races, otherwise the CTL-ALT-ESC sequence into the debugger will leave the xfer unqueued and the keyboard will stop working. --- sys/bus/usb/usbdi.c | 7 ++++++- sys/bus/usb/usbdi.h | 1 + sys/dev/usbmisc/ukbd/ukbd.c | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/sys/bus/usb/usbdi.c b/sys/bus/usb/usbdi.c index 0dfb020f7d..21d423725c 100644 --- a/sys/bus/usb/usbdi.c +++ b/sys/bus/usb/usbdi.c @@ -829,8 +829,13 @@ usb_transfer_complete(usbd_xfer_handle 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. + * + * USBD_CALLBACK_LAST is set by the keyboard driver to ensure + * that the xfer is restarted prior to doing the callback. + * Otherwise a CTL-ALT-ESC into the debugger will leave the + * xfer inactive and the keyboard will stop working. */ - if (repeat) { + if (repeat && (xfer->flags & USBD_CALLBACK_LAST) == 0) { if (xfer->callback) xfer->callback(xfer, xfer->priv, xfer->status); pipe->methods->done(xfer); diff --git a/sys/bus/usb/usbdi.h b/sys/bus/usb/usbdi.h index 8a2ff5d235..7c83843372 100644 --- a/sys/bus/usb/usbdi.h +++ b/sys/bus/usb/usbdi.h @@ -88,6 +88,7 @@ typedef void (*usbd_callback)(usbd_xfer_handle, usbd_private_handle, #define USBD_SYNCHRONOUS 0x02 /* wait for completion */ /* in usb.h #define USBD_SHORT_XFER_OK 0x04*/ /* allow short reads */ #define USBD_FORCE_SHORT_XFER 0x08 /* force last short packet on write */ +#define USBD_CALLBACK_LAST 0x10 /* restart xfer BEFORE making callback */ #define USBD_NO_TIMEOUT 0 #define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */ diff --git a/sys/dev/usbmisc/ukbd/ukbd.c b/sys/dev/usbmisc/ukbd/ukbd.c index b9731e7597..6459cc5157 100644 --- a/sys/dev/usbmisc/ukbd/ukbd.c +++ b/sys/dev/usbmisc/ukbd/ukbd.c @@ -647,7 +647,7 @@ ukbd_enable_intr(keyboard_t *kbd, int on, usbd_intr_t *func) state->ks_ifstate |= INTRENABLED; err = usbd_open_pipe_intr(state->ks_iface, state->ks_ep_addr, - USBD_SHORT_XFER_OK, + USBD_SHORT_XFER_OK | USBD_CALLBACK_LAST, &state->ks_intrpipe, kbd, &state->ks_ndata, sizeof(state->ks_ndata), func, -- 2.11.4.GIT