ACPI: register ACPI Processor as generic thermal cooling device
[safe/jmp/linux-2.6] / drivers / net / lib8390.c
index e726c06..c429a50 100644 (file)
@@ -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]
  */
 
 
@@ -219,15 +265,6 @@ static void ei_tx_timeout(struct net_device *dev)
        int txsr, isr, tickssofar = jiffies - dev->trans_start;
        unsigned long flags;
 
-#if defined(CONFIG_M32R) && defined(CONFIG_SMP)
-       unsigned long icucr;
-
-       local_irq_save(flags);
-       icucr = inl(M32R_ICU_CR1_PORTL);
-       icucr |= M32R_ICUCR_ISMOD11;
-       outl(icucr, M32R_ICU_CR1_PORTL);
-       local_irq_restore(flags);
-#endif
        ei_local->stat.tx_errors++;
 
        spin_lock_irqsave(&ei_local->page_lock, flags);
@@ -722,7 +759,6 @@ static void ei_receive(struct net_device *dev)
                        else
                        {
                                skb_reserve(skb,2);     /* IP headers on 16 byte boundaries */
-                               skb->dev = dev;
                                skb_put(skb, pkt_len);  /* Make room */
                                ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame));
                                skb->protocol=eth_type_trans(skb,dev);