diff options
Diffstat (limited to 'drivers/usb/net/pegasus.c')
| -rw-r--r-- | drivers/usb/net/pegasus.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 7683926a1b6f..ab21f960d255 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c | |||
| @@ -163,6 +163,8 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size, | |||
| 163 | 163 | ||
| 164 | /* using ATOMIC, we'd never wake up if we slept */ | 164 | /* using ATOMIC, we'd never wake up if we slept */ |
| 165 | if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { | 165 | if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { |
| 166 | if (ret == -ENODEV) | ||
| 167 | netif_device_detach(pegasus->net); | ||
| 166 | if (netif_msg_drv(pegasus)) | 168 | if (netif_msg_drv(pegasus)) |
| 167 | dev_err(&pegasus->intf->dev, "%s, status %d\n", | 169 | dev_err(&pegasus->intf->dev, "%s, status %d\n", |
| 168 | __FUNCTION__, ret); | 170 | __FUNCTION__, ret); |
| @@ -217,6 +219,8 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size, | |||
| 217 | set_current_state(TASK_UNINTERRUPTIBLE); | 219 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 218 | 220 | ||
| 219 | if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { | 221 | if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { |
| 222 | if (ret == -ENODEV) | ||
| 223 | netif_device_detach(pegasus->net); | ||
| 220 | if (netif_msg_drv(pegasus)) | 224 | if (netif_msg_drv(pegasus)) |
| 221 | dev_err(&pegasus->intf->dev, "%s, status %d\n", | 225 | dev_err(&pegasus->intf->dev, "%s, status %d\n", |
| 222 | __FUNCTION__, ret); | 226 | __FUNCTION__, ret); |
| @@ -268,6 +272,8 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) | |||
| 268 | set_current_state(TASK_UNINTERRUPTIBLE); | 272 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 269 | 273 | ||
| 270 | if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { | 274 | if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { |
| 275 | if (ret == -ENODEV) | ||
| 276 | netif_device_detach(pegasus->net); | ||
| 271 | if (netif_msg_drv(pegasus)) | 277 | if (netif_msg_drv(pegasus)) |
| 272 | dev_err(&pegasus->intf->dev, "%s, status %d\n", | 278 | dev_err(&pegasus->intf->dev, "%s, status %d\n", |
| 273 | __FUNCTION__, ret); | 279 | __FUNCTION__, ret); |
| @@ -298,10 +304,13 @@ static int update_eth_regs_async(pegasus_t * pegasus) | |||
| 298 | (char *) &pegasus->dr, | 304 | (char *) &pegasus->dr, |
| 299 | pegasus->eth_regs, 3, ctrl_callback, pegasus); | 305 | pegasus->eth_regs, 3, ctrl_callback, pegasus); |
| 300 | 306 | ||
| 301 | if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) | 307 | if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) { |
| 308 | if (ret == -ENODEV) | ||
| 309 | netif_device_detach(pegasus->net); | ||
| 302 | if (netif_msg_drv(pegasus)) | 310 | if (netif_msg_drv(pegasus)) |
| 303 | dev_err(&pegasus->intf->dev, "%s, status %d\n", | 311 | dev_err(&pegasus->intf->dev, "%s, status %d\n", |
| 304 | __FUNCTION__, ret); | 312 | __FUNCTION__, ret); |
| 313 | } | ||
| 305 | 314 | ||
| 306 | return ret; | 315 | return ret; |
| 307 | } | 316 | } |
| @@ -692,7 +701,10 @@ goon: | |||
| 692 | usb_rcvbulkpipe(pegasus->usb, 1), | 701 | usb_rcvbulkpipe(pegasus->usb, 1), |
| 693 | pegasus->rx_skb->data, PEGASUS_MTU + 8, | 702 | pegasus->rx_skb->data, PEGASUS_MTU + 8, |
| 694 | read_bulk_callback, pegasus); | 703 | read_bulk_callback, pegasus); |
| 695 | if (usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) { | 704 | rx_status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); |
| 705 | if (rx_status == -ENODEV) | ||
| 706 | netif_device_detach(pegasus->net); | ||
| 707 | else if (rx_status) { | ||
| 696 | pegasus->flags |= PEGASUS_RX_URB_FAIL; | 708 | pegasus->flags |= PEGASUS_RX_URB_FAIL; |
| 697 | goto tl_sched; | 709 | goto tl_sched; |
| 698 | } else { | 710 | } else { |
| @@ -709,6 +721,7 @@ static void rx_fixup(unsigned long data) | |||
| 709 | { | 721 | { |
| 710 | pegasus_t *pegasus; | 722 | pegasus_t *pegasus; |
| 711 | unsigned long flags; | 723 | unsigned long flags; |
| 724 | int status; | ||
| 712 | 725 | ||
| 713 | pegasus = (pegasus_t *) data; | 726 | pegasus = (pegasus_t *) data; |
| 714 | if (pegasus->flags & PEGASUS_UNPLUG) | 727 | if (pegasus->flags & PEGASUS_UNPLUG) |
| @@ -734,7 +747,10 @@ static void rx_fixup(unsigned long data) | |||
| 734 | pegasus->rx_skb->data, PEGASUS_MTU + 8, | 747 | pegasus->rx_skb->data, PEGASUS_MTU + 8, |
| 735 | read_bulk_callback, pegasus); | 748 | read_bulk_callback, pegasus); |
| 736 | try_again: | 749 | try_again: |
| 737 | if (usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) { | 750 | status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); |
| 751 | if (status == -ENODEV) | ||
| 752 | netif_device_detach(pegasus->net); | ||
| 753 | else if (status) { | ||
| 738 | pegasus->flags |= PEGASUS_RX_URB_FAIL; | 754 | pegasus->flags |= PEGASUS_RX_URB_FAIL; |
| 739 | tasklet_schedule(&pegasus->rx_tl); | 755 | tasklet_schedule(&pegasus->rx_tl); |
| 740 | } else { | 756 | } else { |
| @@ -836,6 +852,8 @@ static void intr_callback(struct urb *urb, struct pt_regs *regs) | |||
| 836 | } | 852 | } |
| 837 | 853 | ||
| 838 | status = usb_submit_urb(urb, SLAB_ATOMIC); | 854 | status = usb_submit_urb(urb, SLAB_ATOMIC); |
| 855 | if (status == -ENODEV) | ||
| 856 | netif_device_detach(pegasus->net); | ||
| 839 | if (status && netif_msg_timer(pegasus)) | 857 | if (status && netif_msg_timer(pegasus)) |
| 840 | printk(KERN_ERR "%s: can't resubmit interrupt urb, %d\n", | 858 | printk(KERN_ERR "%s: can't resubmit interrupt urb, %d\n", |
| 841 | net->name, status); | 859 | net->name, status); |
| @@ -874,6 +892,7 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net) | |||
| 874 | /* cleanup should already have been scheduled */ | 892 | /* cleanup should already have been scheduled */ |
| 875 | break; | 893 | break; |
| 876 | case -ENODEV: /* disconnect() upcoming */ | 894 | case -ENODEV: /* disconnect() upcoming */ |
| 895 | netif_device_detach(pegasus->net); | ||
| 877 | break; | 896 | break; |
| 878 | default: | 897 | default: |
| 879 | pegasus->stats.tx_errors++; | 898 | pegasus->stats.tx_errors++; |
| @@ -999,6 +1018,8 @@ static int pegasus_open(struct net_device *net) | |||
| 999 | pegasus->rx_skb->data, PEGASUS_MTU + 8, | 1018 | pegasus->rx_skb->data, PEGASUS_MTU + 8, |
| 1000 | read_bulk_callback, pegasus); | 1019 | read_bulk_callback, pegasus); |
| 1001 | if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) { | 1020 | if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) { |
| 1021 | if (res == -ENODEV) | ||
| 1022 | netif_device_detach(pegasus->net); | ||
| 1002 | if (netif_msg_ifup(pegasus)) | 1023 | if (netif_msg_ifup(pegasus)) |
| 1003 | pr_debug("%s: failed rx_urb, %d", net->name, res); | 1024 | pr_debug("%s: failed rx_urb, %d", net->name, res); |
| 1004 | goto exit; | 1025 | goto exit; |
| @@ -1009,6 +1030,8 @@ static int pegasus_open(struct net_device *net) | |||
| 1009 | pegasus->intr_buff, sizeof (pegasus->intr_buff), | 1030 | pegasus->intr_buff, sizeof (pegasus->intr_buff), |
| 1010 | intr_callback, pegasus, pegasus->intr_interval); | 1031 | intr_callback, pegasus, pegasus->intr_interval); |
| 1011 | if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) { | 1032 | if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) { |
| 1033 | if (res == -ENODEV) | ||
| 1034 | netif_device_detach(pegasus->net); | ||
| 1012 | if (netif_msg_ifup(pegasus)) | 1035 | if (netif_msg_ifup(pegasus)) |
| 1013 | pr_debug("%s: failed intr_urb, %d\n", net->name, res); | 1036 | pr_debug("%s: failed intr_urb, %d\n", net->name, res); |
| 1014 | usb_kill_urb(pegasus->rx_urb); | 1037 | usb_kill_urb(pegasus->rx_urb); |
