aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-08-10 05:50:55 -0400
committerDavid S. Miller <davem@davemloft.net>2010-08-10 05:50:55 -0400
commitdacb397511289154a68dea1f4bd674c660161c23 (patch)
treead82840c1acd2f8e88d828cf8b8d819f1ca64f6f /drivers/net/usb
parent68fd26b59856b466edd14d8a90d01255983cd3ee (diff)
usbnet: rx_submit() should return an error code.
This patch makes rx_submit() return an error code, and makes some call sites that care check the return value. This is important because it lets us properly handle cases where the device isn't ready to handle URB submissions (e.g., when it is autosuspended under some drivers); previously, we would attempt and fail to submit URBs and reschedule ourselves to try and fail again. This patch is against Linus's 2.6 repo commit 45d7f32c7a43cbb9592886d38190e379e2eb2226. Signed-Off-By: Elizabeth Jones <ellyjones@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb')
-rw-r--r--drivers/net/usb/usbnet.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 7f62e2dea28..ca7fc9df1cc 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -315,7 +315,7 @@ EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
315 315
316static void rx_complete (struct urb *urb); 316static void rx_complete (struct urb *urb);
317 317
318static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) 318static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
319{ 319{
320 struct sk_buff *skb; 320 struct sk_buff *skb;
321 struct skb_data *entry; 321 struct skb_data *entry;
@@ -327,7 +327,7 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
327 netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); 327 netif_dbg(dev, rx_err, dev->net, "no rx skb\n");
328 usbnet_defer_kevent (dev, EVENT_RX_MEMORY); 328 usbnet_defer_kevent (dev, EVENT_RX_MEMORY);
329 usb_free_urb (urb); 329 usb_free_urb (urb);
330 return; 330 return -ENOMEM;
331 } 331 }
332 skb_reserve (skb, NET_IP_ALIGN); 332 skb_reserve (skb, NET_IP_ALIGN);
333 333
@@ -357,6 +357,9 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
357 netif_dbg(dev, ifdown, dev->net, "device gone\n"); 357 netif_dbg(dev, ifdown, dev->net, "device gone\n");
358 netif_device_detach (dev->net); 358 netif_device_detach (dev->net);
359 break; 359 break;
360 case -EHOSTUNREACH:
361 retval = -ENOLINK;
362 break;
360 default: 363 default:
361 netif_dbg(dev, rx_err, dev->net, 364 netif_dbg(dev, rx_err, dev->net,
362 "rx submit, %d\n", retval); 365 "rx submit, %d\n", retval);
@@ -374,6 +377,7 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
374 dev_kfree_skb_any (skb); 377 dev_kfree_skb_any (skb);
375 usb_free_urb (urb); 378 usb_free_urb (urb);
376 } 379 }
380 return retval;
377} 381}
378 382
379 383
@@ -912,6 +916,7 @@ fail_halt:
912 /* tasklet could resubmit itself forever if memory is tight */ 916 /* tasklet could resubmit itself forever if memory is tight */
913 if (test_bit (EVENT_RX_MEMORY, &dev->flags)) { 917 if (test_bit (EVENT_RX_MEMORY, &dev->flags)) {
914 struct urb *urb = NULL; 918 struct urb *urb = NULL;
919 int resched = 1;
915 920
916 if (netif_running (dev->net)) 921 if (netif_running (dev->net))
917 urb = usb_alloc_urb (0, GFP_KERNEL); 922 urb = usb_alloc_urb (0, GFP_KERNEL);
@@ -922,10 +927,12 @@ fail_halt:
922 status = usb_autopm_get_interface(dev->intf); 927 status = usb_autopm_get_interface(dev->intf);
923 if (status < 0) 928 if (status < 0)
924 goto fail_lowmem; 929 goto fail_lowmem;
925 rx_submit (dev, urb, GFP_KERNEL); 930 if (rx_submit (dev, urb, GFP_KERNEL) == -ENOLINK)
931 resched = 0;
926 usb_autopm_put_interface(dev->intf); 932 usb_autopm_put_interface(dev->intf);
927fail_lowmem: 933fail_lowmem:
928 tasklet_schedule (&dev->bh); 934 if (resched)
935 tasklet_schedule (&dev->bh);
929 } 936 }
930 } 937 }
931 938
@@ -1175,8 +1182,11 @@ static void usbnet_bh (unsigned long param)
1175 // don't refill the queue all at once 1182 // don't refill the queue all at once
1176 for (i = 0; i < 10 && dev->rxq.qlen < qlen; i++) { 1183 for (i = 0; i < 10 && dev->rxq.qlen < qlen; i++) {
1177 urb = usb_alloc_urb (0, GFP_ATOMIC); 1184 urb = usb_alloc_urb (0, GFP_ATOMIC);
1178 if (urb != NULL) 1185 if (urb != NULL) {
1179 rx_submit (dev, urb, GFP_ATOMIC); 1186 if (rx_submit (dev, urb, GFP_ATOMIC) ==
1187 -ENOLINK)
1188 return;
1189 }
1180 } 1190 }
1181 if (temp != dev->rxq.qlen) 1191 if (temp != dev->rxq.qlen)
1182 netif_dbg(dev, link, dev->net, 1192 netif_dbg(dev, link, dev->net,