Hi Linus, hi Alan,
attached is a bugfix for the following situation:
scsi_register_device_module() gets called and registers the device (sd, sr)
right at the beginning.
If this functions fails a little bit later in the ->init() function, then
the device does not get removed from the list of devices pointed to by
scsi_devicelist. [The (out_of_space) case is handled correctly, BTW.]
This leaves us with the device getting removed, as module init fails.
However the pointer scsi_devicelist points to the removed device resulting
in kernel Oopses on further SCSI operations.
Aug 26 23:45:57 kurt kernel: Unable to handle kernel paging request at
virtual address c8c1cb30
Aug 26 23:45:57 kurt kernel: EIP: 0010:[scan_scsis_single+1402/2064]
Aug 26 23:45:57 kurt kernel: esi: c8c1cb18 edi: c5091df4 ...
You can loose the ability to access your harddisks by inserting sd_mod in a
kernel with sd compiled in because of this bug.
Attached is a patch to fix it.
Patch is against 2.2.12, but 2.3.15 and 2.0.38 should be affected as well.
--
Kurt Garloff <[EMAIL PROTECTED]> Wuppertal, FRG
PGP2 key: See mail header, key servers Linux kernel development
SuSE GmbH, N�rnberg, FRG SCSI drivers: tmscsim(DC390), DC395
--- 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 02:53:47 1999
@@ -3110,6 +3110,7 @@
Scsi_Device * SDpnt;
struct Scsi_Host * shpnt;
int out_of_space = 0;
+ int no_detect = 0;
if (tpnt->next) return 1;
@@ -3123,7 +3124,7 @@
for(SDpnt = shpnt->host_queue; SDpnt;
SDpnt = SDpnt->next)
{
- if(tpnt->detect) SDpnt->attached += (*tpnt->detect)(SDpnt);
+ if(tpnt->detect) SDpnt->attached += (no_detect = (*tpnt->detect)(SDpnt));
}
}
@@ -3132,7 +3133,15 @@
* init function.
*/
if(tpnt->init && tpnt->dev_noticed)
- if ((*tpnt->init)()) return 1;
+ if ((*tpnt->init)())
+ {
+ /* We don't need full unregister and use our knowledge about
+ * the structure of scsi_devicelist instead. KG, 99/08/27 */
+ /* scsi_unregister_device (tpnt); */
+ SDpnt->attached -= no_detect;
+ scsi_devicelist = scsi_devicelist->next;
+ return 1;
+ }
/*
* Now actually connect the devices to the new driver.
PGP signature