diff options
Diffstat (limited to 'net/core/netpoll.c')
-rw-r--r-- | net/core/netpoll.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index a58f59b9759..94825b10955 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -179,9 +179,8 @@ static void service_arp_queue(struct netpoll_info *npi) | |||
179 | } | 179 | } |
180 | } | 180 | } |
181 | 181 | ||
182 | void netpoll_poll(struct netpoll *np) | 182 | void netpoll_poll_dev(struct net_device *dev) |
183 | { | 183 | { |
184 | struct net_device *dev = np->dev; | ||
185 | const struct net_device_ops *ops; | 184 | const struct net_device_ops *ops; |
186 | 185 | ||
187 | if (!dev || !netif_running(dev)) | 186 | if (!dev || !netif_running(dev)) |
@@ -201,6 +200,11 @@ void netpoll_poll(struct netpoll *np) | |||
201 | zap_completion_queue(); | 200 | zap_completion_queue(); |
202 | } | 201 | } |
203 | 202 | ||
203 | void netpoll_poll(struct netpoll *np) | ||
204 | { | ||
205 | netpoll_poll_dev(np->dev); | ||
206 | } | ||
207 | |||
204 | static void refill_skbs(void) | 208 | static void refill_skbs(void) |
205 | { | 209 | { |
206 | struct sk_buff *skb; | 210 | struct sk_buff *skb; |
@@ -282,7 +286,7 @@ static int netpoll_owner_active(struct net_device *dev) | |||
282 | return 0; | 286 | return 0; |
283 | } | 287 | } |
284 | 288 | ||
285 | static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) | 289 | void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) |
286 | { | 290 | { |
287 | int status = NETDEV_TX_BUSY; | 291 | int status = NETDEV_TX_BUSY; |
288 | unsigned long tries; | 292 | unsigned long tries; |
@@ -308,7 +312,9 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) | |||
308 | tries > 0; --tries) { | 312 | tries > 0; --tries) { |
309 | if (__netif_tx_trylock(txq)) { | 313 | if (__netif_tx_trylock(txq)) { |
310 | if (!netif_tx_queue_stopped(txq)) { | 314 | if (!netif_tx_queue_stopped(txq)) { |
315 | dev->priv_flags |= IFF_IN_NETPOLL; | ||
311 | status = ops->ndo_start_xmit(skb, dev); | 316 | status = ops->ndo_start_xmit(skb, dev); |
317 | dev->priv_flags &= ~IFF_IN_NETPOLL; | ||
312 | if (status == NETDEV_TX_OK) | 318 | if (status == NETDEV_TX_OK) |
313 | txq_trans_update(txq); | 319 | txq_trans_update(txq); |
314 | } | 320 | } |
@@ -756,7 +762,10 @@ int netpoll_setup(struct netpoll *np) | |||
756 | atomic_inc(&npinfo->refcnt); | 762 | atomic_inc(&npinfo->refcnt); |
757 | } | 763 | } |
758 | 764 | ||
759 | if (!ndev->netdev_ops->ndo_poll_controller) { | 765 | npinfo->netpoll = np; |
766 | |||
767 | if ((ndev->priv_flags & IFF_DISABLE_NETPOLL) || | ||
768 | !ndev->netdev_ops->ndo_poll_controller) { | ||
760 | printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n", | 769 | printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n", |
761 | np->name, np->dev_name); | 770 | np->name, np->dev_name); |
762 | err = -ENOTSUPP; | 771 | err = -ENOTSUPP; |
@@ -878,6 +887,7 @@ void netpoll_cleanup(struct netpoll *np) | |||
878 | } | 887 | } |
879 | 888 | ||
880 | if (atomic_dec_and_test(&npinfo->refcnt)) { | 889 | if (atomic_dec_and_test(&npinfo->refcnt)) { |
890 | const struct net_device_ops *ops; | ||
881 | skb_queue_purge(&npinfo->arp_tx); | 891 | skb_queue_purge(&npinfo->arp_tx); |
882 | skb_queue_purge(&npinfo->txq); | 892 | skb_queue_purge(&npinfo->txq); |
883 | cancel_rearming_delayed_work(&npinfo->tx_work); | 893 | cancel_rearming_delayed_work(&npinfo->tx_work); |
@@ -885,7 +895,11 @@ void netpoll_cleanup(struct netpoll *np) | |||
885 | /* clean after last, unfinished work */ | 895 | /* clean after last, unfinished work */ |
886 | __skb_queue_purge(&npinfo->txq); | 896 | __skb_queue_purge(&npinfo->txq); |
887 | kfree(npinfo); | 897 | kfree(npinfo); |
888 | np->dev->npinfo = NULL; | 898 | ops = np->dev->netdev_ops; |
899 | if (ops->ndo_netpoll_cleanup) | ||
900 | ops->ndo_netpoll_cleanup(np->dev); | ||
901 | else | ||
902 | np->dev->npinfo = NULL; | ||
889 | } | 903 | } |
890 | } | 904 | } |
891 | 905 | ||
@@ -908,6 +922,7 @@ void netpoll_set_trap(int trap) | |||
908 | atomic_dec(&trapped); | 922 | atomic_dec(&trapped); |
909 | } | 923 | } |
910 | 924 | ||
925 | EXPORT_SYMBOL(netpoll_send_skb); | ||
911 | EXPORT_SYMBOL(netpoll_set_trap); | 926 | EXPORT_SYMBOL(netpoll_set_trap); |
912 | EXPORT_SYMBOL(netpoll_trap); | 927 | EXPORT_SYMBOL(netpoll_trap); |
913 | EXPORT_SYMBOL(netpoll_print_options); | 928 | EXPORT_SYMBOL(netpoll_print_options); |
@@ -915,4 +930,5 @@ EXPORT_SYMBOL(netpoll_parse_options); | |||
915 | EXPORT_SYMBOL(netpoll_setup); | 930 | EXPORT_SYMBOL(netpoll_setup); |
916 | EXPORT_SYMBOL(netpoll_cleanup); | 931 | EXPORT_SYMBOL(netpoll_cleanup); |
917 | EXPORT_SYMBOL(netpoll_send_udp); | 932 | EXPORT_SYMBOL(netpoll_send_udp); |
933 | EXPORT_SYMBOL(netpoll_poll_dev); | ||
918 | EXPORT_SYMBOL(netpoll_poll); | 934 | EXPORT_SYMBOL(netpoll_poll); |