From: Oliver Neukum <[EMAIL PROTECTED]>

this driver ignores errors while starting the transmit queue. It will
never be reported stopped as the completion handler won't run
and it will never be started again as it will be considered started.
This patch adds error handling.

Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]>
Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
---
 drivers/usb/net/catc.c |   27 +++++++++++++++++++--------
 1 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c
index ffec2e0..86e90c5 100644
--- a/drivers/usb/net/catc.c
+++ b/drivers/usb/net/catc.c
@@ -355,7 +355,7 @@ resubmit:
  * Transmit routines.
  */
 
-static void catc_tx_run(struct catc *catc)
+static int catc_tx_run(struct catc *catc)
 {
        int status;
 
@@ -373,12 +373,14 @@ static void catc_tx_run(struct catc *catc)
        catc->tx_ptr = 0;
 
        catc->netdev->trans_start = jiffies;
+       return status;
 }
 
 static void catc_tx_done(struct urb *urb)
 {
        struct catc *catc = urb->context;
        unsigned long flags;
+       int r;
 
        if (urb->status == -ECONNRESET) {
                dbg("Tx Reset.");
@@ -397,10 +399,13 @@ static void catc_tx_done(struct urb *urb)
 
        spin_lock_irqsave(&catc->tx_lock, flags);
 
-       if (catc->tx_ptr)
-               catc_tx_run(catc);
-       else
+       if (catc->tx_ptr) {
+               r = catc_tx_run(catc);
+               if (unlikely(r < 0))
+                       clear_bit(TX_RUNNING, &catc->flags);
+       } else {
                clear_bit(TX_RUNNING, &catc->flags);
+       }
 
        netif_wake_queue(catc->netdev);
 
@@ -411,6 +416,7 @@ static int catc_hard_start_xmit(struct sk_buff *skb, struct 
net_device *netdev)
 {
        struct catc *catc = netdev_priv(netdev);
        unsigned long flags;
+       int r = 0;
        char *tx_buf;
 
        spin_lock_irqsave(&catc->tx_lock, flags);
@@ -421,8 +427,11 @@ static int catc_hard_start_xmit(struct sk_buff *skb, 
struct net_device *netdev)
        skb_copy_from_linear_data(skb, tx_buf + 2, skb->len);
        catc->tx_ptr += skb->len + 2;
 
-       if (!test_and_set_bit(TX_RUNNING, &catc->flags))
-               catc_tx_run(catc);
+       if (!test_and_set_bit(TX_RUNNING, &catc->flags)) {
+               r = catc_tx_run(catc);
+               if (r < 0)
+                       clear_bit(TX_RUNNING, &catc->flags);
+       }
 
        if ((catc->is_f5u011 && catc->tx_ptr)
             || (catc->tx_ptr >= ((TX_MAX_BURST - 1) * (PKT_SZ + 2))))
@@ -430,8 +439,10 @@ static int catc_hard_start_xmit(struct sk_buff *skb, 
struct net_device *netdev)
 
        spin_unlock_irqrestore(&catc->tx_lock, flags);
 
-       catc->stats.tx_bytes += skb->len;
-       catc->stats.tx_packets++;
+       if (r >= 0) {
+               catc->stats.tx_bytes += skb->len;
+               catc->stats.tx_packets++;
+       }
 
        dev_kfree_skb(skb);
 
-- 
1.5.1.2


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to