summary refs log tree commit diff
path: root/tmk_core/protocol
diff options
context:
space:
mode:
authorxyzz <1065521+xyzz@users.noreply.github.com>2020-01-13 18:08:14 -0500
committerMechMerlin <30334081+mechmerlin@users.noreply.github.com>2020-01-13 15:08:14 -0800
commit83be1aed7631efdeccf9fbcd5d702b3048f08fd7 (patch)
treeb22c45518550edfd690a19007bf31b23543c2f70 /tmk_core/protocol
parentc293d9049a53a9589152571e9322899155b5b623 (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')
-rw-r--r--tmk_core/protocol/chibios/usb_main.c21
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();
 }
 
 /* ---------------------------------------------------------