netdev
[Top] [All Lists]

[Patch 1/5 2.5] e100: Fix e100_watchdog to not accidentally re-enable in

To: "jgarzik@xxxxxxxxx" <jgarzik@xxxxxxxxx>
Subject: [Patch 1/5 2.5] e100: Fix e100_watchdog to not accidentally re-enable interrupts when setting the software interrupt bit.
From: Ganesh Venkatesan <ganesh.venkatesan@xxxxxxxxx>
Date: Fri, 15 Oct 2004 06:53:18 -0700 (PDT)
Cc: netdev <netdev@xxxxxxxxxxx>
Replyto: Ganesh Venkatesan <ganesh.venkatesan@xxxxxxxxx>
Sender: netdev-bounce@xxxxxxxxxxx
diff -up netdev-2.6/drivers/net/e100.c netdev-2.6/drivers/net/e100.c.new
--- netdev-2.6/drivers/net/e100.c       2004-10-07 13:58:59.000000000 -0700
+++ netdev-2.6/drivers/net/e100.c.new   2004-10-07 13:59:00.000000000 -0700
@@ -575,13 +575,21 @@ static inline void e100_write_flush(stru
 
 static inline void e100_enable_irq(struct nic *nic)
 {
+       unsigned long flags;
+
+       spin_lock_irqsave(&nic->cmd_lock, flags);
        writeb(irq_mask_none, &nic->csr->scb.cmd_hi);
+       spin_unlock_irqrestore(&nic->cmd_lock, flags);
        e100_write_flush(nic);
 }
 
 static inline void e100_disable_irq(struct nic *nic)
 {
+       unsigned long flags;
+
+       spin_lock_irqsave(&nic->cmd_lock, flags);
        writeb(irq_mask_all, &nic->csr->scb.cmd_hi);
+       spin_unlock_irqrestore(&nic->cmd_lock, flags);
        e100_write_flush(nic);
 }
 
@@ -1254,8 +1262,13 @@ static void e100_watchdog(unsigned long 
        mii_check_link(&nic->mii);
 
        /* Software generated interrupt to recover from (rare) Rx
-        * allocation failure */
-       writeb(irq_sw_gen, &nic->csr->scb.cmd_hi);
+        * allocation failure. 
+        * Unfortunately have to use a spinlock to not re-enable interrupts 
+        * accidentally, due to hardware that shares a register between the 
+        * interrupt mask bit and the SW Interrupt generation bit */
+       spin_lock_irq(&nic->cmd_lock);
+       writeb(readb(&nic->csr->scb.cmd_hi) | irq_sw_gen,&nic->csr->scb.cmd_hi);
+       spin_unlock_irq(&nic->cmd_lock);
        e100_write_flush(nic);
 
        e100_update_stats(nic);



<Prev in Thread] Current Thread [Next in Thread>