Hangs with new Realtek driver in ac5.

Daniel Kobras (daniel.kobras@student.uni-tuebingen.de)
Sat, 18 Sep 1999 21:15:04 +0200 (CEST)


Hi!

Using the updated rtl8139 in 2.3.18ac5 turned out to be not really a
pleasure. Actually, the card reliably hangs in rtl8129_open(). And it
hangs the whole machine, "hang" meaning I can't even use the ATX power
switch to turn it off. Don't even think about magic syskeys and the like.

The cause seems to be that with the switch to using PCI mem rather than
i/o ports, the driver runs into a load of nasty timing issues. I was
finally able to cure the hangs by forcing each write transaction to
complete before the next one is issued. This probably kills the whole
point of using PCI mem in the first place, so the forced flushes should be
much finer grained but, hey, it's a quick fix and it's a whole lot better
than hanging the machine. (The other obvious fix of course being to switch
back to i/o ports which works fine as well.)

Anyway, here's the patch that was necessary to cure my machine and I'll
try to come up with an improved version with less readb()s.

--[snip]--

--- drivers/net/rtl8139.c.orig Fri Sep 17 23:43:06 1999
+++ drivers/net/rtl8139.c Sat Sep 18 20:51:53 1999
@@ -178,9 +178,9 @@
#define inb readb
#define inw readw
#define inl readl
-#define outb writeb
-#define outw writew
-#define outl writel
+#define outb(val,port) do { writeb((val),(port));readb(port); } while(0)
+#define outw(val,port) do { writew((val),(port));readb(port); } while(0)
+#define outl(val,port) do { writel((val),(port));readb(port); } while(0)
#endif

/* The rest of these values should never change. */

--[snap]--

And while I'm at it, may I suggest the following change to
drivers/pci/scan.c, providing a little more useful information in a
debugging output:

--[snip]--

--- drivers/pci/scan.c~ Thu Sep 16 22:41:31 1999
+++ drivers/pci/scan.c Sat Sep 18 14:52:03 1999
@@ -117,8 +117,11 @@
pciaddr = res->start;

if (debug > 2)
- printk(KERN_INFO "Found %s at PCI address %#lx, IRQ %d.\n",
- pci_tbl[chip_idx].name, pciaddr, irq);
+ printk(KERN_INFO "Found %s at PCI %s in range %#lx-%#lx, IRQ %d.\n",
+ pci_tbl[chip_idx].name,
+ ((res->flags & PCI_BASE_ADDRESS_SPACE_IO) ?
+ "i/o" : "mem"),
+ pciaddr, res->end, irq);

if ((res->flags & PCI_BASE_ADDRESS_SPACE_IO)) {
ioaddr = pciaddr;

--[snap]--

Regards,

Daniel.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/