[PATCH RESEND 2/2] SCSI: add scsi_device->retries

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add scsi_device->retries to provide generic control over command
retries, which is very similar to sdev->timeout.  The initial value is
-1 and high level driver is free to override on attach if negative.
Note that -1 has the same effect as 0 (no retry) and signifies that
it's the default value.  As with sdev->timeout, sdev->retries is
exported under the device sysfs node.

All high level drivers are converted to use it for retry value.
However, there are exceptions.

* sd_sync_cache() and sr::get_sectorsize() loop three more times
  around normal command execution on failure.

* st uses three retry limits - MAX_RETRIES, MAX_WRITE_RETRIES and
  MAX_READY_RETRIES, which are all zero.  This patch only converts
  MAX_RETRIES to sdev->retries.  Defining WRITE and READY retries in
  terms of sdev->retries would make more sense.

Signed-off-by: Tejun Heo <htejun@xxxxxxxxx>
---
 drivers/scsi/osst.c        |  121 +++++++++++++++++++++++++++------------------
 drivers/scsi/scsi_scan.c   |    7 ++
 drivers/scsi/scsi_sysfs.c  |   28 ++++++++++
 drivers/scsi/sd.c          |   22 ++++----
 drivers/scsi/sr.c          |   10 ++-
 drivers/scsi/st.c          |   10 ++-
 include/scsi/scsi_device.h |    1 
 7 files changed, 134 insertions(+), 65 deletions(-)

Index: scsi-misc-2.6/drivers/scsi/sd.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/sd.c
+++ scsi-misc-2.6/drivers/scsi/sd.c
@@ -187,7 +187,7 @@ static ssize_t sd_store_cache_type(struc
 	rcd = ct & 0x01 ? 1 : 0;
 	wce = ct & 0x02 ? 1 : 0;
 	if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), sdp->timeout,
-			    SD_MAX_RETRIES, &data, NULL))
+			    sdp->retries, &data, NULL))
 		return -EINVAL;
 	len = min_t(size_t, sizeof(buffer), data.length - data.header_length -
 		  data.block_descriptor_length);
@@ -198,7 +198,7 @@ static ssize_t sd_store_cache_type(struc
 	sp = buffer_data[0] & 0x80 ? 1 : 0;
 
 	if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, sdp->timeout,
-			     SD_MAX_RETRIES, &data, &sshdr)) {
+			     sdp->retries, &data, &sshdr)) {
 		if (scsi_sense_valid(&sshdr))
 			scsi_print_sense_hdr(sdkp->disk->disk_name, &sshdr);
 		return -EINVAL;
@@ -509,7 +509,7 @@ static int sd_init_command(struct scsi_c
 	 */
 	SCpnt->transfersize = sdp->sector_size;
 	SCpnt->underflow = this_count << 9;
-	SCpnt->allowed = SD_MAX_RETRIES;
+	SCpnt->allowed = sdp->retries;
 	SCpnt->timeout_per_command = sdp->timeout;
 
 	/*
@@ -758,7 +758,7 @@ static int sd_media_changed(struct gendi
 	 */
 	retval = -ENODEV;
 	if (scsi_block_when_processing_errors(sdp))
-		retval = scsi_test_unit_ready(sdp, sdp->timeout, SD_MAX_RETRIES);
+		retval = scsi_test_unit_ready(sdp, sdp->timeout, sdp->retries);
 
 	/*
 	 * Unable to test, unit probably not ready.   This usually
@@ -804,7 +804,7 @@ static int sd_sync_cache(struct scsi_dev
 		 * flush everything.
 		 */
 		res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr,
-				       sdp->timeout, SD_MAX_RETRIES);
+				       sdp->timeout, sdp->retries);
 		if (res == 0)
 			break;
 	}
@@ -1052,7 +1052,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, c
 			the_result = scsi_execute_req(sdp, cmd,
 						      DMA_NONE, NULL, 0,
 						      &sshdr, sdp->timeout,
-						      SD_MAX_RETRIES);
+						      sdp->retries);
 
 			/*
 			 * If the drive has indicated to us that it
@@ -1108,7 +1108,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, c
 				cmd[4] = 1;	/* Start spin cycle */
 				scsi_execute_req(sdp, cmd, DMA_NONE,
 						 NULL, 0, &sshdr,
-						 sdp->timeout, SD_MAX_RETRIES);
+						 sdp->timeout, sdp->retries);
 				spintime_expire = jiffies + 100 * HZ;
 				spintime = 1;
 			}
@@ -1183,7 +1183,7 @@ repeat:
 		
 		the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
 					      buffer, longrc ? 12 : 8, &sshdr,
-					      sdp->timeout, SD_MAX_RETRIES);
+					      sdp->timeout, sdp->retries);
 
 		if (media_not_present(sdkp, &sshdr))
 			return;
@@ -1348,8 +1348,7 @@ sd_do_mode_sense(struct scsi_device *sdp
 		 struct scsi_sense_hdr *sshdr)
 {
 	return scsi_mode_sense(sdp, dbd, modepage, buffer, len,
-			       sdp->timeout, SD_MAX_RETRIES, data,
-			       sshdr);
+			       sdp->timeout, sdp->retries, data, sshdr);
 }
 
 /*
@@ -1673,6 +1672,9 @@ static int sd_probe(struct device *dev)
 			sdp->timeout = SD_MOD_TIMEOUT;
 	}
 
+	if (sdp->retries < 0)
+		sdp->retries = SD_MAX_RETRIES;
+
 	gd->major = sd_major((index & 0xf0) >> 4);
 	gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
 	gd->minors = 16;
Index: scsi-misc-2.6/include/scsi/scsi_device.h
===================================================================
--- scsi-misc-2.6.orig/include/scsi/scsi_device.h
+++ scsi-misc-2.6/include/scsi/scsi_device.h
@@ -134,6 +134,7 @@ struct scsi_device {
 	atomic_t ioerr_cnt;
 
 	int timeout;
+	int retries;
 
 	struct device		sdev_gendev;
 	struct class_device	sdev_classdev;
Index: scsi-misc-2.6/drivers/scsi/scsi_sysfs.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/scsi_sysfs.c
+++ scsi-misc-2.6/drivers/scsi/scsi_sysfs.c
@@ -443,6 +443,33 @@ sdev_store_timeout (struct device *dev, 
 static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout);
 
 static ssize_t
+sdev_show_retries(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	int retries = sdev->retries;
+
+	/* negative indicates uninitialized default */
+	if (retries < 0)
+		retries = 0;
+
+	return snprintf(buf, 20, "%d\n", retries);
+}
+
+static ssize_t
+sdev_store_retries(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	int retries;
+
+	sscanf(buf, "%d\n", &retries);
+	if (retries < 0)
+		return -EINVAL;
+	sdev->retries = retries;
+	return count;
+}
+static DEVICE_ATTR(retries, S_IRUGO | S_IWUSR, sdev_show_retries, sdev_store_retries);
+
+static ssize_t
 store_rescan_field (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	scsi_rescan_device(dev);
@@ -548,6 +575,7 @@ static struct device_attribute *scsi_sys
 	&dev_attr_delete,
 	&dev_attr_state,
 	&dev_attr_timeout,
+	&dev_attr_retries,
 	&dev_attr_iocounterbits,
 	&dev_attr_iorequest_cnt,
 	&dev_attr_iodone_cnt,
Index: scsi-misc-2.6/drivers/scsi/sr.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/sr.c
+++ scsi-misc-2.6/drivers/scsi/sr.c
@@ -185,7 +185,7 @@ int sr_media_change(struct cdrom_device_
 		return -EINVAL;
 	}
 
-	retval = scsi_test_unit_ready(sdev, sdev->timeout, MAX_RETRIES);
+	retval = scsi_test_unit_ready(sdev, sdev->timeout, sdev->retries);
 	if (retval) {
 		/* Unable to test, unit probably not ready.  This usually
 		 * means there is no disc in the drive.  Mark as changed,
@@ -407,7 +407,7 @@ static int sr_init_command(struct scsi_c
 	 */
 	SCpnt->transfersize = sdev->sector_size;
 	SCpnt->underflow = this_count << 9;
-	SCpnt->allowed = MAX_RETRIES;
+	SCpnt->allowed = sdev->retries;
 	SCpnt->timeout_per_command = sdev->timeout;
 
 	/*
@@ -583,6 +583,8 @@ static int sr_probe(struct device *dev)
 
 	if (!sdev->timeout)
 		sdev->timeout = SR_TIMEOUT;
+	if (sdev->retries < 0)
+		sdev->retries = MAX_RETRIES;
 
 	cd->cdi.ops = &sr_dops;
 	cd->cdi.handle = cd;
@@ -643,7 +645,7 @@ static void get_sectorsize(struct scsi_c
 		/* Do the command and wait.. */
 		the_result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE,
 					      buffer, 8, NULL, sdev->timeout,
-					      MAX_RETRIES);
+					      sdev->retries);
 
 		retries--;
 
@@ -748,7 +750,7 @@ static void get_capabilities(struct scsi
 
 		the_result = scsi_execute_req (sdev, cmd, DMA_NONE, NULL,
 					       0, &sshdr, sdev->timeout,
-					       MAX_RETRIES);
+					       sdev->retries);
 
 		retries++;
 	} while (retries < 5 && 
Index: scsi-misc-2.6/drivers/scsi/st.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/st.c
+++ scsi-misc-2.6/drivers/scsi/st.c
@@ -609,7 +609,7 @@ static int cross_eof(struct scsi_tape * 
 		   tape_name(STp), forward ? "forward" : "backward"));
 
 	SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
-			   STp->device->timeout, MAX_RETRIES, 1);
+			   STp->device->timeout, STp->device->retries, 1);
 	if (!SRpnt)
 		return (STp->buffer)->syscall_result;
 
@@ -1787,7 +1787,7 @@ static long read_tape(struct scsi_tape *
 
 	SRpnt = *aSRpnt;
 	SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
-			   STp->device->timeout, MAX_RETRIES, 1);
+			   STp->device->timeout, STp->device->retries, 1);
 	release_buffering(STp, 1);
 	*aSRpnt = SRpnt;
 	if (!SRpnt)
@@ -2451,7 +2451,7 @@ static int do_load_unload(struct scsi_ta
 		);
 
 	SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
-			   timeout, MAX_RETRIES, 1);
+			   timeout, STp->device->retries, 1);
 	if (!SRpnt)
 		return (STp->buffer)->syscall_result;
 
@@ -2751,7 +2751,7 @@ static int st_int_ioctl(struct scsi_tape
 	}
 
 	SRpnt = st_do_scsi(NULL, STp, cmd, datalen, direction,
-			   timeout, MAX_RETRIES, 1);
+			   timeout, STp->device->retries, 1);
 	if (!SRpnt)
 		return (STp->buffer)->syscall_result;
 
@@ -3988,6 +3988,8 @@ static int st_probe(struct device *dev)
 	tpnt->nbr_partitions = 0;
 	if (!SDp->timeout)
 		SDp->timeout = ST_TIMEOUT;
+	if (SDp->retries < 0)
+		SDp->retries = MAX_RETRIES;
 	tpnt->long_timeout = ST_LONG_TIMEOUT;
 	tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
 
Index: scsi-misc-2.6/drivers/scsi/osst.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/osst.c
+++ scsi-misc-2.6/drivers/scsi/osst.c
@@ -667,6 +667,7 @@ err_out:
 static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt,
 				 unsigned timeout, int initial_delay)
 {
+	struct scsi_device    * sdev = STp->device;
 	unsigned char		cmd[MAX_COMMAND_SIZE];
 	struct osst_request   * SRpnt;
 	unsigned long		startwait = jiffies;
@@ -683,7 +684,8 @@ static int osst_wait_ready(struct osst_t
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = TEST_UNIT_READY;
 
-	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE,
+			     sdev->timeout, sdev->retries, 1);
 	*aSRpnt = SRpnt;
 	if (!SRpnt) return (-EBUSY);
 
@@ -704,7 +706,8 @@ static int osst_wait_ready(struct osst_t
 	    memset(cmd, 0, MAX_COMMAND_SIZE);
 	    cmd[0] = TEST_UNIT_READY;
 
-	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
+	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
+				 sdev->timeout, sdev->retries, 1);
 	}
 	*aSRpnt = SRpnt;
 #if DEBUG
@@ -731,6 +734,7 @@ static int osst_wait_ready(struct osst_t
  */
 static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout)
 {
+	struct scsi_device    * sdev = STp->device;
 	unsigned char		cmd[MAX_COMMAND_SIZE];
 	struct osst_request   * SRpnt;
 	unsigned long		startwait = jiffies;
@@ -744,7 +748,8 @@ static int osst_wait_for_medium(struct o
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = TEST_UNIT_READY;
 
-	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE,
+			     sdev->timeout, sdev->retries, 1);
 	*aSRpnt = SRpnt;
 	if (!SRpnt) return (-EBUSY);
 
@@ -762,7 +767,8 @@ static int osst_wait_for_medium(struct o
 	    memset(cmd, 0, MAX_COMMAND_SIZE);
 	    cmd[0] = TEST_UNIT_READY;
 
-	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
+	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
+				 sdev->timeout, sdev->retries, 1);
 	}
 	*aSRpnt = SRpnt;
 #if DEBUG
@@ -800,6 +806,7 @@ static int osst_position_tape_and_confir
  */
 static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt)
 {
+	struct scsi_device    * sdev = STp->device;
 	unsigned char		cmd[MAX_COMMAND_SIZE];
 	struct osst_request   * SRpnt;
 	int			result = 0;
@@ -814,7 +821,8 @@ static int osst_flush_drive_buffer(struc
 	cmd[0] = WRITE_FILEMARKS;
 	cmd[1] = 1;
 
-	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE,
+			     sdev->timeout, sdev->retries, 1);
 	*aSRpnt = SRpnt;
 	if (!SRpnt) return (-EBUSY);
 	if (STp->buffer->syscall_result) {
@@ -889,6 +897,7 @@ static int osst_wait_frame(struct osst_t
 
 static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing)
 {
+	struct scsi_device    * sdev = STp->device;
 	struct osst_request   * SRpnt;
 	unsigned char		cmd[MAX_COMMAND_SIZE];
 	unsigned long   	startwait = jiffies;
@@ -906,7 +915,7 @@ static int osst_recover_wait_frame(struc
 		cmd[0] = WRITE_FILEMARKS;
 		cmd[1] = 1;
 		SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE,
-				     STp->device->timeout, MAX_RETRIES, 1);
+				     sdev->timeout, sdev->retries, 1);
 
 		while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
 
@@ -923,7 +932,7 @@ static int osst_recover_wait_frame(struc
 			cmd[0] = READ_POSITION;
 
 			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE,
-					     STp->device->timeout, MAX_RETRIES, 1);
+					     sdev->timeout, sdev->retries, 1);
 
 			retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
 			STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
@@ -947,6 +956,7 @@ static int osst_recover_wait_frame(struc
  */
 static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout)
 {
+	struct scsi_device    * sdev = STp->device;
 	unsigned char		cmd[MAX_COMMAND_SIZE];
 	struct osst_request   * SRpnt;
 	int			retval = 0;
@@ -969,7 +979,7 @@ static int osst_read_frame(struct osst_t
 		printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
 #endif
 	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
-				      STp->device->timeout, MAX_RETRIES, 1);
+			     sdev->timeout, sdev->retries, 1);
 	*aSRpnt = SRpnt;
 	if (!SRpnt)
 		return (-EBUSY);
@@ -1018,6 +1028,7 @@ static int osst_read_frame(struct osst_t
 
 static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt)
 {
+	struct scsi_device    * sdev = STp->device;
 	struct st_partstat    * STps   = &(STp->ps[STp->partition]);
 	struct osst_request   * SRpnt  ;
 	unsigned char		cmd[MAX_COMMAND_SIZE];
@@ -1045,7 +1056,7 @@ static int osst_initiate_read(struct oss
 		printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
 #endif
 		SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE,
-				       STp->device->timeout, MAX_RETRIES, 1);
+				       sdev->timeout, sdev->retries, 1);
 		*aSRpnt = SRpnt;
 		if ((retval = STp->buffer->syscall_result))
 			printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
@@ -1388,6 +1399,7 @@ static int osst_seek_sector(struct osst_
 static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt,
 						unsigned int frame, unsigned int skip, int pending)
 {
+	struct scsi_device    * sdev = STp->device;
 	struct osst_request   * SRpnt = * aSRpnt;
 	unsigned char	      * buffer, * p;
 	unsigned char		cmd[MAX_COMMAND_SIZE];
@@ -1427,7 +1439,7 @@ static int osst_read_back_buffer_and_rew
 		cmd[8] = 32768 & 0xff;
 
 		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
-				     STp->device->timeout, MAX_RETRIES, 1);
+				     sdev->timeout, sdev->retries, 1);
 	
 		if ((STp->buffer)->syscall_result || !SRpnt) {
 			printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
@@ -1499,7 +1511,7 @@ static int osst_read_back_buffer_and_rew
 				p[0], p[1], p[2], p[3]);
 #endif
 		SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
-				     STp->device->timeout, MAX_RETRIES, 1);
+				     sdev->timeout, sdev->retries, 1);
 
 		if (STp->buffer->syscall_result)
 			flag = 1;
@@ -1515,7 +1527,7 @@ static int osst_read_back_buffer_and_rew
 				cmd[0] = WRITE_FILEMARKS;
 				cmd[1] = 1;
 				SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
-						     STp->device->timeout, MAX_RETRIES, 1);
+						     sdev->timeout, sdev->retries, 1);
 #if DEBUG
 				if (debugging) {
 					printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
@@ -1530,7 +1542,7 @@ static int osst_read_back_buffer_and_rew
 					cmd[0] = TEST_UNIT_READY;
 
 					SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
-							     STp->device->timeout, MAX_RETRIES, 1);
+							     sdev->timeout, sdev->retries, 1);
 
 					if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
 					    (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) {
@@ -1586,6 +1598,7 @@ static int osst_read_back_buffer_and_rew
 static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt,
 					unsigned int frame, unsigned int skip, int pending)
 {
+	struct scsi_device    * sdev = STp->device;
 	unsigned char		cmd[MAX_COMMAND_SIZE];
 	struct osst_request   * SRpnt;
 	char		      * name      = tape_name(STp);
@@ -1635,7 +1648,7 @@ static int osst_reposition_and_retry(str
 					  name, STp->frame_seq_number-1, STp->first_frame_position);
 #endif
 			SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
-					     STp->device->timeout, MAX_RETRIES, 1);
+					     sdev->timeout, sdev->retries, 1);
 			*aSRpnt = SRpnt;
 
 			if (STp->buffer->syscall_result) {		/* additional write error */
@@ -2092,7 +2105,8 @@ static void osst_set_retries(struct osst
 	if (debugging)
 	    printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
 
-	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->device->timeout, 0, 1);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE,
+			     STp->device->timeout, 0, 1);
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result)
@@ -2601,6 +2615,7 @@ static unsigned int osst_parse_firmware_
  */
 static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt)
 {
+	struct scsi_device           * sdev = STp->device;
 	unsigned char                  cmd[MAX_COMMAND_SIZE];
 	char                         * name = tape_name(STp);
 	struct osst_request          * SRpnt = * aSRpnt;
@@ -2618,7 +2633,7 @@ static int osst_configure_onstream(struc
 	}
 	
 	if (STp->os_fw_rev < 10600) {
-	    printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev);
+	    printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, sdev->rev);
 	    printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name);
 	}
 
@@ -2632,7 +2647,7 @@ static int osst_configure_onstream(struc
 	cmd[2] = BLOCK_SIZE_PAGE;
 	cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
-	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, sdev->timeout, 0, 1);
 	if (SRpnt == NULL) {
 #if DEBUG
  	    printk(OSST_DEB_MSG "osst :D: Busy\n");
@@ -2669,7 +2684,7 @@ static int osst_configure_onstream(struc
 	cmd[1] = 0x10;
 	cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
-	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->device->timeout, 0, 1);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, sdev->timeout, 0, 1);
 	*aSRpnt = SRpnt;
 	if ((STp->buffer)->syscall_result != 0) {
 	    printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
@@ -2709,7 +2724,7 @@ static int osst_configure_onstream(struc
 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
 	(STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
 
-	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->device->timeout, 0, 1);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, sdev->timeout, 0, 1);
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result != 0) {
@@ -2724,7 +2739,7 @@ static int osst_configure_onstream(struc
 	cmd[2] = CAPABILITIES_PAGE;
 	cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
-	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, sdev->timeout, 0, 1);
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result != 0) {
@@ -2744,7 +2759,7 @@ static int osst_configure_onstream(struc
 	cmd[2] = TAPE_PARAMTR_PAGE;
 	cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
-	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, sdev->timeout, 0, 1);
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result != 0) {
@@ -2801,6 +2816,7 @@ static int cross_eof(struct osst_tape *S
 
 static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt)
 {
+	struct scsi_device    * sdev = STp->device;
 	unsigned char		scmd[MAX_COMMAND_SIZE];
 	struct osst_request   * SRpnt;
 	int			result = 0;
@@ -2819,7 +2835,7 @@ static int osst_get_frame_position(struc
 
 	STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
 	SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
-			     STp->device->timeout, MAX_RETRIES, 1);
+			     sdev->timeout, sdev->retries, 1);
 	if (!SRpnt) {
 		STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
 		return (-EBUSY);
@@ -2839,7 +2855,7 @@ static int osst_get_frame_position(struc
 			scmd[0] = READ_POSITION;
 			STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
 			SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
-					     STp->device->timeout, MAX_RETRIES, 1);
+					     sdev->timeout, sdev->retries, 1);
 #if DEBUG
 			printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
 					name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
@@ -2917,8 +2933,8 @@ static int osst_set_frame_position(struc
 		if (skip)
 			scmd[9] = 0x80;
 
-		SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout,
-								MAX_RETRIES, 1);
+		SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE,
+				     STp->long_timeout, STp->device->retries, 1);
 		if (!SRpnt)
 			return (-EBUSY);
 		*aSRpnt  = SRpnt;
@@ -2970,6 +2986,7 @@ out:
 /* Flush the write buffer (never need to write if variable blocksize). */
 static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt)
 {
+	struct scsi_device    * sdev = STp->device;
 	int			offset, transfer, blks = 0;
 	int			result = 0;
 	unsigned char		cmd[MAX_COMMAND_SIZE];
@@ -3056,7 +3073,7 @@ static int osst_flush_write_buffer(struc
 #endif
 
 		SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
-				     STp->device->timeout, MAX_RETRIES, 1);
+				     sdev->timeout, sdev->retries, 1);
 		*aSRpnt = SRpnt;
 		if (!SRpnt)
 			return (-EBUSY);
@@ -3162,6 +3179,7 @@ static int osst_flush_buffer(struct osst
 
 static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous)
 {
+	struct scsi_device    * sdev = STp->device;
 	unsigned char		cmd[MAX_COMMAND_SIZE];
 	struct osst_request   * SRpnt;
 	int			blks;
@@ -3212,8 +3230,8 @@ static int osst_write_frame(struct osst_
 	if (!synchronous)
 		STp->write_pending = 1;
 #endif
-	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->device->timeout,
-			     MAX_RETRIES, synchronous);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
+			     sdev->timeout, sdev->retries, synchronous);
 	if (!SRpnt)
 		return (-EBUSY);
 	*aSRpnt = SRpnt;
@@ -3817,6 +3835,7 @@ static void osst_log_options(struct osst
 
 static int osst_set_options(struct osst_tape *STp, long options)
 {
+	struct scsi_device * sdev = STp->device;
 	int		    value;
 	long		    code;
 	struct st_modedef * STm;
@@ -3844,7 +3863,7 @@ static int osst_set_options(struct osst_
 		STp->do_auto_lock     = (options & MT_ST_AUTO_LOCK) != 0;
 		STp->can_bsr          = (options & MT_ST_CAN_BSR) != 0;
 		STp->omit_blklims     = (options & MT_ST_NO_BLKLIMS) != 0;
-		if ((STp->device)->scsi_level >= SCSI_2)
+		if (sdev->scsi_level >= SCSI_2)
 			STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0;
 		STp->scsi2_logical    = (options & MT_ST_SCSI2LOGICAL) != 0;
 		STm->sysv	      = (options & MT_ST_SYSV) != 0;
@@ -3873,7 +3892,7 @@ static int osst_set_options(struct osst_
 			STp->can_bsr = value;
 		if ((options & MT_ST_NO_BLKLIMS) != 0)
 			STp->omit_blklims = value;
-		if ((STp->device)->scsi_level >= SCSI_2 &&
+		if (sdev->scsi_level >= SCSI_2 &&
 		    (options & MT_ST_CAN_PARTITIONS) != 0)
 			STp->can_partitions = value;
 		if ((options & MT_ST_SCSI2LOGICAL) != 0)
@@ -3922,7 +3941,7 @@ static int osst_set_options(struct osst_
 					     (value & ~MT_ST_SET_LONG_TIMEOUT));
 		}
 		else {
-			STp->device->timeout = value * HZ;
+			sdev->timeout = value * HZ;
 			printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
 		}
 	}
@@ -3974,6 +3993,7 @@ static int osst_set_options(struct osst_
 static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt,
 			     unsigned int cmd_in, unsigned long arg)
 {
+	struct scsi_device    * sdev = STp->device;
 	int			timeout;
 	long			ltmp;
 	int			i, ioctl_result;
@@ -4113,7 +4133,7 @@ static int osst_int_ioctl(struct osst_ta
 		 cmd[2] = (arg >> 16);
 		 cmd[3] = (arg >> 8);
 		 cmd[4] = arg;
-		 timeout = STp->device->timeout;
+		 timeout = sdev->timeout;
 #if DEBUG
 		 if (debugging) 
 			   printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
@@ -4140,7 +4160,7 @@ static int osst_int_ioctl(struct osst_ta
 			 cmd[4] = 3;		/* retension then mount */
 		 if (cmd_in == MTOFFL)
 			 cmd[4] = 4;		/* rewind then eject */
-		 timeout = STp->device->timeout;
+		 timeout = sdev->timeout;
 #if DEBUG
 		 if (debugging) {
 			 switch (cmd_in) {
@@ -4249,7 +4269,8 @@ static int osst_int_ioctl(struct osst_ta
 		return (-ENOSYS);
 	}
 
-	SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout,
+			     sdev->retries, 1);
 
 	ioctl_result = (STp->buffer)->syscall_result;
 
@@ -4364,6 +4385,7 @@ static int os_scsi_tape_open(struct inod
 	unsigned char	      cmd[MAX_COMMAND_SIZE];
 	struct osst_request * SRpnt = NULL;
 	struct osst_tape    * STp;
+	struct scsi_device  * sdev;
 	struct st_modedef   * STm;
 	struct st_partstat  * STps;
 	char		    * name;
@@ -4385,6 +4407,7 @@ static int os_scsi_tape_open(struct inod
 	}
 
 	name = tape_name(STp);
+	sdev = STp->device;
 
 	if (STp->in_use) {
 		write_unlock(&os_scsi_tapes_lock);
@@ -4393,7 +4416,7 @@ static int os_scsi_tape_open(struct inod
 #endif
 		return (-EBUSY);
 	}
-	if (scsi_device_get(STp->device)) {
+	if (scsi_device_get(sdev)) {
 		write_unlock(&os_scsi_tapes_lock);
 #if DEBUG
                 printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name);
@@ -4405,7 +4428,7 @@ static int os_scsi_tape_open(struct inod
 	write_unlock(&os_scsi_tapes_lock);
 	STp->rew_at_close = TAPE_REWIND(inode);
 
-	if( !scsi_block_when_processing_errors(STp->device) ) {
+	if( !scsi_block_when_processing_errors(sdev) ) {
 		return -ENXIO;
 	}
 
@@ -4465,7 +4488,8 @@ static int os_scsi_tape_open(struct inod
 	memset (cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = TEST_UNIT_READY;
 
-	SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
+	SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE,
+			     sdev->timeout, sdev->retries, 1);
 	if (!SRpnt) {
 		retval = (STp->buffer)->syscall_result;		/* FIXME - valid? */
 		goto err_out;
@@ -4486,7 +4510,7 @@ static int os_scsi_tape_open(struct inod
 			cmd[1] = 1;
 			cmd[4] = 1;
 			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
-					     STp->device->timeout, MAX_RETRIES, 1);
+					     sdev->timeout, sdev->retries, 1);
 		}
 		osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0);
 	}
@@ -4503,7 +4527,7 @@ static int os_scsi_tape_open(struct inod
 			cmd[0] = TEST_UNIT_READY;
 
 			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
-					     STp->device->timeout, MAX_RETRIES, 1);
+					     sdev->timeout, sdev->retries, 1);
 			if ((SRpnt->sense[0] & 0x70) != 0x70 ||
 			    (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION)
 				break;
@@ -4539,7 +4563,7 @@ static int os_scsi_tape_open(struct inod
 		cmd[2] = VENDOR_IDENT_PAGE;
 		cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
 
-		SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1);
+		SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, sdev->timeout, 0, 1);
 
 		if (STp->buffer->syscall_result                     ||
 		    STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
@@ -4602,7 +4626,7 @@ static int os_scsi_tape_open(struct inod
 #if DEBUG
 		printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
 #endif
-		SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->device->timeout, 0, 1);
+		SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, sdev->timeout, 0, 1);
 
 		STp->header_ok = 0;
 
@@ -4612,7 +4636,7 @@ static int os_scsi_tape_open(struct inod
 			cmd[0] = TEST_UNIT_READY;
 
 			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
-					     STp->device->timeout, MAX_RETRIES, 1);
+					     sdev->timeout, sdev->retries, 1);
 			if ((SRpnt->sense[0] & 0x70) != 0x70 ||
 			    (SRpnt->sense[2] & 0x0f) == NOT_READY)
 			break;
@@ -4640,7 +4664,7 @@ static int os_scsi_tape_open(struct inod
 		 printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name);
 
 	if ((STp->buffer)->syscall_result != 0) {
-		if ((STp->device)->scsi_level >= SCSI_2 &&
+		if (sdev->scsi_level >= SCSI_2 &&
 		    (SRpnt->sense[0] & 0x70) == 0x70 &&
 		    (SRpnt->sense[2] & 0x0f) == NOT_READY &&
 		     SRpnt->sense[12] == 0x3a) { /* Check ASC */
@@ -4718,7 +4742,7 @@ err_out:
 	normalize_buffer(STp->buffer);
 	STp->header_ok = 0;
 	STp->in_use = 0;
-	scsi_device_put(STp->device);
+	scsi_device_put(sdev);
 
 	return retval;
 }
@@ -4849,6 +4873,7 @@ static int osst_ioctl(struct inode * ino
 	struct st_partstat  * STps;
 	struct osst_request * SRpnt = NULL;
 	struct osst_tape    * STp   = file->private_data;
+	struct scsi_device  * sdev  = STp->device;
 	char		    * name  = tape_name(STp);
 	void	    __user  * p     = (void __user *)arg;
 
@@ -4871,7 +4896,7 @@ static int osst_ioctl(struct inode * ino
 	 * may try and take the device offline, in which case all further
 	 * access to the device is prohibited.
 	 */
-	if( !scsi_block_when_processing_errors(STp->device) ) {
+	if( !scsi_block_when_processing_errors(sdev) ) {
 		retval = (-ENXIO);
 		goto out;
 	}
@@ -4958,7 +4983,7 @@ static int osst_ioctl(struct inode * ino
 			}
 			reset_state(STp);
 			/* remove this when the midlevel properly clears was_reset */
-			STp->device->was_reset = 0;
+			sdev->was_reset = 0;
 		}
 
 		if (mtc.mt_op != MTCOMPRESSION  && mtc.mt_op != MTLOCK         &&
@@ -5165,7 +5190,7 @@ static int osst_ioctl(struct inode * ino
 
 	up(&STp->lock);
 
-	return scsi_ioctl(STp->device, cmd_in, p);
+	return scsi_ioctl(sdev, cmd_in, p);
 
 out:
 	if (SRpnt) osst_release_request(SRpnt);
@@ -5825,6 +5850,8 @@ static int osst_probe(struct device *dev
 	tpnt->max_block = OS_DATA_SIZE;
 	if (!SDp->timeout)
 		SDp->timeout = OSST_TIMEOUT;
+	if (SDp->retries < 0)
+		SDp->retries = MAX_RETRIES;
 	tpnt->long_timeout = OSST_LONG_TIMEOUT;
 
 	/* Recognize OnStream tapes */
Index: scsi-misc-2.6/drivers/scsi/scsi_scan.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/scsi_scan.c
+++ scsi-misc-2.6/drivers/scsi/scsi_scan.c
@@ -261,6 +261,13 @@ static struct scsi_device *scsi_alloc_sd
 	 */
 	sdev->borken = 1;
 
+	/*
+	 * -1 indicates uninitialized default and equivalent to zero
+	 * in effect.  High level driver is allowed to adjust retries
+	 * if it's negative.
+	 */
+	sdev->retries = -1;
+
 	sdev->request_queue = scsi_alloc_queue(sdev);
 	if (!sdev->request_queue) {
 		/* release fn is set up in scsi_sysfs_device_initialise, so
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux