diff options
author | xyzz <1065521+xyzz@users.noreply.github.com> | 2020-01-13 18:08:14 -0500 |
---|---|---|
committer | MechMerlin <30334081+mechmerlin@users.noreply.github.com> | 2020-01-13 15:08:14 -0800 |
commit | 83be1aed7631efdeccf9fbcd5d702b3048f08fd7 (patch) | |
tree | b22c45518550edfd690a19007bf31b23543c2f70 /tmk_core/protocol/chibios/usb_main.c | |
parent | c293d9049a53a9589152571e9322899155b5b623 (diff) |
chibios/usb_main: re-check USB status in send_keyboard after sleeping the thread (#7784)
* chibios/usb_main: re-check USB status in send_keyboard after sleeping the thread
* change send_keyboard to only have 1 exit point
Diffstat (limited to 'tmk_core/protocol/chibios/usb_main.c')
-rw-r--r-- | tmk_core/protocol/chibios/usb_main.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index a4f996b8d7..8fbe877dbf 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -620,10 +620,8 @@ uint8_t keyboard_leds(void) { return (uint8_t)(keyboard_led_stats & 0xFF); } void send_keyboard(report_keyboard_t *report) { osalSysLock(); if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - osalSysUnlock(); - return; + goto unlock; } - osalSysUnlock(); #ifdef NKRO_ENABLE if (keymap_config.nkro && keyboard_protocol) { /* NKRO protocol */ @@ -632,28 +630,35 @@ void send_keyboard(report_keyboard_t *report) { * until *after* the packet has been transmitted. I think * this is more efficient */ /* busy wait, should be short and not very common */ - osalSysLock(); if (usbGetTransmitStatusI(&USB_DRIVER, SHARED_IN_EPNUM)) { /* Need to either suspend, or loop and call unlock/lock during * every iteration - otherwise the system will remain locked, * no interrupts served, so USB not going through as well. * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ osalThreadSuspendS(&(&USB_DRIVER)->epc[SHARED_IN_EPNUM]->in_state->thread); + + /* after osalThreadSuspendS returns USB status might have changed */ + if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { + goto unlock; + } } usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)report, sizeof(struct nkro_report)); - osalSysUnlock(); } else #endif /* NKRO_ENABLE */ { /* regular protocol */ /* need to wait until the previous packet has made it through */ /* busy wait, should be short and not very common */ - osalSysLock(); if (usbGetTransmitStatusI(&USB_DRIVER, KEYBOARD_IN_EPNUM)) { /* Need to either suspend, or loop and call unlock/lock during * every iteration - otherwise the system will remain locked, * no interrupts served, so USB not going through as well. * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ osalThreadSuspendS(&(&USB_DRIVER)->epc[KEYBOARD_IN_EPNUM]->in_state->thread); + + /* after osalThreadSuspendS returns USB status might have changed */ + if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { + goto unlock; + } } uint8_t *data, size; if (keyboard_protocol) { @@ -664,9 +669,11 @@ void send_keyboard(report_keyboard_t *report) { size = 8; } usbStartTransmitI(&USB_DRIVER, KEYBOARD_IN_EPNUM, data, size); - osalSysUnlock(); } keyboard_report_sent = *report; + +unlock: + osalSysUnlock(); } /* --------------------------------------------------------- |