]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/core/netpoll.c
Pull osi into release branch
[linux-2.6-omap-h63xx.git] / net / core / netpoll.c
index cf40ff91ac01da94912ed4ed67ce6b80649bdfbf..de1b26aa5720f011616413d87d852f94d46f9c52 100644 (file)
@@ -66,14 +66,14 @@ static void queue_process(struct work_struct *work)
 
                local_irq_save(flags);
                netif_tx_lock(dev);
-               if (netif_queue_stopped(dev) ||
-                   dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
+               if ((netif_queue_stopped(dev) ||
+                    netif_subqueue_stopped(dev, skb->queue_mapping)) ||
+                    dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
                        skb_queue_head(&npinfo->txq, skb);
                        netif_tx_unlock(dev);
                        local_irq_restore(flags);
 
-                       if (atomic_read(&npinfo->refcnt))
-                               schedule_delayed_work(&npinfo->tx_work, HZ/10);
+                       schedule_delayed_work(&npinfo->tx_work, HZ/10);
                        return;
                }
                netif_tx_unlock(dev);
@@ -255,7 +255,8 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
                for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
                     tries > 0; --tries) {
                        if (netif_tx_trylock(dev)) {
-                               if (!netif_queue_stopped(dev))
+                               if (!netif_queue_stopped(dev) &&
+                                   !netif_subqueue_stopped(dev, skb->queue_mapping))
                                        status = dev->hard_start_xmit(skb, dev);
                                netif_tx_unlock(dev);
 
@@ -782,12 +783,10 @@ void netpoll_cleanup(struct netpoll *np)
                                spin_unlock_irqrestore(&npinfo->rx_lock, flags);
                        }
 
-                       np->dev->npinfo = NULL;
                        if (atomic_dec_and_test(&npinfo->refcnt)) {
                                skb_queue_purge(&npinfo->arp_tx);
                                skb_queue_purge(&npinfo->txq);
-                               cancel_delayed_work(&npinfo->tx_work);
-                               flush_scheduled_work();
+                               cancel_rearming_delayed_work(&npinfo->tx_work);
 
                                /* clean after last, unfinished work */
                                if (!skb_queue_empty(&npinfo->txq)) {
@@ -796,6 +795,7 @@ void netpoll_cleanup(struct netpoll *np)
                                        kfree_skb(skb);
                                }
                                kfree(npinfo);
+                               np->dev->npinfo = NULL;
                        }
                }