Messages in this thread Patch in this message | | | Date | Sun, 28 Apr 1996 10:08:59 -0500 (CDT) | From | Tom Grigg <> | Subject | Re: Serial Driver Bug?? (and patch!) |
| |
On Fri, 26 Apr 1996, Theodore Y. Ts'o wrote:
> I haven't seen any of these symptoms on my machine, and neither has any > of the other people whom I'm familiar with who have tried using the > modular serial driver.
I hadn't seen any of them either (except an occasional 'couldn't get a free page' message, which I didn't attribute to the serial driver) until I started playing around with the things he mentioned.
> 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.
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 */
-- Tom Grigg st588@jetson.uh.edu http://www.egr.uh.edu/~eac64750/tom/
| |