public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently
@ 2006-11-19 12:51 Tejun Heo
  2006-11-19 12:52 ` [PATCH RESEND 2/2] SCSI: add scsi_device->retries Tejun Heo
  2006-11-19 22:01 ` [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently Kai Makisara
  0 siblings, 2 replies; 9+ messages in thread
From: Tejun Heo @ 2006-11-19 12:51 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi

Each high level driver uses scsi_device->timeout diffrently.

* sd sets sdev->timeout to SD_TIMEOUT if it's zero on attach.
  sdev->timeout is used for commands received from block queue but
 internal commands use SD_TIMEOUT directly.

* sr uses constant SR_TIMEOUT for all non-ioctl commands and
  IOCTL_TIMEOUT for sr ioctls.

* st sets sdev->timeout to ST_TIMEOUT unconditionally.  st uses
  either sdev->timeout or scsi_tape->long_timeout depending on command
  type.

* osst uses osst_tape->timeout and osst_tape->long_timeout.

This patch unifies differing behaviors as follows.

* All highlevel drivers initialize sdev->timeout to its default value
  iff it's zero; otherwise, the specified value is used.

* All commands w/o specific timeout requirement use sdev->timeout.
  Commands which require special timeout uses HL-specific value such
  as IOCTL_TIMEOUT and scsi/osst_tape->long_timeout.

This patch also adds sdev local variable for shorter notation where
multiple references to sdev are added.

Signed-off-by: Tejun Heo <htejun@gmail.com>
---

Sorry, the original post had linux-scsi-owner@vger instead of
linux-scsi@vger.  Reposting.

 drivers/scsi/osst.c |   78 ++++++++++++++++++++++++++--------------------------
 drivers/scsi/osst.h |    1 
 drivers/scsi/sd.c   |   31 +++++++++++---------
 drivers/scsi/sr.c   |   49 ++++++++++++++++++--------------
 drivers/scsi/st.c   |    3 +-
 5 files changed, 87 insertions(+), 75 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
@@ -186,7 +186,7 @@ static ssize_t sd_store_cache_type(struc
 		return -EINVAL;
 	rcd = ct & 0x01 ? 1 : 0;
 	wce = ct & 0x02 ? 1 : 0;
-	if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), SD_TIMEOUT,
+	if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), sdp->timeout,
 			    SD_MAX_RETRIES, &data, NULL))
 		return -EINVAL;
 	len = min_t(size_t, sizeof(buffer), data.length - data.header_length -
@@ -197,7 +197,7 @@ static ssize_t sd_store_cache_type(struc
 	buffer_data[2] |= wce << 2 | rcd;
 	sp = buffer_data[0] & 0x80 ? 1 : 0;
 
-	if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, SD_TIMEOUT,
+	if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, sdp->timeout,
 			     SD_MAX_RETRIES, &data, &sshdr)) {
 		if (scsi_sense_valid(&sshdr))
 			scsi_print_sense_hdr(sdkp->disk->disk_name, &sshdr);
@@ -370,7 +370,6 @@ static int sd_init_command(struct scsi_c
 	struct gendisk *disk = rq->rq_disk;
 	sector_t block = rq->sector;
 	unsigned int this_count = SCpnt->request_bufflen >> 9;
-	unsigned int timeout = sdp->timeout;
 
 	SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, "
 			    "count=%d\n", disk->disk_name,
@@ -511,7 +510,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->timeout_per_command = timeout;
+	SCpnt->timeout_per_command = sdp->timeout;
 
 	/*
 	 * This is the completion routine we use.  This is matched in terms
@@ -759,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, SD_TIMEOUT, SD_MAX_RETRIES);
+		retval = scsi_test_unit_ready(sdp, sdp->timeout, SD_MAX_RETRIES);
 
 	/*
 	 * Unable to test, unit probably not ready.   This usually
@@ -805,7 +804,7 @@ static int sd_sync_cache(struct scsi_dev
 		 * flush everything.
 		 */
 		res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr,
-				       SD_TIMEOUT, SD_MAX_RETRIES);
+				       sdp->timeout, SD_MAX_RETRIES);
 		if (res == 0)
 			break;
 	}
@@ -838,9 +837,12 @@ static int sd_issue_flush(struct device 
 
 static void sd_prepare_flush(request_queue_t *q, struct request *rq)
 {
+	struct device *dev = rq->rq_disk->driverfs_dev;
+	struct scsi_device *sdp = to_scsi_device(dev);
+
 	memset(rq->cmd, 0, sizeof(rq->cmd));
 	rq->cmd_type = REQ_TYPE_BLOCK_PC;
-	rq->timeout = SD_TIMEOUT;
+	rq->timeout = sdp->timeout;
 	rq->cmd[0] = SYNCHRONIZE_CACHE;
 	rq->cmd_len = 10;
 }
@@ -1028,6 +1030,7 @@ static int media_not_present(struct scsi
 static void
 sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
 {
+	struct scsi_device *sdp = sdkp->device;
 	unsigned char cmd[10];
 	unsigned long spintime_expire = 0;
 	int retries, spintime;
@@ -1046,9 +1049,9 @@ sd_spinup_disk(struct scsi_disk *sdkp, c
 			cmd[0] = TEST_UNIT_READY;
 			memset((void *) &cmd[1], 0, 9);
 
-			the_result = scsi_execute_req(sdkp->device, cmd,
+			the_result = scsi_execute_req(sdp, cmd,
 						      DMA_NONE, NULL, 0,
-						      &sshdr, SD_TIMEOUT,
+						      &sshdr, sdp->timeout,
 						      SD_MAX_RETRIES);
 
 			/*
@@ -1079,7 +1082,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, c
 		/*
 		 * The device does not want the automatic start to be issued.
 		 */
-		if (sdkp->device->no_start_on_add) {
+		if (sdp->no_start_on_add) {
 			break;
 		}
 
@@ -1103,9 +1106,9 @@ sd_spinup_disk(struct scsi_disk *sdkp, c
 				cmd[1] = 1;	/* Return immediately */
 				memset((void *) &cmd[2], 0, 8);
 				cmd[4] = 1;	/* Start spin cycle */
-				scsi_execute_req(sdkp->device, cmd, DMA_NONE,
+				scsi_execute_req(sdp, cmd, DMA_NONE,
 						 NULL, 0, &sshdr,
-						 SD_TIMEOUT, SD_MAX_RETRIES);
+						 sdp->timeout, SD_MAX_RETRIES);
 				spintime_expire = jiffies + 100 * HZ;
 				spintime = 1;
 			}
@@ -1180,7 +1183,7 @@ repeat:
 		
 		the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
 					      buffer, longrc ? 12 : 8, &sshdr,
-					      SD_TIMEOUT, SD_MAX_RETRIES);
+					      sdp->timeout, SD_MAX_RETRIES);
 
 		if (media_not_present(sdkp, &sshdr))
 			return;
@@ -1345,7 +1348,7 @@ sd_do_mode_sense(struct scsi_device *sdp
 		 struct scsi_sense_hdr *sshdr)
 {
 	return scsi_mode_sense(sdp, dbd, modepage, buffer, len,
-			       SD_TIMEOUT, SD_MAX_RETRIES, data,
+			       sdp->timeout, SD_MAX_RETRIES, data,
 			       sshdr);
 }
 
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
@@ -177,6 +177,7 @@ static void scsi_cd_put(struct scsi_cd *
 int sr_media_change(struct cdrom_device_info *cdi, int slot)
 {
 	struct scsi_cd *cd = cdi->handle;
+	struct scsi_device *sdev = cd->device;
 	int retval;
 
 	if (CDSL_CURRENT != slot) {
@@ -184,19 +185,19 @@ int sr_media_change(struct cdrom_device_
 		return -EINVAL;
 	}
 
-	retval = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES);
+	retval = scsi_test_unit_ready(sdev, sdev->timeout, MAX_RETRIES);
 	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.  */
-		cd->device->changed = 1;
+		sdev->changed = 1;
 		return 1;	/* This will force a flush, if called from
 				 * check_disk_change */
 	};
 
-	retval = cd->device->changed;
-	cd->device->changed = 0;
+	retval = sdev->changed;
+	sdev->changed = 0;
 	/* If the disk changed, the capacity will now be different,
 	 * so we force a re-read of this information */
 	if (retval) {
@@ -297,20 +298,21 @@ static void rw_intr(struct scsi_cmnd * S
 
 static int sr_init_command(struct scsi_cmnd * SCpnt)
 {
-	int block=0, this_count, s_size, timeout = SR_TIMEOUT;
+	int block=0, this_count, s_size;
 	struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk);
+	struct scsi_device *sdev = cd->device;
 
 	SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n",
 				cd->disk->disk_name, block));
 
-	if (!cd->device || !scsi_device_online(cd->device)) {
+	if (!sdev || !scsi_device_online(sdev)) {
 		SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n",
 					SCpnt->request->nr_sectors));
 		SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt));
 		return 0;
 	}
 
-	if (cd->device->changed) {
+	if (sdev->changed) {
 		/*
 		 * quietly refuse to do anything to a changed disc until the
 		 * changed bit has been reset
@@ -322,7 +324,7 @@ static int sr_init_command(struct scsi_c
 	 * we do lazy blocksize switching (when reading XA sectors,
 	 * see CDROMREADMODE2 ioctl) 
 	 */
-	s_size = cd->device->sector_size;
+	s_size = sdev->sector_size;
 	if (s_size > 2048) {
 		if (!in_interrupt())
 			sr_set_blocklength(cd, 2048);
@@ -336,7 +338,7 @@ static int sr_init_command(struct scsi_c
 	}
 
 	if (rq_data_dir(SCpnt->request) == WRITE) {
-		if (!cd->device->writeable)
+		if (!sdev->writeable)
 			return 0;
 		SCpnt->cmnd[0] = WRITE_10;
 		SCpnt->sc_data_direction = DMA_TO_DEVICE;
@@ -403,10 +405,10 @@ static int sr_init_command(struct scsi_c
 	 * host adapter, it's safe to assume that we can at least transfer
 	 * this many bytes between each connect / disconnect.
 	 */
-	SCpnt->transfersize = cd->device->sector_size;
+	SCpnt->transfersize = sdev->sector_size;
 	SCpnt->underflow = this_count << 9;
 	SCpnt->allowed = MAX_RETRIES;
-	SCpnt->timeout_per_command = timeout;
+	SCpnt->timeout_per_command = sdev->timeout;
 
 	/*
 	 * This is the completion routine we use.  This is matched in terms
@@ -579,6 +581,9 @@ static int sr_probe(struct device *dev)
 	cd->readcd_known = 0;
 	cd->readcd_cdda = 0;
 
+	if (!sdev->timeout)
+		sdev->timeout = SR_TIMEOUT;
+
 	cd->cdi.ops = &sr_dops;
 	cd->cdi.handle = cd;
 	cd->cdi.mask = 0;
@@ -619,6 +624,7 @@ fail:
 
 static void get_sectorsize(struct scsi_cd *cd)
 {
+	struct scsi_device *sdev = cd->device;
 	unsigned char cmd[10];
 	unsigned char *buffer;
 	int the_result, retries = 3;
@@ -635,8 +641,8 @@ static void get_sectorsize(struct scsi_c
 		memset(buffer, 0, 8);
 
 		/* Do the command and wait.. */
-		the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE,
-					      buffer, 8, NULL, SR_TIMEOUT,
+		the_result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE,
+					      buffer, 8, NULL, sdev->timeout,
 					      MAX_RETRIES);
 
 		retries--;
@@ -681,7 +687,7 @@ static void get_sectorsize(struct scsi_c
 			cd->capacity = 0;
 		}
 
-		cd->device->sector_size = sector_size;
+		sdev->sector_size = sector_size;
 
 		/*
 		 * Add this so that we have the ability to correctly gauge
@@ -690,7 +696,7 @@ static void get_sectorsize(struct scsi_c
 		set_capacity(cd->disk, cd->capacity);
 	}
 
-	queue = cd->device->request_queue;
+	queue = sdev->request_queue;
 	blk_queue_hardsect_size(queue, sector_size);
 out:
 	kfree(buffer);
@@ -698,12 +704,13 @@ out:
 
 Enomem:
 	cd->capacity = 0x1fffff;
-	cd->device->sector_size = 2048;	/* A guess, just in case */
+	sdev->sector_size = 2048;	/* A guess, just in case */
 	goto out;
 }
 
 static void get_capabilities(struct scsi_cd *cd)
 {
+	struct scsi_device *sdev = cd->device;
 	unsigned char *buffer;
 	struct scsi_mode_data data;
 	unsigned char cmd[MAX_COMMAND_SIZE];
@@ -739,8 +746,8 @@ static void get_capabilities(struct scsi
 		memset((void *)cmd, 0, MAX_COMMAND_SIZE);
 		cmd[0] = TEST_UNIT_READY;
 
-		the_result = scsi_execute_req (cd->device, cmd, DMA_NONE, NULL,
-					       0, &sshdr, SR_TIMEOUT,
+		the_result = scsi_execute_req (sdev, cmd, DMA_NONE, NULL,
+					       0, &sshdr, sdev->timeout,
 					       MAX_RETRIES);
 
 		retries++;
@@ -750,8 +757,8 @@ static void get_capabilities(struct scsi
 		   sshdr.sense_key == UNIT_ATTENTION)));
 
 	/* ask for mode page 0x2a */
-	rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128,
-			     SR_TIMEOUT, 3, &data, NULL);
+	rc = scsi_mode_sense(sdev, 0, 0x2a, buffer, 128,
+			     sdev->timeout, 3, &data, NULL);
 
 	if (!scsi_status_is_good(rc)) {
 		/* failed, drive doesn't have capabilities mode page */
@@ -816,7 +823,7 @@ static void get_capabilities(struct scsi
 	 */
 	if ((cd->cdi.mask & (CDC_DVD_RAM | CDC_MRW_W | CDC_RAM | CDC_CD_RW)) !=
 			(CDC_DVD_RAM | CDC_MRW_W | CDC_RAM | CDC_CD_RW)) {
-		cd->device->writeable = 1;
+		sdev->writeable = 1;
 	}
 
 	kfree(buffer);
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
@@ -3986,7 +3986,8 @@ static int st_probe(struct device *dev)
 	tpnt->partition = 0;
 	tpnt->new_partition = 0;
 	tpnt->nbr_partitions = 0;
-	tpnt->device->timeout = ST_TIMEOUT;
+	if (!SDp->timeout)
+		SDp->timeout = ST_TIMEOUT;
 	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
@@ -683,7 +683,7 @@ 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->timeout, MAX_RETRIES, 1);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
 	*aSRpnt = SRpnt;
 	if (!SRpnt) return (-EBUSY);
 
@@ -704,7 +704,7 @@ 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->timeout, MAX_RETRIES, 1);
+	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
 	}
 	*aSRpnt = SRpnt;
 #if DEBUG
@@ -744,7 +744,7 @@ 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->timeout, MAX_RETRIES, 1);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
 	*aSRpnt = SRpnt;
 	if (!SRpnt) return (-EBUSY);
 
@@ -762,7 +762,7 @@ 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->timeout, MAX_RETRIES, 1);
+	    SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
 	}
 	*aSRpnt = SRpnt;
 #if DEBUG
@@ -814,7 +814,7 @@ 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->timeout, MAX_RETRIES, 1);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
 	*aSRpnt = SRpnt;
 	if (!SRpnt) return (-EBUSY);
 	if (STp->buffer->syscall_result) {
@@ -905,8 +905,8 @@ static int osst_recover_wait_frame(struc
 		memset(cmd, 0, MAX_COMMAND_SIZE);
 		cmd[0] = WRITE_FILEMARKS;
 		cmd[1] = 1;
-		SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
-								MAX_RETRIES, 1);
+		SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE,
+				     STp->device->timeout, MAX_RETRIES, 1);
 
 		while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
 
@@ -922,8 +922,8 @@ static int osst_recover_wait_frame(struc
 			memset(cmd, 0, MAX_COMMAND_SIZE);
 			cmd[0] = READ_POSITION;
 
-			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
-										MAX_RETRIES, 1);
+			SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE,
+					     STp->device->timeout, MAX_RETRIES, 1);
 
 			retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
 			STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
@@ -969,7 +969,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->timeout, MAX_RETRIES, 1);
+				      STp->device->timeout, MAX_RETRIES, 1);
 	*aSRpnt = SRpnt;
 	if (!SRpnt)
 		return (-EBUSY);
@@ -1044,7 +1044,8 @@ static int osst_initiate_read(struct oss
 #if DEBUG
 		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->timeout, MAX_RETRIES, 1);
+		SRpnt   = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE,
+				       STp->device->timeout, MAX_RETRIES, 1);
 		*aSRpnt = SRpnt;
 		if ((retval = STp->buffer->syscall_result))
 			printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
@@ -1426,7 +1427,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->timeout, MAX_RETRIES, 1);
+				     STp->device->timeout, MAX_RETRIES, 1);
 	
 		if ((STp->buffer)->syscall_result || !SRpnt) {
 			printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
@@ -1498,7 +1499,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->timeout, MAX_RETRIES, 1);
+				     STp->device->timeout, MAX_RETRIES, 1);
 
 		if (STp->buffer->syscall_result)
 			flag = 1;
@@ -1514,7 +1515,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->timeout, MAX_RETRIES, 1);
+						     STp->device->timeout, MAX_RETRIES, 1);
 #if DEBUG
 				if (debugging) {
 					printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
@@ -1528,8 +1529,8 @@ static int osst_read_back_buffer_and_rew
 					memset(cmd, 0, MAX_COMMAND_SIZE);
 					cmd[0] = TEST_UNIT_READY;
 
-					SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
-												MAX_RETRIES, 1);
+					SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
+							     STp->device->timeout, MAX_RETRIES, 1);
 
 					if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
 					    (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) {
@@ -1634,7 +1635,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->timeout, MAX_RETRIES, 1);
+					     STp->device->timeout, MAX_RETRIES, 1);
 			*aSRpnt = SRpnt;
 
 			if (STp->buffer->syscall_result) {		/* additional write error */
@@ -2091,7 +2092,7 @@ 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->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)
@@ -2631,7 +2632,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->timeout, 0, 1);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1);
 	if (SRpnt == NULL) {
 #if DEBUG
  	    printk(OSST_DEB_MSG "osst :D: Busy\n");
@@ -2668,7 +2669,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->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 != 0) {
 	    printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
@@ -2708,7 +2709,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->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 != 0) {
@@ -2723,7 +2724,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->timeout, 0, 1);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1);
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result != 0) {
@@ -2743,7 +2744,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->timeout, 0, 1);
+	SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1);
 	*aSRpnt = SRpnt;
 
 	if ((STp->buffer)->syscall_result != 0) {
@@ -2818,7 +2819,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->timeout, MAX_RETRIES, 1);
+			     STp->device->timeout, MAX_RETRIES, 1);
 	if (!SRpnt) {
 		STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
 		return (-EBUSY);
@@ -2838,7 +2839,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->timeout, MAX_RETRIES, 1);
+					     STp->device->timeout, MAX_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:",
@@ -3055,7 +3056,7 @@ static int osst_flush_write_buffer(struc
 #endif
 
 		SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
-					      STp->timeout, MAX_RETRIES, 1);
+				     STp->device->timeout, MAX_RETRIES, 1);
 		*aSRpnt = SRpnt;
 		if (!SRpnt)
 			return (-EBUSY);
@@ -3211,8 +3212,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->timeout,
-									MAX_RETRIES, synchronous);
+	SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->device->timeout,
+			     MAX_RETRIES, synchronous);
 	if (!SRpnt)
 		return (-EBUSY);
 	*aSRpnt = SRpnt;
@@ -3921,7 +3922,7 @@ static int osst_set_options(struct osst_
 					     (value & ~MT_ST_SET_LONG_TIMEOUT));
 		}
 		else {
-			STp->timeout = value * HZ;
+			STp->device->timeout = value * HZ;
 			printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
 		}
 	}
@@ -4112,7 +4113,7 @@ static int osst_int_ioctl(struct osst_ta
 		 cmd[2] = (arg >> 16);
 		 cmd[3] = (arg >> 8);
 		 cmd[4] = arg;
-		 timeout = STp->timeout;
+		 timeout = STp->device->timeout;
 #if DEBUG
 		 if (debugging) 
 			   printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
@@ -4139,7 +4140,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->timeout;
+		 timeout = STp->device->timeout;
 #if DEBUG
 		 if (debugging) {
 			 switch (cmd_in) {
@@ -4464,7 +4465,7 @@ 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->timeout, MAX_RETRIES, 1);
+	SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
 	if (!SRpnt) {
 		retval = (STp->buffer)->syscall_result;		/* FIXME - valid? */
 		goto err_out;
@@ -4485,7 +4486,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->timeout, MAX_RETRIES, 1);
+					     STp->device->timeout, MAX_RETRIES, 1);
 		}
 		osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0);
 	}
@@ -4502,7 +4503,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->timeout, MAX_RETRIES, 1);
+					     STp->device->timeout, MAX_RETRIES, 1);
 			if ((SRpnt->sense[0] & 0x70) != 0x70 ||
 			    (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION)
 				break;
@@ -4538,7 +4539,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->timeout, 0, 1);
+		SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1);
 
 		if (STp->buffer->syscall_result                     ||
 		    STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
@@ -4601,7 +4602,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->timeout, 0, 1);
+		SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->device->timeout, 0, 1);
 
 		STp->header_ok = 0;
 
@@ -4611,7 +4612,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->timeout, MAX_RETRIES, 1);
+					     STp->device->timeout, MAX_RETRIES, 1);
 			if ((SRpnt->sense[0] & 0x70) != 0x70 ||
 			    (SRpnt->sense[2] & 0x0f) == NOT_READY)
 			break;
@@ -5822,7 +5823,8 @@ static int osst_probe(struct device *dev
 	tpnt->nbr_partitions = 0;
 	tpnt->min_block = 512;
 	tpnt->max_block = OS_DATA_SIZE;
-	tpnt->timeout = OSST_TIMEOUT;
+	if (!SDp->timeout)
+		SDp->timeout = OSST_TIMEOUT;
 	tpnt->long_timeout = OSST_LONG_TIMEOUT;
 
 	/* Recognize OnStream tapes */
Index: scsi-misc-2.6/drivers/scsi/osst.h
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/osst.h
+++ scsi-misc-2.6/drivers/scsi/osst.h
@@ -548,7 +548,6 @@ struct osst_tape {
   unsigned char default_drvbuffer;  /* 0xff = don't touch, value 3 bits */
   unsigned char pos_unknown;        /* after reset position unknown */
   int write_threshold;
-  int timeout;			/* timeout for normal commands */
   int long_timeout;		/* timeout for commands known to take long time*/
 
   /* Mode characteristics */

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH RESEND 2/2] SCSI: add scsi_device->retries
  2006-11-19 12:51 [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently Tejun Heo
@ 2006-11-19 12:52 ` Tejun Heo
  2006-11-19 22:32   ` Kai Makisara
  2006-11-19 22:01 ` [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently Kai Makisara
  1 sibling, 1 reply; 9+ messages in thread
From: Tejun Heo @ 2006-11-19 12:52 UTC (permalink / raw)
  To: James.Bottomley, linux-scsi

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@gmail.com>
---
 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

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently
  2006-11-19 12:51 [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently Tejun Heo
  2006-11-19 12:52 ` [PATCH RESEND 2/2] SCSI: add scsi_device->retries Tejun Heo
@ 2006-11-19 22:01 ` Kai Makisara
  2006-11-19 23:26   ` Tejun Heo
  1 sibling, 1 reply; 9+ messages in thread
From: Kai Makisara @ 2006-11-19 22:01 UTC (permalink / raw)
  To: Tejun Heo; +Cc: James Bottomley, linux-scsi

On Sun, 19 Nov 2006, Tejun Heo wrote:

> Each high level driver uses scsi_device->timeout diffrently.
> 
...
> 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
> @@ -3986,7 +3986,8 @@ static int st_probe(struct device *dev)
>  	tpnt->partition = 0;
>  	tpnt->new_partition = 0;
>  	tpnt->nbr_partitions = 0;
> -	tpnt->device->timeout = ST_TIMEOUT;
> +	if (!SDp->timeout)
> +		SDp->timeout = ST_TIMEOUT;

I don't think this should be done. It probably makes the default timeout 
way too short. The error recovery with tapes takes a long time. The user 
can change the timeout if the default (900 seconds) seems too long (or 
short).

I don't think there is anything in the midlevel or low-level code to set 
the timeout based on the device characteristics. This is left to the ULD.

-- 
Kai

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RESEND 2/2] SCSI: add scsi_device->retries
  2006-11-19 12:52 ` [PATCH RESEND 2/2] SCSI: add scsi_device->retries Tejun Heo
@ 2006-11-19 22:32   ` Kai Makisara
  2006-11-19 23:31     ` Tejun Heo
  0 siblings, 1 reply; 9+ messages in thread
From: Kai Makisara @ 2006-11-19 22:32 UTC (permalink / raw)
  To: Tejun Heo; +Cc: James.Bottomley, linux-scsi

On Sun, 19 Nov 2006, Tejun Heo wrote:

> 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.
> 
I am neither acking nor naking this now. The patch does not change st 
behavior but moves part of the retry strategy out of the driver. (Which is 
also good because it makes one of the retry limits user changeable.)

Combining all retry counts is something that may not be a good thing. 
Below is justification why st has three different retry limits.

For some devices one number of retries is not perfect for all functions.

The firmware of tape devices usually retries quite thoroughly before 
returning error. This is why the default zero applies to most cases.

MAX_WRITE_RETRIES is separate from MAX_RETRIES because a plausible 
strategy might be (maybe not any more) to allow no retries for write but 
allow retries for reading and repositioning. The writes should fail 
directly so that the minimum number of marginal errors will be written. 
The reads can be retried so that even marginal data can be recovered. 
(Note that this may lead to tape positioning errors and may not be a 
good strategy in all cases.)

MAX_READY_RETRIES is used for commands that don't move the tape. This is a 
situation where retrying is probably harmless.

-- 
Kai

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently
  2006-11-19 22:01 ` [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently Kai Makisara
@ 2006-11-19 23:26   ` Tejun Heo
  2006-11-20 21:25     ` Kai Makisara
  0 siblings, 1 reply; 9+ messages in thread
From: Tejun Heo @ 2006-11-19 23:26 UTC (permalink / raw)
  To: Kai Makisara; +Cc: James Bottomley, linux-scsi

Kai Makisara wrote:
> On Sun, 19 Nov 2006, Tejun Heo wrote:
> 
>> Each high level driver uses scsi_device->timeout diffrently.
>>
> ...
>> 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
>> @@ -3986,7 +3986,8 @@ static int st_probe(struct device *dev)
>>  	tpnt->partition = 0;
>>  	tpnt->new_partition = 0;
>>  	tpnt->nbr_partitions = 0;
>> -	tpnt->device->timeout = ST_TIMEOUT;
>> +	if (!SDp->timeout)
>> +		SDp->timeout = ST_TIMEOUT;
> 
> I don't think this should be done. It probably makes the default timeout 
> way too short. The error recovery with tapes takes a long time. The user 
> can change the timeout if the default (900 seconds) seems too long (or 
> short).
> 
> I don't think there is anything in the midlevel or low-level code to set 
> the timeout based on the device characteristics. This is left to the ULD.

Low level driver should configure timeout or retries to a known value 
iff it knows what it's doing, when it knows both transport and 
device-type specific characteristic.  AFAICS, the only driver which 
modifies sdev->timeout is ipr and it does so only when it knows the 
device is of certain type.  So, I don't think it will cause any trouble, 
and using different initialization in different ULDs is too subtle.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RESEND 2/2] SCSI: add scsi_device->retries
  2006-11-19 22:32   ` Kai Makisara
@ 2006-11-19 23:31     ` Tejun Heo
  2006-11-20 21:42       ` Kai Makisara
  0 siblings, 1 reply; 9+ messages in thread
From: Tejun Heo @ 2006-11-19 23:31 UTC (permalink / raw)
  To: Kai Makisara; +Cc: James.Bottomley, linux-scsi

Hello,

Kai Makisara wrote:
>> * 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.
>>
> I am neither acking nor naking this now. The patch does not change st 
> behavior but moves part of the retry strategy out of the driver. (Which is 
> also good because it makes one of the retry limits user changeable.)
> 
> Combining all retry counts is something that may not be a good thing. 
> Below is justification why st has three different retry limits.
> 
> For some devices one number of retries is not perfect for all functions.
> 
> The firmware of tape devices usually retries quite thoroughly before 
> returning error. This is why the default zero applies to most cases.
> 
> MAX_WRITE_RETRIES is separate from MAX_RETRIES because a plausible 
> strategy might be (maybe not any more) to allow no retries for write but 
> allow retries for reading and repositioning. The writes should fail 
> directly so that the minimum number of marginal errors will be written. 
> The reads can be retried so that even marginal data can be recovered. 
> (Note that this may lead to tape positioning errors and may not be a 
> good strategy in all cases.)
> 
> MAX_READY_RETRIES is used for commands that don't move the tape. This is a 
> situation where retrying is probably harmless.

I see.  Then, how about adding and initializing STp->write_retries and 
STp->ready_retries according to SDp->retries (some reasonable default 
value, say write_retries is always zero while ready_retries is round up 
of retries * 1.1) and export both through sysfs?  That will give lower 
level primitive control as other ULDs do and also allow users to 
configure each timeout separately if necessary.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently
  2006-11-19 23:26   ` Tejun Heo
@ 2006-11-20 21:25     ` Kai Makisara
  2006-11-21  2:14       ` Tejun Heo
  0 siblings, 1 reply; 9+ messages in thread
From: Kai Makisara @ 2006-11-20 21:25 UTC (permalink / raw)
  To: Tejun Heo; +Cc: James Bottomley, linux-scsi

On Mon, 20 Nov 2006, Tejun Heo wrote:

> Kai Makisara wrote:
> > On Sun, 19 Nov 2006, Tejun Heo wrote:
> > 
> > > Each high level driver uses scsi_device->timeout diffrently.
> > >
> > ...
> > > 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
> >> @@ -3986,7 +3986,8 @@ static int st_probe(struct device *dev)
> > >   tpnt->partition = 0;
> > >   tpnt->new_partition = 0;
> > >   tpnt->nbr_partitions = 0;
> > > -	tpnt->device->timeout = ST_TIMEOUT;
> > > +	if (!SDp->timeout)
> > > +		SDp->timeout = ST_TIMEOUT;
> > 
> > I don't think this should be done. It probably makes the default timeout way
> > too short. The error recovery with tapes takes a long time. The user can
> > change the timeout if the default (900 seconds) seems too long (or short).
> > 
> > I don't think there is anything in the midlevel or low-level code to set the
> > timeout based on the device characteristics. This is left to the ULD.
> 
> Low level driver should configure timeout or retries to a known value iff it
> knows what it's doing, when it knows both transport and device-type specific
> characteristic.

I am not so optimistic ;-)

>                 AFAICS, the only driver which modifies sdev->timeout is ipr
> and it does so only when it knows the device is of certain type.  So, I don't
> think it will cause any trouble, and using different initialization in
> different ULDs is too subtle.
> 
It does not cause trouble now but I think it is an accident waiting to 
happen. The ULD probably knows more about the device characteristics than 
the low-level driver. (I admit that there are other than device specific 
aspects in setting timeouts and these should not be in ULD.)

What about this variant:
	if (SDp->timeout < ST_TIMEOUT)
		SDp->timeout = ST_TIMEOUT;

It does guarantee that the timeout is long enough for tape drives. It also 
lets the low-level driver set a longer timeout if it has some reason to 
make it longer than the ULD does.

-- 
Kai

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RESEND 2/2] SCSI: add scsi_device->retries
  2006-11-19 23:31     ` Tejun Heo
@ 2006-11-20 21:42       ` Kai Makisara
  0 siblings, 0 replies; 9+ messages in thread
From: Kai Makisara @ 2006-11-20 21:42 UTC (permalink / raw)
  To: Tejun Heo; +Cc: James Bottomley, linux-scsi

On Mon, 20 Nov 2006, Tejun Heo wrote:

> Hello,
> 
> Kai Makisara wrote:
> > > * 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.
> > >
> > I am neither acking nor naking this now. The patch does not change st
> > behavior but moves part of the retry strategy out of the driver. (Which is
> > also good because it makes one of the retry limits user changeable.)
> > 
> > Combining all retry counts is something that may not be a good thing. Below
> > is justification why st has three different retry limits.
> > 
> > For some devices one number of retries is not perfect for all functions.
> > 
> > The firmware of tape devices usually retries quite thoroughly before
> > returning error. This is why the default zero applies to most cases.
> > 
> > MAX_WRITE_RETRIES is separate from MAX_RETRIES because a plausible strategy
> > might be (maybe not any more) to allow no retries for write but allow
> > retries for reading and repositioning. The writes should fail directly so
> > that the minimum number of marginal errors will be written. The reads can be
> > retried so that even marginal data can be recovered. (Note that this may
> > lead to tape positioning errors and may not be a good strategy in all
> > cases.)
> > 
> > MAX_READY_RETRIES is used for commands that don't move the tape. This is a
> > situation where retrying is probably harmless.
> 
> I see.  Then, how about adding and initializing STp->write_retries and
> STp->ready_retries according to SDp->retries (some reasonable default value,
> say write_retries is always zero while ready_retries is round up of retries *
> 1.1) and export both through sysfs?  That will give lower level primitive
> control as other ULDs do and also allow users to configure each timeout
> separately if necessary.
> 
When I made the timeouts user changeable (using ioctl), I also thought 
about making retries changeable. However, there did not seem to be any 
real need to change the retry limits and I postponed the implementation. 
Now it would be easy to implement with sysfs but it may be still best to 
postpone that until someone asks for that feature.

One possibility would be to transform the different retry limit philosophy 
into a comment in the source and use lowlevel retry limit for all 
commands. The different limits are actually comments also now because I 
don't think anyone changes the defaults. (If anyone does, please tell us!)

If this is done, I will have the suspicion that someone some time changes 
the low-level retry limit to other than zero without knowing what this 
does to tapes.

-- 
Kai

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently
  2006-11-20 21:25     ` Kai Makisara
@ 2006-11-21  2:14       ` Tejun Heo
  0 siblings, 0 replies; 9+ messages in thread
From: Tejun Heo @ 2006-11-21  2:14 UTC (permalink / raw)
  To: Kai Makisara; +Cc: James Bottomley, linux-scsi

Hello,

Kai Makisara wrote:
>>> I don't think there is anything in the midlevel or low-level code to set the
>>> timeout based on the device characteristics. This is left to the ULD.
>> Low level driver should configure timeout or retries to a known value iff it
>> knows what it's doing, when it knows both transport and device-type specific
>> characteristic.
> 
> I am not so optimistic ;-)
> 
>>                 AFAICS, the only driver which modifies sdev->timeout is ipr
>> and it does so only when it knows the device is of certain type.  So, I don't
>> think it will cause any trouble, and using different initialization in
>> different ULDs is too subtle.
>>
> It does not cause trouble now but I think it is an accident waiting to 
> happen. The ULD probably knows more about the device characteristics than 
> the low-level driver. (I admit that there are other than device specific 
> aspects in setting timeouts and these should not be in ULD.)

Yeah, in general, ULD should be in charge for determining default values 
but, then again, SCSI ULDs are driving extremely wide variety of devices 
hanging off all sorts of transports these days.

> What about this variant:
> 	if (SDp->timeout < ST_TIMEOUT)
> 		SDp->timeout = ST_TIMEOUT;
> 
> It does guarantee that the timeout is long enough for tape drives. It also 
> lets the low-level driver set a longer timeout if it has some reason to 
> make it longer than the ULD does.

I don't know enough about tape devices to determine what's right here. 
I think it's better for me to leave st and osst to people who know 
better.  I'll re-submit without os and osst changes.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2006-11-21  2:14 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-19 12:51 [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently Tejun Heo
2006-11-19 12:52 ` [PATCH RESEND 2/2] SCSI: add scsi_device->retries Tejun Heo
2006-11-19 22:32   ` Kai Makisara
2006-11-19 23:31     ` Tejun Heo
2006-11-20 21:42       ` Kai Makisara
2006-11-19 22:01 ` [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently Kai Makisara
2006-11-19 23:26   ` Tejun Heo
2006-11-20 21:25     ` Kai Makisara
2006-11-21  2:14       ` Tejun Heo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox