linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3] SG_SCSI_RESET ioctl: add no_escalate values
@ 2014-10-18 20:11 Douglas Gilbert
  2014-10-20 11:30 ` Hannes Reinecke
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Douglas Gilbert @ 2014-10-18 20:11 UTC (permalink / raw)
  To: SCSI development list, Christoph Hellwig
  Cc: Elliott, Robert (Server Storage), Jeremy Linton

[-- Attachment #1: Type: text/plain, Size: 1992 bytes --]

Further to a January 2013 thread titled: "[PATCH] SG_SCSI_RESET ioctl
should only perform requested operation" by Jeremy Linton a patch (v3)
is presented that expands the existing ioctl to include "no_escalate"
versions to the existing resets. This requires no changes to SCSI low
level drivers (LLDs); it adds several more finely tuned reset options
to the user space. For example:

   /* This call remains the same, with the same escalating semantics
    * if the device (LU) reset fail. That is: on failure to try a
    * target reset and if that fails, try a bus reset, and if that fails
    * try a host (i.e. LLD) reset. */
   val = SG_SCSI_RESET_DEVICE;
   res = ioctl(<sg_or_block_fd>, SG_SCSI_RESET, &val);

   /* What follows is a new option introduced by this patch series. Only
    * a device reset is attempted. If that fails then an appropriate
    * error code is provided. N.B. There is no reset escalation. */
   val = SG_SCSI_RESET_DEVICE | SG_SCSI_RESET_NO_ESCALATE;
   res = ioctl(<sg_or_block_fd>, SG_SCSI_RESET, &val);

This patches applies to lk 3.17.0 and Christoph's drivers-for-3.18
tree. The sg_reset utility has been extended to use this new option
since sg3_utils-1.36 package which was released on 20130531.

v3 of this patch changes adding, subtracting and arithmetic
comparisons to the corresponding bitwise logical operations.
For example 'SG_SCSI_RESET_DEVICE + SG_SCSI_RESET_NO_ESCALATE' has
been changed to 'SG_SCSI_RESET_DEVICE | SG_SCSI_RESET_NO_ESCALATE'.

ChangeLog:
   - modify SG_SCSI_RESET ioctl so the SG_SCSI_RESET_NO_ESCALATE
     value may be OR-ed to the existing values. If so the existing
     device->target->bus->host escalation does not occur. The
     SG_SCSI_RESET ioctl is modified in both the sg driver and
     scsi_ioctl.c (so block devices can use it).
   - modify scsi_reset_provider() in the scsi_error.c file in a
     similar way to support this additional functionality.

Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>

[-- Attachment #2: scsi_reset_no_escal3.patch --]
[-- Type: text/x-patch, Size: 5931 bytes --]

diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 6b20ef3..1338479 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -2362,8 +2362,18 @@ scsi_reset_provider(struct scsi_device *dev, int flag)
 			break;
 		/* FALLTHROUGH */
 	case SCSI_TRY_RESET_HOST:
+	case SCSI_TRY_RESET_HOST | SCSI_TRY_RESET_NO_ESCALATE:
 		rtn = scsi_try_host_reset(scmd);
 		break;
+	case SCSI_TRY_RESET_DEVICE | SCSI_TRY_RESET_NO_ESCALATE:
+		rtn = scsi_try_bus_device_reset(scmd);
+		break;
+	case SCSI_TRY_RESET_TARGET | SCSI_TRY_RESET_NO_ESCALATE:
+		rtn = scsi_try_target_reset(scmd);
+		break;
+	case SCSI_TRY_RESET_BUS | SCSI_TRY_RESET_NO_ESCALATE:
+		rtn = scsi_try_bus_reset(scmd);
+		break;
 	default:
 		rtn = FAILED;
 	}
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index 1aaaf43..12fe676 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -285,13 +285,14 @@ EXPORT_SYMBOL(scsi_ioctl);
  * scsi_nonblockable_ioctl() - Handle SG_SCSI_RESET
  * @sdev: scsi device receiving ioctl
  * @cmd: Must be SC_SCSI_RESET
- * @arg: pointer to int containing SG_SCSI_RESET_{DEVICE,BUS,HOST}
+ * @arg: pointer to int containing SG_SCSI_RESET_{DEVICE,TARGET,BUS,HOST}
+ *       possibly OR-ed with SG_SCSI_RESET_NO_ESCALATE
  * @ndelay: file mode O_NDELAY flag
  */
 int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd,
 			    void __user *arg, int ndelay)
 {
-	int val, result;
+	int val, val2, result;
 
 	/* The first set of iocts may be executed even if we're doing
 	 * error processing, as long as the device was opened
@@ -307,27 +308,32 @@ int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd,
 		result = get_user(val, (int __user *)arg);
 		if (result)
 			return result;
+		if (val & SG_SCSI_RESET_NO_ESCALATE) {
+			val &= ~SG_SCSI_RESET_NO_ESCALATE;
+			val2 = SCSI_TRY_RESET_NO_ESCALATE;
+		} else
+			val2 = 0;
 		if (val == SG_SCSI_RESET_NOTHING)
 			return 0;
 		switch (val) {
 		case SG_SCSI_RESET_DEVICE:
-			val = SCSI_TRY_RESET_DEVICE;
+			val2 |= SCSI_TRY_RESET_DEVICE;
 			break;
 		case SG_SCSI_RESET_TARGET:
-			val = SCSI_TRY_RESET_TARGET;
+			val2 |= SCSI_TRY_RESET_TARGET;
 			break;
 		case SG_SCSI_RESET_BUS:
-			val = SCSI_TRY_RESET_BUS;
+			val2 |= SCSI_TRY_RESET_BUS;
 			break;
 		case SG_SCSI_RESET_HOST:
-			val = SCSI_TRY_RESET_HOST;
+			val2 |= SCSI_TRY_RESET_HOST;
 			break;
 		default:
 			return -EINVAL;
 		}
 		if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
 			return -EACCES;
-		return (scsi_reset_provider(sdev, val) ==
+		return (scsi_reset_provider(sdev, val2) ==
 			SUCCESS) ? 0 : -EIO;
 	}
 	return -ENODEV;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 01cf888..8345fab 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -847,7 +847,7 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
 {
 	void __user *p = (void __user *)arg;
 	int __user *ip = p;
-	int result, val, read_only;
+	int result, val, val2, read_only;
 	Sg_device *sdp;
 	Sg_fd *sfp;
 	Sg_request *srp;
@@ -1082,27 +1082,32 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
 		result = get_user(val, ip);
 		if (result)
 			return result;
+		if (val & SG_SCSI_RESET_NO_ESCALATE) {
+			val &= ~SG_SCSI_RESET_NO_ESCALATE;
+			val2 = SCSI_TRY_RESET_NO_ESCALATE;
+		} else
+			val2 = 0;
 		if (SG_SCSI_RESET_NOTHING == val)
 			return 0;
 		switch (val) {
 		case SG_SCSI_RESET_DEVICE:
-			val = SCSI_TRY_RESET_DEVICE;
+			val2 |= SCSI_TRY_RESET_DEVICE;
 			break;
 		case SG_SCSI_RESET_TARGET:
-			val = SCSI_TRY_RESET_TARGET;
+			val2 |= SCSI_TRY_RESET_TARGET;
 			break;
 		case SG_SCSI_RESET_BUS:
-			val = SCSI_TRY_RESET_BUS;
+			val2 |= SCSI_TRY_RESET_BUS;
 			break;
 		case SG_SCSI_RESET_HOST:
-			val = SCSI_TRY_RESET_HOST;
+			val2 |= SCSI_TRY_RESET_HOST;
 			break;
 		default:
 			return -EINVAL;
 		}
 		if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
 			return -EACCES;
-		return (scsi_reset_provider(sdp->device, val) ==
+		return (scsi_reset_provider(sdp->device, val2) ==
 			SUCCESS) ? 0 : -EIO;
 	case SCSI_IOCTL_SEND_COMMAND:
 		if (atomic_read(&sdp->detaching))
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h
index 06a8790..49af14a 100644
--- a/include/scsi/scsi_eh.h
+++ b/include/scsi/scsi_eh.h
@@ -62,11 +62,16 @@ extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq);
 
 /*
  * Reset request from external source
+ * Note: if SCSI_TRY_RESET_DEVICE fails then it will escalate to
+ * SCSI_TRY_RESET_TARGET which if it fails will escalate to
+ * SCSI_TRY_RESET_BUS which if it fails will escalate to SCSI_TRY_RESET_HOST.
+ * To prevent escalation OR with SCSI_TRY_RESET_NO_ESCALATE.
  */
 #define SCSI_TRY_RESET_DEVICE	1
 #define SCSI_TRY_RESET_BUS	2
 #define SCSI_TRY_RESET_HOST	3
 #define SCSI_TRY_RESET_TARGET	4
+#define SCSI_TRY_RESET_NO_ESCALATE	0x100	/* OR-ed to prior defines */
 
 extern int scsi_reset_provider(struct scsi_device *, int);
 
diff --git a/include/scsi/sg.h b/include/scsi/sg.h
index 750e5db..3afec70 100644
--- a/include/scsi/sg.h
+++ b/include/scsi/sg.h
@@ -164,12 +164,15 @@ typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
 
 /* Returns -EBUSY if occupied. 3rd argument pointer to int (see next) */
 #define SG_SCSI_RESET 0x2284
-/* Associated values that can be given to SG_SCSI_RESET follow */
+/* Associated values that can be given to SG_SCSI_RESET follow.
+ * SG_SCSI_RESET_NO_ESCALATE may be OR-ed to the _DEVICE, _TARGET, _BUS
+ * or _HOST reset value so only that action is attempted. */
 #define		SG_SCSI_RESET_NOTHING	0
 #define		SG_SCSI_RESET_DEVICE	1
 #define		SG_SCSI_RESET_BUS	2
 #define		SG_SCSI_RESET_HOST	3
 #define		SG_SCSI_RESET_TARGET	4
+#define		SG_SCSI_RESET_NO_ESCALATE	0x100
 
 /* synchronous SCSI command ioctl, (only in version 3 interface) */
 #define SG_IO 0x2285   /* similar effect as write() followed by read() */

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

* Re: [PATCH v3] SG_SCSI_RESET ioctl: add no_escalate values
  2014-10-18 20:11 [PATCH v3] SG_SCSI_RESET ioctl: add no_escalate values Douglas Gilbert
@ 2014-10-20 11:30 ` Hannes Reinecke
  2014-10-20 18:15 ` Jeremy Linton
  2014-10-23 17:12 ` Christoph Hellwig
  2 siblings, 0 replies; 4+ messages in thread
From: Hannes Reinecke @ 2014-10-20 11:30 UTC (permalink / raw)
  To: dgilbert, SCSI development list, Christoph Hellwig
  Cc: Elliott, Robert (Server Storage), Jeremy Linton

On 10/18/2014 10:11 PM, Douglas Gilbert wrote:
> Further to a January 2013 thread titled: "[PATCH] SG_SCSI_RESET ioctl
> should only perform requested operation" by Jeremy Linton a patch (v3)
> is presented that expands the existing ioctl to include "no_escalate"
> versions to the existing resets. This requires no changes to SCSI low
> level drivers (LLDs); it adds several more finely tuned reset options
> to the user space. For example:
> 
>   /* This call remains the same, with the same escalating semantics
>    * if the device (LU) reset fail. That is: on failure to try a
>    * target reset and if that fails, try a bus reset, and if that fails
>    * try a host (i.e. LLD) reset. */
>   val = SG_SCSI_RESET_DEVICE;
>   res = ioctl(<sg_or_block_fd>, SG_SCSI_RESET, &val);
> 
>   /* What follows is a new option introduced by this patch series. Only
>    * a device reset is attempted. If that fails then an appropriate
>    * error code is provided. N.B. There is no reset escalation. */
>   val = SG_SCSI_RESET_DEVICE | SG_SCSI_RESET_NO_ESCALATE;
>   res = ioctl(<sg_or_block_fd>, SG_SCSI_RESET, &val);
> 
> This patches applies to lk 3.17.0 and Christoph's drivers-for-3.18
> tree. The sg_reset utility has been extended to use this new option
> since sg3_utils-1.36 package which was released on 20130531.
> 
> v3 of this patch changes adding, subtracting and arithmetic
> comparisons to the corresponding bitwise logical operations.
> For example 'SG_SCSI_RESET_DEVICE + SG_SCSI_RESET_NO_ESCALATE' has
> been changed to 'SG_SCSI_RESET_DEVICE | SG_SCSI_RESET_NO_ESCALATE'.
> 
> ChangeLog:
>   - modify SG_SCSI_RESET ioctl so the SG_SCSI_RESET_NO_ESCALATE
>     value may be OR-ed to the existing values. If so the existing
>     device->target->bus->host escalation does not occur. The
>     SG_SCSI_RESET ioctl is modified in both the sg driver and
>     scsi_ioctl.c (so block devices can use it).
>   - modify scsi_reset_provider() in the scsi_error.c file in a
>     similar way to support this additional functionality.
> 
> Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>

Reviewed-by: Hannes Reinecke <hare@suse.de>

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		      zSeries & Storage
hare@suse.de			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v3] SG_SCSI_RESET ioctl: add no_escalate values
  2014-10-18 20:11 [PATCH v3] SG_SCSI_RESET ioctl: add no_escalate values Douglas Gilbert
  2014-10-20 11:30 ` Hannes Reinecke
@ 2014-10-20 18:15 ` Jeremy Linton
  2014-10-23 17:12 ` Christoph Hellwig
  2 siblings, 0 replies; 4+ messages in thread
From: Jeremy Linton @ 2014-10-20 18:15 UTC (permalink / raw)
  To: dgilbert, SCSI development list, Christoph Hellwig
  Cc: Elliott, Robert (Server Storage)

Reviewed-by: Jeremy Linton <jlinton@tributary.com>

I will test it (next week or so) when I have access to a configuration that can
test it in a meaningful way.

Thanks,










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

* Re: [PATCH v3] SG_SCSI_RESET ioctl: add no_escalate values
  2014-10-18 20:11 [PATCH v3] SG_SCSI_RESET ioctl: add no_escalate values Douglas Gilbert
  2014-10-20 11:30 ` Hannes Reinecke
  2014-10-20 18:15 ` Jeremy Linton
@ 2014-10-23 17:12 ` Christoph Hellwig
  2 siblings, 0 replies; 4+ messages in thread
From: Christoph Hellwig @ 2014-10-23 17:12 UTC (permalink / raw)
  To: Douglas Gilbert
  Cc: SCSI development list, Elliott, Robert (Server Storage),
	Jeremy Linton

Thanks,

applied to the core-for-3.19 branch.

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

end of thread, other threads:[~2014-10-23 17:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-18 20:11 [PATCH v3] SG_SCSI_RESET ioctl: add no_escalate values Douglas Gilbert
2014-10-20 11:30 ` Hannes Reinecke
2014-10-20 18:15 ` Jeremy Linton
2014-10-23 17:12 ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).