patch-1.3.5 linux/drivers/scsi/sd.c

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

diff -u --recursive --new-file v1.3.4/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
@@ -1,19 +1,19 @@
 /*
- *	sd.c Copyright (C) 1992 Drew Eckhardt 
- *	     Copyright (C) 1993, 1994, 1995 Eric Youngdale
+ *      sd.c Copyright (C) 1992 Drew Eckhardt 
+ *           Copyright (C) 1993, 1994, 1995 Eric Youngdale
  *
- *	Linux scsi disk driver
- *		Initial versions: Drew Eckhardt 
- *		Subsequent revisions: Eric Youngdale
+ *      Linux scsi disk driver
+ *              Initial versions: Drew Eckhardt 
+ *              Subsequent revisions: Eric Youngdale
  *
- *	<drew@colorado.edu>
+ *      <drew@colorado.edu>
  *
  *       Modified by Eric Youngdale ericy@cais.com to
  *       add scatter-gather, multiple outstanding request, and other
  *       enhancements.
  *
- *	 Modified by Eric Youngdale eric@aib.com to support loadable
- *	 low-level scsi drivers.
+ *       Modified by Eric Youngdale eric@aib.com to support loadable
+ *       low-level scsi drivers.
  */
 
 #include <linux/fs.h>
@@ -35,20 +35,20 @@
 #include <linux/genhd.h>
 
 /*
-static const char RCSid[] = "$Header:";
-*/
+ *  static const char RCSid[] = "$Header:";
+ */
 
 #define MAX_RETRIES 5
 
 /*
- *	Time out in seconds for disks and Magneto-opticals (which are slower).
+ *  Time out in seconds for disks and Magneto-opticals (which are slower).
  */
 
-#define SD_TIMEOUT 600
+#define SD_TIMEOUT 700
 #define SD_MOD_TIMEOUT 750
 
-#define CLUSTERABLE_DEVICE(SC) (SC->host->hostt->use_clustering && \
-			    SC->device->type != TYPE_MOD)
+#define CLUSTERABLE_DEVICE(SC) (SC->host->use_clustering && \
+				SC->device->type != TYPE_MOD)
 
 struct hd_struct * sd;
 int revalidate_scsidisk(int dev, int maxusage);
@@ -56,7 +56,7 @@
 Scsi_Disk * rscsi_disks = NULL;
 static int * sd_sizes;
 static int * sd_blocksizes;
-static int * sd_hardsizes;		/* Hardware sector size */
+static int * sd_hardsizes;              /* Hardware sector size */
 
 extern int sd_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
 
@@ -73,1112 +73,1160 @@
 static int sd_detect(Scsi_Device *);
 static void sd_detach(Scsi_Device *);
 
-struct Scsi_Device_Template sd_template = {NULL, "disk", "sd", TYPE_DISK, 
-					     SCSI_DISK_MAJOR, 0, 0, 0, 1,
-					     sd_detect, sd_init,
-					     sd_finish, sd_attach, sd_detach};
+struct Scsi_Device_Template sd_template = 
+{ NULL, "disk", "sd", NULL, TYPE_DISK, 
+      SCSI_DISK_MAJOR, 0, 0, 0, 1,
+      sd_detect, sd_init,
+      sd_finish, sd_attach, sd_detach
+};
 
 static int sd_open(struct inode * inode, struct file * filp)
 {
-        int target;
-	target =  DEVICE_NR(MINOR(inode->i_rdev));
-
-	if(target >= sd_template.dev_max || !rscsi_disks[target].device)
-	  return -ENXIO;   /* No such device */
+    int target;
+    target =  DEVICE_NR(MINOR(inode->i_rdev));
+    
+    if(target >= sd_template.dev_max || !rscsi_disks[target].device)
+	return -ENXIO;   /* No such device */
+    
+    /* 
+     * Make sure that only one process can do a check_change_disk at one time.
+     * This is also used to lock out further access when the partition table 
+     * is being re-read. 
+     */
+    
+    while (rscsi_disks[target].device->busy)
+    barrier();   
+    if(rscsi_disks[target].device->removable) {
+	check_disk_change(inode->i_rdev);
 	
-/* Make sure that only one process can do a check_change_disk at one time.
- This is also used to lock out further access when the partition table is being re-read. */
-
-	while (rscsi_disks[target].device->busy)
-	  barrier();
-
-	if(rscsi_disks[target].device->removable) {
-	  check_disk_change(inode->i_rdev);
-
-	  if(!rscsi_disks[target].device->access_count)
+	if(!rscsi_disks[target].device->access_count)
 	    sd_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
-	};
-	/*
-	 * See if we are requesting a non-existent partition.  Do this
-	 * after checking for disk change.
-	 */
-	if(sd_sizes[MINOR(inode->i_rdev)] == 0)
-	  return -ENXIO;
+    };
 
-	rscsi_disks[target].device->access_count++;
-	if (rscsi_disks[target].device->host->hostt->usage_count)
-	  (*rscsi_disks[target].device->host->hostt->usage_count)++;
-	return 0;
+    /*
+     * See if we are requesting a non-existent partition.  Do this
+     * after checking for disk change.
+     */
+    if(sd_sizes[MINOR(inode->i_rdev)] == 0)
+	return -ENXIO;
+    
+    rscsi_disks[target].device->access_count++;
+    if (rscsi_disks[target].device->host->hostt->usage_count)
+	(*rscsi_disks[target].device->host->hostt->usage_count)++;
+    if(sd_template.usage_count) (*sd_template.usage_count)++;
+    return 0;
 }
 
 static void sd_release(struct inode * inode, struct file * file)
 {
-        int target;
-	sync_dev(inode->i_rdev);
-
-	target =  DEVICE_NR(MINOR(inode->i_rdev));
-
-	rscsi_disks[target].device->access_count--;
-	if (rscsi_disks[target].device->host->hostt->usage_count)
-	  (*rscsi_disks[target].device->host->hostt->usage_count)--;
-
-	if(rscsi_disks[target].device->removable) {
-	  if(!rscsi_disks[target].device->access_count)
+    int target;
+    sync_dev(inode->i_rdev);
+    
+    target =  DEVICE_NR(MINOR(inode->i_rdev));
+    
+    rscsi_disks[target].device->access_count--;
+    if (rscsi_disks[target].device->host->hostt->usage_count)
+	(*rscsi_disks[target].device->host->hostt->usage_count)--;
+    if(sd_template.usage_count) (*sd_template.usage_count)--;
+    
+    if(rscsi_disks[target].device->removable) {
+	if(!rscsi_disks[target].device->access_count)
 	    sd_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
-	};
+    }
 }
 
 static void sd_geninit(void);
 
 static struct file_operations sd_fops = {
-	NULL,			/* lseek - default */
-	block_read,		/* read - general block-dev read */
-	block_write,		/* write - general block-dev write */
-	NULL,			/* readdir - bad */
-	NULL,			/* select */
-	sd_ioctl,		/* ioctl */
-	NULL,			/* mmap */
-	sd_open,		/* open code */
-	sd_release,		/* release */
-	block_fsync,		/* fsync */
-	NULL,			/* fasync */
-	check_scsidisk_media_change,  /* Disk change */
-	fop_revalidate_scsidisk     /* revalidate */
+    NULL,                        /* lseek - default */
+    block_read,                  /* read - general block-dev read */
+    block_write,                 /* write - general block-dev write */
+    NULL,                        /* readdir - bad */
+    NULL,                        /* select */
+    sd_ioctl,                    /* ioctl */
+    NULL,                        /* mmap */
+    sd_open,                     /* open code */
+    sd_release,                  /* release */
+    block_fsync,                 /* fsync */
+    NULL,                        /* fasync */
+    check_scsidisk_media_change, /* Disk change */
+    fop_revalidate_scsidisk      /* revalidate */
 };
 
 static struct gendisk sd_gendisk = {
-	MAJOR_NR,		/* Major number */
-	"sd",		/* Major name */
-	4,		/* Bits to shift to get real from partition */
-	1 << 4,		/* Number of partitions per real */
-	0,		/* maximum number of real */
-	sd_geninit,	/* init function */
-	NULL,		/* hd struct */
-	NULL,	/* block sizes */
-	0,		/* number */
-	NULL,	/* internal */
-	NULL		/* next */
+    MAJOR_NR,                    /* Major number */
+    "sd",                        /* Major name */
+    4,                           /* Bits to shift to get real from partition */
+    1 << 4,                      /* Number of partitions per real */
+    0,                           /* maximum number of real */
+    sd_geninit,                  /* init function */
+    NULL,                        /* hd struct */
+    NULL,                        /* block sizes */
+    0,                           /* number */
+    NULL,                        /* internal */
+    NULL                         /* next */
 };
 
 static void sd_geninit (void)
 {
-	int i;
-
-	for (i = 0; i < sd_template.dev_max; ++i)
-	  if(rscsi_disks[i].device) 
+    int i;
+    
+    for (i = 0; i < sd_template.dev_max; ++i)
+	if(rscsi_disks[i].device) 
 	    sd[i << 4].nr_sects = rscsi_disks[i].capacity;
 #if 0
-	/* No longer needed - we keep track of this as we attach/detach */
-	sd_gendisk.nr_real = sd_template.dev_max;
+    /* No longer needed - we keep track of this as we attach/detach */
+    sd_gendisk.nr_real = sd_template.dev_max;
 #endif
 }
 
 /*
-	rw_intr is the interrupt routine for the device driver.  It will
-	be notified on the end of a SCSI read / write, and
-	will take on of several actions based on success or failure.
-*/
+ * rw_intr is the interrupt routine for the device driver.  It will
+ * be notified on the end of a SCSI read / write, and
+ * will take on of several actions based on success or failure.
+ */
 
 static void rw_intr (Scsi_Cmnd *SCpnt)
 {
-  int result = SCpnt->result;
-  int this_count = SCpnt->bufflen >> 9;
-
+    int result = SCpnt->result;
+    int this_count = SCpnt->bufflen >> 9;
+    
 #ifdef DEBUG
-  printk("sd%c : rw_intr(%d, %d)\n", 'a' + MINOR(SCpnt->request.dev), SCpnt->host->host_no, result);
+    printk("sd%c : rw_intr(%d, %d)\n", 'a' + MINOR(SCpnt->request.dev), 
+	   SCpnt->host->host_no, result);
 #endif
+    
+    /*
+     * First case : we assume that the command succeeded.  One of two things 
+     * will happen here.  Either we will be finished, or there will be more
+     * sectors that we were unable to read last time.
+     */
 
-/*
-  First case : we assume that the command succeeded.  One of two things will
-  happen here.  Either we will be finished, or there will be more
-  sectors that we were unable to read last time.
-*/
-
-  if (!result) {
-
+    if (!result) {
+	
 #ifdef DEBUG
-    printk("sd%c : %d sectors remain.\n", 'a' + MINOR(SCpnt->request.dev), SCpnt->request.nr_sectors);
-    printk("use_sg is %d\n ",SCpnt->use_sg);
+	printk("sd%c : %d sectors remain.\n", 'a' + MINOR(SCpnt->request.dev),
+	       SCpnt->request.nr_sectors);
+	printk("use_sg is %d\n ",SCpnt->use_sg);
 #endif
-    if (SCpnt->use_sg) {
-      struct scatterlist * sgpnt;
-      int i;
-      sgpnt = (struct scatterlist *) SCpnt->buffer;
-      for(i=0; i<SCpnt->use_sg; i++) {
+	if (SCpnt->use_sg) {
+	    struct scatterlist * sgpnt;
+	    int i;
+	    sgpnt = (struct scatterlist *) SCpnt->buffer;
+	    for(i=0; i<SCpnt->use_sg; i++) {
 #ifdef DEBUG
-	printk(":%x %x %d\n",sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
+		printk(":%x %x %d\n",sgpnt[i].alt_address, sgpnt[i].address, 
+		       sgpnt[i].length);
 #endif
-	if (sgpnt[i].alt_address) {
-	  if (SCpnt->request.cmd == READ)
-	    memcpy(sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
-	  scsi_free(sgpnt[i].address, sgpnt[i].length);
-	};
-      };
-      scsi_free(SCpnt->buffer, SCpnt->sglist_len);  /* Free list of scatter-gather pointers */
-    } else {
-      if (SCpnt->buffer != SCpnt->request.buffer) {
+		if (sgpnt[i].alt_address) {
+		    if (SCpnt->request.cmd == READ)
+			memcpy(sgpnt[i].alt_address, sgpnt[i].address, 
+			       sgpnt[i].length);
+		    scsi_free(sgpnt[i].address, sgpnt[i].length);
+		};
+	    };
+
+	    /* Free list of scatter-gather pointers */
+	    scsi_free(SCpnt->buffer, SCpnt->sglist_len);  
+	} else {
+	    if (SCpnt->buffer != SCpnt->request.buffer) {
 #ifdef DEBUG
-	printk("nosg: %x %x %d\n",SCpnt->request.buffer, SCpnt->buffer,
-		   SCpnt->bufflen);
-#endif	
-	  if (SCpnt->request.cmd == READ)
-	    memcpy(SCpnt->request.buffer, SCpnt->buffer,
-		   SCpnt->bufflen);
-	  scsi_free(SCpnt->buffer, SCpnt->bufflen);
-      };
-    };
-/*
- * 	If multiple sectors are requested in one buffer, then
- *	they will have been finished off by the first command.  If
- *	not, then we have a multi-buffer command.
- */
-    if (SCpnt->request.nr_sectors > this_count)
-      {
-	SCpnt->request.errors = 0;
-	
-	if (!SCpnt->request.bh)
-	  {
+		printk("nosg: %x %x %d\n",SCpnt->request.buffer, SCpnt->buffer,
+		       SCpnt->bufflen);
+#endif  
+		if (SCpnt->request.cmd == READ)
+		    memcpy(SCpnt->request.buffer, SCpnt->buffer,
+			   SCpnt->bufflen);
+		scsi_free(SCpnt->buffer, SCpnt->bufflen);
+	    };
+	};
+	/*
+	 * If multiple sectors are requested in one buffer, then
+	 * they will have been finished off by the first command.
+	 * If not, then we have a multi-buffer command.
+	 */
+	if (SCpnt->request.nr_sectors > this_count)
+	{
+	    SCpnt->request.errors = 0;
+	    
+	    if (!SCpnt->request.bh)
+	    {
 #ifdef DEBUG
-	    printk("sd%c : handling page request, no buffer\n",
-		   'a' + MINOR(SCpnt->request.dev));
+		printk("sd%c : handling page request, no buffer\n",
+		       'a' + MINOR(SCpnt->request.dev));
 #endif
-/*
-  The SCpnt->request.nr_sectors field is always done in 512 byte sectors,
-  even if this really isn't the case.
-*/
-	    panic("sd.c: linked page request (%lx %x)",
-		  SCpnt->request.sector, this_count);
-	  }
-      }
-    SCpnt = end_scsi_request(SCpnt, 1, this_count);
-    requeue_sd_request(SCpnt);
-    return;
-  }
-
-/* Free up any indirection buffers we allocated for DMA purposes. */
+		/*
+		 * The SCpnt->request.nr_sectors field is always done in 
+		 * 512 byte sectors, even if this really isn't the case.
+		 */
+		panic("sd.c: linked page request (%lx %x)",
+		      SCpnt->request.sector, this_count);
+	    }
+	}
+	SCpnt = end_scsi_request(SCpnt, 1, this_count);
+	requeue_sd_request(SCpnt);
+	return;
+    }
+    
+    /* Free up any indirection buffers we allocated for DMA purposes. */
     if (SCpnt->use_sg) {
-      struct scatterlist * sgpnt;
-      int i;
-      sgpnt = (struct scatterlist *) SCpnt->buffer;
-      for(i=0; i<SCpnt->use_sg; i++) {
+	struct scatterlist * sgpnt;
+	int i;
+	sgpnt = (struct scatterlist *) SCpnt->buffer;
+	for(i=0; i<SCpnt->use_sg; i++) {
 #ifdef DEBUG
-	printk("err: %x %x %d\n",SCpnt->request.buffer, SCpnt->buffer,
+	    printk("err: %x %x %d\n",SCpnt->request.buffer, SCpnt->buffer,
 		   SCpnt->bufflen);
 #endif
-	if (sgpnt[i].alt_address) {
-	  scsi_free(sgpnt[i].address, sgpnt[i].length);
+	    if (sgpnt[i].alt_address) {
+		scsi_free(sgpnt[i].address, sgpnt[i].length);
+	    };
 	};
-      };
-      scsi_free(SCpnt->buffer, SCpnt->sglist_len);  /* Free list of scatter-gather pointers */
+	scsi_free(SCpnt->buffer, SCpnt->sglist_len);  /* Free list of scatter-gather pointers */
     } else {
 #ifdef DEBUG
-      printk("nosgerr: %x %x %d\n",SCpnt->request.buffer, SCpnt->buffer,
-		   SCpnt->bufflen);
+	printk("nosgerr: %x %x %d\n",SCpnt->request.buffer, SCpnt->buffer,
+	       SCpnt->bufflen);
 #endif
-      if (SCpnt->buffer != SCpnt->request.buffer)
-	scsi_free(SCpnt->buffer, SCpnt->bufflen);
+	if (SCpnt->buffer != SCpnt->request.buffer)
+	    scsi_free(SCpnt->buffer, SCpnt->bufflen);
     };
+    
+    /*
+     * Now, if we were good little boys and girls, Santa left us a request
+     * sense buffer.  We can extract information from this, so we
+     * can choose a block to remap, etc.
+     */
 
-/*
-	Now, if we were good little boys and girls, Santa left us a request
-	sense buffer.  We can extract information from this, so we
-	can choose a block to remap, etc.
-*/
-
-        if (driver_byte(result) != 0) {
-	  if (suggestion(result) == SUGGEST_REMAP) {
+    if (driver_byte(result) != 0) {
+	if (suggestion(result) == SUGGEST_REMAP) {
 #ifdef REMAP
-/*
-	Not yet implemented.  A read will fail after being remapped,
-	a write will call the strategy routine again.
-*/
+	    /*
+	     * Not yet implemented.  A read will fail after being remapped,
+	     * a write will call the strategy routine again.
+	     */
 	    if rscsi_disks[DEVICE_NR(SCpnt->request.dev)].remap
-	      {
+	    {
 		result = 0;
-	      }
+	    }
 	    else
-	      
 #endif
-	    }
-
-	  if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) {
+	}
+	
+	if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) {
 	    if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
-	      if(rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->removable) {
-	      /* detected disc change.  set a bit and quietly refuse	*/
-	      /* further access.					*/
-	      
-		rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->changed = 1;
-		SCpnt = end_scsi_request(SCpnt, 0, this_count);
-		requeue_sd_request(SCpnt);
-		return;
-	      }
+		if(rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->removable) {
+		    /* detected disc change.  set a bit and quietly refuse
+		     * further access.
+		     */  
+		    rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->changed = 1;
+		    SCpnt = end_scsi_request(SCpnt, 0, this_count);
+		    requeue_sd_request(SCpnt);
+		    return;
+		}
 	    }
-	  }
-	  
-
-/* 	If we had an ILLEGAL REQUEST returned, then we may have
-performed an unsupported command.  The only thing this should be would
-be a ten byte read where only a six byte read was supported.  Also,
-on a system where READ CAPACITY failed, we have have read past the end
-of the 	disk. 
-*/
+	}
+	
+	
+	/* If we had an ILLEGAL REQUEST returned, then we may have
+	 * performed an unsupported command.  The only thing this should be 
+	 * would be a ten byte read where only a six byte read was supported.
+	 * Also, on a system where READ CAPACITY failed, we have have read 
+	 * past the end of the disk. 
+	 */
 
-	  if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) {
+	if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) {
 	    if (rscsi_disks[DEVICE_NR(SCpnt->request.dev)].ten) {
-	      rscsi_disks[DEVICE_NR(SCpnt->request.dev)].ten = 0;
-	      requeue_sd_request(SCpnt);
-	      result = 0;
+		rscsi_disks[DEVICE_NR(SCpnt->request.dev)].ten = 0;
+		requeue_sd_request(SCpnt);
+		result = 0;
 	    } else {
+		/* ???? */
 	    }
-	  }
-	}  /* driver byte != 0 */
-	if (result) {
-		printk("SCSI disk error : host %d id %d lun %d return code = %x\n",
-		       rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->host->host_no,
-		       rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->id,
-		       rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->lun, result);
-
-		if (driver_byte(result) & DRIVER_SENSE)
-			print_sense("sd", SCpnt);
-		SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.current_nr_sectors);
-		requeue_sd_request(SCpnt);
-		return;
 	}
+    }  /* driver byte != 0 */
+    if (result) {
+	printk("SCSI disk error : host %d channel %d id %d lun %d return code = %x\n",
+	       rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->host->host_no,
+	       rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->channel,
+	   rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->id,
+	     rscsi_disks[DEVICE_NR(SCpnt->request.dev)].device->lun, result);
+	
+	if (driver_byte(result) & DRIVER_SENSE)
+	    print_sense("sd", SCpnt);
+	SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.current_nr_sectors);
+	requeue_sd_request(SCpnt);
+	return;
+    }
 }
 
 /*
-	requeue_sd_request() is the request handler function for the sd driver.
-	Its function in life is to take block device requests, and translate
-	them to SCSI commands.
-*/
+ * requeue_sd_request() is the request handler function for the sd driver.
+ * Its function in life is to take block device requests, and translate
+ * them to SCSI commands.
+ */
 
 static void do_sd_request (void)
 {
-  Scsi_Cmnd * SCpnt = NULL;
-  struct request * req = NULL;
-  unsigned long flags;
-  int flag = 0;
-
-  save_flags(flags);
-  while (1==1){
-    cli();
-    if (CURRENT != NULL && CURRENT->dev == -1) {
-      restore_flags(flags);
-      return;
-    };
-
-    INIT_SCSI_REQUEST;
-
+    Scsi_Cmnd * SCpnt = NULL;
+    struct request * req = NULL;
+    unsigned long flags;
+    int flag = 0;
+    
+    save_flags(flags);
+    while (1==1){
+	cli();
+	if (CURRENT != NULL && CURRENT->dev == -1) {
+	    restore_flags(flags);
+	    return;
+	};
+	
+	INIT_SCSI_REQUEST;
+		
+	/* We have to be careful here. allocate_device will get a free pointer,
+	 * but there is no guarantee that it is queueable.  In normal usage, 
+	 * we want to call this, because other types of devices may have the 
+	 * host all tied up, and we want to make sure that we have at least 
+	 * one request pending for this type of device. We can also come 
+	 * through here while servicing an interrupt, because of the need to 
+	 * start another command. If we call allocate_device more than once, 
+	 * then the system can wedge if the command is not queueable. The 
+	 * request_queueable function is safe because it checks to make sure 
+	 * that the host is able to take another command before it returns
+	 * a pointer.  
+	 */
 
-/* We have to be careful here.  allocate_device will get a free pointer, but
-   there is no guarantee that it is queueable.  In normal usage, we want to
-   call this, because other types of devices may have the host all tied up,
-   and we want to make sure that we have at least one request pending for this
-   type of device.   We can also come through here while servicing an
-   interrupt, because of the need to start another command.  If we call
-   allocate_device more than once, then the system can wedge if the command
-   is not queueable.  The request_queueable function is safe because it checks
-   to make sure that the host is able to take another command before it returns
-   a pointer.  */
-
-    if (flag++ == 0)
-      SCpnt = allocate_device(&CURRENT,
-			      rscsi_disks[DEVICE_NR(MINOR(CURRENT->dev))].device, 0); 
-    else SCpnt = NULL;
+	if (flag++ == 0)
+	    SCpnt = allocate_device(&CURRENT,
+				    rscsi_disks[DEVICE_NR(MINOR(CURRENT->dev))].device, 0); 
+	else SCpnt = NULL;
+	
+	/*
+	 * The following restore_flags leads to latency problems.  FIXME.
+	 * Using a "sti()" gets rid of the latency problems but causes
+	 * race conditions and crashes.
+	 */
+	restore_flags(flags);
 
-    /*
-     * The following restore_flags leads to latency problems.  FIXME.
-     * Using a "sti()" gets rid of the latency problems but causes
-     * race conditions and crashes.
-     */
-    restore_flags(flags);
+	/* This is a performance enhancement. We dig down into the request 
+	 * list and try and find a queueable request (i.e. device not busy, 
+	 * and host able to accept another command. If we find one, then we 
+	 * queue it. This can make a big difference on systems with more than 
+	 * one disk drive.  We want to have the interrupts off when monkeying 
+	 * with the request list, because otherwise the kernel might try and 
+	 * slip in a request in between somewhere. 
+	 */
 
-/* This is a performance enhancement.  We dig down into the request list and
-   try and find a queueable request (i.e. device not busy, and host able to
-   accept another command.  If we find one, then we queue it. This can
-   make a big difference on systems with more than one disk drive.  We want
-   to have the interrupts off when monkeying with the request list, because
-   otherwise the kernel might try and slip in a request in between somewhere. */
-
-    if (!SCpnt && sd_template.nr_dev > 1){
-      struct request *req1;
-      req1 = NULL;
-      cli();
-      req = CURRENT;
-      while(req){
-	SCpnt = request_queueable(req,
-				  rscsi_disks[DEVICE_NR(MINOR(req->dev))].device);
-	if(SCpnt) break;
-	req1 = req;
-	req = req->next;
-      };
-      if (SCpnt && req->dev == -1) {
-	if (req == CURRENT) 
-	  CURRENT = CURRENT->next;
-	else
-	  req1->next = req->next;
-      };
-      restore_flags(flags);
-    };
-    
-    if (!SCpnt) return; /* Could not find anything to do */
-        
-    /* Queue command */
-    requeue_sd_request(SCpnt);
-  };  /* While */
+	if (!SCpnt && sd_template.nr_dev > 1){
+	    struct request *req1;
+	    req1 = NULL;
+	    cli();
+	    req = CURRENT;
+	    while(req){
+		SCpnt = request_queueable(req, rscsi_disks[DEVICE_NR(MINOR(req->dev))].device);
+		if(SCpnt) break;
+		req1 = req;
+		req = req->next;
+	    };
+	    if (SCpnt && req->dev == -1) {
+		if (req == CURRENT) 
+		    CURRENT = CURRENT->next;
+		else
+		    req1->next = req->next;
+	    };
+	    restore_flags(flags);
+	};
+	
+	if (!SCpnt) return; /* Could not find anything to do */
+	
+	/* Queue command */
+	requeue_sd_request(SCpnt);
+    };  /* While */
 }    
 
 static void requeue_sd_request (Scsi_Cmnd * SCpnt)
 {
-	int dev, block, this_count;
-	unsigned char cmd[10];
-	int bounce_size, contiguous;
-	int max_sg;
-	struct buffer_head * bh, *bhp;
-	char * buff, *bounce_buffer;
-
-repeat:
-
-	if(!SCpnt || SCpnt->request.dev <= 0) {
-	  do_sd_request();
-	  return;
-	}
-
-	dev =  MINOR(SCpnt->request.dev);
-	block = SCpnt->request.sector;
-	this_count = 0;
-
-#ifdef DEBUG
-	printk("Doing sd request, dev = %d, block = %d\n", dev, block);
-#endif
-
-	if (dev >= (sd_template.dev_max << 4) || 
-	    !rscsi_disks[DEVICE_NR(dev)].device ||
-	    block + SCpnt->request.nr_sectors > sd[dev].nr_sects)
-		{
-		SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
-		goto repeat;
-		}
-
-	block += sd[dev].start_sect;
-	dev = DEVICE_NR(dev);
-
-	if (rscsi_disks[dev].device->changed)
-	        {
-/*
- * quietly refuse to do anything to a changed disc until the changed bit has been reset
- */
-		/* printk("SCSI disk has been changed.  Prohibiting further I/O.\n");	*/
-		SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
-		goto repeat;
-		}
+    int dev, block, this_count;
+    unsigned char cmd[10];
+    int bounce_size, contiguous;
+    int max_sg;
+    struct buffer_head * bh, *bhp;
+    char * buff, *bounce_buffer;
+    
+ repeat:
+    
+    if(!SCpnt || SCpnt->request.dev <= 0) {
+	do_sd_request();
+	return;
+    }
+    
+    dev =  MINOR(SCpnt->request.dev);
+    block = SCpnt->request.sector;
+    this_count = 0;
 
 #ifdef DEBUG
-	printk("sd%c : real dev = /dev/sd%c, block = %d\n", 'a' + MINOR(SCpnt->request.dev), dev, block);
+    printk("Doing sd request, dev = %d, block = %d\n", dev, block);
 #endif
-
+    
+    if (dev >= (sd_template.dev_max << 4) || 
+	!rscsi_disks[DEVICE_NR(dev)].device ||
+	block + SCpnt->request.nr_sectors > sd[dev].nr_sects)
+    {
+	SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
+	goto repeat;
+    }
+    
+    block += sd[dev].start_sect;
+    dev = DEVICE_NR(dev);
+    
+    if (rscsi_disks[dev].device->changed)
+    {
 	/*
-	 * If we have a 1K hardware sectorsize, prevent access to single
-	 * 512 byte sectors.  In theory we could handle this - in fact
-	 * the scsi cdrom driver must be able to handle this because
-	 * we typically use 1K blocksizes, and cdroms typically have
-	 * 2K hardware sectorsizes.  Of course, things are simpler
-	 * with the cdrom, since it is read-only.  For performance
-	 * reasons, the filesystems should be able to handle this
-	 * and not force the scsi disk driver to use bounce buffers
-	 * for this.
+	 * quietly refuse to do anything to a changed disc until the changed 
+	 * bit has been reset
 	 */
-	if (rscsi_disks[dev].sector_size == 1024)
-	  if((block & 1) || (SCpnt->request.nr_sectors & 1)) {
-	 	printk("sd.c:Bad block number requested");
-		SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
-		goto repeat;
+	/* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */
+	SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
+	goto repeat;
+    }
+    
+#ifdef DEBUG
+    printk("sd%c : real dev = /dev/sd%c, block = %d\n", 
+	   'a' + MINOR(SCpnt->request.dev), dev, block);
+#endif
+    
+    /*
+     * If we have a 1K hardware sectorsize, prevent access to single
+     * 512 byte sectors.  In theory we could handle this - in fact
+     * the scsi cdrom driver must be able to handle this because
+     * we typically use 1K blocksizes, and cdroms typically have
+     * 2K hardware sectorsizes.  Of course, things are simpler
+     * with the cdrom, since it is read-only.  For performance
+     * reasons, the filesystems should be able to handle this
+     * and not force the scsi disk driver to use bounce buffers
+     * for this.
+     */
+    if (rscsi_disks[dev].sector_size == 1024)
+	if((block & 1) || (SCpnt->request.nr_sectors & 1)) {
+	    printk("sd.c:Bad block number requested");
+	    SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
+	    goto repeat;
 	}
-	
-	switch (SCpnt->request.cmd)
-		{
-		case WRITE :
-			if (!rscsi_disks[dev].device->writeable)
-				{
-				SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
-				goto repeat;
-				}
-			cmd[0] = WRITE_6;
-			break;
-		case READ :
-			cmd[0] = READ_6;
-			break;
-		default :
-			panic ("Unknown sd command %d\n", SCpnt->request.cmd);
-		      }
-
-	SCpnt->this_count = 0;
-
-	/* If the host adapter can deal with very large scatter-gather
-	   requests, it is a waste of time to cluster */
-	contiguous = (!CLUSTERABLE_DEVICE(SCpnt) ? 0 :1);
-	bounce_buffer = NULL;
-	bounce_size = (SCpnt->request.nr_sectors << 9);
-
-	/* First see if we need a bounce buffer for this request.  If we do, make sure
-	   that we can allocate a buffer.  Do not waste space by allocating a bounce
-	   buffer if we are straddling the 16Mb line */
-
-	
-	if (contiguous && SCpnt->request.bh &&
-	    ((long) SCpnt->request.bh->b_data) + (SCpnt->request.nr_sectors << 9) - 1 > 
-	    ISA_DMA_THRESHOLD && SCpnt->host->unchecked_isa_dma) {
-	  if(((long) SCpnt->request.bh->b_data) > ISA_DMA_THRESHOLD)
+    
+    switch (SCpnt->request.cmd)
+    {
+    case WRITE :
+	if (!rscsi_disks[dev].device->writeable)
+	{
+	    SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
+	    goto repeat;
+	}
+	cmd[0] = WRITE_6;
+	break;
+    case READ :
+	cmd[0] = READ_6;
+	break;
+    default :
+	panic ("Unknown sd command %d\n", SCpnt->request.cmd);
+    }
+    
+    SCpnt->this_count = 0;
+    
+    /* If the host adapter can deal with very large scatter-gather
+     * requests, it is a waste of time to cluster 
+     */
+    contiguous = (!CLUSTERABLE_DEVICE(SCpnt) ? 0 :1);
+    bounce_buffer = NULL;
+    bounce_size = (SCpnt->request.nr_sectors << 9);
+    
+    /* First see if we need a bounce buffer for this request. If we do, make 
+     * sure that we can allocate a buffer. Do not waste space by allocating 
+     * a bounce buffer if we are straddling the 16Mb line 
+     */ 
+    if (contiguous && SCpnt->request.bh &&
+	((long) SCpnt->request.bh->b_data) 
+	+ (SCpnt->request.nr_sectors << 9) - 1 > ISA_DMA_THRESHOLD 
+	&& SCpnt->host->unchecked_isa_dma) {
+	if(((long) SCpnt->request.bh->b_data) > ISA_DMA_THRESHOLD)
 	    bounce_buffer = (char *) scsi_malloc(bounce_size);
-	  if(!bounce_buffer) contiguous = 0;
-	};
-
-	if(contiguous && SCpnt->request.bh && SCpnt->request.bh->b_reqnext)
-	  for(bh = SCpnt->request.bh, bhp = bh->b_reqnext; bhp; bh = bhp, 
-	      bhp = bhp->b_reqnext) {
+	if(!bounce_buffer) contiguous = 0;
+    };
+    
+    if(contiguous && SCpnt->request.bh && SCpnt->request.bh->b_reqnext)
+	for(bh = SCpnt->request.bh, bhp = bh->b_reqnext; bhp; bh = bhp, 
+	    bhp = bhp->b_reqnext) {
 	    if(!CONTIGUOUS_BUFFERS(bh,bhp)) { 
-	      if(bounce_buffer) scsi_free(bounce_buffer, bounce_size);
-	      contiguous = 0;
-	      break;
+		if(bounce_buffer) scsi_free(bounce_buffer, bounce_size);
+		contiguous = 0;
+		break;
 	    } 
-	  };
-	if (!SCpnt->request.bh || contiguous) {
-
-	  /* case of page request (i.e. raw device), or unlinked buffer */
-	  this_count = SCpnt->request.nr_sectors;
-	  buff = SCpnt->request.buffer;
-	  SCpnt->use_sg = 0;
-
-	} else if (SCpnt->host->sg_tablesize == 0 ||
-		   (need_isa_buffer && 
-		    dma_free_sectors <= 10)) {
-
-	  /* Case of host adapter that cannot scatter-gather.  We also
-	   come here if we are running low on DMA buffer memory.  We set
-	   a threshold higher than that we would need for this request so
-	   we leave room for other requests.  Even though we would not need
-	   it all, we need to be conservative, because if we run low enough
-	   we have no choice but to panic. */
-
-	  if (SCpnt->host->sg_tablesize != 0 &&
-	      need_isa_buffer && 
-	      dma_free_sectors <= 10)
+	};
+    if (!SCpnt->request.bh || contiguous) {
+	
+	/* case of page request (i.e. raw device), or unlinked buffer */
+	this_count = SCpnt->request.nr_sectors;
+	buff = SCpnt->request.buffer;
+	SCpnt->use_sg = 0;
+	
+    } else if (SCpnt->host->sg_tablesize == 0 ||
+	       (need_isa_buffer && dma_free_sectors <= 10)) {
+	
+	/* Case of host adapter that cannot scatter-gather.  We also
+	 * come here if we are running low on DMA buffer memory.  We set
+	 * a threshold higher than that we would need for this request so
+	 * we leave room for other requests.  Even though we would not need
+	 * it all, we need to be conservative, because if we run low enough
+	 * we have no choice but to panic. 
+	 */
+	if (SCpnt->host->sg_tablesize != 0 &&
+	    need_isa_buffer && 
+	    dma_free_sectors <= 10)
 	    printk("Warning: SCSI DMA buffer space running low.  Using non scatter-gather I/O.\n");
-
-	  this_count = SCpnt->request.current_nr_sectors;
-	  buff = SCpnt->request.buffer;
-	  SCpnt->use_sg = 0;
-
-	} else {
-
-	  /* Scatter-gather capable host adapter */
-	  struct scatterlist * sgpnt;
-	  int count, this_count_max;
-	  int counted;
-
-	  bh = SCpnt->request.bh;
-	  this_count = 0;
-	  this_count_max = (rscsi_disks[dev].ten ? 0xffff : 0xff);
-	  count = 0;
-	  bhp = NULL;
-	  while(bh) {
+	
+	this_count = SCpnt->request.current_nr_sectors;
+	buff = SCpnt->request.buffer;
+	SCpnt->use_sg = 0;
+	
+    } else {
+	
+	/* Scatter-gather capable host adapter */
+	struct scatterlist * sgpnt;
+	int count, this_count_max;
+	int counted;
+	
+	bh = SCpnt->request.bh;
+	this_count = 0;
+	this_count_max = (rscsi_disks[dev].ten ? 0xffff : 0xff);
+	count = 0;
+	bhp = NULL;
+	while(bh) {
 	    if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
 	    if(!bhp || !CONTIGUOUS_BUFFERS(bhp,bh) ||
 	       !CLUSTERABLE_DEVICE(SCpnt) ||
 	       (SCpnt->host->unchecked_isa_dma &&
-	       ((unsigned long) bh->b_data-1) == ISA_DMA_THRESHOLD)) {
-	      if (count < SCpnt->host->sg_tablesize) count++;
-	      else break;
+		((unsigned long) bh->b_data-1) == ISA_DMA_THRESHOLD)) {
+		if (count < SCpnt->host->sg_tablesize) count++;
+		else break;
 	    };
 	    this_count += (bh->b_size >> 9);
 	    bhp = bh;
 	    bh = bh->b_reqnext;
-	  };
+	};
 #if 0
-	  if(SCpnt->host->unchecked_isa_dma &&
-	     ((unsigned int) SCpnt->request.bh->b_data-1) == ISA_DMA_THRESHOLD) count--;
+	if(SCpnt->host->unchecked_isa_dma &&
+	   ((unsigned int) SCpnt->request.bh->b_data-1) == ISA_DMA_THRESHOLD) count--;
 #endif
-	  SCpnt->use_sg = count;  /* Number of chains */
-	  count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes*/
-	  while( count < (SCpnt->use_sg * sizeof(struct scatterlist))) 
+	SCpnt->use_sg = count;  /* Number of chains */
+	count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes */
+	while( count < (SCpnt->use_sg * sizeof(struct scatterlist))) 
 	    count = count << 1;
-	  SCpnt->sglist_len = count;
-	  max_sg = count / sizeof(struct scatterlist);
-	  if(SCpnt->host->sg_tablesize < max_sg) max_sg = SCpnt->host->sg_tablesize;
-	  sgpnt = (struct scatterlist * ) scsi_malloc(count);
-	  memset(sgpnt, 0, count);  /* Zero so it is easy to fill */
-	  if (!sgpnt) {
+	SCpnt->sglist_len = count;
+	max_sg = count / sizeof(struct scatterlist);
+	if(SCpnt->host->sg_tablesize < max_sg) 
+	    max_sg = SCpnt->host->sg_tablesize;
+	sgpnt = (struct scatterlist * ) scsi_malloc(count);
+	if (!sgpnt) {
 	    printk("Warning - running *really* short on DMA buffers\n");
-	    SCpnt->use_sg = 0;  /* No memory left - bail out */
+	    SCpnt->use_sg = 0;    /* No memory left - bail out */
 	    this_count = SCpnt->request.current_nr_sectors;
 	    buff = SCpnt->request.buffer;
-	  } else {
+	} else {
+	    memset(sgpnt, 0, count);  /* Zero so it is easy to fill, but only
+				       * if memory is available 
+				       */
 	    buff = (char *) sgpnt;
 	    counted = 0;
 	    for(count = 0, bh = SCpnt->request.bh, bhp = bh->b_reqnext;
 		count < SCpnt->use_sg && bh; 
 		count++, bh = bhp) {
-
-	      bhp = bh->b_reqnext;
-
-	      if(!sgpnt[count].address) sgpnt[count].address = bh->b_data;
-	      sgpnt[count].length += bh->b_size;
-	      counted += bh->b_size >> 9;
-
-	      if (((long) sgpnt[count].address) + sgpnt[count].length - 1 > 
-		  ISA_DMA_THRESHOLD && (SCpnt->host->unchecked_isa_dma) &&
-		  !sgpnt[count].alt_address) {
-		sgpnt[count].alt_address = sgpnt[count].address;
-		/* We try and avoid exhausting the DMA pool, since it is easier
-		   to control usage here.  In other places we might have a more
-		   pressing need, and we would be screwed if we ran out */
-		if(dma_free_sectors < (sgpnt[count].length >> 9) + 10) {
-		  sgpnt[count].address = NULL;
-		} else {
-		  sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
-		};
-/* If we start running low on DMA buffers, we abort the scatter-gather
-   operation, and free all of the memory we have allocated.  We want to
-   ensure that all scsi operations are able to do at least a non-scatter/gather
-   operation */
-		if(sgpnt[count].address == NULL){ /* Out of dma memory */
+		
+		bhp = bh->b_reqnext;
+		
+		if(!sgpnt[count].address) sgpnt[count].address = bh->b_data;
+		sgpnt[count].length += bh->b_size;
+		counted += bh->b_size >> 9;
+		
+		if (((long) sgpnt[count].address) + sgpnt[count].length - 1 > 
+		    ISA_DMA_THRESHOLD && (SCpnt->host->unchecked_isa_dma) &&
+		    !sgpnt[count].alt_address) {
+		    sgpnt[count].alt_address = sgpnt[count].address;
+		    /* We try and avoid exhausting the DMA pool, since it is 
+		     * easier to control usage here. In other places we might 
+		     * have a more pressing need, and we would be screwed if 
+		     * we ran out */
+		    if(dma_free_sectors < (sgpnt[count].length >> 9) + 10) {
+			sgpnt[count].address = NULL;
+		    } else {
+			sgpnt[count].address = 
+			    (char *) scsi_malloc(sgpnt[count].length);
+		    };
+		    /* If we start running low on DMA buffers, we abort the 
+		     * scatter-gather operation, and free all of the memory 
+		     * we have allocated.  We want to ensure that all scsi 
+		     * operations are able to do at least a non-scatter/gather
+		     * operation */
+		    if(sgpnt[count].address == NULL){ /* Out of dma memory */
 #if 0
-		  printk("Warning: Running low on SCSI DMA buffers");
-		  /* Try switching back to a non scatter-gather operation. */
-		  while(--count >= 0){
-		    if(sgpnt[count].alt_address) 
-		      scsi_free(sgpnt[count].address, sgpnt[count].length);
-		  };
-		  this_count = SCpnt->request.current_nr_sectors;
-		  buff = SCpnt->request.buffer;
-		  SCpnt->use_sg = 0;
-		  scsi_free(sgpnt, SCpnt->sglist_len);
+			printk("Warning: Running low on SCSI DMA buffers");
+			/* Try switching back to a non s-g operation. */
+			while(--count >= 0){
+			    if(sgpnt[count].alt_address) 
+				scsi_free(sgpnt[count].address, 
+					  sgpnt[count].length);
+			};
+			this_count = SCpnt->request.current_nr_sectors;
+			buff = SCpnt->request.buffer;
+			SCpnt->use_sg = 0;
+			scsi_free(sgpnt, SCpnt->sglist_len);
 #endif
-		  SCpnt->use_sg = count;
-		  this_count = counted -= bh->b_size >> 9;
-		  break;
-		};
-
-	      };
-
-	      /* Only cluster buffers if we know that we can supply DMA buffers
-		 large enough to satisfy the request.  Do not cluster a new
-		 request if this would mean that we suddenly need to start
-		 using DMA bounce buffers */
-	      if(bhp && CONTIGUOUS_BUFFERS(bh,bhp) && CLUSTERABLE_DEVICE(SCpnt)) {
-		char * tmp;
-
-		if (((long) sgpnt[count].address) + sgpnt[count].length +
-		    bhp->b_size - 1 > ISA_DMA_THRESHOLD && 
-		    (SCpnt->host->unchecked_isa_dma) &&
-		    !sgpnt[count].alt_address) continue;
-
-		if(!sgpnt[count].alt_address) {count--; continue; }
-		if(dma_free_sectors > 10)
-		  tmp = (char *) scsi_malloc(sgpnt[count].length + bhp->b_size);
-		else {
-		  tmp = NULL;
-		  max_sg = SCpnt->use_sg;
-		};
-		if(tmp){
-		  scsi_free(sgpnt[count].address, sgpnt[count].length);
-		  sgpnt[count].address = tmp;
-		  count--;
-		  continue;
+			SCpnt->use_sg = count;
+			this_count = counted -= bh->b_size >> 9;
+			break;
+		    };
+		    
 		};
-
-		/* If we are allowed another sg chain, then increment counter so we
-		   can insert it.  Otherwise we will end up truncating */
-
-		if (SCpnt->use_sg < max_sg) SCpnt->use_sg++;
-	      };  /* contiguous buffers */
+		
+		/* Only cluster buffers if we know that we can supply DMA 
+		 * buffers large enough to satisfy the request. Do not cluster
+		 * a new request if this would mean that we suddenly need to 
+		 * start using DMA bounce buffers */
+		if(bhp && CONTIGUOUS_BUFFERS(bh,bhp) 
+		   && CLUSTERABLE_DEVICE(SCpnt)) {
+		    char * tmp;
+		    
+		    if (((long) sgpnt[count].address) + sgpnt[count].length +
+			bhp->b_size - 1 > ISA_DMA_THRESHOLD && 
+			(SCpnt->host->unchecked_isa_dma) &&
+			!sgpnt[count].alt_address) continue;
+		    
+		    if(!sgpnt[count].alt_address) {count--; continue; }
+		    if(dma_free_sectors > 10)
+			tmp = (char *) scsi_malloc(sgpnt[count].length 
+						   + bhp->b_size);
+		    else {
+			tmp = NULL;
+			max_sg = SCpnt->use_sg;
+		    };
+		    if(tmp){
+			scsi_free(sgpnt[count].address, sgpnt[count].length);
+			sgpnt[count].address = tmp;
+			count--;
+			continue;
+		    };
+		    
+		    /* If we are allowed another sg chain, then increment 
+		     * counter so we can insert it.  Otherwise we will end 
+		     up truncating */
+		    
+		    if (SCpnt->use_sg < max_sg) SCpnt->use_sg++;
+		};  /* contiguous buffers */
 	    }; /* for loop */
-
-	    this_count = counted; /* This is actually how many we are going to transfer */
-
-	    if(count < SCpnt->use_sg || SCpnt->use_sg > SCpnt->host->sg_tablesize){
-	      bh = SCpnt->request.bh;
-	      printk("Use sg, count %d %x %d\n", SCpnt->use_sg, count, dma_free_sectors);
-	      printk("maxsg = %x, counted = %d this_count = %d\n", max_sg, counted, this_count);
-	      while(bh){
-		printk("[%p %lx] ", bh->b_data, bh->b_size);
-		bh = bh->b_reqnext;
-	      };
-	      if(SCpnt->use_sg < 16)
-		for(count=0; count<SCpnt->use_sg; count++)
-		  printk("{%d:%p %p %d}  ", count,
-			 sgpnt[count].address,
-			 sgpnt[count].alt_address,
-			 sgpnt[count].length);
-	      panic("Ooops");
+	    
+	    /* This is actually how many we are going to transfer */
+	    this_count = counted; 
+	    
+	    if(count < SCpnt->use_sg || SCpnt->use_sg 
+	       > SCpnt->host->sg_tablesize){
+		bh = SCpnt->request.bh;
+		printk("Use sg, count %d %x %d\n", 
+		       SCpnt->use_sg, count, dma_free_sectors);
+		printk("maxsg = %x, counted = %d this_count = %d\n", 
+		       max_sg, counted, this_count);
+		while(bh){
+		    printk("[%p %lx] ", bh->b_data, bh->b_size);
+		    bh = bh->b_reqnext;
+		};
+		if(SCpnt->use_sg < 16)
+		    for(count=0; count<SCpnt->use_sg; count++)
+			printk("{%d:%p %p %d}  ", count,
+			       sgpnt[count].address,
+			       sgpnt[count].alt_address,
+			       sgpnt[count].length);
+		panic("Ooops");
 	    };
-
+	    
 	    if (SCpnt->request.cmd == WRITE)
-	      for(count=0; count<SCpnt->use_sg; count++)
-		if(sgpnt[count].alt_address)
-		  memcpy(sgpnt[count].address, sgpnt[count].alt_address, 
-			 sgpnt[count].length);
-	  };  /* Able to malloc sgpnt */
-	};  /* Host adapter capable of scatter-gather */
-
-/* Now handle the possibility of DMA to addresses > 16Mb */
-
-	if(SCpnt->use_sg == 0){
-	  if (((long) buff) + (this_count << 9) - 1 > ISA_DMA_THRESHOLD && 
+		for(count=0; count<SCpnt->use_sg; count++)
+		    if(sgpnt[count].alt_address)
+			memcpy(sgpnt[count].address, sgpnt[count].alt_address, 
+			       sgpnt[count].length);
+	};  /* Able to malloc sgpnt */
+    };  /* Host adapter capable of scatter-gather */
+    
+    /* Now handle the possibility of DMA to addresses > 16Mb */
+    
+    if(SCpnt->use_sg == 0){
+	if (((long) buff) + (this_count << 9) - 1 > ISA_DMA_THRESHOLD && 
 	    (SCpnt->host->unchecked_isa_dma)) {
 	    if(bounce_buffer)
-	      buff = bounce_buffer;
+		buff = bounce_buffer;
 	    else
-	      buff = (char *) scsi_malloc(this_count << 9);
+		buff = (char *) scsi_malloc(this_count << 9);
 	    if(buff == NULL) {  /* Try backing off a bit if we are low on mem*/
-	      this_count = SCpnt->request.current_nr_sectors;
-	      buff = (char *) scsi_malloc(this_count << 9);
-	      if(!buff) panic("Ran out of DMA buffers.");
+		this_count = SCpnt->request.current_nr_sectors;
+		buff = (char *) scsi_malloc(this_count << 9);
+		if(!buff) panic("Ran out of DMA buffers.");
 	    };
 	    if (SCpnt->request.cmd == WRITE)
-	      memcpy(buff, (char *)SCpnt->request.buffer, this_count << 9);
-	  };
+		memcpy(buff, (char *)SCpnt->request.buffer, this_count << 9);
 	};
+    };
 #ifdef DEBUG
-	printk("sd%c : %s %d/%d 512 byte blocks.\n", 'a' + MINOR(SCpnt->request.dev),
-		(SCpnt->request.cmd == WRITE) ? "writing" : "reading",
-		this_count, SCpnt->request.nr_sectors);
+    printk("sd%c : %s %d/%d 512 byte blocks.\n", 
+	   'a' + MINOR(SCpnt->request.dev),
+	   (SCpnt->request.cmd == WRITE) ? "writing" : "reading",
+	   this_count, SCpnt->request.nr_sectors);
 #endif
-
-	cmd[1] = (SCpnt->lun << 5) & 0xe0;
-
-	if (rscsi_disks[dev].sector_size == 1024){
-	  if(block & 1) panic("sd.c:Bad block number requested");
-	  if(this_count & 1) panic("sd.c:Bad block number requested");
-	  block = block >> 1;
-	  this_count = this_count >> 1;
-	};
-
-	if (rscsi_disks[dev].sector_size == 256){
-	  block = block << 1;
-	  this_count = this_count << 1;
-	};
-
-	if (((this_count > 0xff) ||  (block > 0x1fffff)) && rscsi_disks[dev].ten)
-		{
-		if (this_count > 0xffff)
-			this_count = 0xffff;
-
-		cmd[0] += READ_10 - READ_6 ;
-		cmd[2] = (unsigned char) (block >> 24) & 0xff;
-		cmd[3] = (unsigned char) (block >> 16) & 0xff;
-		cmd[4] = (unsigned char) (block >> 8) & 0xff;
-		cmd[5] = (unsigned char) block & 0xff;
-		cmd[6] = cmd[9] = 0;
-		cmd[7] = (unsigned char) (this_count >> 8) & 0xff;
-		cmd[8] = (unsigned char) this_count & 0xff;
-		}
-	else
-		{
-		if (this_count > 0xff)
-			this_count = 0xff;
-
-		cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
-		cmd[2] = (unsigned char) ((block >> 8) & 0xff);
-		cmd[3] = (unsigned char) block & 0xff;
-		cmd[4] = (unsigned char) this_count;
-		cmd[5] = 0;
-		}
-
-/*
- * We shouldn't disconnect in the middle of a sector, so with a dumb 
- * host adapter, it's safe to assume that we can at least transfer 
- * this many bytes between each connect / disconnect.  
- */
-
-        SCpnt->transfersize = rscsi_disks[dev].sector_size;
-        SCpnt->underflow = this_count << 9; 
-	scsi_do_cmd (SCpnt, (void *) cmd, buff, 
-		     this_count * rscsi_disks[dev].sector_size,
-		     rw_intr, 
-		     (SCpnt->device->type == TYPE_DISK ? 
-		                     SD_TIMEOUT : SD_MOD_TIMEOUT),
-		     MAX_RETRIES);
+    
+    cmd[1] = (SCpnt->lun << 5) & 0xe0;
+    
+    if (rscsi_disks[dev].sector_size == 1024){
+	if(block & 1) panic("sd.c:Bad block number requested");
+	if(this_count & 1) panic("sd.c:Bad block number requested");
+	block = block >> 1;
+	this_count = this_count >> 1;
+    };
+    
+    if (rscsi_disks[dev].sector_size == 256){
+	block = block << 1;
+	this_count = this_count << 1;
+    };
+    
+    if (((this_count > 0xff) ||  (block > 0x1fffff)) && rscsi_disks[dev].ten)
+    {
+	if (this_count > 0xffff)
+	    this_count = 0xffff;
+	
+	cmd[0] += READ_10 - READ_6 ;
+	cmd[2] = (unsigned char) (block >> 24) & 0xff;
+	cmd[3] = (unsigned char) (block >> 16) & 0xff;
+	cmd[4] = (unsigned char) (block >> 8) & 0xff;
+	cmd[5] = (unsigned char) block & 0xff;
+	cmd[6] = cmd[9] = 0;
+	cmd[7] = (unsigned char) (this_count >> 8) & 0xff;
+	cmd[8] = (unsigned char) this_count & 0xff;
+    }
+    else
+    {
+	if (this_count > 0xff)
+	    this_count = 0xff;
+	
+	cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
+	cmd[2] = (unsigned char) ((block >> 8) & 0xff);
+	cmd[3] = (unsigned char) block & 0xff;
+	cmd[4] = (unsigned char) this_count;
+	cmd[5] = 0;
+    }
+    
+    /*
+     * We shouldn't disconnect in the middle of a sector, so with a dumb 
+     * host adapter, it's safe to assume that we can at least transfer 
+     * this many bytes between each connect / disconnect.  
+     */
+    
+    SCpnt->transfersize = rscsi_disks[dev].sector_size;
+    SCpnt->underflow = this_count << 9; 
+    scsi_do_cmd (SCpnt, (void *) cmd, buff, 
+		 this_count * rscsi_disks[dev].sector_size,
+		 rw_intr, 
+		 (SCpnt->device->type == TYPE_DISK ? 
+		  SD_TIMEOUT : SD_MOD_TIMEOUT),
+		 MAX_RETRIES);
 }
 
 static int check_scsidisk_media_change(dev_t full_dev){
-        int retval;
-	int target;
-	struct inode inode;
-	int flag = 0;
-
-	target =  DEVICE_NR(MINOR(full_dev));
-
-	if (target >= sd_template.dev_max ||
-	    !rscsi_disks[target].device) {
-		printk("SCSI disk request error: invalid device.\n");
-		return 0;
-	};
-
-	if(!rscsi_disks[target].device->removable) return 0;
-
-	inode.i_rdev = full_dev;  /* This is all we really need here */
-	retval = sd_ioctl(&inode, NULL, SCSI_IOCTL_TEST_UNIT_READY, 0);
-
-	if(retval){ /* Unable to test, unit probably not ready.  This usually
-		     means there is no disc in the drive.  Mark as changed,
-		     and we will figure it out later once the drive is
-		     available again.  */
-
-	  rscsi_disks[target].device->changed = 1;
-	  return 1; /* This will force a flush, if called from
-		       check_disk_change */
-	};
-
-	retval = rscsi_disks[target].device->changed;
-	if(!flag) rscsi_disks[target].device->changed = 0;
-	return retval;
+    int retval;
+    int target;
+    struct inode inode;
+    int flag = 0;
+    
+    target =  DEVICE_NR(MINOR(full_dev));
+    
+    if (target >= sd_template.dev_max ||
+	!rscsi_disks[target].device) {
+	printk("SCSI disk request error: invalid device.\n");
+	return 0;
+    };
+    
+    if(!rscsi_disks[target].device->removable) return 0;
+    
+    inode.i_rdev = full_dev;  /* This is all we really need here */
+    retval = sd_ioctl(&inode, NULL, SCSI_IOCTL_TEST_UNIT_READY, 0);
+    
+    if(retval){ /* Unable to test, unit probably not ready.  This usually
+		 * means there is no disc in the drive.  Mark as changed,
+		 * and we will figure it out later once the drive is
+		 * available again.  */
+	
+	rscsi_disks[target].device->changed = 1;
+	return 1; /* This will force a flush, if called from
+		   * check_disk_change */
+    };
+    
+    retval = rscsi_disks[target].device->changed;
+    if(!flag) rscsi_disks[target].device->changed = 0;
+    return retval;
 }
 
 static void sd_init_done (Scsi_Cmnd * SCpnt)
 {
-  struct request * req;
-  
-  req = &SCpnt->request;
-  req->dev = 0xfffe; /* Busy, but indicate request done */
-  
-  if (req->sem != NULL) {
-    up(req->sem);
-  }
+    struct request * req;
+    
+    req = &SCpnt->request;
+    req->dev = 0xfffe; /* Busy, but indicate request done */
+    
+    if (req->sem != NULL) {
+	up(req->sem);
+    }
 }
 
 static int sd_init_onedisk(int i)
 {
-  unsigned char cmd[10];
-  unsigned char *buffer;
-  unsigned long spintime;
-  int the_result, retries;
-  Scsi_Cmnd * SCpnt;
-
-  /* We need to retry the READ_CAPACITY because a UNIT_ATTENTION is considered
-     a fatal error, and many devices report such an error just after a scsi
-     bus reset. */
-
-  SCpnt = allocate_device(NULL, rscsi_disks[i].device, 1);
-  buffer = (unsigned char *) scsi_malloc(512);
-
-  spintime = 0;
-
-  /* Spin up drives, as required.  Only do this at boot time */
-  if (current == task[0]){
-    do{
-      cmd[0] = TEST_UNIT_READY;
-      cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
-      memset ((void *) &cmd[2], 0, 8);
-      SCpnt->request.dev = 0xffff;  /* Mark as really busy again */
-      SCpnt->cmd_len = 0;
-      SCpnt->sense_buffer[0] = 0;
-      SCpnt->sense_buffer[2] = 0;
-      
-      scsi_do_cmd (SCpnt,
-		   (void *) cmd, (void *) buffer,
-		   512, sd_init_done,  SD_TIMEOUT,
-		   MAX_RETRIES);
-      
-      while(SCpnt->request.dev != 0xfffe) barrier();
-      
-      the_result = SCpnt->result;
-      
-      /* Look for non-removable devices that return NOT_READY.  Issue command
-	 to spin up drive for these cases. */
-      if(the_result && !rscsi_disks[i].device->removable && 
-	 SCpnt->sense_buffer[2] == NOT_READY) {
-	int time1;
-	if(!spintime){
-	  printk( "sd%c: Spinning up disk...", 'a' + i );
-	  cmd[0] = START_STOP;
-	  cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
-	  cmd[1] |= 1;  /* Return immediately */
-	  memset ((void *) &cmd[2], 0, 8);
-	  cmd[4] = 1; /* Start spin cycle */
-	  SCpnt->request.dev = 0xffff;  /* Mark as really busy again */
-	  SCpnt->cmd_len = 0;
-	  SCpnt->sense_buffer[0] = 0;
-	  SCpnt->sense_buffer[2] = 0;
-	  
-	  scsi_do_cmd (SCpnt,
-		       (void *) cmd, (void *) buffer,
-		       512, sd_init_done,  SD_TIMEOUT,
-		       MAX_RETRIES);
-	  
-	  while(SCpnt->request.dev != 0xfffe) barrier();
-
-	  spintime = jiffies;
-	};
-
-	time1 = jiffies;
-	while(jiffies < time1 + HZ); /* Wait 1 second for next try */
-	printk( "." );
-      };
-    } while(the_result && spintime && spintime+100*HZ > jiffies);
-    if (spintime) {
-       if (the_result)
-           printk( "not responding...\n" );
-       else
-           printk( "ready\n" );
-    }
-  };  /* current == task[0] */
-
-
-  retries = 3;
-  do {
-    cmd[0] = READ_CAPACITY;
-    cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
-    memset ((void *) &cmd[2], 0, 8);
-    memset ((void *) buffer, 0, 8);
-    SCpnt->request.dev = 0xffff;  /* Mark as really busy again */
-    SCpnt->cmd_len = 0;
-    SCpnt->sense_buffer[0] = 0;
-    SCpnt->sense_buffer[2] = 0;
-    
-    scsi_do_cmd (SCpnt,
-		 (void *) cmd, (void *) buffer,
-		 8, sd_init_done,  SD_TIMEOUT,
-		 MAX_RETRIES);
+    unsigned char cmd[10];
+    unsigned char *buffer;
+    unsigned long spintime;
+    int the_result, retries;
+    Scsi_Cmnd * SCpnt;
     
-    if (current == task[0])
-      while(SCpnt->request.dev != 0xfffe) barrier();
-    else
-      if (SCpnt->request.dev != 0xfffe){
-      	struct semaphore sem = MUTEX_LOCKED;
-	SCpnt->request.sem = &sem;
-	down(&sem);
-	/* Hmm.. Have to ask about this one.. */
-	while (SCpnt->request.dev != 0xfffe) schedule();
-      };
-    
-    the_result = SCpnt->result;
-    retries--;
-
-  } while(the_result && retries);
-
-  SCpnt->request.dev = -1;  /* Mark as not busy */
-
-  wake_up(&SCpnt->device->device_wait); 
-
-  /* Wake up a process waiting for device*/
-
-  /*
-   *	The SCSI standard says "READ CAPACITY is necessary for self configuring software"
-   *	While not mandatory, support of READ CAPACITY is strongly encouraged.
-   *	We used to die if we couldn't successfully do a READ CAPACITY.
-   *	But, now we go on about our way.  The side effects of this are
-   *
-   *	1.  We can't know block size with certainty.  I have said "512 bytes is it"
-   *	   	as this is most common.
-   *
-   *	2.  Recovery from when some one attempts to read past the end of the raw device will
-   *	    be slower.
-   */
-
-  if (the_result)
+    /* We need to retry the READ_CAPACITY because a UNIT_ATTENTION is 
+     * considered a fatal error, and many devices report such an error 
+     * just after a scsi bus reset. */
+    
+    SCpnt = allocate_device(NULL, rscsi_disks[i].device, 1);
+    buffer = (unsigned char *) scsi_malloc(512);
+    
+    spintime = 0;
+    
+    /* Spin up drives, as required.  Only do this at boot time */
+    if (current->pid == 0){
+	do{
+	    retries = 0;
+	    while(retries < 3)
+	    {
+		cmd[0] = TEST_UNIT_READY;
+		cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
+		memset ((void *) &cmd[2], 0, 8);
+		SCpnt->request.dev = 0xffff;  /* Mark as really busy again */
+		SCpnt->cmd_len = 0;
+		SCpnt->sense_buffer[0] = 0;
+		SCpnt->sense_buffer[2] = 0;
+		
+		scsi_do_cmd (SCpnt,
+			     (void *) cmd, (void *) buffer,
+			     512, sd_init_done,  SD_TIMEOUT,
+			     MAX_RETRIES);
+		
+		while(SCpnt->request.dev != 0xfffe) barrier();
+		
+		the_result = SCpnt->result;
+		retries++;
+		if(   the_result == 0
+		   || SCpnt->sense_buffer[2] != UNIT_ATTENTION)
+		    break;
+	    }
+	    
+	    /* Look for non-removable devices that return NOT_READY.  
+	     * Issue command to spin up drive for these cases. */
+	    if(the_result && !rscsi_disks[i].device->removable && 
+	       SCpnt->sense_buffer[2] == NOT_READY) {
+		int time1;
+		if(!spintime){
+		    printk( "sd%c: Spinning up disk...", 'a' + i );
+		    cmd[0] = START_STOP;
+		    cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
+		    cmd[1] |= 1;  /* Return immediately */
+		    memset ((void *) &cmd[2], 0, 8);
+		    cmd[4] = 1; /* Start spin cycle */
+		    /* Mark as really busy again */
+		    SCpnt->request.dev = 0xffff; 
+		    SCpnt->cmd_len = 0;
+		    SCpnt->sense_buffer[0] = 0;
+		    SCpnt->sense_buffer[2] = 0;
+		    
+		    scsi_do_cmd (SCpnt,
+				 (void *) cmd, (void *) buffer,
+				 512, sd_init_done,  SD_TIMEOUT,
+				 MAX_RETRIES);
+		    
+		    while(SCpnt->request.dev != 0xfffe)
+	    barrier();
+		    
+		    spintime = jiffies;
+		};
+		
+		time1 = jiffies;
+		while(jiffies < time1 + HZ); /* Wait 1 second for next try */
+		printk( "." );
+	    };
+	} while(the_result && spintime && spintime+100*HZ > jiffies);
+	if (spintime) {
+	    if (the_result)
+		printk( "not responding...\n" );
+	    else
+		printk( "ready\n" );
+	}
+    };  /* current->pid == 0 */
+    
+    
+    retries = 3;
+    do {
+	cmd[0] = READ_CAPACITY;
+	cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
+	memset ((void *) &cmd[2], 0, 8);
+	memset ((void *) buffer, 0, 8);
+	SCpnt->request.dev = 0xffff;  /* Mark as really busy again */
+	SCpnt->cmd_len = 0;
+	SCpnt->sense_buffer[0] = 0;
+	SCpnt->sense_buffer[2] = 0;
+	
+	scsi_do_cmd (SCpnt,
+		     (void *) cmd, (void *) buffer,
+		     8, sd_init_done,  SD_TIMEOUT,
+		     MAX_RETRIES);
+	
+	if (current->pid == 0)
+	    while(SCpnt->request.dev != 0xfffe)
+	barrier();
+	else
+	    if (SCpnt->request.dev != 0xfffe){
+		struct semaphore sem = MUTEX_LOCKED;
+		SCpnt->request.sem = &sem;
+		down(&sem);
+		/* Hmm.. Have to ask about this one.. */
+		while (SCpnt->request.dev != 0xfffe) 
+	    schedule();
+	    };
+	
+	the_result = SCpnt->result;
+	retries--;
+	
+    } while(the_result && retries);
+    
+    SCpnt->request.dev = -1;  /* Mark as not busy */
+    
+    wake_up(&SCpnt->device->device_wait); 
+    
+    /* Wake up a process waiting for device */
+    
+    /*
+     * The SCSI standard says: 
+     * "READ CAPACITY is necessary for self configuring software"
+     *  While not mandatory, support of READ CAPACITY is strongly encouraged.
+     *  We used to die if we couldn't successfully do a READ CAPACITY.
+     *  But, now we go on about our way.  The side effects of this are
+     *
+     *  1. We can't know block size with certainty. I have said "512 bytes 
+     *     is it" as this is most common.
+     *
+     *  2. Recovery from when some one attempts to read past the end of the 
+     *     raw device will be slower.
+     */
+    
+    if (the_result)
     {
-      printk ("sd%c : READ CAPACITY failed.\n"
-	      "sd%c : status = %x, message = %02x, host = %d, driver = %02x \n",
-	      'a' + i, 'a' + i,
-	      status_byte(the_result),
-	      msg_byte(the_result),
-	      host_byte(the_result),
-	      driver_byte(the_result)
-	      );
-      if (driver_byte(the_result)  & DRIVER_SENSE)
-	printk("sd%c : extended sense code = %1x \n", 'a' + i, SCpnt->sense_buffer[2] & 0xf);
-      else
-	printk("sd%c : sense not available. \n", 'a' + i);
-
-      printk("sd%c : block size assumed to be 512 bytes, disk size 1GB.  \n", 'a' + i);
-      rscsi_disks[i].capacity = 0x1fffff;
-      rscsi_disks[i].sector_size = 512;
-
-      /* Set dirty bit for removable devices if not ready - sometimes drives
-	 will not report this properly. */
-      if(rscsi_disks[i].device->removable && 
-	 SCpnt->sense_buffer[2] == NOT_READY)
-	rscsi_disks[i].device->changed = 1;
-
+	printk ("sd%c : READ CAPACITY failed.\n"
+		"sd%c : status = %x, message = %02x, host = %d, driver = %02x \n",
+		'a' + i, 'a' + i,
+		status_byte(the_result),
+		msg_byte(the_result),
+		host_byte(the_result),
+		driver_byte(the_result)
+		);
+	if (driver_byte(the_result)  & DRIVER_SENSE)
+	    printk("sd%c : extended sense code = %1x \n", 
+		   'a' + i, SCpnt->sense_buffer[2] & 0xf);
+	else
+	    printk("sd%c : sense not available. \n", 'a' + i);
+	
+	printk("sd%c : block size assumed to be 512 bytes, disk size 1GB.  \n",
+	       'a' + i);
+	rscsi_disks[i].capacity = 0x1fffff;
+	rscsi_disks[i].sector_size = 512;
+	
+	/* Set dirty bit for removable devices if not ready - sometimes drives
+	 * will not report this properly. */
+	if(rscsi_disks[i].device->removable && 
+	   SCpnt->sense_buffer[2] == NOT_READY)
+	    rscsi_disks[i].device->changed = 1;
+	
     }
-  else
+    else
     {
-      rscsi_disks[i].capacity = (buffer[0] << 24) |
-	(buffer[1] << 16) |
-	  (buffer[2] << 8) |
-	    buffer[3];
-
-      rscsi_disks[i].sector_size = (buffer[4] << 24) |
-	(buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
-
-      if (rscsi_disks[i].sector_size != 512 &&
-	  rscsi_disks[i].sector_size != 1024 &&
-	  rscsi_disks[i].sector_size != 256)
+	rscsi_disks[i].capacity = (buffer[0] << 24) |
+	    (buffer[1] << 16) |
+		(buffer[2] << 8) |
+		    buffer[3];
+	
+	rscsi_disks[i].sector_size = (buffer[4] << 24) |
+	    (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
+	
+	if (rscsi_disks[i].sector_size != 512 &&
+	    rscsi_disks[i].sector_size != 1024 &&
+	    rscsi_disks[i].sector_size != 256)
 	{
-	  printk ("sd%c : unsupported sector size %d.\n",
-		  'a' + i, rscsi_disks[i].sector_size);
-	  if(rscsi_disks[i].device->removable){
-	    rscsi_disks[i].capacity = 0;
-	  } else {
-	    printk ("scsi : deleting disk entry.\n");
-	    rscsi_disks[i].device = NULL;
-	    sd_template.nr_dev--;
-	    return i;
-	  };
+	    printk ("sd%c : unsupported sector size %d.\n",
+		    'a' + i, rscsi_disks[i].sector_size);
+	    if(rscsi_disks[i].device->removable){
+		rscsi_disks[i].capacity = 0;
+	    } else {
+		printk ("scsi : deleting disk entry.\n");
+		rscsi_disks[i].device = NULL;
+		sd_template.nr_dev--;
+		return i;
+	    };
 	}
     {
-       /*
-          The msdos fs need to know the hardware sector size
-          So I have created this table. See ll_rw_blk.c
-          Jacques Gelinas (Jacques@solucorp.qc.ca)
-       */
-       int m;
-       int hard_sector = rscsi_disks[i].sector_size;
-       /* There is 16 minor allocated for each devices */
-       for (m=i<<4; m<((i+1)<<4); m++){
-         sd_hardsizes[m] = hard_sector;
-       }
-       printk ("SCSI Hardware sector size is %d bytes on device sd%c\n"
-         ,hard_sector,i+'a');
+	/*
+	 * The msdos fs need to know the hardware sector size
+	 * So I have created this table. See ll_rw_blk.c
+	 * Jacques Gelinas (Jacques@solucorp.qc.ca)
+	 */
+	int m;
+	int hard_sector = rscsi_disks[i].sector_size;
+	/* There is 16 minor allocated for each devices */
+	for (m=i<<4; m<((i+1)<<4); m++){
+	    sd_hardsizes[m] = hard_sector;
+	}
+	printk ("SCSI Hardware sector size is %d bytes on device sd%c\n",
+		hard_sector,i+'a');
     }
-      if(rscsi_disks[i].sector_size == 1024)
-	rscsi_disks[i].capacity <<= 1;  /* Change this into 512 byte sectors */
-      if(rscsi_disks[i].sector_size == 256)
-	rscsi_disks[i].capacity >>= 1;  /* Change this into 512 byte sectors */
+	if(rscsi_disks[i].sector_size == 1024)
+	    rscsi_disks[i].capacity <<= 1;  /* Change into 512 byte sectors */
+	if(rscsi_disks[i].sector_size == 256)
+	    rscsi_disks[i].capacity >>= 1;  /* Change into 512 byte sectors */
     }
-
-  rscsi_disks[i].ten = 1;
-  rscsi_disks[i].remap = 1;
-  scsi_free(buffer, 512);
-  return i;
+    
+    rscsi_disks[i].ten = 1;
+    rscsi_disks[i].remap = 1;
+    scsi_free(buffer, 512);
+    return i;
 }
 
 /*
-	The sd_init() function looks at all SCSI drives present, determines
-	their size, and reads partition	table entries for them.
-*/
+ * The sd_init() function looks at all SCSI drives present, determines
+ * their size, and reads partition table entries for them.
+ */
 
 
 static void sd_init()
 {
-	int i;
-	static int sd_registered = 0;
-
-	if (sd_template.dev_noticed == 0) return;
-
-	if(!sd_registered) {
+    int i;
+    static int sd_registered = 0;
+    
+    if (sd_template.dev_noticed == 0) return;
+    
+    if(!sd_registered) {
 	  if (register_blkdev(MAJOR_NR,"sd",&sd_fops)) {
-	    printk("Unable to get major %d for SCSI disk\n",MAJOR_NR);
-	    return;
+	      printk("Unable to get major %d for SCSI disk\n",MAJOR_NR);
+	      return;
 	  }
 	  sd_registered++;
-	}
-
-	/* We do not support attaching loadable devices yet. */
-	if(rscsi_disks) return;
-
-	sd_template.dev_max = sd_template.dev_noticed + SD_EXTRA_DEVS;
-
-	rscsi_disks = (Scsi_Disk *) 
-	  scsi_init_malloc(sd_template.dev_max * sizeof(Scsi_Disk), GFP_ATOMIC);
-	memset(rscsi_disks, 0, sd_template.dev_max * sizeof(Scsi_Disk));
-
-	sd_sizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * 
+      }
+    
+    /* We do not support attaching loadable devices yet. */
+    if(rscsi_disks) return;
+    
+    sd_template.dev_max = sd_template.dev_noticed + SD_EXTRA_DEVS;
+    
+    rscsi_disks = (Scsi_Disk *) 
+	scsi_init_malloc(sd_template.dev_max * sizeof(Scsi_Disk), GFP_ATOMIC);
+    memset(rscsi_disks, 0, sd_template.dev_max * sizeof(Scsi_Disk));
+    
+    sd_sizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * 
+					sizeof(int), GFP_ATOMIC);
+    memset(sd_sizes, 0, (sd_template.dev_max << 4) * sizeof(int));
+    
+    sd_blocksizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * 
+					     sizeof(int), GFP_ATOMIC);
+    
+    sd_hardsizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * 
 					    sizeof(int), GFP_ATOMIC);
-	memset(sd_sizes, 0, (sd_template.dev_max << 4) * sizeof(int));
-
-	sd_blocksizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * 
-						 sizeof(int), GFP_ATOMIC);
-
-	sd_hardsizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * 
-						   sizeof(struct hd_struct), GFP_ATOMIC);
-
-	for(i=0;i<(sd_template.dev_max << 4);i++){
-		sd_blocksizes[i] = 1024;
-		sd_hardsizes[i] = 512;
-	}
-	blksize_size[MAJOR_NR] = sd_blocksizes;
-	hardsect_size[MAJOR_NR] = sd_hardsizes;
-	sd = (struct hd_struct *) scsi_init_malloc((sd_template.dev_max << 4) *
-						   sizeof(struct hd_struct),
-						   GFP_ATOMIC);
-
-
-	sd_gendisk.max_nr = sd_template.dev_max;
-	sd_gendisk.part = sd;
-	sd_gendisk.sizes = sd_sizes;
-	sd_gendisk.real_devices = (void *) rscsi_disks;
-
+    
+    for(i=0;i<(sd_template.dev_max << 4);i++){
+	sd_blocksizes[i] = 1024;
+	sd_hardsizes[i] = 512;
+    }
+    blksize_size[MAJOR_NR] = sd_blocksizes;
+    hardsect_size[MAJOR_NR] = sd_hardsizes;
+    sd = (struct hd_struct *) scsi_init_malloc((sd_template.dev_max << 4) *
+					       sizeof(struct hd_struct),
+					       GFP_ATOMIC);
+    
+    
+    sd_gendisk.max_nr = sd_template.dev_max;
+    sd_gendisk.part = sd;
+    sd_gendisk.sizes = sd_sizes;
+    sd_gendisk.real_devices = (void *) rscsi_disks;
+    
 }
 
 static void sd_finish()
 {
-        int i;
-
-	blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
-
-	sd_gendisk.next = gendisk_head;
-	gendisk_head = &sd_gendisk;
-
-	for (i = 0; i < sd_template.dev_max; ++i)
-	    if (!rscsi_disks[i].capacity && 
-		  rscsi_disks[i].device)
-	      {
-		i = sd_init_onedisk(i);
-		if (scsi_loadable_module_flag 
-		    && !rscsi_disks[i].has_part_table) {
-		  sd_sizes[i << 4] = rscsi_disks[i].capacity;
-		  revalidate_scsidisk(i << 4, 0);
-		}
-		rscsi_disks[i].has_part_table = 1;
-	      }
-
-	/* If our host adapter is capable of scatter-gather, then we increase
-	   the read-ahead to 16 blocks (32 sectors).  If not, we use
-	   a two block (4 sector) read ahead. */
-	if(rscsi_disks[0].device && rscsi_disks[0].device->host->sg_tablesize)
-	  read_ahead[MAJOR_NR] = 120;
-	/* 64 sector read-ahead */
-	else
-	  read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */
-	
-	return;
+    int i;
+    
+    blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
+    
+    sd_gendisk.next = gendisk_head;
+    gendisk_head = &sd_gendisk;
+    
+    for (i = 0; i < sd_template.dev_max; ++i)
+	if (!rscsi_disks[i].capacity && 
+	    rscsi_disks[i].device)
+	{
+	    i = sd_init_onedisk(i);
+	    if (scsi_loadable_module_flag 
+		&& !rscsi_disks[i].has_part_table) {
+		sd_sizes[i << 4] = rscsi_disks[i].capacity;
+		revalidate_scsidisk(i << 4, 0);
+	    }
+	    rscsi_disks[i].has_part_table = 1;
+	}
+    
+    /* If our host adapter is capable of scatter-gather, then we increase
+     * the read-ahead to 16 blocks (32 sectors).  If not, we use
+     * a two block (4 sector) read ahead. 
+     */
+    if(rscsi_disks[0].device && rscsi_disks[0].device->host->sg_tablesize)
+	read_ahead[MAJOR_NR] = 120;
+    /* 64 sector read-ahead */
+    else
+	read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */
+    
+    return;
 }
 
 static int sd_detect(Scsi_Device * SDp){
-  if(SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) return 0;
-
-  printk("Detected scsi disk sd%c at scsi%d, id %d, lun %d\n", 
-	 'a'+ (sd_template.dev_noticed++),
-	 SDp->host->host_no , SDp->id, SDp->lun); 
-
-	 return 1;
-
+    if(SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) return 0;
+    
+    printk("Detected scsi disk sd%c at scsi%d, channel %d, id %d, lun %d\n", 
+	   'a'+ (sd_template.dev_noticed++),
+	   SDp->host->host_no, SDp->channel, SDp->id, SDp->lun); 
+    
+    return 1;
 }
 
 static int sd_attach(Scsi_Device * SDp){
-   Scsi_Disk * dpnt;
-   int i;
-
-   if(SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) return 0;
-
-   if(sd_template.nr_dev >= sd_template.dev_max) {
+    Scsi_Disk * dpnt;
+    int i;
+    
+    if(SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) return 0;
+    
+    if(sd_template.nr_dev >= sd_template.dev_max) {
 	SDp->attached--;
 	return 1;
-   }
-   
-   for(dpnt = rscsi_disks, i=0; i<sd_template.dev_max; i++, dpnt++) 
-     if(!dpnt->device) break;
-
-   if(i >= sd_template.dev_max) panic ("scsi_devices corrupt (sd)");
-
-   SDp->scsi_request_fn = do_sd_request;
-   rscsi_disks[i].device = SDp;
-   rscsi_disks[i].has_part_table = 0;
-   sd_template.nr_dev++;
-   sd_gendisk.nr_real++;
-   return 0;
+    }
+    
+    for(dpnt = rscsi_disks, i=0; i<sd_template.dev_max; i++, dpnt++) 
+	if(!dpnt->device) break;
+    
+    if(i >= sd_template.dev_max) panic ("scsi_devices corrupt (sd)");
+    
+    SDp->scsi_request_fn = do_sd_request;
+    rscsi_disks[i].device = SDp;
+    rscsi_disks[i].has_part_table = 0;
+    sd_template.nr_dev++;
+    sd_gendisk.nr_real++;
+    return 0;
 }
 
 #define DEVICE_BUSY rscsi_disks[target].device->busy
@@ -1188,111 +1236,177 @@
 #define GENDISK_STRUCT sd_gendisk
 
 /* This routine is called to flush all partitions and partition tables
-   for a changed scsi disk, and then re-read the new partition table.
-   If we are revalidating a disk because of a media change, then we
-   enter with usage == 0.  If we are using an ioctl, we automatically have
-   usage == 1 (we need an open channel to use an ioctl :-), so this
-   is our limit.
+ * for a changed scsi disk, and then re-read the new partition table.
+ * If we are revalidating a disk because of a media change, then we
+ * enter with usage == 0.  If we are using an ioctl, we automatically have
+ * usage == 1 (we need an open channel to use an ioctl :-), so this
+ * is our limit.
  */
 int revalidate_scsidisk(int dev, int maxusage){
-	  int target, major;
-	  struct gendisk * gdev;
-	  unsigned long flags;
-	  int max_p;
-	  int start;
-	  int i;
-
-	  target =  DEVICE_NR(MINOR(dev));
-	  gdev = &GENDISK_STRUCT;
-
-	  save_flags(flags);
-	  cli();
-	  if (DEVICE_BUSY || USAGE > maxusage) {
-	    restore_flags(flags);
-	    printk("Device busy for revalidation (usage=%d)\n", USAGE);
-	    return -EBUSY;
-	  };
-	  DEVICE_BUSY = 1;
-	  restore_flags(flags);
-
-	  max_p = gdev->max_p;
-	  start = target << gdev->minor_shift;
-	  major = MAJOR_NR << 8;
-
-	  for (i=max_p - 1; i >=0 ; i--) {
-	    sync_dev(major | start | i);
-	    invalidate_inodes(major | start | i);
-	    invalidate_buffers(major | start | i);
-	    gdev->part[start+i].start_sect = 0;
-	    gdev->part[start+i].nr_sects = 0;
-	  };
-
+    int target, major;
+    struct gendisk * gdev;
+    unsigned long flags;
+    int max_p;
+    int start;
+    int i;
+    
+    target =  DEVICE_NR(MINOR(dev));
+    gdev = &GENDISK_STRUCT;
+    
+    save_flags(flags);
+    cli();
+    if (DEVICE_BUSY || USAGE > maxusage) {
+	restore_flags(flags);
+	printk("Device busy for revalidation (usage=%d)\n", USAGE);
+	return -EBUSY;
+    };
+    DEVICE_BUSY = 1;
+    restore_flags(flags);
+    
+    max_p = gdev->max_p;
+    start = target << gdev->minor_shift;
+    major = MAJOR_NR << 8;
+    
+    for (i=max_p - 1; i >=0 ; i--) {
+	sync_dev(major | start | i);
+	invalidate_inodes(major | start | i);
+	invalidate_buffers(major | start | i);
+	gdev->part[start+i].start_sect = 0;
+	gdev->part[start+i].nr_sects = 0;
+    };
+    
 #ifdef MAYBE_REINIT
-	  MAYBE_REINIT;
+    MAYBE_REINIT;
 #endif
-
-	  gdev->part[start].nr_sects = CAPACITY;
-	  resetup_one_dev(gdev, target);
-
-	  DEVICE_BUSY = 0;
-	  return 0;
+    
+    gdev->part[start].nr_sects = CAPACITY;
+    resetup_one_dev(gdev, target);
+    
+    DEVICE_BUSY = 0;
+    return 0;
 }
 
 static int fop_revalidate_scsidisk(dev_t dev){
-  return revalidate_scsidisk(dev, 0);
+    return revalidate_scsidisk(dev, 0);
 }
 
 
 static void sd_detach(Scsi_Device * SDp)
 {
-  Scsi_Disk * dpnt;
-  int i;
-  int max_p;
-  int major;
-  int start;
-  
-  for(dpnt = rscsi_disks, i=0; i<sd_template.dev_max; i++, dpnt++) 
-    if(dpnt->device == SDp) {
-
-      /* If we are disconnecting a disk driver, sync and invalidate everything */
-      max_p = sd_gendisk.max_p;
-      start = i << sd_gendisk.minor_shift;
-      major = MAJOR_NR << 8;
+    Scsi_Disk * dpnt;
+    int i;
+    int max_p;
+    int major;
+    int start;
+    
+    for(dpnt = rscsi_disks, i=0; i<sd_template.dev_max; i++, dpnt++) 
+	if(dpnt->device == SDp) {
+	    
+	    /* If we are disconnecting a disk driver, sync and invalidate 
+	     * everything */
+	    max_p = sd_gendisk.max_p;
+	    start = i << sd_gendisk.minor_shift;
+	    major = MAJOR_NR << 8;
+	    
+	    for (i=max_p - 1; i >=0 ; i--) {
+		sync_dev(major | start | i);
+		invalidate_inodes(major | start | i);
+		invalidate_buffers(major | start | i);
+		sd_gendisk.part[start+i].start_sect = 0;
+		sd_gendisk.part[start+i].nr_sects = 0;
+		sd_sizes[start+i] = 0;
+	    };
+	    
+	    dpnt->has_part_table = 0;
+	    dpnt->device = NULL;
+	    dpnt->capacity = 0;
+	    SDp->attached--;
+	    sd_template.dev_noticed--;
+	    sd_template.nr_dev--;
+	    sd_gendisk.nr_real--;
+	    return;
+	}
+    return;
+}
 
-      for (i=max_p - 1; i >=0 ; i--) {
-	sync_dev(major | start | i);
-	invalidate_inodes(major | start | i);
-	invalidate_buffers(major | start | i);
-	sd_gendisk.part[start+i].start_sect = 0;
-	sd_gendisk.part[start+i].nr_sects = 0;
-	sd_sizes[start+i] = 0;
-      };
-      
-      dpnt->has_part_table = 0;
-      dpnt->device = NULL;
-      dpnt->capacity = 0;
-      SDp->attached--;
-      sd_template.dev_noticed--;
-      sd_template.nr_dev--;
-      sd_gendisk.nr_real--;
-      return;
+#ifdef MODULE
+#include <linux/module.h>
+#include <linux/version.h>
+
+char kernel_version[] = UTS_RELEASE;
+
+int init_module(void) {
+    sd_template.usage_count = &mod_use_count_;
+    return scsi_register_module(MODULE_SCSI_DEV, &sd_template);
+}
+
+void cleanup_module( void) 
+{
+    struct gendisk * prev_sdgd;
+    struct gendisk * sdgd;
+    
+    if (MOD_IN_USE) {
+	printk(KERN_INFO __FILE__ ": module is in use, remove rejected\n");
+	return;
     }
-  return;
+    scsi_unregister_module(MODULE_SCSI_DEV, &sd_template);
+    unregister_blkdev(SCSI_GENERIC_MAJOR, "sd");
+    if( rscsi_disks != NULL )
+    {
+	scsi_init_free((char *) rscsi_disks,
+		       (sd_template.dev_noticed + SD_EXTRA_DEVS) 
+		       * sizeof(Scsi_Disk));
+	
+	scsi_init_free((char *) sd_sizes, sd_template.dev_max * sizeof(int));
+	scsi_init_free((char *) sd_blocksizes, sd_template.dev_max * sizeof(int));
+	scsi_init_free((char *) sd_hardsizes, sd_template.dev_max * sizeof(int));
+	scsi_init_free((char *) sd, 
+		       (sd_template.dev_max << 4) * sizeof(struct hd_struct));
+	/*
+	 * Now remove sd_gendisk from the linked list
+	 */
+	sdgd = gendisk_head;
+	prev_sdgd = NULL;
+	while(sdgd != &sd_gendisk)
+	{
+	    prev_sdgd = sdgd;
+	    sdgd = sdgd->next;
+	}
+	
+	if(sdgd != &sd_gendisk)
+	    printk("sd_gendisk not in disk chain.\n");
+	else {
+	    if(prev_sdgd != NULL)
+		prev_sdgd->next = sdgd->next;
+	    else
+		gendisk_head = sdgd->next;
+	}
+    }
+    
+    blksize_size[MAJOR_NR] = NULL;
+    blk_dev[MAJOR_NR].request_fn = NULL;
+    blk_size[MAJOR_NR] = NULL;  
+    hardsect_size[MAJOR_NR] = NULL;
+    read_ahead[MAJOR_NR] = 0;
+    sd_template.dev_max = 0;
 }
+#endif /* MODULE */
 
 /*
- * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Overrides for Emacs so that we almost follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
  * adjust the settings for this buffer only.  This must remain at the end
  * of the file.
  * ---------------------------------------------------------------------------
  * Local variables:
- * c-indent-level: 8
+ * c-indent-level: 4
  * c-brace-imaginary-offset: 0
- * c-brace-offset: -8
- * c-argdecl-indent: 8
- * c-label-offset: -8
- * c-continued-statement-offset: 8
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
  * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
  * End:
  */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this