usb_buf: Limit the maximum queue length to 3 elements
If there are already three elements in the to-be-transmitted queue
for the EP, let's free the first element of the queue. This is a
clear indication that the USB host is not polling the endpoint
regularly. Maybe there's no host application running at all?
This should obsolete Change-Id Ie9ebdd2ff966f67c9afd1ed760f106558f0091ad
Change-Id: Ie15183f16b22193ffdaf01845db2eae4c7f43c17
Closes: OS#4251
diff --git a/firmware/libcommon/source/usb_buf.c b/firmware/libcommon/source/usb_buf.c
index 8ad5a0e..7892d6e 100644
--- a/firmware/libcommon/source/usb_buf.c
+++ b/firmware/libcommon/source/usb_buf.c
@@ -24,6 +24,7 @@
#include <errno.h>
#define USB_ALLOC_SIZE 280
+#define USB_MAX_QLEN 3
static struct usb_buffered_ep usb_buffered_ep[BOARD_USB_NUMENDPOINTS];
@@ -78,6 +79,17 @@
/* no need for irqsafe operation, as the usb_tx_queue is
* processed only by the main loop context */
+
+ if (ep->queue_len > USB_MAX_QLEN) {
+ struct msgb *evict;
+ /* free the first pending buffer in the queue */
+ TRACE_INFO("EP%02x: dropping first queue element (qlen=%u)\r\n",
+ ep->ep, ep->queue_len);
+ evict = msgb_dequeue_count(&ep->queue, &ep->queue_len);
+ OSMO_ASSERT(evict);
+ usb_buf_free(evict);
+ }
+
msgb_enqueue_count(&ep->queue, msg, &ep->queue_len);
return 0;
}