aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/net/rtl8150.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/net/rtl8150.c')
-rw-r--r--drivers/usb/net/rtl8150.c83
1 files changed, 71 insertions, 12 deletions
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c
index e5e6e4f3ef87..bd09232ce13c 100644
--- a/drivers/usb/net/rtl8150.c
+++ b/drivers/usb/net/rtl8150.c
@@ -175,6 +175,8 @@ static inline struct sk_buff *pull_skb(rtl8150_t *);
175static void rtl8150_disconnect(struct usb_interface *intf); 175static void rtl8150_disconnect(struct usb_interface *intf);
176static int rtl8150_probe(struct usb_interface *intf, 176static int rtl8150_probe(struct usb_interface *intf,
177 const struct usb_device_id *id); 177 const struct usb_device_id *id);
178static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message);
179static int rtl8150_resume(struct usb_interface *intf);
178 180
179static const char driver_name [] = "rtl8150"; 181static const char driver_name [] = "rtl8150";
180 182
@@ -183,6 +185,8 @@ static struct usb_driver rtl8150_driver = {
183 .probe = rtl8150_probe, 185 .probe = rtl8150_probe,
184 .disconnect = rtl8150_disconnect, 186 .disconnect = rtl8150_disconnect,
185 .id_table = rtl8150_table, 187 .id_table = rtl8150_table,
188 .suspend = rtl8150_suspend,
189 .resume = rtl8150_resume
186}; 190};
187 191
188/* 192/*
@@ -238,9 +242,11 @@ static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size)
238 usb_fill_control_urb(dev->ctrl_urb, dev->udev, 242 usb_fill_control_urb(dev->ctrl_urb, dev->udev,
239 usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr, 243 usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr,
240 &dev->rx_creg, size, ctrl_callback, dev); 244 &dev->rx_creg, size, ctrl_callback, dev);
241 if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) 245 if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) {
246 if (ret == -ENODEV)
247 netif_device_detach(dev->netdev);
242 err("control request submission failed: %d", ret); 248 err("control request submission failed: %d", ret);
243 else 249 } else
244 set_bit(RX_REG_SET, &dev->flags); 250 set_bit(RX_REG_SET, &dev->flags);
245 251
246 return ret; 252 return ret;
@@ -416,6 +422,7 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
416 struct sk_buff *skb; 422 struct sk_buff *skb;
417 struct net_device *netdev; 423 struct net_device *netdev;
418 u16 rx_stat; 424 u16 rx_stat;
425 int status;
419 426
420 dev = urb->context; 427 dev = urb->context;
421 if (!dev) 428 if (!dev)
@@ -465,7 +472,10 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
465goon: 472goon:
466 usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), 473 usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
467 dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); 474 dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
468 if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) { 475 status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
476 if (status == -ENODEV)
477 netif_device_detach(dev->netdev);
478 else if (status) {
469 set_bit(RX_URB_FAIL, &dev->flags); 479 set_bit(RX_URB_FAIL, &dev->flags);
470 goto resched; 480 goto resched;
471 } else { 481 } else {
@@ -481,6 +491,7 @@ static void rx_fixup(unsigned long data)
481{ 491{
482 rtl8150_t *dev; 492 rtl8150_t *dev;
483 struct sk_buff *skb; 493 struct sk_buff *skb;
494 int status;
484 495
485 dev = (rtl8150_t *)data; 496 dev = (rtl8150_t *)data;
486 497
@@ -499,10 +510,13 @@ static void rx_fixup(unsigned long data)
499 usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), 510 usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
500 dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); 511 dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
501try_again: 512try_again:
502 if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) { 513 status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC);
514 if (status == -ENODEV) {
515 netif_device_detach(dev->netdev);
516 } else if (status) {
503 set_bit(RX_URB_FAIL, &dev->flags); 517 set_bit(RX_URB_FAIL, &dev->flags);
504 goto tlsched; 518 goto tlsched;
505 } else { 519 } else {
506 clear_bit(RX_URB_FAIL, &dev->flags); 520 clear_bit(RX_URB_FAIL, &dev->flags);
507 } 521 }
508 522
@@ -574,12 +588,43 @@ static void intr_callback(struct urb *urb, struct pt_regs *regs)
574 588
575resubmit: 589resubmit:
576 status = usb_submit_urb (urb, SLAB_ATOMIC); 590 status = usb_submit_urb (urb, SLAB_ATOMIC);
577 if (status) 591 if (status == -ENODEV)
592 netif_device_detach(dev->netdev);
593 else if (status)
578 err ("can't resubmit intr, %s-%s/input0, status %d", 594 err ("can't resubmit intr, %s-%s/input0, status %d",
579 dev->udev->bus->bus_name, 595 dev->udev->bus->bus_name,
580 dev->udev->devpath, status); 596 dev->udev->devpath, status);
581} 597}
582 598
599static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message)
600{
601 rtl8150_t *dev = usb_get_intfdata(intf);
602
603 netif_device_detach(dev->netdev);
604
605 if (netif_running(dev->netdev)) {
606 usb_kill_urb(dev->rx_urb);
607 usb_kill_urb(dev->intr_urb);
608 }
609 return 0;
610}
611
612static int rtl8150_resume(struct usb_interface *intf)
613{
614 rtl8150_t *dev = usb_get_intfdata(intf);
615
616 netif_device_attach(dev->netdev);
617 if (netif_running(dev->netdev)) {
618 dev->rx_urb->status = 0;
619 dev->rx_urb->actual_length = 0;
620 read_bulk_callback(dev->rx_urb, NULL);
621
622 dev->intr_urb->status = 0;
623 dev->intr_urb->actual_length = 0;
624 intr_callback(dev->intr_urb, NULL);
625 }
626 return 0;
627}
583 628
584/* 629/*
585** 630**
@@ -690,9 +735,14 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev)
690 usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), 735 usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2),
691 skb->data, count, write_bulk_callback, dev); 736 skb->data, count, write_bulk_callback, dev);
692 if ((res = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))) { 737 if ((res = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))) {
693 warn("failed tx_urb %d\n", res); 738 /* Can we get/handle EPIPE here? */
694 dev->stats.tx_errors++; 739 if (res == -ENODEV)
695 netif_start_queue(netdev); 740 netif_device_detach(dev->netdev);
741 else {
742 warn("failed tx_urb %d\n", res);
743 dev->stats.tx_errors++;
744 netif_start_queue(netdev);
745 }
696 } else { 746 } else {
697 dev->stats.tx_packets++; 747 dev->stats.tx_packets++;
698 dev->stats.tx_bytes += skb->len; 748 dev->stats.tx_bytes += skb->len;
@@ -729,16 +779,25 @@ static int rtl8150_open(struct net_device *netdev)
729 779
730 usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), 780 usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
731 dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); 781 dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev);
732 if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) 782 if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) {
783 if (res == -ENODEV)
784 netif_device_detach(dev->netdev);
733 warn("%s: rx_urb submit failed: %d", __FUNCTION__, res); 785 warn("%s: rx_urb submit failed: %d", __FUNCTION__, res);
786 return res;
787 }
734 usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3), 788 usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3),
735 dev->intr_buff, INTBUFSIZE, intr_callback, 789 dev->intr_buff, INTBUFSIZE, intr_callback,
736 dev, dev->intr_interval); 790 dev, dev->intr_interval);
737 if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) 791 if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) {
792 if (res == -ENODEV)
793 netif_device_detach(dev->netdev);
738 warn("%s: intr_urb submit failed: %d", __FUNCTION__, res); 794 warn("%s: intr_urb submit failed: %d", __FUNCTION__, res);
739 netif_start_queue(netdev); 795 usb_kill_urb(dev->rx_urb);
796 return res;
797 }
740 enable_net_traffic(dev); 798 enable_net_traffic(dev);
741 set_carrier(netdev); 799 set_carrier(netdev);
800 netif_start_queue(netdev);
742 801
743 return res; 802 return res;
744} 803}