diff options
Diffstat (limited to 'drivers/usb/net/catc.c')
| -rw-r--r-- | 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 ffec2e01b896..86e90c59d551 100644 --- a/drivers/usb/net/catc.c +++ b/drivers/usb/net/catc.c | |||
| @@ -355,7 +355,7 @@ resubmit: | |||
| 355 | * Transmit routines. | 355 | * Transmit routines. |
| 356 | */ | 356 | */ |
| 357 | 357 | ||
| 358 | static void catc_tx_run(struct catc *catc) | 358 | static int catc_tx_run(struct catc *catc) |
| 359 | { | 359 | { |
| 360 | int status; | 360 | int status; |
| 361 | 361 | ||
| @@ -373,12 +373,14 @@ static void catc_tx_run(struct catc *catc) | |||
| 373 | catc->tx_ptr = 0; | 373 | catc->tx_ptr = 0; |
| 374 | 374 | ||
| 375 | catc->netdev->trans_start = jiffies; | 375 | catc->netdev->trans_start = jiffies; |
| 376 | return status; | ||
| 376 | } | 377 | } |
| 377 | 378 | ||
| 378 | static void catc_tx_done(struct urb *urb) | 379 | static void catc_tx_done(struct urb *urb) |
| 379 | { | 380 | { |
| 380 | struct catc *catc = urb->context; | 381 | struct catc *catc = urb->context; |
| 381 | unsigned long flags; | 382 | unsigned long flags; |
| 383 | int r; | ||
| 382 | 384 | ||
| 383 | if (urb->status == -ECONNRESET) { | 385 | if (urb->status == -ECONNRESET) { |
| 384 | dbg("Tx Reset."); | 386 | dbg("Tx Reset."); |
| @@ -397,10 +399,13 @@ static void catc_tx_done(struct urb *urb) | |||
| 397 | 399 | ||
| 398 | spin_lock_irqsave(&catc->tx_lock, flags); | 400 | spin_lock_irqsave(&catc->tx_lock, flags); |
| 399 | 401 | ||
| 400 | if (catc->tx_ptr) | 402 | if (catc->tx_ptr) { |
| 401 | catc_tx_run(catc); | 403 | r = catc_tx_run(catc); |
| 402 | else | 404 | if (unlikely(r < 0)) |
| 405 | clear_bit(TX_RUNNING, &catc->flags); | ||
| 406 | } else { | ||
| 403 | clear_bit(TX_RUNNING, &catc->flags); | 407 | clear_bit(TX_RUNNING, &catc->flags); |
| 408 | } | ||
| 404 | 409 | ||
| 405 | netif_wake_queue(catc->netdev); | 410 | netif_wake_queue(catc->netdev); |
| 406 | 411 | ||
| @@ -411,6 +416,7 @@ static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
| 411 | { | 416 | { |
| 412 | struct catc *catc = netdev_priv(netdev); | 417 | struct catc *catc = netdev_priv(netdev); |
| 413 | unsigned long flags; | 418 | unsigned long flags; |
| 419 | int r = 0; | ||
| 414 | char *tx_buf; | 420 | char *tx_buf; |
| 415 | 421 | ||
| 416 | spin_lock_irqsave(&catc->tx_lock, flags); | 422 | 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 | skb_copy_from_linear_data(skb, tx_buf + 2, skb->len); | 427 | skb_copy_from_linear_data(skb, tx_buf + 2, skb->len); |
| 422 | catc->tx_ptr += skb->len + 2; | 428 | catc->tx_ptr += skb->len + 2; |
| 423 | 429 | ||
| 424 | if (!test_and_set_bit(TX_RUNNING, &catc->flags)) | 430 | if (!test_and_set_bit(TX_RUNNING, &catc->flags)) { |
| 425 | catc_tx_run(catc); | 431 | r = catc_tx_run(catc); |
| 432 | if (r < 0) | ||
| 433 | clear_bit(TX_RUNNING, &catc->flags); | ||
| 434 | } | ||
| 426 | 435 | ||
| 427 | if ((catc->is_f5u011 && catc->tx_ptr) | 436 | if ((catc->is_f5u011 && catc->tx_ptr) |
| 428 | || (catc->tx_ptr >= ((TX_MAX_BURST - 1) * (PKT_SZ + 2)))) | 437 | || (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 | 439 | ||
| 431 | spin_unlock_irqrestore(&catc->tx_lock, flags); | 440 | spin_unlock_irqrestore(&catc->tx_lock, flags); |
| 432 | 441 | ||
| 433 | catc->stats.tx_bytes += skb->len; | 442 | if (r >= 0) { |
| 434 | catc->stats.tx_packets++; | 443 | catc->stats.tx_bytes += skb->len; |
| 444 | catc->stats.tx_packets++; | ||
| 445 | } | ||
| 435 | 446 | ||
| 436 | dev_kfree_skb(skb); | 447 | dev_kfree_skb(skb); |
| 437 | 448 | ||
