diff options
| author | Michael Stapelberg <stapelberg@users.noreply.github.com> | 2021-04-10 17:03:38 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-04-10 16:03:38 +0100 |
| commit | 7d953332e0d7c0394c607156bf4099881bdf3f43 (patch) | |
| tree | be928f6749a52c34fa1d528266c566671be36239 | |
| parent | 03685309fd857c64ed16c231507017214e4805ca (diff) | |
| download | qmk_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.c | 14 |
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 | ||
| 83 | static size_t _write(void *ip, const uint8_t *bp, size_t n) { return obqWriteTimeout(&((QMKUSBDriver *)ip)->obqueue, bp, n, TIME_INFINITE); } | 83 | static 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 | ||
| 85 | static size_t _read(void *ip, uint8_t *bp, size_t n) { return ibqReadTimeout(&((QMKUSBDriver *)ip)->ibqueue, bp, n, TIME_INFINITE); } | 97 | static size_t _read(void *ip, uint8_t *bp, size_t n) { return ibqReadTimeout(&((QMKUSBDriver *)ip)->ibqueue, bp, n, TIME_INFINITE); } |
| 86 | 98 | ||
