[PATCH 2/2] SCSI: add scsi_device->retries, take #2

[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.

sd and sr are converted to use it for retry value. Note that
sd_sync_cache() and sr::get_sectorsize() loop three more times around
normal command execution on failure.

st and osst are left alone as they have different requirements.  Those
will be updated separately if necessary.

Signed-off-by: Tejun Heo <htejun@xxxxxxxxx>

Index: scsi-misc-2.6/drivers/scsi/sd.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/sd.c	2006-11-21 11:39:29.000000000 +0900
+++ scsi-misc-2.6/drivers/scsi/sd.c	2006-11-21 11:39:33.000000000 +0900
@@ -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	2006-11-19 21:14:59.000000000 +0900
+++ scsi-misc-2.6/include/scsi/scsi_device.h	2006-11-21 11:39:33.000000000 +0900
@@ -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	2006-11-19 21:14:59.000000000 +0900
+++ scsi-misc-2.6/drivers/scsi/scsi_sysfs.c	2006-11-21 11:39:33.000000000 +0900
@@ -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	2006-11-21 11:39:29.000000000 +0900
+++ scsi-misc-2.6/drivers/scsi/sr.c	2006-11-21 11:39:33.000000000 +0900
@@ -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/scsi_scan.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/scsi_scan.c	2006-11-19 21:14:59.000000000 +0900
+++ scsi-misc-2.6/drivers/scsi/scsi_scan.c	2006-11-21 11:39:33.000000000 +0900
@@ -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