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 | ||