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)  	}  } -void netpoll_poll(struct netpoll *np) +void netpoll_poll_dev(struct net_device *dev)  { -	struct net_device *dev = np->dev;  	const struct net_device_ops *ops;  	if (!dev || !netif_running(dev)) @@ -201,6 +200,11 @@ void netpoll_poll(struct netpoll *np)  	zap_completion_queue();  } +void netpoll_poll(struct netpoll *np) +{ +	netpoll_poll_dev(np->dev); +} +  static void refill_skbs(void)  {  	struct sk_buff *skb; @@ -282,7 +286,7 @@ static int netpoll_owner_active(struct net_device *dev)  	return 0;  } -static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) +void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)  {  	int status = NETDEV_TX_BUSY;  	unsigned long tries; @@ -308,7 +312,9 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)  		     tries > 0; --tries) {  			if (__netif_tx_trylock(txq)) {  				if (!netif_tx_queue_stopped(txq)) { +					dev->priv_flags |= IFF_IN_NETPOLL;  					status = ops->ndo_start_xmit(skb, dev); +					dev->priv_flags &= ~IFF_IN_NETPOLL;  					if (status == NETDEV_TX_OK)  						txq_trans_update(txq);  				} @@ -756,7 +762,10 @@ int netpoll_setup(struct netpoll *np)  		atomic_inc(&npinfo->refcnt);  	} -	if (!ndev->netdev_ops->ndo_poll_controller) { +	npinfo->netpoll = np; + +	if ((ndev->priv_flags & IFF_DISABLE_NETPOLL) || +	    !ndev->netdev_ops->ndo_poll_controller) {  		printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",  		       np->name, np->dev_name);  		err = -ENOTSUPP; @@ -878,6 +887,7 @@ void netpoll_cleanup(struct netpoll *np)  			}  			if (atomic_dec_and_test(&npinfo->refcnt)) { +				const struct net_device_ops *ops;  				skb_queue_purge(&npinfo->arp_tx);  				skb_queue_purge(&npinfo->txq);  				cancel_rearming_delayed_work(&npinfo->tx_work); @@ -885,7 +895,11 @@ void netpoll_cleanup(struct netpoll *np)  				/* clean after last, unfinished work */  				__skb_queue_purge(&npinfo->txq);  				kfree(npinfo); -				np->dev->npinfo = NULL; +				ops = np->dev->netdev_ops; +				if (ops->ndo_netpoll_cleanup) +					ops->ndo_netpoll_cleanup(np->dev); +				else +					np->dev->npinfo = NULL;  			}  		} @@ -908,6 +922,7 @@ void netpoll_set_trap(int trap)  		atomic_dec(&trapped);  } +EXPORT_SYMBOL(netpoll_send_skb);  EXPORT_SYMBOL(netpoll_set_trap);  EXPORT_SYMBOL(netpoll_trap);  EXPORT_SYMBOL(netpoll_print_options); @@ -915,4 +930,5 @@ EXPORT_SYMBOL(netpoll_parse_options);  EXPORT_SYMBOL(netpoll_setup);  EXPORT_SYMBOL(netpoll_cleanup);  EXPORT_SYMBOL(netpoll_send_udp); +EXPORT_SYMBOL(netpoll_poll_dev);  EXPORT_SYMBOL(netpoll_poll);  |