patch-2.1.132 linux/drivers/net/3c509.c
Next file: linux/drivers/net/3c515.c
Previous file: linux/drivers/net/3c505.c
Back to the patch index
Back to the overall index
- Lines: 95
- Date:
Thu Dec 17 09:03:57 1998
- Orig file:
v2.1.131/linux/drivers/net/3c509.c
- Orig date:
Sun Nov 8 14:02:59 1998
diff -u --recursive --new-file v2.1.131/linux/drivers/net/3c509.c linux/drivers/net/3c509.c
@@ -63,6 +63,7 @@
#include <asm/spinlock.h>
#include <asm/bitops.h>
#include <asm/io.h>
+#include <asm/irq.h>
#ifdef EL3_DEBUG
int el3_debug = EL3_DEBUG;
@@ -407,7 +408,7 @@
/* Set the spinlock before grabbing IRQ! */
((struct el3_private *)dev->priv)->lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
- if (request_irq(dev->irq, &el3_interrupt, 0, "3c509", dev)) {
+ if (request_irq(dev->irq, &el3_interrupt, 0, dev->name, dev)) {
return -EAGAIN;
}
@@ -526,10 +527,21 @@
if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
- unsigned long flags;
-
- /* Spin on the lock, until we're clear of an IRQ */
- spin_lock_irqsave(&lp->lock, flags);
+ /*
+ * We lock the driver against other processors. Note
+ * we don't need to lock versus the IRQ as we suspended
+ * that. This means that we lose the ability to take
+ * an RX during a TX upload. That sucks a bit with SMP
+ * on an original 3c509 (2K buffer)
+ *
+ * Using disable_irq stops us crapping on other
+ * time sensitive devices.
+ */
+
+#ifdef __SMP__
+ disable_irq(dev->irq);
+ spin_lock(&lp->lock);
+#endif
/* Put out the doubleword header... */
outw(skb->len, ioaddr + TX_FIFO);
@@ -547,8 +559,10 @@
} else
/* Interrupt us when the FIFO has room for max-sized packet. */
outw(SetTxThreshold + 1536, ioaddr + EL3_CMD);
-
- spin_unlock_irqrestore(&lp->lock, flags);
+#ifdef __SMP__
+ spin_unlock(&lp->lock);
+ enable_irq(dev->irq);
+#endif
}
dev_kfree_skb (skb);
@@ -658,10 +672,14 @@
struct el3_private *lp = (struct el3_private *)dev->priv;
unsigned long flags;
- save_flags(flags);
- cli();
+ /*
+ * This is fast enough not to bother with disable IRQ
+ * stuff.
+ */
+
+ spin_lock_irqsave(&lp->lock, flags);
update_stats(dev);
- restore_flags(flags);
+ spin_unlock_irqrestore(&lp->lock, flags);
return &lp->stats;
}
@@ -683,13 +701,13 @@
EL3WINDOW(6);
lp->stats.tx_carrier_errors += inb(ioaddr + 0);
lp->stats.tx_heartbeat_errors += inb(ioaddr + 1);
- /* Multiple collisions. */ inb(ioaddr + 2);
- lp->stats.collisions += inb(ioaddr + 3);
- lp->stats.tx_window_errors += inb(ioaddr + 4);
- lp->stats.rx_fifo_errors += inb(ioaddr + 5);
- lp->stats.tx_packets += inb(ioaddr + 6);
- /* Rx packets */ inb(ioaddr + 7);
- /* Tx deferrals */ inb(ioaddr + 8);
+ /* Multiple collisions. */ inb(ioaddr + 2);
+ lp->stats.collisions += inb(ioaddr + 3);
+ lp->stats.tx_window_errors += inb(ioaddr + 4);
+ lp->stats.rx_fifo_errors += inb(ioaddr + 5);
+ lp->stats.tx_packets += inb(ioaddr + 6);
+ /* Rx packets */ inb(ioaddr + 7);
+ /* Tx deferrals */ inb(ioaddr + 8);
inw(ioaddr + 10); /* Total Rx and Tx octets. */
inw(ioaddr + 12);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov