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

Reply via email to