From 1ea54e5052fdf2ced1e19ff5a5f54a9d25156d1d Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Sat, 22 Oct 2022 20:16:09 +0300 Subject: [PATCH] ChibiOS USB: Add a dummy IN callback to work around LLD bugs (#18811) In #18631 some IN notification callbacks that were doing nothing were removed, which should be a valid thing to do (ChibiOS HAL checks the `in_cb` and `out_cb` pointers for being non-NULL before invoking those optional callbacks). However, it turned out that some less popular USB LLDs (KINETIS and MIMXRT1062) have their own checks for those pointers, and (incorrectly) skip the ChibiOS callback handling when those pointers are NULL, which breaks the code for the `USB_USE_WAIT` configuration option (the waiting thread never gets resumed if the corresponding callback pointer is NULL). Add those dummy callbacks again (but use a single function for all of them instead of individual ones for each endpoint); this restores the KINETIS and MIMXRT1062 boards to the working state while the LLDs are getting fixed. --- tmk_core/protocol/chibios/usb_main.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index 2bf273488b8..fb3d5758468 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -120,6 +120,16 @@ static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype return &desc; } +/* + * USB notification callback that does nothing. Needed to work around bugs in + * some USB LLDs that fail to resume the waiting thread when the notification + * callback pointer is NULL. + */ +static void dummy_usb_cb(USBDriver *usbp, usbep_t ep) { + (void)usbp; + (void)ep; +} + #ifndef KEYBOARD_SHARED_EP /* keyboard endpoint state structure */ static USBInEndpointState kbd_ep_state; @@ -127,7 +137,7 @@ static USBInEndpointState kbd_ep_state; static const USBEndpointConfig kbd_ep_config = { USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ NULL, /* SETUP packet notification callback */ - NULL, /* IN notification callback */ + dummy_usb_cb, /* IN notification callback */ NULL, /* OUT notification callback */ KEYBOARD_EPSIZE, /* IN maximum packet size */ 0, /* OUT maximum packet size */ @@ -145,7 +155,7 @@ static USBInEndpointState mouse_ep_state; static const USBEndpointConfig mouse_ep_config = { USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ NULL, /* SETUP packet notification callback */ - NULL, /* IN notification callback */ + dummy_usb_cb, /* IN notification callback */ NULL, /* OUT notification callback */ MOUSE_EPSIZE, /* IN maximum packet size */ 0, /* OUT maximum packet size */ @@ -163,7 +173,7 @@ static USBInEndpointState shared_ep_state; static const USBEndpointConfig shared_ep_config = { USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ NULL, /* SETUP packet notification callback */ - NULL, /* IN notification callback */ + dummy_usb_cb, /* IN notification callback */ NULL, /* OUT notification callback */ SHARED_EPSIZE, /* IN maximum packet size */ 0, /* OUT maximum packet size */ @@ -181,7 +191,7 @@ static USBInEndpointState joystick_ep_state; static const USBEndpointConfig joystick_ep_config = { USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ NULL, /* SETUP packet notification callback */ - NULL, /* IN notification callback */ + dummy_usb_cb, /* IN notification callback */ NULL, /* OUT notification callback */ JOYSTICK_EPSIZE, /* IN maximum packet size */ 0, /* OUT maximum packet size */ @@ -199,7 +209,7 @@ static USBInEndpointState digitizer_ep_state; static const USBEndpointConfig digitizer_ep_config = { USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ NULL, /* SETUP packet notification callback */ - NULL, /* IN notification callback */ + dummy_usb_cb, /* IN notification callback */ NULL, /* OUT notification callback */ DIGITIZER_EPSIZE, /* IN maximum packet size */ 0, /* OUT maximum packet size */