diff options
-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); |