diff -u --recursive --new-file andries/drivers/block/genhd.c brouwer/drivers/block/genhd.c
--- andries/drivers/block/genhd.c	Sun Jun  9 07:29:50 2002
+++ brouwer/drivers/block/genhd.c	Mon Jun 10 01:58:36 2002
@@ -177,9 +177,10 @@
 	if (sgp == gendisk_head)
 		seq_puts(part, "major minor  #blocks  name\n\n");
 
-	/* show all non-0 size partitions of this disk */
+	/* show the full disk and all non-0 size partitions of it */
 	for (n = 0; n < (sgp->nr_real << sgp->minor_shift); n++) {
-		if (sgp->part[n].nr_sects == 0)
+		int minormask = (1<<sgp->minor_shift) - 1;
+		if ((n & minormask) && sgp->part[n].nr_sects == 0)
 			continue;
 		seq_printf(part, "%4d  %4d %10d %s\n",
 			sgp->major, n, sgp->sizes[n],
diff -u --recursive --new-file andries/drivers/scsi/NCR53C9x.c brouwer/drivers/scsi/NCR53C9x.c
--- andries/drivers/scsi/NCR53C9x.c	Sun Jun  9 07:28:04 2002
+++ brouwer/drivers/scsi/NCR53C9x.c	Sun Jun  9 16:32:34 2002
@@ -2048,7 +2048,7 @@
 	 * and not only for the entire host adapter as it is now, the workaround
 	 * is way to expensive performance wise.
 	 * Instead, it turns out that when this happens the target has disconnected
-	 * allready but it doesn't show in the interrupt register. Compensate for
+	 * already but it doesn't show in the interrupt register. Compensate for
 	 * that here to try and avoid a SCSI bus reset.
 	 */
 	if(!esp->fas_premature_intr_workaround && (fifocnt == 1) &&
diff -u --recursive --new-file andries/drivers/scsi/scsi_error.c brouwer/drivers/scsi/scsi_error.c
--- andries/drivers/scsi/scsi_error.c	Sun Jun  9 07:26:30 2002
+++ brouwer/drivers/scsi/scsi_error.c	Sun Jun  9 22:17:53 2002
@@ -1095,6 +1095,8 @@
  */
 STATIC int scsi_eh_completed_normally(Scsi_Cmnd * SCpnt)
 {
+	int rtn;
+
 	/*
 	 * First check the host byte, to see if there is anything in there
 	 * that would indicate what we need to do.
@@ -1102,20 +1104,25 @@
 	if (host_byte(SCpnt->result) == DID_RESET) {
 		if (SCpnt->flags & IS_RESETTING) {
 			/*
-			 * OK, this is normal.  We don't know whether in fact the
-			 * command in question really needs to be rerun or not - 
-			 * if this was the original data command then the answer is yes,
-			 * otherwise we just flag it as success.
+			 * OK, this is normal.  We don't know whether in fact
+			 * the command in question really needs to be rerun
+			 * or not - if this was the original data command then
+			 * the answer is yes, otherwise we just flag it as
+			 * success.
 			 */
 			SCpnt->flags &= ~IS_RESETTING;
-			return NEEDS_RETRY;
+			goto maybe_retry;
 		}
 		/*
-		 * Rats.  We are already in the error handler, so we now get to try
-		 * and figure out what to do next.  If the sense is valid, we have
-		 * a pretty good idea of what to do.  If not, we mark it as failed.
+		 * Rats.  We are already in the error handler, so we now
+		 * get to try and figure out what to do next.  If the sense
+		 * is valid, we have a pretty good idea of what to do.
+		 * If not, we mark it as failed.
 		 */
-		return scsi_check_sense(SCpnt);
+		rtn = scsi_check_sense(SCpnt);
+		if (rtn == NEEDS_RETRY)
+			goto maybe_retry;
+		return rtn;
 	}
 	if (host_byte(SCpnt->result) != DID_OK) {
 		return FAILED;
@@ -1127,14 +1134,18 @@
 		return FAILED;
 	}
 	/*
-	 * Now, check the status byte to see if this indicates anything special.
+	 * Now, check the status byte to see if this indicates
+	 * anything special.
 	 */
 	switch (status_byte(SCpnt->result)) {
 	case GOOD:
 	case COMMAND_TERMINATED:
 		return SUCCESS;
 	case CHECK_CONDITION:
-		return scsi_check_sense(SCpnt);
+		rtn = scsi_check_sense(SCpnt);
+		if (rtn == NEEDS_RETRY)
+			goto maybe_retry;
+		return rtn;
 	case CONDITION_GOOD:
 	case INTERMEDIATE_GOOD:
 	case INTERMEDIATE_C_GOOD:
@@ -1149,6 +1160,14 @@
 		return FAILED;
 	}
 	return FAILED;
+
+ maybe_retry:
+	if ((++SCpnt->retries) < SCpnt->allowed) {
+		return NEEDS_RETRY;
+	} else {
+		/* No more retries - report this one back to upper level */
+		return SUCCESS;
+	}
 }
 
 /*
diff -u --recursive --new-file andries/drivers/scsi/scsi_ioctl.c brouwer/drivers/scsi/scsi_ioctl.c
--- andries/drivers/scsi/scsi_ioctl.c	Sun Jun  9 07:31:27 2002
+++ brouwer/drivers/scsi/scsi_ioctl.c	Mon Jun 10 02:21:16 2002
@@ -127,7 +127,7 @@
 				/* gag this error, VFS will log it anyway /axboe */
 				/* printk(KERN_INFO "Disc change detected.\n"); */
 				break;
-			};
+			}
 		default:	/* Fall through for non-removable media */
 			printk("SCSI error: host %d id %d lun %d return code = %x\n",
 			       dev->host->host_no,
@@ -139,7 +139,7 @@
 			       sense_error(SRpnt->sr_sense_buffer[0]),
 			       SRpnt->sr_sense_buffer[2] & 0xf);
 
-		};
+		}
 
 	result = SRpnt->sr_result;
 
@@ -152,7 +152,7 @@
 }
 
 /*
- * This interface is depreciated - users should use the scsi generic (sg)
+ * This interface is deprecated - users should use the scsi generic (sg)
  * interface instead, as this is a more flexible approach to performing
  * generic SCSI commands on a device.
  *
@@ -516,22 +516,3 @@
 	set_fs(oldfs);
 	return tmp;
 }
-
-/*
- * 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: 4
- * c-brace-imaginary-offset: 0
- * 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:
- */
diff -u --recursive --new-file andries/drivers/scsi/sd.c brouwer/drivers/scsi/sd.c
--- andries/drivers/scsi/sd.c	Sun Jun  9 07:27:53 2002
+++ brouwer/drivers/scsi/sd.c	Mon Jun 10 10:16:24 2002
@@ -95,7 +95,7 @@
 static int check_scsidisk_media_change(kdev_t);
 static int fop_revalidate_scsidisk(kdev_t);
 
-static int sd_init_onedisk(Scsi_Disk * sdkp, int dsk_nr);
+static void sd_init_onedisk(Scsi_Disk * sdkp, int dsk_nr);
 
 static int sd_init(void);
 static void sd_finish(void);
@@ -151,22 +151,24 @@
 	Scsi_Device *sdp;
 	struct Scsi_Host *shp = hp;
 	int dsk_nr;
+	kdev_t retval = NODEV;
 	unsigned long iflags;
 
 	SCSI_LOG_HLQUEUE(3, printk("sd_find_target: host_nr=%d, "
 			    "scsi_id=%d\n", shp->host_no, scsi_id));
 	read_lock_irqsave(&sd_dsk_arr_lock, iflags);
 	for (dsk_nr = 0; dsk_nr < sd_template.dev_max; ++dsk_nr) {
-		if (NULL == (sdkp = sd_dsk_arr[dsk_nr]))
+		sdkp = sd_dsk_arr[dsk_nr];
+		if (sdkp == NULL)
 			continue;
 		sdp = sdkp->device;
 		if (sdp && (sdp->host == shp) && (sdp->id == scsi_id)) {
-			read_unlock_irqrestore(&sd_dsk_arr_lock, iflags);
-			return MKDEV_SD(dsk_nr);
+			retval = MKDEV_SD(dsk_nr);
+			break;
 		}
 	}
 	read_unlock_irqrestore(&sd_dsk_arr_lock, iflags);
-	return NODEV;
+	return retval;
 }
 #endif
 
@@ -221,8 +223,8 @@
 	
 			/* default to most commonly used values */
 	
-		        diskinfo[0] = 0x40;
-	        	diskinfo[1] = 0x20;
+		        diskinfo[0] = 0x40;	/* 1 << 6 */
+	        	diskinfo[1] = 0x20;	/* 1 << 5 */
 	        	diskinfo[2] = sdkp->capacity >> 11;
 	
 			/* override with calculated, extended default, 
@@ -530,7 +532,7 @@
 		/*
 		 * If the drive is empty, just let the open fail.
 		 */
-		if ((!sdkp->ready) && !(filp->f_flags & O_NDELAY)) {
+		if ((!sdkp->media_present) && !(filp->f_flags & O_NDELAY)) {
 			retval = -ENOMEDIUM;
 			goto error_out;
 		}
@@ -786,8 +788,7 @@
 	 * that we would ever take a device offline in the first place.
 	 */
 	if (sdp->online == FALSE) {
-		sdkp->ready = 0;
-		sdp->changed = 1;
+		sd_set_media_not_present(sdkp);
 		return 1;	/* This will force a flush, if called from
 				 * check_disk_change */
 	}
@@ -808,18 +809,17 @@
 				 * it out later once the drive is available
 				 * again.  */
 
-		sdkp->ready = 0;
-		sdp->changed = 1;
+		sd_set_media_not_present(sdkp);
 		return 1;	/* This will force a flush, if called from
 				 * check_disk_change */
 	}
 	/*
-	 * for removable scsi disk ( FLOPTICAL ) we have to recognise the
-	 * presence of disk in the drive. This is kept in the Scsi_Disk
+	 * For removable scsi disk we have to recognise the presence
+	 * of a disk in the drive. This is kept in the Scsi_Disk
 	 * struct and tested at open !  Daniel Roche ( dan@lectra.fr )
 	 */
 
-	sdkp->ready = 1;	/* FLOPTICAL */
+	sdkp->media_present = 1;
 
 	retval = sdp->changed;
 	if (!flag)
@@ -827,63 +827,38 @@
 	return retval;
 }
 
-/**
- *	sd_init_onedisk - called the first time a new disk is seen,
- *	performs read_capacity, disk spin up (as required), etc.
- *	@sdkp: pointer to associated Scsi_Disk object
- *	@dsk_nr: disk number within this driver (e.g. 0->/dev/sda,
- *	1->/dev/sdb, etc)
- *
- *	Returns dsk_nr (pointless)
- *
- *	Note: this function is local to this driver.
- **/
-static int sd_init_onedisk(Scsi_Disk * sdkp, int dsk_nr)
-{
-	unsigned char cmd[10];
-	char nbuff[6];
-	unsigned char *buffer;
-	unsigned long spintime_value = 0;
-	int the_result, retries, spintime;
-	int sector_size;
-	Scsi_Device *sdp;
-	Scsi_Request *SRpnt;
-
-	SCSI_LOG_HLQUEUE(3, printk("sd_init_onedisk: dsk_nr=%d\n", 
-			    dsk_nr));
-	/*
-	 * Get the name of the disk, in case we need to log it somewhere.
-	 */
-	sd_dskname(dsk_nr, nbuff);
-
-	/*
-	 * If the device is offline, don't try and read capacity or any
-	 * of the other niceties.
-	 */
-	sdp = sdkp->device;
-	if (sdp->online == FALSE)
-		return dsk_nr;
-
-	/*
-	 * 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.
-	 */
+static void
+sd_set_media_not_present(Scsi_Disk *sdkp) {
+	sdkp->media_present = 0;
+	sdkp->capacity = 0;
+	sdkp->device->changed = 1;
+}
 
-	SRpnt = scsi_allocate_request(sdp);
-	if (!SRpnt) {
-		printk(KERN_WARNING "(sd_init_onedisk:) Request allocation "
-		       "failure.\n");
-		return dsk_nr;
+static int
+sd_media_not_present(Scsi_Disk *sdkp, Scsi_Request *SRpnt) {
+	int the_result = SRpnt->sr_result;
+
+	if (the_result != 0
+	    && (driver_byte(the_result) & DRIVER_SENSE) != 0
+	    && (SRpnt->sr_sense_buffer[2] == NOT_READY ||
+		SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION)
+	    && SRpnt->sr_sense_buffer[12] == 0x3A /* medium not present */) {
+		sd_set_media_not_present(sdkp);
+		return 1;
 	}
+	return 0;
+}
 
-	buffer = kmalloc(512, GFP_DMA);
-	if (!buffer) {
-		printk(KERN_WARNING "(sd_init_onedisk:) Memory allocation "
-		       "failure.\n");
-		scsi_release_request(SRpnt);
-		return dsk_nr;
-	}
+/*
+ * spinup disk - called only in sd_init_onedisk()
+ */
+static void
+sd_spinup_disk(Scsi_Disk *sdkp, char *diskname,
+	       Scsi_Request *SRpnt, unsigned char *buffer) {
+	unsigned char cmd[10];
+	Scsi_Device *sdp = sdkp->device;
+	unsigned long spintime_value = 0;
+	int the_result, retries, spintime;
 
 	spintime = 0;
 
@@ -895,15 +870,16 @@
 		while (retries < 3) {
 			cmd[0] = TEST_UNIT_READY;
 			cmd[1] = (sdp->scsi_level <= SCSI_2) ?
-				 ((sdp->lun << 5) & 0xe0) : 0;
+				((sdp->lun << 5) & 0xe0) : 0;
 			memset((void *) &cmd[2], 0, 8);
+
 			SRpnt->sr_cmd_len = 0;
 			SRpnt->sr_sense_buffer[0] = 0;
 			SRpnt->sr_sense_buffer[2] = 0;
 			SRpnt->sr_data_direction = SCSI_DATA_NONE;
 
 			scsi_wait_req (SRpnt, (void *) cmd, (void *) buffer,
-				0/*512*/, SD_TIMEOUT, MAX_RETRIES);
+				       0/*512*/, SD_TIMEOUT, MAX_RETRIES);
 
 			the_result = SRpnt->sr_result;
 			retries++;
@@ -917,16 +893,8 @@
 		 * any media in it, don't bother with any of the rest of
 		 * this crap.
 		 */
-		if( the_result != 0
-		    && ((driver_byte(the_result) & DRIVER_SENSE) != 0)
-		    && SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION
-		    && SRpnt->sr_sense_buffer[12] == 0x3A ) {
-			sdkp->capacity = 0x1fffff;
-			sector_size = 512;
-			sdp->changed = 1;
-			sdkp->ready = 0;
-			break;
-		}
+		if (sd_media_not_present(sdkp, SRpnt))
+			return;
 
 		/* Look for non-removable devices that return NOT_READY.
 		 * Issue command to spin up drive for these cases. */
@@ -935,10 +903,10 @@
 			unsigned long time1;
 			if (!spintime) {
 				printk(KERN_NOTICE "%s: Spinning up disk...",
-				       nbuff);
+				       diskname);
 				cmd[0] = START_STOP;
 				cmd[1] = (sdp->scsi_level <= SCSI_2) ?
-				 	 ((sdp->lun << 5) & 0xe0) : 0;
+					((sdp->lun << 5) & 0xe0) : 0;
 				cmd[1] |= 1;	/* Return immediately */
 				memset((void *) &cmd[2], 0, 8);
 				cmd[4] = 1;	/* Start spin cycle */
@@ -963,65 +931,63 @@
 		}
 	} while (the_result && spintime &&
 		 time_after(spintime_value + 100 * HZ, jiffies));
+
 	if (spintime) {
 		if (the_result)
 			printk("not responding...\n");
 		else
 			printk("ready\n");
 	}
+}
+
+/*
+ * read disk capacity - called only in sd_init_onedisk()
+ */
+static void
+sd_read_capacity(Scsi_Disk *sdkp, char *diskname,
+		 Scsi_Request *SRpnt, unsigned char *buffer) {
+	unsigned char cmd[10];
+	Scsi_Device *sdp = sdkp->device;
+	int the_result, retries;
+	int sector_size;
+
 	retries = 3;
 	do {
 		cmd[0] = READ_CAPACITY;
 		cmd[1] = (sdp->scsi_level <= SCSI_2) ?
-			 ((sdp->lun << 5) & 0xe0) : 0;
+			((sdp->lun << 5) & 0xe0) : 0;
 		memset((void *) &cmd[2], 0, 8);
 		memset((void *) buffer, 0, 8);
+
 		SRpnt->sr_cmd_len = 0;
 		SRpnt->sr_sense_buffer[0] = 0;
 		SRpnt->sr_sense_buffer[2] = 0;
-
 		SRpnt->sr_data_direction = SCSI_DATA_READ;
+
 		scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
-			    8, SD_TIMEOUT, MAX_RETRIES);
+			      8, SD_TIMEOUT, MAX_RETRIES);
+
+		if (sd_media_not_present(sdkp, SRpnt))
+			return;
 
 		the_result = SRpnt->sr_result;
 		retries--;
 
 	} while (the_result && retries);
 
-	/*
-	 * 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 someone attempts to read past the
-	 *     end of the raw device will be slower.
-	 */
-
 	if (the_result) {
 		printk(KERN_NOTICE "%s : READ CAPACITY failed.\n"
 		       "%s : status=%x, message=%02x, host=%d, driver=%02x \n",
-		       nbuff, nbuff,
+		       diskname, diskname,
 		       status_byte(the_result),
 		       msg_byte(the_result),
 		       host_byte(the_result),
-		       driver_byte(the_result)
-		    );
+		       driver_byte(the_result));
+
 		if (driver_byte(the_result) & DRIVER_SENSE)
 			print_req_sense("sd", SRpnt);
 		else
-			printk("%s : sense not available. \n", nbuff);
-
-		printk(KERN_NOTICE "%s : block size assumed to be 512 "
-		       "bytes, disk size 1GB.  \n", nbuff);
-		sdkp->capacity = 0x1fffff;
-		sector_size = 512;
+			printk("%s : sense not available. \n", diskname);
 
 		/* Set dirty bit for removable devices if not ready -
 		 * sometimes drives will not report this properly. */
@@ -1029,130 +995,193 @@
 		    SRpnt->sr_sense_buffer[2] == NOT_READY)
 			sdp->changed = 1;
 
-	} else {
+		/* Either no media are present but the drive didnt tell us,
+		   or they are present but the read capacity command fails */
+		/* sdkp->media_present = 0; -- not always correct */
+		sdkp->capacity = 0x200000; /* 1 GB - random */
+
+		return;
+	}
+
+	sdkp->capacity = 1 + ((buffer[0] << 24) |
+			      (buffer[1] << 16) |
+			      (buffer[2] << 8) |
+			      buffer[3]);
+
+	sector_size = (buffer[4] << 24) |
+		(buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
+
+	if (sector_size == 0) {
+		sector_size = 512;
+		printk(KERN_NOTICE "%s : sector size 0 reported, "
+		       "assuming 512.\n", diskname);
+	}
+
+	if (sector_size != 512 &&
+	    sector_size != 1024 &&
+	    sector_size != 2048 &&
+	    sector_size != 4096 &&
+	    sector_size != 256) {
+		printk(KERN_NOTICE "%s : unsupported sector size "
+		       "%d.\n", diskname, sector_size);
 		/*
-		 * FLOPTICAL, if read_capa is ok, drive is assumed to be ready
+		 * The user might want to re-format the drive with
+		 * a supported sectorsize.  Once this happens, it
+		 * would be relatively trivial to set the thing up.
+		 * For this reason, we leave the thing in the table.
 		 */
-		sdkp->ready = 1;
+		sdkp->capacity = 0;
+	}
+	{
+		/*
+		 * The msdos fs needs to know the hardware sector size
+		 * So I have created this table. See ll_rw_blk.c
+		 * Jacques Gelinas (Jacques@solucorp.qc.ca)
+		 */
+		int hard_sector = sector_size;
+		int sz = sdkp->capacity * (hard_sector/256);
+		request_queue_t *queue = &sdp->request_queue;
+
+		blk_queue_hardsect_size(queue, hard_sector);
+		printk(KERN_NOTICE "SCSI device %s: "
+		       "%d %d-byte hdwr sectors (%d MB)\n",
+		       diskname, sdkp->capacity,
+		       hard_sector, (sz/2 - sz/1250 + 974)/1950);
+	}
+
+	/* Rescale capacity to 512-byte units */
+	if (sector_size == 4096)
+		sdkp->capacity <<= 3;
+	if (sector_size == 2048)
+		sdkp->capacity <<= 2;
+	if (sector_size == 1024)
+		sdkp->capacity <<= 1;
+	if (sector_size == 256)
+		sdkp->capacity >>= 1;
 
-		sdkp->capacity = 1 + ((buffer[0] << 24) |
-				      (buffer[1] << 16) |
-				      (buffer[2] << 8) |
-				      buffer[3]);
-
-		sector_size = (buffer[4] << 24) |
-		    (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
-
-		if (sector_size == 0) {
-			sector_size = 512;
-			printk(KERN_NOTICE "%s : sector size 0 reported, "
-			       "assuming 512.\n", nbuff);
-		}
-		if (sector_size != 512 &&
-		    sector_size != 1024 &&
-		    sector_size != 2048 &&
-		    sector_size != 4096 &&
-		    sector_size != 256) {
-			printk(KERN_NOTICE "%s : unsupported sector size "
-			       "%d.\n", nbuff, sector_size);
-			/*
-			 * The user might want to re-format the drive with
-			 * a supported sectorsize.  Once this happens, it
-			 * would be relatively trivial to set the thing up.
-			 * For this reason, we leave the thing in the table.
-			 */
-			sdkp->capacity = 0;
-		}
-		{
-			/*
-			 * The msdos fs needs to know the hardware sector size
-			 * So I have created this table. See ll_rw_blk.c
-			 * Jacques Gelinas (Jacques@solucorp.qc.ca)
-			 */
-			int hard_sector = sector_size;
-			int sz = sdkp->capacity * (hard_sector/256);
-			request_queue_t *queue = &sdp->request_queue;
-
-			blk_queue_hardsect_size(queue, hard_sector);
-			printk(KERN_NOTICE "SCSI device %s: "
-			       "%d %d-byte hdwr sectors (%d MB)\n",
-			       nbuff, sdkp->capacity,
-			       hard_sector, (sz/2 - sz/1250 + 974)/1950);
-		}
+	sdkp->device->sector_size = sector_size;
+}
 
-		/* Rescale capacity to 512-byte units */
-		if (sector_size == 4096)
-			sdkp->capacity <<= 3;
-		if (sector_size == 2048)
-			sdkp->capacity <<= 2;
-		if (sector_size == 1024)
-			sdkp->capacity <<= 1;
-		if (sector_size == 256)
-			sdkp->capacity >>= 1;
+/*
+ * read write protect setting, if possible - called only in sd_init_onedisk()
+ */
+static void
+sd_read_write_protect_flag(Scsi_Disk *sdkp, char *diskname,
+			   Scsi_Request *SRpnt, unsigned char *buffer) {
+	Scsi_Device *sdp = sdkp->device;
+	unsigned char cmd[8];
+	int the_result;
+
+	/*
+	 * For removable scsi disks we have to recognise the
+	 * Write Protect Flag. This flag is kept in the Scsi_Disk
+	 * struct and tested at open !
+	 * Daniel Roche ( dan@lectra.fr )
+	 *
+	 * Changed to get all pages (0x3f) rather than page 1 to
+	 * get around devices which do not have a page 1.  Since
+	 * we're only interested in the header anyway, this should
+	 * be fine.
+	 *   -- Matthew Dharm (mdharm-scsi@one-eyed-alien.net)
+	 *
+	 * As it turns out, some devices return an error for
+	 * every MODE_SENSE request except one for page 0.
+	 * So, we should also try that. --aeb
+	 */
+
+	memset((void *) &cmd[0], 0, 8);
+	cmd[0] = MODE_SENSE;
+	cmd[1] = (sdp->scsi_level <= SCSI_2) ?
+		((sdp->lun << 5) & 0xe0) : 0;
+	cmd[2] = 0x3f;	/* Get all pages */
+	cmd[4] = 255;   /* Ask for 255 bytes, even tho we want just the first 8 */
+	SRpnt->sr_cmd_len = 0;
+	SRpnt->sr_sense_buffer[0] = 0;
+	SRpnt->sr_sense_buffer[2] = 0;
+	SRpnt->sr_data_direction = SCSI_DATA_READ;
+
+	scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
+		      512, SD_TIMEOUT, MAX_RETRIES);
+
+	the_result = SRpnt->sr_result;
+
+	if (the_result) {
+		printk("%s: test WP failed, assume Write Enabled\n",
+		       diskname);
+		/* alternatively, try page 0 */
+	} else {
+		sdkp->write_prot = ((buffer[2] & 0x80) != 0);
+		printk(KERN_NOTICE "%s: Write Protect is %s\n", diskname,
+		       sdkp->write_prot ? "on" : "off");
 	}
+}
 
+/**
+ *	sd_init_onedisk - called the first time a new disk is seen,
+ *	performs disk spin up, read_capacity, etc.
+ *	@sdkp: pointer to associated Scsi_Disk object
+ *	@dsk_nr: disk number within this driver (e.g. 0->/dev/sda,
+ *	1->/dev/sdb, etc)
+ *
+ *	Note: this function is local to this driver.
+ **/
+static void
+sd_init_onedisk(Scsi_Disk * sdkp, int dsk_nr) {
+	char diskname[40];
+	unsigned char *buffer;
+	Scsi_Device *sdp;
+	Scsi_Request *SRpnt;
+
+	SCSI_LOG_HLQUEUE(3, printk("sd_init_onedisk: dsk_nr=%d\n", dsk_nr));
 
 	/*
-	 * Unless otherwise specified, this is not write protected.
+	 * Get the name of the disk, in case we need to log it somewhere.
 	 */
-	sdkp->write_prot = 0;
-	if (sdp->removable && sdkp->ready) {
-		/* FLOPTICAL */
+	sd_dskname(dsk_nr, diskname);
 
-		/*
-		 * For removable scsi disk ( FLOPTICAL ) we have to recognise
-		 * the Write Protect Flag. This flag is kept in the Scsi_Disk
-		 * struct and tested at open !
-		 * Daniel Roche ( dan@lectra.fr )
-		 *
-		 * Changed to get all pages (0x3f) rather than page 1 to
-		 * get around devices which do not have a page 1.  Since
-		 * we're only interested in the header anyway, this should
-		 * be fine.
-		 *   -- Matthew Dharm (mdharm-scsi@one-eyed-alien.net)
-		 *
-		 * As it turns out, some devices return an error for
-		 * every MODE_SENSE request except one for page 0.
-		 * So, we should also try that. --aeb
-		 */
+	/*
+	 * If the device is offline, don't try and read capacity or any
+	 * of the other niceties.
+	 */
+	sdp = sdkp->device;
+	if (sdp->online == FALSE)
+		return;
 
-		memset((void *) &cmd[0], 0, 8);
-		cmd[0] = MODE_SENSE;
-		cmd[1] = (sdp->scsi_level <= SCSI_2) ?
-			 ((sdp->lun << 5) & 0xe0) : 0;
-		cmd[2] = 0x3f;	/* Get all pages */
-		cmd[4] = 255;   /* Ask for 255 bytes, even tho we want just the first 8 */
-		SRpnt->sr_cmd_len = 0;
-		SRpnt->sr_sense_buffer[0] = 0;
-		SRpnt->sr_sense_buffer[2] = 0;
+	SRpnt = scsi_allocate_request(sdp);
+	if (!SRpnt) {
+		printk(KERN_WARNING "(sd_init_onedisk:) Request allocation "
+		       "failure.\n");
+		return;
+	}
 
-		/* same code as READCAPA !! */
-		SRpnt->sr_data_direction = SCSI_DATA_READ;
-		scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
-			    512, SD_TIMEOUT, MAX_RETRIES);
+	buffer = kmalloc(512, GFP_DMA);
+	if (!buffer) {
+		printk(KERN_WARNING "(sd_init_onedisk:) Memory allocation "
+		       "failure.\n");
+		goto leave;
+	}
 
-		the_result = SRpnt->sr_result;
+	/* defaults, until the device tells us otherwise */
+	sdkp->capacity = 0;
+	sdkp->device->sector_size = 512;
+	sdkp->media_present = 1;
+	sdkp->write_prot = 0;
 
-		if (the_result) {
-			printk("%s: test WP failed, assume Write Enabled\n",
-			       nbuff);
-			/* alternatively, try page 0 */
-		} else {
-			sdkp->write_prot = ((buffer[2] & 0x80) != 0);
-			printk(KERN_NOTICE "%s: Write Protect is %s\n", nbuff,
-			       sdkp->write_prot ? "on" : "off");
-		}
+	sd_spinup_disk(sdkp, diskname, SRpnt, buffer);
+
+	if (sdkp->media_present)
+		sd_read_capacity(sdkp, diskname, SRpnt, buffer);
+
+	if (sdp->removable && sdkp->media_present)
+		sd_read_write_protect_flag(sdkp, diskname, SRpnt, buffer);
 
-	}			/* check for write protect */
 	SRpnt->sr_device->ten = 1;
 	SRpnt->sr_device->remap = 1;
-	SRpnt->sr_device->sector_size = sector_size;
-	/* Wake up a process waiting for device */
+
+ leave:
 	scsi_release_request(SRpnt);
-	SRpnt = NULL;
 
 	kfree(buffer);
-	return dsk_nr;
 }
 
 /*
@@ -1275,18 +1304,15 @@
 		vfree(sd_gendisks[k].flags);
 	}
 cleanup_mem:
-	if (sd_gendisks) vfree(sd_gendisks);
+	vfree(sd_gendisks);
 	sd_gendisks = NULL;
-	if (sd) vfree(sd);
+	vfree(sd);
 	sd = NULL;
-	if (sd_sizes) vfree(sd_sizes);
+	vfree(sd_sizes);
 	sd_sizes = NULL;
 	if (sd_dsk_arr) {
-                for (k = 0; k < sd_template.dev_max; ++k) {
-			sdkp = sd_dsk_arr[k];
-			if (sdkp)
-				vfree(sdkp);
-		}
+                for (k = 0; k < sd_template.dev_max; ++k)
+			vfree(sd_dsk_arr[k]);
 		vfree(sd_dsk_arr);
 		sd_dsk_arr = NULL;
 	}
@@ -1321,12 +1347,12 @@
 		sdkp = sd_get_sdisk(k);
 		if (sdkp && (0 == sdkp->capacity) && sdkp->device) {
 			sd_init_onedisk(sdkp, k);
-			if (!sdkp->has_part_table) {
+			if (!sdkp->has_been_registered) {
 				sd_sizes[k << 4] = sdkp->capacity;
 				register_disk(&SD_GENDISK(k), MKDEV_SD(k),
 						1<<4, &sd_fops,
 						sdkp->capacity);
-				sdkp->has_part_table = 1;
+				sdkp->has_been_registered = 1;
 			}
 		}
 	}
@@ -1372,7 +1398,7 @@
         unsigned int devnum;
 	Scsi_Disk *sdkp;
 	int dsk_nr;
-	char nbuff[6];
+	char diskname[6];
 	unsigned long iflags;
 
 	if ((NULL == sdp) ||
@@ -1393,8 +1419,8 @@
 	for (dsk_nr = 0; dsk_nr < sd_template.dev_max; dsk_nr++) {
 		sdkp = sd_dsk_arr[dsk_nr];
 		if (!sdkp->device) {
+			memset(sdkp, 0, sizeof(Scsi_Disk));
 			sdkp->device = sdp;
-			sdkp->has_part_table = 0;
 			break;
 		}
 	}
@@ -1412,10 +1438,10 @@
         SD_GENDISK(dsk_nr).de_arr[devnum] = sdp->de;
         if (sdp->removable)
 		SD_GENDISK(dsk_nr).flags[devnum] |= GENHD_FL_REMOVABLE;
-	sd_dskname(dsk_nr, nbuff);
+	sd_dskname(dsk_nr, diskname);
 	printk(KERN_NOTICE "Attached scsi %sdisk %s at scsi%d, channel %d, "
 	       "id %d, lun %d\n", sdp->removable ? "removable " : "",
-	       nbuff, sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
+	       diskname, sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
 	return 0;
 }
 
@@ -1436,8 +1462,8 @@
 	Scsi_Disk * sdkp;
 	Scsi_Device * sdp;
 
-	 SCSI_LOG_HLQUEUE(3, printk("revalidate_scsidisk: dsk_nr=%d\n", 
-			     DEVICE_NR(dev)));
+	SCSI_LOG_HLQUEUE(3, printk("revalidate_scsidisk: dsk_nr=%d\n", 
+				   DEVICE_NR(dev)));
 	sdkp = sd_get_sdisk(dsk_nr);
 	if ((NULL == sdkp) || (NULL == (sdp = sdkp->device)))
 		return -ENODEV;
@@ -1457,6 +1483,7 @@
 	sd_init_onedisk(sdkp, dsk_nr);
 
 	grok_partitions(dev, sdkp->capacity);
+
 leave:
 	sdp->busy = 0;
 	return res;
@@ -1494,7 +1521,7 @@
 	for (dsk_nr = 0; dsk_nr < sd_template.dev_max; dsk_nr++) {
 		sdkp = sd_dsk_arr[dsk_nr];
 		if (sdkp->device == sdp) {
-			sdkp->has_part_table = 0;
+			sdkp->has_been_registered = 0;
 			sdkp->device = NULL;
 			sdkp->capacity = 0;
 			/* sdkp->detaching = 1; */
diff -u --recursive --new-file andries/drivers/scsi/sd.h brouwer/drivers/scsi/sd.h
--- andries/drivers/scsi/sd.h	Sun Jun  9 07:30:31 2002
+++ brouwer/drivers/scsi/sd.h	Mon Jun 10 10:00:21 2002
@@ -11,9 +11,6 @@
  */
 #ifndef _SD_H
 #define _SD_H
-/*
-   $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/sd.h,v 1.1 1992/07/24 06:27:38 root Exp root $
- */
 
 #ifndef _SCSI_H
 #include "scsi.h"
@@ -26,13 +23,11 @@
 extern struct hd_struct *sd;
 
 typedef struct scsi_disk {
-	unsigned capacity;	/* size in blocks */
+	unsigned capacity;		/* size in 512-byte sectors */
 	Scsi_Device *device;
-	unsigned char ready;	/* flag ready for FLOPTICAL */
-	unsigned char write_prot;	/* flag write_protect for rmvable dev */
-	unsigned char sector_bit_size;	/* sector_size = 2 to the  bit size power */
-	unsigned char sector_bit_shift;		/* power of 2 sectors per FS block */
-	unsigned has_part_table:1;	/* has partition table */
+	unsigned char media_present;
+	unsigned char write_prot;
+	unsigned has_been_registered:1;
 } Scsi_Disk;
 
 extern int revalidate_scsidisk(kdev_t dev, int maxusage);
@@ -48,22 +43,3 @@
 #define SD_PARTITION(i)		(((major(i) & SD_MAJOR_MASK) << 8) | (minor(i) & 255))
 
 #endif
-
-/*
- * Overrides for Emacs so that we 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: 4
- * c-brace-imaginary-offset: 0
- * 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:
- */
diff -u --recursive --new-file andries/drivers/scsi/sr.h brouwer/drivers/scsi/sr.h
--- andries/drivers/scsi/sr.h	Sun Jun  9 07:28:56 2002
+++ brouwer/drivers/scsi/sr.h	Sun Jun  9 15:40:26 2002
@@ -24,8 +24,6 @@
 	Scsi_Device *device;
 	unsigned int vendor;	/* vendor code, see sr_vendor.c         */
 	unsigned long ms_offset;	/* for reading multisession-CD's        */
-	unsigned char sector_bit_size;	/* sector size = 2^sector_bit_size      */
-	unsigned char sector_bit_shift;		/* sectors/FS block = 2^sector_bit_shift */
 	unsigned needs_sector_size:1;	/* needs to get sector size */
 	unsigned use:1;		/* is this device still supportable     */
 	unsigned xa_flag:1;	/* CD has XA sectors ? */
diff -u --recursive --new-file andries/fs/partitions/check.c brouwer/fs/partitions/check.c
--- andries/fs/partitions/check.c	Sun Jun  9 07:28:55 2002
+++ brouwer/fs/partitions/check.c	Mon Jun 10 10:19:44 2002
@@ -412,8 +412,8 @@
 
 	g->part[first_minor].nr_sects = size;
 
-	/* No such device or no minors to use for partitions */
-	if (!size || minors == 1)
+	/* No minors to use for partitions */
+	if (minors == 1)
 		return;
 
 	if (g->sizes) {
@@ -422,6 +422,11 @@
 			g->sizes[i] = 0;
 	}
 	blk_size[g->major] = g->sizes;
+
+	/* No such device (e.g., media were just removed) */
+	if (!size)
+		return;
+
 	check_partition(g, mk_kdev(g->major, first_minor), 1 + first_minor);
 
  	/*
diff -u --recursive --new-file andries/include/scsi/scsi.h brouwer/include/scsi/scsi.h
--- andries/include/scsi/scsi.h	Sun Jun  9 07:31:29 2002
+++ brouwer/include/scsi/scsi.h	Mon Jun 10 00:34:54 2002
@@ -223,23 +223,4 @@
 /* Used to get the PCI location of a device */
 #define SCSI_IOCTL_GET_PCI 0x5387
 
-/*
- * Overrides for Emacs so that we 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: 4 
- * c-brace-imaginary-offset: 0
- * 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:
- */
-
 #endif