Re: Serial Driver Bug?? (and patch!)

Andrew E. Mileski (aem@nic.ott.hookup.net)
Sun, 28 Apr 1996 18:26:28 -0400 (EDT)


> > Do any of these problems (cat /proc/ioports causing system crashes,
> > etc.) happen *before* the first time the serial driver is loaded?
>
> No. In fact, they only happen after ther serial driver has been loaded
> and then unloaded (and possibly loaded again). The problem seems to be
> that 'release_region' is never called at module unload time, and so the
> kernel's resource tables contain wild pointers.
>
> Below is a patch that I send to Andrew yesterday; it fixes the problem
> for me. It also adds a KERN_INFO priority to some of the printk()s
> (so my console doesn't get littered by them when kerneld loads the
> module). Comments welcome.

The patch works fine for me too. Thanks! :-)

Too bad you can't fix the AIC7XXX driver so I can actually use a
v1.3.9* kernel for more than 3 minutes...

I go through /proc/ioports more often than most because my PnP
code deals with hardware resources. In fact, I re-wrote the
I/O and DMA code to unify it. This unified code also gets me
a /proc/addresses and /proc/irq (not the same as /proc/interrupts).
Hopefully PnP will make it into a v1.5.* (or is that v2.1.* ?)
kernel.

Anyhoot, thanks.

--
Andrew E. Mileski
mailto:aem@ott.hookup.net   http://www.redhat.com/~aem/
Linux Plug-and-Play Project http://www.redhat.com/pnp/
"You can't have everything. Where would you put it?" - Steven Wright

Index: linux/drivers/char/serial.c =================================================================== RCS file: /usr/local/cvsroot/linux/drivers/char/serial.c,v retrieving revision 1.1.1.4 diff -u -r1.1.1.4 serial.c --- serial.c 1996/04/18 20:36:08 1.1.1.4 +++ serial.c 1996/04/27 09:27:41 @@ -2448,7 +2448,7 @@ */ static void show_serial_version(void) { - printk("%s version %s with", serial_name, serial_version); + printk(KERN_INFO "%s version %s with", serial_name, serial_version); #ifdef CONFIG_HUB6 printk(" HUB-6"); #define SERIAL_OPT @@ -2797,7 +2797,7 @@ autoconfig(info); if (info->type == PORT_UNKNOWN) continue; - printk("tty%02d%s at 0x%04x (irq = %d)", info->line, + printk(KERN_INFO "tty%02d%s at 0x%04x (irq = %d)", info->line, (info->flags & ASYNC_FOURPORT) ? " FourPort" : "", info->port, info->irq); switch (info->type) { @@ -2867,7 +2867,7 @@ printk("register_serial(): autoconfig failed\n"); return -1; } - printk("tty%02d at 0x%04x (irq = %d)", info->line, + printk(KERN_INFO "tty%02d at 0x%04x (irq = %d)", info->line, info->port, info->irq); switch (info->type) { case PORT_8250: @@ -2895,7 +2895,7 @@ if (info->tty) tty_hangup(info->tty); info->type = PORT_UNKNOWN; - printk("tty%02d unloaded\n", info->line); + printk(KERN_INFO "tty%02d unloaded\n", info->line); restore_flags(flags); } @@ -2909,6 +2909,7 @@ { unsigned long flags; int e1, e2; + int i; /* printk("Unloading %s: version %s\n", serial_name, serial_version); */ save_flags(flags); @@ -2923,5 +2924,10 @@ printk("SERIAL: failed to unregister callout driver (%d)\n", e2); restore_flags(flags); + + for (i = 0; i < NR_PORTS; i++) { + if (rs_table[i].type != PORT_UNKNOWN) + release_region(rs_table[i].port, 8); + } } #endif /* MODULE */