diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-13 13:38:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-13 13:38:12 -0400 |
commit | 2f2c779583e9646097b57599f8efeb8eca7bd654 (patch) | |
tree | aa7c88eb4f4deb668cba56e6f1fddd8dcc5006cf /drivers/net/usb/usbnet.c | |
parent | 2897c684d1d5140e0e0302e73660c7cb97981b27 (diff) | |
parent | 3c09e2647b5e1f1f9fd383971468823c2505e1b0 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (30 commits)
ctcm: rename READ/WRITE defines to avoid redefinitions
claw: rename READ/WRITE defines to avoid redefinitions
phylib: available for any speed ethernet
can: add limit for nframes and clean up signed/unsigned variables
pkt_sched: Check .walk and .leaf class handlers
pkt_sched: Fix sch_sfq vs tc_modify_qdisc oops
caif-spi: Bugfix SPI_DATA_POS settings were inverted.
caif: Bugfix - Increase default headroom size for control channel.
net: make netpoll_rx return bool for !CONFIG_NETPOLL
Bluetooth: Use 3-DH5 payload size for default ERTM max PDU size
Bluetooth: Fix incorrect setting of remote_tx_win for L2CAP ERTM
Bluetooth: Change default L2CAP ERTM retransmit timeout
Bluetooth: Fix endianness issue with L2CAP MPS configuration
net: Use NET_XMIT_SUCCESS where possible.
isdn: mISDN: call pci_disable_device() if pci_probe() failed
isdn: avm: call pci_disable_device() if pci_probe() failed
isdn: avm: call pci_disable_device() if pci_probe() failed
usbnet: rx_submit() should return an error code.
pkt_sched: Add some basic qdisc class ops verification. Was: [PATCH] sfq: add dummy bind/unbind handles
pkt_sched: sch_sfq: Add dummy unbind_tcf and put handles. Was: [PATCH] sfq: add dummy bind/unbind handles
...
Diffstat (limited to 'drivers/net/usb/usbnet.c')
-rw-r--r-- | drivers/net/usb/usbnet.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 7f62e2dea28f..ca7fc9df1ccf 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 | ||
316 | static void rx_complete (struct urb *urb); | 316 | static void rx_complete (struct urb *urb); |
317 | 317 | ||
318 | static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) | 318 | static 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); |
927 | fail_lowmem: | 933 | fail_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, |