diff options
| author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-08-02 23:25:35 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-08-02 23:25:35 -0400 |
| commit | 90eb29efd0ca9301d80d03ea13662d32436f060e (patch) | |
| tree | 4d019d931c99dc4b91e516ea181aabcbb36528b4 /drivers/usb/net/rtl8150.c | |
| parent | 1398ab7cb92b21d8d5add3bdc25b2c00462cfd5c (diff) | |
| parent | cae74b30dd98c10baa5b47b4698bf67e5eb15687 (diff) | |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (24 commits)
Revert "[PATCH] USB: move usb_device_class class devices to be real devices"
Revert "[PATCH] USB: convert usb class devices to real devices"
USB: UHCI: Don't test the Short Packet Detect bit
USB: unusual_devs entry for Nokia 3250
USB: dummy-hcd: disable interrupts during req->complete
USB: fix the USB_GADGET_DUMMY_HCD dependencies
USB: ati_remote.c: autorepeat fix
USB: doc: fixes devio.c location in proc_usb_info.txt.
USB: doc: usb-help.txt update.
USB: Patch for rtl8150 to fix unplug problems
USB: cypress driver comment updates
USB: unusual_devs device removal
usb-storage: Add US_FL_IGNORE_DEVICE flag; ignore ZyXEL G220F
USB: New USB ID for Belkin Serial Adapter
USB: Additional PID for the ftdi_sio driver
USB: adding support for SHARP WS003SH to ipaq.c
USB: Fix Freescale high-speed USB host dependency
USB: Removed 3-port device handler from Option driver
USB: Drop Sierra Wireless MC8755 from the Option driver
USB: Let option driver handle Anydata CDMA modems. Remove anydata driver.
...
Diffstat (limited to 'drivers/usb/net/rtl8150.c')
| -rw-r--r-- | drivers/usb/net/rtl8150.c | 83 |
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 *); | |||
| 175 | static void rtl8150_disconnect(struct usb_interface *intf); | 175 | static void rtl8150_disconnect(struct usb_interface *intf); |
| 176 | static int rtl8150_probe(struct usb_interface *intf, | 176 | static int rtl8150_probe(struct usb_interface *intf, |
| 177 | const struct usb_device_id *id); | 177 | const struct usb_device_id *id); |
| 178 | static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message); | ||
| 179 | static int rtl8150_resume(struct usb_interface *intf); | ||
| 178 | 180 | ||
| 179 | static const char driver_name [] = "rtl8150"; | 181 | static 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) | |||
| 465 | goon: | 472 | goon: |
| 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); |
| 501 | try_again: | 512 | try_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 | ||
| 575 | resubmit: | 589 | resubmit: |
| 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 | ||
| 599 | static 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 | |||
| 612 | static 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 | } |
