Messages in this thread Patch in this message | | | From | (Bjorn Ekwall) | Subject | Patch to mcd.c (was: Re: Bug in sysmount:1.3.75 ?) | Date | Wed, 20 Mar 1996 21:38:29 +0100 (MET) |
| |
Andreas Dietrich <quasi@baccus.franken.de> wrote: > > Hello! > > I'm using kernel 1.3.75 and I had the following oops, when trying to > mount my Mitsumi Doublespeed CDROM, which failed to initialize. > (This happens sometimes -- also with the dos-drivers!). > > I've experienced this bug several times, with different kernels; > unfortunately I do not remember exactly (was just too lazy to report it > earlier -- Sorry about that!) > > I compiled mcd as a module, using kerneld to load it, in case this > is important. > I used gcc2.6.3/a.out to compile kernel and modules. > > The command that lead to the oops was mount /cd.
The initialisation of the module wasn't clean w.r.t. (un)register_blkdev.
When kerneld was triggered to load the module, modprobe failed since init_module exited with "Init failed. No mcd device at 0x330 irq 10".
This made modprobe _unload_ the module, but the entry for this device was left in the kernel table for block-devices!
When sys_mount then tried to check fops->open, it accessed the memory where the module _used_ to be. Since it was unloaded, you got an Ooops!
The included patch cleans that one up.
Bjorn <bj0rn@blox.se>
--- linux/drivers/cdrom/mcd.c.org Wed Mar 20 21:02:26 1996 +++ linux/drivers/cdrom/mcd.c Wed Mar 20 21:34:07 1996 @@ -60,6 +60,7 @@ 17 June 95 Modifications By Andrew J. Kroll <ag784@freenet.buffalo.edu> 07 July 1995 Modifications by Andrew J. Kroll + Bjorn Ekwall <bj0rn@blox.se> added unregister_blkdev to mcd_init() */ #include <linux/module.h> @@ -1181,6 +1182,7 @@ } if (check_region(mcd_port, 4)) { + unregister_blkdev(MAJOR_NR, "mcd"); printk("Init failed, I/O port (%X) already in use\n", mcd_port); return -EIO; @@ -1204,6 +1206,7 @@ if (count >= 2000000) { printk("Init failed. No mcd device at 0x%x irq %d\n", mcd_port, mcd_irq); + unregister_blkdev(MAJOR_NR, "mcd"); return -EIO; } count = inb(MCDPORT(0)); /* pick up the status */ @@ -1211,13 +1214,16 @@ outb(MCMD_GET_VERSION,MCDPORT(0)); for(count=0;count<3;count++) if(getValue(result+count)) { + unregister_blkdev(MAJOR_NR, "mcd"); printk("mitsumi get version failed at 0x%d\n", mcd_port); return -EIO; } - if (result[0] == result[1] && result[1] == result[2]) + if (result[0] == result[1] && result[1] == result[2]) { + unregister_blkdev(MAJOR_NR, "mcd"); return -EIO; + } printk("Mitsumi status, type and version : %02X %c %x ", result[0],result[1],result[2]); @@ -1239,6 +1245,7 @@ if (request_irq(mcd_irq, mcd_interrupt, SA_INTERRUPT, "Mitsumi CD", NULL)) { printk("Unable to get IRQ%d for Mitsumi CD-ROM\n", mcd_irq); + unregister_blkdev(MAJOR_NR, "mcd"); return -EIO; } request_region(mcd_port, 4,"mcd");
| |