]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] Fix oopses in fealnx driver TX path
authorJeff Garzik <jgarzik@pobox.com>
Wed, 31 Mar 2004 04:01:25 +0000 (20:01 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Wed, 31 Mar 2004 04:01:25 +0000 (20:01 -0800)
In both uniprocessor and SMP, the fealnx driver's TX-submit path can
race against the interrupt handler, with disastrous results.  Add the
lock that needed to be there all along, to fix this.

There's another problem in the RX path, that will be sent as a separate
patch, as soon as we get that patch 100% nailed down, and acceptable for
a Release Candidate.

drivers/net/fealnx.c

index 251482e8db356372e85827159860e01c698319fd..24b6aa9eec9a12f5ba1d880bb76af41225898206 100644 (file)
@@ -1303,14 +1303,15 @@ static void init_ring(struct net_device *dev)
        /* for the last tx descriptor */
        np->tx_ring[i - 1].next_desc = np->tx_ring_dma;
        np->tx_ring[i - 1].next_desc_logical = &np->tx_ring[0];
-
-       return;
 }
 
 
 static int start_tx(struct sk_buff *skb, struct net_device *dev)
 {
        struct netdev_private *np = dev->priv;
+       unsigned long flags;
+
+       spin_lock_irqsave(&np->lock, flags);
 
        np->cur_tx_copy->skbuff = skb;
 
@@ -1377,6 +1378,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
        writel(0, dev->base_addr + TXPDR);
        dev->trans_start = jiffies;
 
+       spin_unlock_irqrestore(&np->lock, flags);
        return 0;
 }
 
@@ -1423,6 +1425,8 @@ static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs
        unsigned int num_tx = 0;
        int handled = 0;
 
+       spin_lock(&np->lock);
+
        writel(0, dev->base_addr + IMR);
 
        ioaddr = dev->base_addr;
@@ -1565,6 +1569,8 @@ static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs
 
        writel(np->imrvalue, ioaddr + IMR);
 
+       spin_unlock(&np->lock);
+
        return IRQ_RETVAL(handled);
 }