Re: NE2000 PCI problems FIXED!

Richard B. Johnson (root@chaos.analogic.com)
Fri, 22 May 1998 08:41:38 -0400 (EDT)


On Fri, 22 May 1998, Olaf Titz wrote:

> > Okay I will fix it. Some things need to be moved around a bit. I
>
> While you're at it, check the cleanup_module() routine, that one has a
> similar problem:
>
> if (dev->priv != NULL) {
> kfree(dev->priv);
> dev->priv = NULL;
> free_irq(dev->irq, dev);
> irq2dev_map[dev->irq] = NULL;
> release_region(dev->base_addr, NE_IO_EXTENT);
> unregister_netdev(dev);
> }
>
> I think this order is more or less completely turned upside down...

Okay. I didn't see this one because it doesn't make an OOPS, but
surely the memory should be freed last just in case shutting down
the ISR causes a spurious interrupt.

I sent a patch out (against 2.1.102) last night. If rearranges the
allocation in ne.c (this should be permanent), and comments out
some enable/disable irq stuff in 8390.c, which the 2.1.102 SMP
kernel doesn't like, causing the driver to eventually fail
stone-cold-dead. My patched kernel has been doing continuous data
transfers all night long. Because the the temporary 8390 stuff,
I occasionally get a few error messages, but it continues to run.

Here is the patch (so far).

--- linux-2.1.102/drivers/net/ne.c.orig Thu May 21 17:06:15 1998
+++ linux-2.1.102/drivers/net/ne.c Thu May 21 17:34:41 1998
@@ -25,6 +25,8 @@
Paul Gortmaker : Support for PCI ne2k clones, similar to lance.c
Paul Gortmaker : Allow users with bad cards to avoid full probe.
Paul Gortmaker : PCI probe changes, more PCI cards supported.
+ rjohnson@analogic.com : Changed init order so an interrupt will only
+ occur after memory is allocated for dev->priv.

*/

@@ -416,6 +418,12 @@
return EAGAIN;
}

+ /* Allocate dev->priv and fill in 8390 specific dev fields. */
+ if (ethdev_init(dev)) {
+ printk (" unable to get memory for dev->priv.\n");
+ return -ENOMEM;
+ }
+
/* Snarf the interrupt now. There's no point in waiting since we cannot
share and the board will usually be enabled. */
{
@@ -423,19 +431,12 @@
pci_irq_line ? SA_SHIRQ : 0, name, dev);
if (irqval) {
printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval);
+
+ kfree(dev->priv);
return EAGAIN;
}
}
-
dev->base_addr = ioaddr;
-
- /* Allocate dev->priv and fill in 8390 specific dev fields. */
- if (ethdev_init(dev)) {
- printk (" unable to get memory for dev->priv.\n");
- free_irq(dev->irq, dev);
- return -ENOMEM;
- }
-
request_region(ioaddr, NE_IO_EXTENT, name);

for(i = 0; i < ETHER_ADDR_LEN; i++) {
--- linux-2.1.102/drivers/net/8390.c.orig Thu May 21 17:09:45 1998
+++ linux-2.1.102/drivers/net/8390.c Thu May 21 19:03:11 1998
@@ -193,13 +193,19 @@

/* Mask interrupts from the ethercard. */
outb_p(0x00, e8390_base + EN0_IMR);
+#if 0
disable_irq(dev->irq);
synchronize_irq();
+#endif
+
if (dev->interrupt)
{
printk(KERN_WARNING "%s: Tx request while isr active.\n",dev->name);
outb_p(ENISR_ALL, e8390_base + EN0_IMR);
+#if 0
enable_irq(dev->irq);
+#endif
+
ei_local->stat.tx_errors++;
dev_kfree_skb(skb);
return 0;
@@ -242,7 +248,10 @@
ei_local->irqlock = 0;
dev->tbusy = 1;
outb_p(ENISR_ALL, e8390_base + EN0_IMR);
+#if 0
enable_irq(dev->irq);
+#endif
+
ei_local->stat.tx_errors++;
return 1;
}
@@ -293,7 +302,9 @@
/* Turn 8390 interrupts back on. */
ei_local->irqlock = 0;
outb_p(ENISR_ALL, e8390_base + EN0_IMR);
+#if 0
enable_irq(dev->irq);
+#endif

dev_kfree_skb (skb);
ei_local->stat.tx_bytes += send_length;
@@ -333,7 +344,9 @@
}

dev->interrupt = 1;
+#if 0
sti();
+#endif

/* Change to page 0 and read the intr status reg. */
outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD);

Cheers,
Dick Johnson
***** FILE SYSTEM MODIFIED *****
Penguin : Linux version 2.1.101 on an i586 machine (66.15 BogoMips).
Warning : It's hard to remain at the trailing edge of technology.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu