Messages in this thread Patch in this message | | | Date | Fri, 22 May 1998 08:41:38 -0400 (EDT) | From | "Richard B. Johnson" <> | Subject | Re: NE2000 PCI problems FIXED! |
| |
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
| |