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:2.873 / U:0.592 seconds]
    ©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site