aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/net/catc.c27
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
358static void catc_tx_run(struct catc *catc) 358static 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
378static void catc_tx_done(struct urb *urb) 379static 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