patch-2.1.75 linux/drivers/scsi/sg.c

Next file: linux/drivers/scsi/sr.c
Previous file: linux/drivers/scsi/seagate.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.74/linux/drivers/scsi/sg.c linux/drivers/scsi/sg.c
@@ -67,10 +67,22 @@
 static int sg_ioctl(struct inode * inode,struct file * file,
 		    unsigned int cmd_in, unsigned long arg)
 {
-    int result;
-    int dev = MINOR(inode->i_rdev);
+    int                         dev = MINOR(inode->i_rdev);
+    int                         result;
+
     if ((dev<0) || (dev>=sg_template.dev_max))
 	return -ENXIO;
+
+    /*
+     * If we are in the middle of error recovery, then don't allow any
+     * access to this device.  Also, error recovery *may* have taken the
+     * device offline, in which case all further access is prohibited.
+     */
+    if( !scsi_block_when_processing_errors(scsi_generics[dev].device) )
+      {
+        return -ENXIO;
+      }
+
     switch(cmd_in)
     {
     case SG_SET_TIMEOUT:
@@ -92,6 +104,12 @@
     int flags=filp->f_flags;
     if (dev>=sg_template.dev_max || !scsi_generics[dev].device)
 	return -ENXIO;
+
+    if( !scsi_block_when_processing_errors(scsi_generics[dev].device) )
+      {
+        return -ENXIO;
+      }
+
     if (O_RDWR!=(flags & O_ACCMODE))
 	return -EACCES;
 
@@ -209,6 +227,17 @@
     unsigned long flags;
     struct scsi_generic *device=&scsi_generics[dev];
 
+    /*
+     * If we are in the middle of error recovery, don't let anyone
+     * else try and use this device.  Also, if error recovery fails, it
+     * may try and take the device offline, in which case all further
+     * access to the device is prohibited.
+     */
+    if( !scsi_block_when_processing_errors(scsi_generics[dev].device) )
+      {
+        return -ENXIO;
+      }
+
     if (ppos != &filp->f_pos) {
       /* FIXME: Hmm.  Seek to the right place, or fail?  */
     }
@@ -278,7 +307,8 @@
     if (!device->pending)
     {
 	printk("unexpected done for sg %d\n",dev);
-	SCpnt->request.rq_status = RQ_INACTIVE;
+        scsi_release_command(SCpnt);
+        SCpnt = NULL;
 	return;
     }
 
@@ -325,7 +355,8 @@
      * result.
      */
     device->complete=1;
-    SCpnt->request.rq_status = RQ_INACTIVE;
+    scsi_release_command(SCpnt);
+    SCpnt = NULL;
     wake_up(&scsi_generics[dev].read_wait);
 }
 
@@ -342,6 +373,17 @@
     unsigned char	  opcode;
     Scsi_Cmnd		* SCpnt;
 
+    /*
+     * If we are in the middle of error recovery, don't let anyone
+     * else try and use this device.  Also, if error recovery fails, it
+     * may try and take the device offline, in which case all further
+     * access to the device is prohibited.
+     */
+    if( !scsi_block_when_processing_errors(scsi_generics[dev].device) )
+      {
+        return -ENXIO;
+      }
+
     if (ppos != &filp->f_pos) {
       /* FIXME: Hmm.  Seek to the right place, or fail?  */
     }
@@ -444,7 +486,7 @@
      * Grab a device pointer for the device we want to talk to.  If we
      * don't want to block, just return with the appropriate message.
      */
-    if (!(SCpnt=allocate_device(NULL,device->device, !(filp->f_flags & O_NONBLOCK))))
+    if (!(SCpnt=scsi_allocate_device(NULL,device->device, !(filp->f_flags & O_NONBLOCK))))
     {
 	device->pending=0;
 	wake_up(&device->write_wait);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov