ChibiOS USB driver: prevent deadlock with CONSOLE_ENABLE = yes

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
This commit is contained in:
Michael Stapelberg 2021-04-03 19:02:13 +02:00
parent 60e1910e5b
commit c823fe2d3f

View File

@ -80,7 +80,19 @@ static bool qmkusb_start_receive(QMKUSBDriver *qmkusbp) {
* Interface implementation. * Interface implementation.
*/ */
static size_t _write(void *ip, const uint8_t *bp, size_t n) { return obqWriteTimeout(&((QMKUSBDriver *)ip)->obqueue, bp, n, TIME_INFINITE); } static size_t _write(void *ip, const uint8_t *bp, size_t n) {
output_buffers_queue_t *obqueue = &((QMKUSBDriver *)ip)->obqueue;
chSysLock();
const bool full = obqIsFullI(obqueue);
chSysUnlock();
if (full || bqIsSuspendedX(obqueue)) {
/* Discard any writes while the queue is suspended or full, i.e. the hidraw
interface is not open. If we tried to send with an infinite timeout, we
would deadlock the keyboard otherwise. */
return -1;
}
return obqWriteTimeout(obqueue, bp, n, TIME_INFINITE);
}
static size_t _read(void *ip, uint8_t *bp, size_t n) { return ibqReadTimeout(&((QMKUSBDriver *)ip)->ibqueue, bp, n, TIME_INFINITE); } static size_t _read(void *ip, uint8_t *bp, size_t n) { return ibqReadTimeout(&((QMKUSBDriver *)ip)->ibqueue, bp, n, TIME_INFINITE); }