aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/lib8390.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-30 16:38:05 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-30 16:38:05 -0700
commitcbdd3deb52ac9b013a63e4a60530717f75ce3177 (patch)
tree50fb6c194616cbbea2e8f3392b90223780c0714d /drivers/net/lib8390.c
parent4dcf39c6cc5f9f01c46aa71fe95cae9927edeeab (diff)
parentc196d80f994ef4ffefd5a7c62e3f42bd75d538bc (diff)
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: Fix a potential NULL pointer dereference in mace_interrupt() in drivers/net/pcmcia/nmclan_cs.c PATCH kernel 2.6.22] PCMCIA-NETDEV : modify smc91c92_cs.c to become SMP safe S2io: Increment received packet count correctly S2io: Fix crash when resetting adapter S2io: Mask spurious interrupts S2IO: Implementing review comments from old patches S2IO: Checking for the return value of pci map function S2IO: Removing MSI support from driver S2IO: Removing 3 buffer mode support from the driver netxen: drop redudant spinlock netxen: Fix interrupt handling for multiport adapters netxen: re-init station address after h/w init tulip: Remove tulip maintainer forcedeth: mac address correct gfar: Fix modpost warning lib8390: comment on locking by Alan Cox Fix a potential NULL pointer dereference in write_bulk_callback() in drivers/net/usb/pegasus.c
Diffstat (limited to 'drivers/net/lib8390.c')
-rw-r--r--drivers/net/lib8390.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/net/lib8390.c b/drivers/net/lib8390.c
index 721ee38d224..c429a5002dd 100644
--- a/drivers/net/lib8390.c
+++ b/drivers/net/lib8390.c
@@ -143,6 +143,52 @@ static void __NS8390_init(struct net_device *dev, int startp);
* annoying the transmit function is called bh atomic. That places
* restrictions on the user context callers as disable_irq won't save
* them.
+ *
+ * Additional explanation of problems with locking by Alan Cox:
+ *
+ * "The author (me) didn't use spin_lock_irqsave because the slowness of the
+ * card means that approach caused horrible problems like losing serial data
+ * at 38400 baud on some chips. Rememeber many 8390 nics on PCI were ISA
+ * chips with FPGA front ends.
+ *
+ * Ok the logic behind the 8390 is very simple:
+ *
+ * Things to know
+ * - IRQ delivery is asynchronous to the PCI bus
+ * - Blocking the local CPU IRQ via spin locks was too slow
+ * - The chip has register windows needing locking work
+ *
+ * So the path was once (I say once as people appear to have changed it
+ * in the mean time and it now looks rather bogus if the changes to use
+ * disable_irq_nosync_irqsave are disabling the local IRQ)
+ *
+ *
+ * Take the page lock
+ * Mask the IRQ on chip
+ * Disable the IRQ (but not mask locally- someone seems to have
+ * broken this with the lock validator stuff)
+ * [This must be _nosync as the page lock may otherwise
+ * deadlock us]
+ * Drop the page lock and turn IRQs back on
+ *
+ * At this point an existing IRQ may still be running but we can't
+ * get a new one
+ *
+ * Take the lock (so we know the IRQ has terminated) but don't mask
+ * the IRQs on the processor
+ * Set irqlock [for debug]
+ *
+ * Transmit (slow as ****)
+ *
+ * re-enable the IRQ
+ *
+ *
+ * We have to use disable_irq because otherwise you will get delayed
+ * interrupts on the APIC bus deadlocking the transmit path.
+ *
+ * Quite hairy but the chip simply wasn't designed for SMP and you can't
+ * even ACK an interrupt without risking corrupting other parallel
+ * activities on the chip." [lkml, 25 Jul 2007]
*/