kernel freeze with Digiboard PC/X driver

Sergey Kononenko (sergk@kiyavia.crimea.ua)
Sat, 6 Jul 2002 19:04:57 +0300


--yrj/dFKFPuw6o+aM
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi, All.

Then I try to upgrade server (Dual PII-233), working on 2.2.20 kerel to 2.4.18.
And after loading driver for Digiboard PC/X serial multiport card (pcxx.o)
kernel imediatly freeze. I try 2.4.19-rc1 try compile this driver in
the kernel, but it is not solve the problem. Also I noticed that dirver
freeze kernel even in UP machine _wihtout_ digiboard card, but in 2.2.x it
correctly report that device not found.
I spent some time to explore this problem, and discover, that freeze happen
in pcxe_init() while calling function pcxxdelay() in this code (pcxx.c):

for(crd=0; crd < numcards; crd++) {
bd = &boards[crd];
outb(FEPRST, bd->port);
pcxxdelay(1);

for(i=0; (inb(bd->port) & FEPMASK) != FEPRST; i++) {

But pcxxdelay is only wrapper for mdelay:

static void pcxxdelay(int msec)
{
mdelay(msec);
}

I simply replace all calls of pcxxdelay by mdelay in pcxx.c and this solve
the problem! After that dirver work perfectly without any freezes. I can't
explain why calling mdelay in wrapper cause the problem an why this trivial
change fix freezing. May be this is bug in compiler optimizations, but I
compile kernel with standart gcc 2.95.3 and default optimization flags.

So I attach my patch in a hope, that somebody test it and this or more
correct patch will be included in official kernel.

P.S. Sorry for my bad English.

SergK.

--yrj/dFKFPuw6o+aM
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pcxx.c.patch"

--- pcxx.c.orig 2002-07-02 13:41:47.000000000 +0300
+++ pcxx.c 2002-07-02 13:42:39.000000000 +0300
@@ -153,7 +153,6 @@
DECLARE_TASK_QUEUE(tq_pcxx);

static void pcxxpoll(unsigned long dummy);
-static void pcxxdelay(int);
static void fepcmd(struct channel *, int, int, int, int, int);
static void pcxe_put_char(struct tty_struct *, unsigned char);
static void pcxe_flush_chars(struct tty_struct *);
@@ -1271,7 +1270,7 @@
for(crd=0; crd < numcards; crd++) {
bd = &boards[crd];
outb(FEPRST, bd->port);
- pcxxdelay(1);
+ mdelay(1);

for(i=0; (inb(bd->port) & FEPMASK) != FEPRST; i++) {
if(i > 100) {
@@ -1283,7 +1282,7 @@
#ifdef MODULE
schedule();
#endif
- pcxxdelay(10);
+ mdelay(10);
}
if(bd->status == DISABLED)
continue;
@@ -1362,7 +1361,7 @@
#ifdef MODULE
schedule();
#endif
- pcxxdelay(1);
+ mdelay(1);
}
if(bd->status == DISABLED)
continue;
@@ -1413,7 +1412,7 @@
#ifdef MODULE
schedule();
#endif
- pcxxdelay(50);
+ mdelay(50);
}

printk("\nPC/Xx: BIOS download failed for board at 0x%x(addr=%lx-%lx)!\n",
@@ -1443,7 +1442,7 @@
#ifdef MODULE
schedule();
#endif
- pcxxdelay(10);
+ mdelay(10);
}

printk("\nPC/Xx: BIOS download failed on the %s at 0x%x!\n",
@@ -1487,7 +1486,7 @@
#ifdef MODULE
schedule();
#endif
- pcxxdelay(1);
+ mdelay(1);
}

if(bd->status == DISABLED)
@@ -1520,7 +1519,7 @@
#ifdef MODULE
schedule();
#endif
- pcxxdelay(1);
+ mdelay(1);
}
if(bd->status == DISABLED)
continue;
@@ -1825,15 +1824,6 @@
}


-/*
- * pcxxdelay - delays a specified number of milliseconds
- */
-static void pcxxdelay(int msec)
-{
- mdelay(msec);
-}
-
-
static void
fepcmd(struct channel *ch, int cmd, int word_or_byte, int byte2, int ncmds,
int bytecmd)

--yrj/dFKFPuw6o+aM--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/