lkml.org 
[lkml]   [2009]   [May]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 5/5] usb_debug: EXPERIMENTAL - poll hcd device to force writes
Date
The problem that this patch tries to solve is that data is lost
because there are too many outstanding transmit urb's.

The question is what is the right way to force the controller to catch
up, and ideally let the kernel do some other things in the mean time?

This patch takes the route of forcibly polling the hcd device to drain
the urb queue and initiate the bulk write call backs.

NOTE this patch is not signed off, it is a question of what is the
right way to do this?
---
drivers/usb/core/hcd.c | 1 +
drivers/usb/serial/usb_debug.c | 23 +++++++++++++++++++++++
2 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 42b93da..57c09c2 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1760,6 +1760,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd)
local_irq_restore(flags);
return rc;
}
+EXPORT_SYMBOL_GPL(usb_hcd_irq);

/*-------------------------------------------------------------------------*/

diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c
index 58feab9..8838418 100644
--- a/drivers/usb/serial/usb_debug.c
+++ b/drivers/usb/serial/usb_debug.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
+#include "../core/hcd.h"

#define URB_UPPER_LIMIT 42
#define USB_DEBUG_MAX_PACKET_SIZE 8
@@ -91,6 +92,23 @@ static int usb_debug_port_probe(struct usb_serial_port *port)
return 0;
}

+/* If the driver is close to running of tx urb's try to free some up
+ * by asking the hcd device to do some processing. XXX This needs
+ * review as to if this is a reasonable way to implement forcing the
+ * HCD device to run.
+ */
+static void poll_hcd_irq(struct urb *urb)
+{
+ struct usb_hcd *hcd;
+
+ if (!urb)
+ return;
+
+ hcd = bus_to_hcd(urb->dev->bus);
+ if (hcd)
+ usb_hcd_irq(0, hcd);
+}
+
static int usb_debug_write_room(struct tty_struct *tty)
{
unsigned long flags;
@@ -156,10 +174,15 @@ static int usb_debug_write(struct tty_struct *tty,
dbg("%s - write request of 0 bytes", __func__);

while (count > 0) {
+ int loops = 1000;
+try_again:
spin_lock_irqsave(&priv->tx_lock, flags);
if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) {
spin_unlock_irqrestore(&priv->tx_lock, flags);
dbg("%s - write limit hit\n", __func__);
+ poll_hcd_irq(port->read_urb);
+ if (loops-- > 0)
+ goto try_again;
return bwrite;
}

--
1.6.3.rc0.1.gf800


\
 
 \ /
  Last update: 2009-05-06 04:05    [W:0.167 / U:0.040 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site