|
Justin M. Forbes |
d4cdad |
From cc5740ae8aa68dbbdc690f694b0e55d70f9c49ee Mon Sep 17 00:00:00 2001
|
|
Justin M. Forbes |
d4cdad |
From: Hans de Goede <hdegoede@redhat.com>
|
|
Justin M. Forbes |
d4cdad |
Date: Mon, 19 Dec 2011 13:42:40 +0100
|
|
Justin M. Forbes |
d4cdad |
Subject: [PATCH 102/118] usb-redir: Dynamically adjust iso buffering size
|
|
Justin M. Forbes |
d4cdad |
based on ep interval
|
|
Justin M. Forbes |
d4cdad |
|
|
Justin M. Forbes |
d4cdad |
Note the bufpq_target_size id stored in the endpoint info struct,
|
|
Justin M. Forbes |
d4cdad |
even though it only used once. This is done because it will be
|
|
Justin M. Forbes |
d4cdad |
referenced from other code in a follow up patch.
|
|
Justin M. Forbes |
d4cdad |
|
|
Justin M. Forbes |
d4cdad |
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
Justin M. Forbes |
d4cdad |
---
|
|
Justin M. Forbes |
d4cdad |
usb-redir.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++-----
|
|
Justin M. Forbes |
d4cdad |
1 files changed, 47 insertions(+), 5 deletions(-)
|
|
Justin M. Forbes |
d4cdad |
|
|
Justin M. Forbes |
d4cdad |
diff --git a/usb-redir.c b/usb-redir.c
|
|
Justin M. Forbes |
d4cdad |
index 7678f1a..ab2c8fa 100644
|
|
Justin M. Forbes |
d4cdad |
--- a/usb-redir.c
|
|
Justin M. Forbes |
d4cdad |
+++ b/usb-redir.c
|
|
Justin M. Forbes |
d4cdad |
@@ -61,6 +61,7 @@ struct endp_data {
|
|
Justin M. Forbes |
d4cdad |
uint8_t interrupt_started;
|
|
Justin M. Forbes |
d4cdad |
uint8_t interrupt_error;
|
|
Justin M. Forbes |
d4cdad |
QTAILQ_HEAD(, buf_packet) bufpq;
|
|
Justin M. Forbes |
d4cdad |
+ int bufpq_target_size;
|
|
Justin M. Forbes |
d4cdad |
};
|
|
Justin M. Forbes |
d4cdad |
|
|
Justin M. Forbes |
d4cdad |
struct USBRedirDevice {
|
|
Justin M. Forbes |
d4cdad |
@@ -332,15 +333,41 @@ static int usbredir_handle_iso_data(USBRedirDevice *dev, USBPacket *p,
|
|
Justin M. Forbes |
d4cdad |
uint8_t ep)
|
|
Justin M. Forbes |
d4cdad |
{
|
|
Justin M. Forbes |
d4cdad |
int status, len;
|
|
Justin M. Forbes |
d4cdad |
-
|
|
Justin M. Forbes |
d4cdad |
if (!dev->endpoint[EP2I(ep)].iso_started &&
|
|
Justin M. Forbes |
d4cdad |
!dev->endpoint[EP2I(ep)].iso_error) {
|
|
Justin M. Forbes |
d4cdad |
struct usb_redir_start_iso_stream_header start_iso = {
|
|
Justin M. Forbes |
d4cdad |
.endpoint = ep,
|
|
Justin M. Forbes |
d4cdad |
- /* TODO maybe do something with these depending on ep interval? */
|
|
Justin M. Forbes |
d4cdad |
- .pkts_per_urb = 32,
|
|
Justin M. Forbes |
d4cdad |
- .no_urbs = 3,
|
|
Justin M. Forbes |
d4cdad |
};
|
|
Justin M. Forbes |
d4cdad |
+ int pkts_per_sec;
|
|
Justin M. Forbes |
d4cdad |
+
|
|
Justin M. Forbes |
d4cdad |
+ if (dev->dev.speed == USB_SPEED_HIGH)
|
|
Justin M. Forbes |
d4cdad |
+ pkts_per_sec = 8000 / dev->endpoint[EP2I(ep)].interval;
|
|
Justin M. Forbes |
d4cdad |
+ else
|
|
Justin M. Forbes |
d4cdad |
+ pkts_per_sec = 1000 / dev->endpoint[EP2I(ep)].interval;
|
|
Justin M. Forbes |
d4cdad |
+ /* Testing has shown that we need circa 60 ms buffer */
|
|
Justin M. Forbes |
d4cdad |
+ dev->endpoint[EP2I(ep)].bufpq_target_size = (pkts_per_sec * 60) / 1000;
|
|
Justin M. Forbes |
d4cdad |
+
|
|
Justin M. Forbes |
d4cdad |
+ /* Aim for approx 100 interrupts / second on the client to
|
|
Justin M. Forbes |
d4cdad |
+ balance latency and interrupt load */
|
|
Justin M. Forbes |
d4cdad |
+ start_iso.pkts_per_urb = pkts_per_sec / 100;
|
|
Justin M. Forbes |
d4cdad |
+ if (start_iso.pkts_per_urb < 1) {
|
|
Justin M. Forbes |
d4cdad |
+ start_iso.pkts_per_urb = 1;
|
|
Justin M. Forbes |
d4cdad |
+ } else if (start_iso.pkts_per_urb > 32) {
|
|
Justin M. Forbes |
d4cdad |
+ start_iso.pkts_per_urb = 32;
|
|
Justin M. Forbes |
d4cdad |
+ }
|
|
Justin M. Forbes |
d4cdad |
+
|
|
Justin M. Forbes |
d4cdad |
+ start_iso.no_urbs = (dev->endpoint[EP2I(ep)].bufpq_target_size +
|
|
Justin M. Forbes |
d4cdad |
+ start_iso.pkts_per_urb - 1) /
|
|
Justin M. Forbes |
d4cdad |
+ start_iso.pkts_per_urb;
|
|
Justin M. Forbes |
d4cdad |
+ /* Output endpoints pre-fill only 1/2 of the packets, keeping the rest
|
|
Justin M. Forbes |
d4cdad |
+ as overflow buffer. Also see the usbredir protocol documentation */
|
|
Justin M. Forbes |
d4cdad |
+ if (!(ep & USB_DIR_IN)) {
|
|
Justin M. Forbes |
d4cdad |
+ start_iso.no_urbs *= 2;
|
|
Justin M. Forbes |
d4cdad |
+ }
|
|
Justin M. Forbes |
d4cdad |
+ if (start_iso.no_urbs > 16) {
|
|
Justin M. Forbes |
d4cdad |
+ start_iso.no_urbs = 16;
|
|
Justin M. Forbes |
d4cdad |
+ }
|
|
Justin M. Forbes |
d4cdad |
+
|
|
Justin M. Forbes |
d4cdad |
/* No id, we look at the ep when receiving a status back */
|
|
Justin M. Forbes |
d4cdad |
usbredirparser_send_start_iso_stream(dev->parser, 0, &start_iso);
|
|
Justin M. Forbes |
d4cdad |
usbredirparser_do_write(dev->parser);
|
|
Justin M. Forbes |
d4cdad |
@@ -961,9 +988,24 @@ static void usbredir_ep_info(void *priv,
|
|
Justin M. Forbes |
d4cdad |
dev->endpoint[i].type = ep_info->type[i];
|
|
Justin M. Forbes |
d4cdad |
dev->endpoint[i].interval = ep_info->interval[i];
|
|
Justin M. Forbes |
d4cdad |
dev->endpoint[i].interface = ep_info->interface[i];
|
|
Justin M. Forbes |
d4cdad |
- if (dev->endpoint[i].type != usb_redir_type_invalid) {
|
|
Justin M. Forbes |
d4cdad |
+ switch (dev->endpoint[i].type) {
|
|
Justin M. Forbes |
d4cdad |
+ case usb_redir_type_invalid:
|
|
Justin M. Forbes |
d4cdad |
+ break;
|
|
Justin M. Forbes |
d4cdad |
+ case usb_redir_type_iso:
|
|
Justin M. Forbes |
d4cdad |
+ case usb_redir_type_interrupt:
|
|
Justin M. Forbes |
d4cdad |
+ if (dev->endpoint[i].interval == 0) {
|
|
Justin M. Forbes |
d4cdad |
+ ERROR("Received 0 interval for isoc or irq endpoint\n");
|
|
Justin M. Forbes |
d4cdad |
+ usbredir_device_disconnect(dev);
|
|
Justin M. Forbes |
d4cdad |
+ }
|
|
Justin M. Forbes |
d4cdad |
+ /* Fall through */
|
|
Justin M. Forbes |
d4cdad |
+ case usb_redir_type_control:
|
|
Justin M. Forbes |
d4cdad |
+ case usb_redir_type_bulk:
|
|
Justin M. Forbes |
d4cdad |
DPRINTF("ep: %02X type: %d interface: %d\n", I2EP(i),
|
|
Justin M. Forbes |
d4cdad |
dev->endpoint[i].type, dev->endpoint[i].interface);
|
|
Justin M. Forbes |
d4cdad |
+ break;
|
|
Justin M. Forbes |
d4cdad |
+ default:
|
|
Justin M. Forbes |
d4cdad |
+ ERROR("Received invalid endpoint type\n");
|
|
Justin M. Forbes |
d4cdad |
+ usbredir_device_disconnect(dev);
|
|
Justin M. Forbes |
d4cdad |
}
|
|
Justin M. Forbes |
d4cdad |
}
|
|
Justin M. Forbes |
d4cdad |
}
|
|
Justin M. Forbes |
d4cdad |
--
|
|
Justin M. Forbes |
d4cdad |
1.7.7.5
|
|
Justin M. Forbes |
d4cdad |
|