Commit 5a9f4e33 authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman

USB: fix catc error handling

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: default avatarOliver Neukum <oneukum@suse.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 949ce471
...@@ -355,7 +355,7 @@ static void catc_irq_done(struct urb *urb) ...@@ -355,7 +355,7 @@ static void catc_irq_done(struct urb *urb)
* Transmit routines. * Transmit routines.
*/ */
static void catc_tx_run(struct catc *catc) static int catc_tx_run(struct catc *catc)
{ {
int status; int status;
...@@ -373,12 +373,14 @@ static void catc_tx_run(struct catc *catc) ...@@ -373,12 +373,14 @@ static void catc_tx_run(struct catc *catc)
catc->tx_ptr = 0; catc->tx_ptr = 0;
catc->netdev->trans_start = jiffies; catc->netdev->trans_start = jiffies;
return status;
} }
static void catc_tx_done(struct urb *urb) static void catc_tx_done(struct urb *urb)
{ {
struct catc *catc = urb->context; struct catc *catc = urb->context;
unsigned long flags; unsigned long flags;
int r;
if (urb->status == -ECONNRESET) { if (urb->status == -ECONNRESET) {
dbg("Tx Reset."); dbg("Tx Reset.");
...@@ -397,10 +399,13 @@ static void catc_tx_done(struct urb *urb) ...@@ -397,10 +399,13 @@ static void catc_tx_done(struct urb *urb)
spin_lock_irqsave(&catc->tx_lock, flags); spin_lock_irqsave(&catc->tx_lock, flags);
if (catc->tx_ptr) if (catc->tx_ptr) {
catc_tx_run(catc); r = catc_tx_run(catc);
else if (unlikely(r < 0))
clear_bit(TX_RUNNING, &catc->flags);
} else {
clear_bit(TX_RUNNING, &catc->flags); clear_bit(TX_RUNNING, &catc->flags);
}
netif_wake_queue(catc->netdev); netif_wake_queue(catc->netdev);
...@@ -411,6 +416,7 @@ static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *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); struct catc *catc = netdev_priv(netdev);
unsigned long flags; unsigned long flags;
int r = 0;
char *tx_buf; char *tx_buf;
spin_lock_irqsave(&catc->tx_lock, flags); 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) ...@@ -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); skb_copy_from_linear_data(skb, tx_buf + 2, skb->len);
catc->tx_ptr += skb->len + 2; catc->tx_ptr += skb->len + 2;
if (!test_and_set_bit(TX_RUNNING, &catc->flags)) if (!test_and_set_bit(TX_RUNNING, &catc->flags)) {
catc_tx_run(catc); r = catc_tx_run(catc);
if (r < 0)
clear_bit(TX_RUNNING, &catc->flags);
}
if ((catc->is_f5u011 && catc->tx_ptr) if ((catc->is_f5u011 && catc->tx_ptr)
|| (catc->tx_ptr >= ((TX_MAX_BURST - 1) * (PKT_SZ + 2)))) || (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) ...@@ -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); spin_unlock_irqrestore(&catc->tx_lock, flags);
if (r >= 0) {
catc->stats.tx_bytes += skb->len; catc->stats.tx_bytes += skb->len;
catc->stats.tx_packets++; catc->stats.tx_packets++;
}
dev_kfree_skb(skb); dev_kfree_skb(skb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment