aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stapelberg <stapelberg@users.noreply.github.com>2021-04-10 17:03:38 +0200
committerGitHub <noreply@github.com>2021-04-10 16:03:38 +0100
commit7d953332e0d7c0394c607156bf4099881bdf3f43 (patch)
treebe928f6749a52c34fa1d528266c566671be36239
parent03685309fd857c64ed16c231507017214e4805ca (diff)
downloadqmk_firmware-7d953332e0d7c0394c607156bf4099881bdf3f43.tar.gz
qmk_firmware-7d953332e0d7c0394c607156bf4099881bdf3f43.zip
ChibiOS USB driver: prevent deadlock with CONSOLE_ENABLE = yes (#12472)
Before this commit, attaching an ARM-based (i.e. ChibiOS-based) keyboard that uses CONSOLE_ENABLE = yes and produces debug messages would deadlock the keyboard unless one was running hid_listen. With this commit, dead-locking writes to the queue are detected and prevented. fixes #5631
-rw-r--r--tmk_core/protocol/chibios/usb_driver.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/tmk_core/protocol/chibios/usb_driver.c b/tmk_core/protocol/chibios/usb_driver.c
index cc0ce7600..eb72f8ff6 100644
--- a/tmk_core/protocol/chibios/usb_driver.c
+++ b/tmk_core/protocol/chibios/usb_driver.c
@@ -80,7 +80,19 @@ static bool qmkusb_start_receive(QMKUSBDriver *qmkusbp) {
80 * Interface implementation. 80 * Interface implementation.
81 */ 81 */
82 82
83static size_t _write(void *ip, const uint8_t *bp, size_t n) { return obqWriteTimeout(&((QMKUSBDriver *)ip)->obqueue, bp, n, TIME_INFINITE); } 83static size_t _write(void *ip, const uint8_t *bp, size_t n) {
84 output_buffers_queue_t *obqueue = &((QMKUSBDriver *)ip)->obqueue;
85 chSysLock();
86 const bool full = obqIsFullI(obqueue);
87 chSysUnlock();
88 if (full || bqIsSuspendedX(obqueue)) {
89 /* Discard any writes while the queue is suspended or full, i.e. the hidraw
90 interface is not open. If we tried to send with an infinite timeout, we
91 would deadlock the keyboard otherwise. */
92 return -1;
93 }
94 return obqWriteTimeout(obqueue, bp, n, TIME_INFINITE);
95}
84 96
85static size_t _read(void *ip, uint8_t *bp, size_t n) { return ibqReadTimeout(&((QMKUSBDriver *)ip)->ibqueue, bp, n, TIME_INFINITE); } 97static size_t _read(void *ip, uint8_t *bp, size_t n) { return ibqReadTimeout(&((QMKUSBDriver *)ip)->ibqueue, bp, n, TIME_INFINITE); }
86 98