diff options
Diffstat (limited to 'drivers/usb/net/catc.c')
-rw-r--r-- | drivers/usb/net/catc.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c index 4852012735f6..86e90c59d551 100644 --- a/drivers/usb/net/catc.c +++ b/drivers/usb/net/catc.c | |||
@@ -255,7 +255,6 @@ static void catc_rx_done(struct urb *urb) | |||
255 | if (!(skb = dev_alloc_skb(pkt_len))) | 255 | if (!(skb = dev_alloc_skb(pkt_len))) |
256 | return; | 256 | return; |
257 | 257 | ||
258 | skb->dev = catc->netdev; | ||
259 | eth_copy_and_sum(skb, pkt_start + pkt_offset, pkt_len, 0); | 258 | eth_copy_and_sum(skb, pkt_start + pkt_offset, pkt_len, 0); |
260 | skb_put(skb, pkt_len); | 259 | skb_put(skb, pkt_len); |
261 | 260 | ||
@@ -356,7 +355,7 @@ resubmit: | |||
356 | * Transmit routines. | 355 | * Transmit routines. |
357 | */ | 356 | */ |
358 | 357 | ||
359 | static void catc_tx_run(struct catc *catc) | 358 | static int catc_tx_run(struct catc *catc) |
360 | { | 359 | { |
361 | int status; | 360 | int status; |
362 | 361 | ||
@@ -374,12 +373,14 @@ static void catc_tx_run(struct catc *catc) | |||
374 | catc->tx_ptr = 0; | 373 | catc->tx_ptr = 0; |
375 | 374 | ||
376 | catc->netdev->trans_start = jiffies; | 375 | catc->netdev->trans_start = jiffies; |
376 | return status; | ||
377 | } | 377 | } |
378 | 378 | ||
379 | static void catc_tx_done(struct urb *urb) | 379 | static void catc_tx_done(struct urb *urb) |
380 | { | 380 | { |
381 | struct catc *catc = urb->context; | 381 | struct catc *catc = urb->context; |
382 | unsigned long flags; | 382 | unsigned long flags; |
383 | int r; | ||
383 | 384 | ||
384 | if (urb->status == -ECONNRESET) { | 385 | if (urb->status == -ECONNRESET) { |
385 | dbg("Tx Reset."); | 386 | dbg("Tx Reset."); |
@@ -398,10 +399,13 @@ static void catc_tx_done(struct urb *urb) | |||
398 | 399 | ||
399 | spin_lock_irqsave(&catc->tx_lock, flags); | 400 | spin_lock_irqsave(&catc->tx_lock, flags); |
400 | 401 | ||
401 | if (catc->tx_ptr) | 402 | if (catc->tx_ptr) { |
402 | catc_tx_run(catc); | 403 | r = catc_tx_run(catc); |
403 | else | 404 | if (unlikely(r < 0)) |
405 | clear_bit(TX_RUNNING, &catc->flags); | ||
406 | } else { | ||
404 | clear_bit(TX_RUNNING, &catc->flags); | 407 | clear_bit(TX_RUNNING, &catc->flags); |
408 | } | ||
405 | 409 | ||
406 | netif_wake_queue(catc->netdev); | 410 | netif_wake_queue(catc->netdev); |
407 | 411 | ||
@@ -412,6 +416,7 @@ static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
412 | { | 416 | { |
413 | struct catc *catc = netdev_priv(netdev); | 417 | struct catc *catc = netdev_priv(netdev); |
414 | unsigned long flags; | 418 | unsigned long flags; |
419 | int r = 0; | ||
415 | char *tx_buf; | 420 | char *tx_buf; |
416 | 421 | ||
417 | spin_lock_irqsave(&catc->tx_lock, flags); | 422 | spin_lock_irqsave(&catc->tx_lock, flags); |
@@ -419,11 +424,14 @@ static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
419 | catc->tx_ptr = (((catc->tx_ptr - 1) >> 6) + 1) << 6; | 424 | catc->tx_ptr = (((catc->tx_ptr - 1) >> 6) + 1) << 6; |
420 | tx_buf = catc->tx_buf[catc->tx_idx] + catc->tx_ptr; | 425 | tx_buf = catc->tx_buf[catc->tx_idx] + catc->tx_ptr; |
421 | *((u16*)tx_buf) = (catc->is_f5u011) ? cpu_to_be16((u16)skb->len) : cpu_to_le16((u16)skb->len); | 426 | *((u16*)tx_buf) = (catc->is_f5u011) ? cpu_to_be16((u16)skb->len) : cpu_to_le16((u16)skb->len); |
422 | memcpy(tx_buf + 2, skb->data, skb->len); | 427 | skb_copy_from_linear_data(skb, tx_buf + 2, skb->len); |
423 | catc->tx_ptr += skb->len + 2; | 428 | catc->tx_ptr += skb->len + 2; |
424 | 429 | ||
425 | if (!test_and_set_bit(TX_RUNNING, &catc->flags)) | 430 | if (!test_and_set_bit(TX_RUNNING, &catc->flags)) { |
426 | catc_tx_run(catc); | 431 | r = catc_tx_run(catc); |
432 | if (r < 0) | ||
433 | clear_bit(TX_RUNNING, &catc->flags); | ||
434 | } | ||
427 | 435 | ||
428 | if ((catc->is_f5u011 && catc->tx_ptr) | 436 | if ((catc->is_f5u011 && catc->tx_ptr) |
429 | || (catc->tx_ptr >= ((TX_MAX_BURST - 1) * (PKT_SZ + 2)))) | 437 | || (catc->tx_ptr >= ((TX_MAX_BURST - 1) * (PKT_SZ + 2)))) |
@@ -431,8 +439,10 @@ static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
431 | 439 | ||
432 | spin_unlock_irqrestore(&catc->tx_lock, flags); | 440 | spin_unlock_irqrestore(&catc->tx_lock, flags); |
433 | 441 | ||
434 | catc->stats.tx_bytes += skb->len; | 442 | if (r >= 0) { |
435 | catc->stats.tx_packets++; | 443 | catc->stats.tx_bytes += skb->len; |
444 | catc->stats.tx_packets++; | ||
445 | } | ||
436 | 446 | ||
437 | dev_kfree_skb(skb); | 447 | dev_kfree_skb(skb); |
438 | 448 | ||