Re: [kernel] Re: [PATCH] Bug wrt failing init of scsi modules

Kurt Garloff (garloff@suse.de)
Fri, 27 Aug 1999 15:56:29 +0200


--U+BazGySraz5kW0T
Content-Type: multipart/mixed; boundary="/9DWx/yDrRhgMJTb"

--/9DWx/yDrRhgMJTb
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

On Fri, Aug 27, 1999 at 10:12:48AM +0200, Kurt Garloff wrote:
> Unfortunately I did this patch in two steps and erroneously booted the
> middle kernel instead of the latest one when testing. While the error
> description is correct, the patch sent out is wrong. Sorry!
> I will send another one after thourough testing.

So, here is a patch for this problem. A minimal patch would have just added
__DEC_MOD_USE_COUNT(tpnt->module); unregister_SCSI_device(tpnt);
at the right places.

However, I found the module usage counters to be messy and fixed them as we=
ll.
I did some tests, but I have to do some more with fully modularized scsi
code to see, if I didn't miss anything there.

I also solved another problem with sr/sd_mod being loaded in presence of
compiled in versions of the kernel. This was detected by the
register_blkdev() call in the past. The problem was that it was only called,
when devices of this category were actually found. So you could end up with
a sr_mod and a sr in the kernel.
I added is_reg_blk/chrdev(uint major) to the kernel and made the high level
SCSI code test for already being registered before succeeding their init.

A formatting typo in scsi_dump_info() is also fixed and the dump of the
scsi_devicelist has been added. (Should be called scsi_devicetemplate_list,
BTW)=20

One problem is not addressed by this patch:
Nothing protects scsi_mod from being loaded with scsi support in the kernel.
I did not yet see a nice solution for this, as no resources are registered.
Addind a global var is not a nice way, either. Suggestions?

Patch (again against 2.2.12) is appended. I'd suggest inclusion into the
kernel after some more tests.

Regards,
--=20
Kurt Garloff <garloff@suse.de> Wuppertal, FRG
PGP2 key: See mail header, key servers Linux kernel development
SuSE GmbH, N=FCrnberg, FRG SCSI drivers: tmscsim(DC390), DC395

--/9DWx/yDrRhgMJTb
Content-Type: text/plain; charset=us-ascii
Content-Description: 22x-scsi-mod-unregister2.diff
Content-Disposition: attachment; filename="22x-scsi-mod-unregister2.diff"
Content-Transfer-Encoding: quoted-printable

--- linux-2.2.12/fs/devices.c.orig Wed Dec 23 20:39:49 1998
+++ linux-2.2.12/fs/devices.c Fri Aug 27 11:36:48 1999
@@ -370,3 +370,13 @@
sprintf(buffer, "%s(%d,%d)", name, MAJOR(dev), MINOR(dev));
return buffer;
}
+
+struct file_operations * is_reg_blkdev(unsigned int major)
+{
+ return blkdevs[major].fops;
+}
+
+struct file_operations * is_reg_chrdev(unsigned int major)
+{
+ return chrdevs[major].fops;
+}
--- linux-2.2.12/kernel/ksyms.c.orig Mon Aug 9 21:04:41 1999
+++ linux-2.2.12/kernel/ksyms.c Fri Aug 27 11:34:14 1999
@@ -196,8 +196,10 @@
/* device registration */
EXPORT_SYMBOL(register_chrdev);
EXPORT_SYMBOL(unregister_chrdev);
+EXPORT_SYMBOL(is_reg_chrdev);
EXPORT_SYMBOL(register_blkdev);
EXPORT_SYMBOL(unregister_blkdev);
+EXPORT_SYMBOL(is_reg_blkdev);
EXPORT_SYMBOL(tty_register_driver);
EXPORT_SYMBOL(tty_unregister_driver);
EXPORT_SYMBOL(tty_std_termios);
--- linux-2.2.12/include/linux/fs.h.orig Fri Aug 27 01:53:30 1999
+++ linux-2.2.12/include/linux/fs.h Fri Aug 27 11:34:44 1999
@@ -728,7 +728,8 @@
extern char * bdevname(kdev_t dev);
extern char * cdevname(kdev_t dev);
extern char * kdevname(kdev_t dev);
-
+extern inline struct file_operations * is_reg_blkdev(unsigned int major);
+extern inline struct file_operations * is_reg_chrdev(unsigned int major);
=20
extern void init_fifo(struct inode * inode);
extern struct inode_operations fifo_inode_operations;
--- linux-2.2.12/drivers/scsi/scsi.c.orig Mon Aug 9 21:04:40 1999
+++ linux-2.2.12/drivers/scsi/scsi.c Fri Aug 27 15:33:31 1999
@@ -34,6 +34,10 @@
* Jiffies wrap fixes (host->resetting), 3 Dec 1998 Andrea Arcangeli
*
* out_of_space + add-single-device work, D. Gilbert (dpg) 990612
+ *=20
+ * Call init regardless of dev_noticed and have the s?_init() handle it
+ * and unregister in case of failure. Similar for host adapters.
+ * Fixed module counters. garloff@suse.de 990827
*/
=20
#include <linux/config.h>
@@ -2709,13 +2713,19 @@
else
tpnt->present =3D tpnt->detect(tpnt);
=20
- if (tpnt->present)
+ /* No need to clean up. The host should scsi_unregister() if
+ * detect() called scsi_register() before but detection failed. */
+ if (!tpnt->present)
+ return 1;
+ else
{
+ MOD_INC_USE_COUNT;
if(pcount =3D=3D next_scsi_host)=20
{
if(tpnt->present > 1)=20
{
printk("Failure to register low-level scsi driver");
+ __MOD_DEC_USE_COUNT(tpnt->module);
scsi_unregister_host(tpnt);
return 1;
}
@@ -2723,6 +2733,7 @@
* The low-level driver failed to register a driver. We
* can do this now.
*/
+ printk("Register driver for host %s\n", tpnt->name);
scsi_register(tpnt,0);
}
tpnt->next =3D scsi_hosts; /* Add to the linked list */
@@ -2841,9 +2852,8 @@
(scsi_memory_upper_value - scsi_init_memory_start) / 1024);
#endif
=20
- MOD_INC_USE_COUNT;
-
if (out_of_space) {
+ __MOD_DEC_USE_COUNT(tpnt->module);
scsi_unregister_host(tpnt); /* easiest way to clean up?? */
return 1;
}
@@ -3114,6 +3124,7 @@
if (tpnt->next) return 1;
=20
scsi_register_device(tpnt);
+ MOD_INC_USE_COUNT;
/*
* First scan the devices that we know about, and see if we notice the=
m.
*/
@@ -3131,8 +3142,13 @@
* If any of the devices would match this driver, then perform the
* init function.
*/
- if(tpnt->init && tpnt->dev_noticed)
- if ((*tpnt->init)()) return 1;
+ if(tpnt->init)
+ if ((*tpnt->init)())=20
+ {
+ __MOD_DEC_USE_COUNT(tpnt->module);
+ scsi_unregister_device (tpnt);
+ return 1;
+ }
=20
/*
* Now actually connect the devices to the new driver.
@@ -3163,9 +3179,9 @@
if(tpnt->finish && tpnt->nr_dev) (*tpnt->finish)();
if (! out_of_space)
resize_dma_pool();
- MOD_INC_USE_COUNT;
=20
if (out_of_space) {
+ __MOD_DEC_USE_COUNT(tpnt->module);
scsi_unregister_device(tpnt); /* easiest way to clean up?? */
return 1;
}
@@ -3318,6 +3334,7 @@
struct Scsi_Host * shpnt;
Scsi_Cmnd * SCpnt;
Scsi_Device * SDpnt;
+ struct Scsi_Device_Template * sdtpnt;
printk("Dump of scsi host parameters:\n");
i =3D 0;
for(shpnt =3D scsi_hostlist; shpnt; shpnt =3D shpnt->next)
@@ -3341,7 +3358,7 @@
for(SCpnt=3DSDpnt->device_queue; SCpnt; SCpnt =3D SCpnt->next)
{
/* (0) h:c:t:l (dev sect nsect cnumsec sg) (ret all flg) =
(to/cmd to ito) cmd snse result %d %x */
- printk("(%3d) %2d:%1d:%2d:%2d (%6s %4ld %4ld %4ld %4x %1d)=
(%1d %1d 0x%2x) (%4d %4d %4d) 0x%2.2x 0x%2.2x 0x%8.8x\n",
+ printk("(%3d) %2d:%1d:%2d:%2d (%6s %4ld %4ld %4ld %4x %1d)=
(%1d %1d 0x%2.2x) (%4d %4d %4d) 0x%2.2x 0x%2.2x 0x%8.8x\n",
i++,=20
=20
SCpnt->host ? SCpnt->host->host_no : -1,
@@ -3400,6 +3417,15 @@
}
}
printk("wait_for_request =3D %p\n", wait_for_request);
+ sdtpnt =3D scsi_devicelist;
+ printk("SCSI List of Device Templates: %p", sdtpnt);
+ while (sdtpnt)
+ {
+ printk ("(%s)->%p", sdtpnt->tag, sdtpnt->next);
+ sdtpnt =3D sdtpnt->next;
+ }
+ printk ("\n");
+
#endif /* CONFIG_SCSI_LOGGING */ /* } */
#endif /* CONFIG_PROC_FS */
}
--- linux-2.2.12/drivers/scsi/sd.c.orig Mon Aug 9 21:05:05 1999
+++ linux-2.2.12/drivers/scsi/sd.c Fri Aug 27 13:39:10 1999
@@ -1494,6 +1494,11 @@
{
int i;
=20
+ if(!sd_registered && is_reg_blkdev(SD_MAJOR(0))) {
+ printk("Unable to get major %d for SCSI disk\n", SD_MAJOR(0));
+ return 1;
+ }
+
if (sd_template.dev_noticed =3D=3D 0) return 0;
=20
if (!rscsi_disks)
--- linux-2.2.12/drivers/scsi/sr.c.orig Fri Jan 15 23:41:04 1999
+++ linux-2.2.12/drivers/scsi/sr.c Fri Aug 27 13:43:26 1999
@@ -1014,14 +1014,16 @@
static int sr_init()
{
int i;
+ =20
+ if (!sr_registered && is_reg_blkdev(SCSI_CDROM_MAJOR)) {
+ printk("Unable to get major %d for SCSI-CD\n",SCSI_CDROM_MAJOR);
+ return 1;
+ }
=20
if(sr_template.dev_noticed =3D=3D 0) return 0;
=20
if(!sr_registered) {
- if (register_blkdev(MAJOR_NR,"sr",&cdrom_fops)) {
- printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
- return 1;
- }
+ register_blkdev(SCSI_CDROM_MAJOR,"sr",&cdrom_fops);
sr_registered++;
}
=20
--- linux-2.2.12/drivers/scsi/sg.c.orig Tue Jun 8 01:27:06 1999
+++ linux-2.2.12/drivers/scsi/sg.c Fri Aug 27 15:35:16 1999
@@ -113,7 +113,7 @@
static void sg_detach(Scsi_Device *);
=20
=20
-struct Scsi_Device_Template sg_template =3D {NULL, NULL, "sg", NULL, 0xff,
+struct Scsi_Device_Template sg_template =3D {NULL, "generic", "sg", NULL, =
0xff,
SCSI_GENERIC_MAJOR, 0, 0, 0, 0,
sg_detect, sg_init,
sg_finish, sg_attach, sg_detach=
};
@@ -948,16 +948,17 @@
static int sg_init()
{
static int sg_registered =3D 0;
+ =20
+ if(!sg_registered && is_reg_chrdev(SCSI_GENERIC_MAJOR)) {
+ printk("Unable to get major %d for generic SCSI device\n",
+ SCSI_GENERIC_MAJOR);
+ return 1;
+ }
=20
if (sg_template.dev_noticed =3D=3D 0) return 0;
=20
if(!sg_registered) {
- if (register_chrdev(SCSI_GENERIC_MAJOR,"sg",&sg_fops))
- {
- printk("Unable to get major %d for generic SCSI device\n",
- SCSI_GENERIC_MAJOR);
- return 1;
- }
+ register_chrdev(SCSI_GENERIC_MAJOR,"sg",&sg_fops);
sg_registered++;
}
=20
--- linux-2.2.12/drivers/scsi/st.c.orig Sat May 22 23:51:26 1999
+++ linux-2.2.12/drivers/scsi/st.c Fri Aug 27 13:41:28 1999
@@ -3453,13 +3453,15 @@
int target_nbr;
#endif
=20
+ if(!st_registered && is_reg_chrdev(SCSI_TAPE_MAJOR)) {
+ printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",SCSI_TAPE_=
MAJOR);
+ return 1;
+ }
+
if (st_template.dev_noticed =3D=3D 0) return 0;
=20
if(!st_registered) {
- if (register_chrdev(SCSI_TAPE_MAJOR,"st",&st_fops)) {
- printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",MAJOR_NR);
- return 1;
- }
+ register_chrdev(SCSI_TAPE_MAJOR,"st",&st_fops);
st_registered++;
}
=20

--/9DWx/yDrRhgMJTb--

--U+BazGySraz5kW0T
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: 2.6.3i

iQCVAwUBN8aZDRaQN/7O/JIVAQGyIQP/UVeo4ZKPtbv4lMv6+XZhY3uz1xjK7QW1
w4FMj0xza4FjA3HHGYikIkiLHZFZ8ms4KVVkHS3bgOqOUoa/U+327EFl7t6I//26
jq/1SF1G6W20KggSBBTOOfY0BdjBiJJ+LFJ55+pgmxCoOlPgOPZ1JH134NEBLitt
iESFU7mrbgA=
=t+Iv
-----END PGP SIGNATURE-----

--U+BazGySraz5kW0T--

-
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/