|
@@ -163,6 +163,8 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
|
|
|
|
|
|
/* using ATOMIC, we'd never wake up if we slept */
|
|
|
if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
|
|
|
+ if (ret == -ENODEV)
|
|
|
+ netif_device_detach(pegasus->net);
|
|
|
if (netif_msg_drv(pegasus))
|
|
|
dev_err(&pegasus->intf->dev, "%s, status %d\n",
|
|
|
__FUNCTION__, ret);
|
|
@@ -217,6 +219,8 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
|
|
|
set_current_state(TASK_UNINTERRUPTIBLE);
|
|
|
|
|
|
if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
|
|
|
+ if (ret == -ENODEV)
|
|
|
+ netif_device_detach(pegasus->net);
|
|
|
if (netif_msg_drv(pegasus))
|
|
|
dev_err(&pegasus->intf->dev, "%s, status %d\n",
|
|
|
__FUNCTION__, ret);
|
|
@@ -268,6 +272,8 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data)
|
|
|
set_current_state(TASK_UNINTERRUPTIBLE);
|
|
|
|
|
|
if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
|
|
|
+ if (ret == -ENODEV)
|
|
|
+ netif_device_detach(pegasus->net);
|
|
|
if (netif_msg_drv(pegasus))
|
|
|
dev_err(&pegasus->intf->dev, "%s, status %d\n",
|
|
|
__FUNCTION__, ret);
|
|
@@ -298,10 +304,13 @@ static int update_eth_regs_async(pegasus_t * pegasus)
|
|
|
(char *) &pegasus->dr,
|
|
|
pegasus->eth_regs, 3, ctrl_callback, pegasus);
|
|
|
|
|
|
- if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC)))
|
|
|
+ if ((ret = usb_submit_urb(pegasus->ctrl_urb, GFP_ATOMIC))) {
|
|
|
+ if (ret == -ENODEV)
|
|
|
+ netif_device_detach(pegasus->net);
|
|
|
if (netif_msg_drv(pegasus))
|
|
|
dev_err(&pegasus->intf->dev, "%s, status %d\n",
|
|
|
__FUNCTION__, ret);
|
|
|
+ }
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
@@ -692,7 +701,10 @@ goon:
|
|
|
usb_rcvbulkpipe(pegasus->usb, 1),
|
|
|
pegasus->rx_skb->data, PEGASUS_MTU + 8,
|
|
|
read_bulk_callback, pegasus);
|
|
|
- if (usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) {
|
|
|
+ rx_status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC);
|
|
|
+ if (rx_status == -ENODEV)
|
|
|
+ netif_device_detach(pegasus->net);
|
|
|
+ else if (rx_status) {
|
|
|
pegasus->flags |= PEGASUS_RX_URB_FAIL;
|
|
|
goto tl_sched;
|
|
|
} else {
|
|
@@ -709,6 +721,7 @@ static void rx_fixup(unsigned long data)
|
|
|
{
|
|
|
pegasus_t *pegasus;
|
|
|
unsigned long flags;
|
|
|
+ int status;
|
|
|
|
|
|
pegasus = (pegasus_t *) data;
|
|
|
if (pegasus->flags & PEGASUS_UNPLUG)
|
|
@@ -734,7 +747,10 @@ static void rx_fixup(unsigned long data)
|
|
|
pegasus->rx_skb->data, PEGASUS_MTU + 8,
|
|
|
read_bulk_callback, pegasus);
|
|
|
try_again:
|
|
|
- if (usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) {
|
|
|
+ status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC);
|
|
|
+ if (status == -ENODEV)
|
|
|
+ netif_device_detach(pegasus->net);
|
|
|
+ else if (status) {
|
|
|
pegasus->flags |= PEGASUS_RX_URB_FAIL;
|
|
|
tasklet_schedule(&pegasus->rx_tl);
|
|
|
} else {
|
|
@@ -836,6 +852,8 @@ static void intr_callback(struct urb *urb, struct pt_regs *regs)
|
|
|
}
|
|
|
|
|
|
status = usb_submit_urb(urb, SLAB_ATOMIC);
|
|
|
+ if (status == -ENODEV)
|
|
|
+ netif_device_detach(pegasus->net);
|
|
|
if (status && netif_msg_timer(pegasus))
|
|
|
printk(KERN_ERR "%s: can't resubmit interrupt urb, %d\n",
|
|
|
net->name, status);
|
|
@@ -874,6 +892,7 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
|
|
|
/* cleanup should already have been scheduled */
|
|
|
break;
|
|
|
case -ENODEV: /* disconnect() upcoming */
|
|
|
+ netif_device_detach(pegasus->net);
|
|
|
break;
|
|
|
default:
|
|
|
pegasus->stats.tx_errors++;
|
|
@@ -999,6 +1018,8 @@ static int pegasus_open(struct net_device *net)
|
|
|
pegasus->rx_skb->data, PEGASUS_MTU + 8,
|
|
|
read_bulk_callback, pegasus);
|
|
|
if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) {
|
|
|
+ if (res == -ENODEV)
|
|
|
+ netif_device_detach(pegasus->net);
|
|
|
if (netif_msg_ifup(pegasus))
|
|
|
pr_debug("%s: failed rx_urb, %d", net->name, res);
|
|
|
goto exit;
|
|
@@ -1009,6 +1030,8 @@ static int pegasus_open(struct net_device *net)
|
|
|
pegasus->intr_buff, sizeof (pegasus->intr_buff),
|
|
|
intr_callback, pegasus, pegasus->intr_interval);
|
|
|
if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) {
|
|
|
+ if (res == -ENODEV)
|
|
|
+ netif_device_detach(pegasus->net);
|
|
|
if (netif_msg_ifup(pegasus))
|
|
|
pr_debug("%s: failed intr_urb, %d\n", net->name, res);
|
|
|
usb_kill_urb(pegasus->rx_urb);
|