All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] scsi_dh: Move dm device handler to SCSI layer
@ 2008-01-24  0:30 Chandra Seetharaman
  2008-01-24  0:30 ` [PATCH 1/9] scsi_dh: add REQ_LB_OP_TRANSITION and errors Chandra Seetharaman
                   ` (8 more replies)
  0 siblings, 9 replies; 37+ messages in thread
From: Chandra Seetharaman @ 2008-01-24  0:30 UTC (permalink / raw)
  To: dm-devel, linux-scsi; +Cc: andmike, michaelc, Chandra Seetharaman, jens.axboe

Hello,

The set of patches that follow this email facilitate movement of hardware
handlers from dm layer to SCSI layer.

Patches posted along with this email are based off of the patches
Mike Christie posted on June 09, 2007. The first email Mike posted
gives the rationale for moving the hardware handler from dm to SCSI.

Patches posted by Mike Christie:
http://marc.info/?l=linux-scsi&m=118141609715090&w=2
http://marc.info/?l=linux-scsi&m=118141614418681&w=2
http://marc.info/?l=linux-scsi&m=118141614501241&w=2
http://marc.info/?l=linux-scsi&m=118141614303990&w=2
http://marc.info/?l=linux-scsi&m=118141614425996&w=2
http://marc.info/?l=linux-scsi&m=118141802719861&w=2
http://marc.info/?l=linux-scsi&m=118141614331436&w=2
http://marc.info/?l=linux-scsi&m=118141614421759&w=2

Current set of patches has 3 additional advantages:
 1. It is totally compatible with the current multipath tools.
 2. Moving from dm hardware handler to SCSI hardware handler is not
    imposed on the user community. They can use either of those by using
    either of the modules.
    dm hardware handler can be depracated slowly.
 3. It adds a new device state SDEV_PASSIVE which avoids I/O being sent
    to the passive side of a multipath device, thereby reducing the device
    probe time and boot time.
    Booting a system with 40 luns with 1 active path and 1 inactive path
    shows the following as the last printk before login prompt.
    ------------
    With SCSI HW Handler
    [  171.702366] Buffer I/O error on device sdbl, logical block 262128

    Without SCSI HW Handler
    [ 1426.772390] end_request: I/O error, dev sdbm, sector 2097136
    ------------

Patches are created on top of 2.6.24-rc8-mm1.

Testing has been done with a IBM DS4800 storage device, which means the
infrastructure and the lsi_rdac hardware handler has been tested. Testing
by someone with the EMC hardware and/or HP hardware would be appreciated.

Comments, suggestions solicited.

Thanks,

chandra

-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------

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

* [PATCH 1/9] scsi_dh: add REQ_LB_OP_TRANSITION and errors
  2008-01-24  0:30 [PATCH 0/9] scsi_dh: Move dm device handler to SCSI layer Chandra Seetharaman
@ 2008-01-24  0:30 ` Chandra Seetharaman
  2008-01-24  0:30 ` [PATCH 2/9] scsi_dh: change sd_prep_fn to call common code Chandra Seetharaman
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 37+ messages in thread
From: Chandra Seetharaman @ 2008-01-24  0:30 UTC (permalink / raw)
  To: dm-devel, linux-scsi; +Cc: andmike, michaelc, Chandra Seetharaman, jens.axboe

Subject: scsi_dh: add REQ_LB_OP_TRANSITION and errors

From: Mike Christie <michaelc@cs.wisc.edu>

This patch adds REQ_LB_OP_TRANSITION which is a REQ_TYPE_LINUX_BLOCK
type of command. It also adds the error codes which are used by
REQ_LB_OP_TRANSITION to blkdev.h.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---

 block/ll_rw_blk.c      |    2 	1 +	1 -	0 !
 include/linux/blkdev.h |   41 	41 +	0 -	0 !
 2 files changed, 42 insertions(+), 1 deletion(-)

Index: linux-2.6.24-rc8/block/ll_rw_blk.c
===================================================================
--- linux-2.6.24-rc8.orig/block/ll_rw_blk.c
+++ linux-2.6.24-rc8/block/ll_rw_blk.c
@@ -3456,7 +3456,7 @@ static int __end_that_request_first(stru
 	 * for a REQ_BLOCK_PC request, we want to carry any eventual
 	 * sense key with us all the way through
 	 */
-	if (!blk_pc_request(req))
+	if (!blk_pc_request(req) && !blk_linux_request(req))
 		req->errors = 0;
 
 	if (!uptodate) {
Index: linux-2.6.24-rc8/include/linux/blkdev.h
===================================================================
--- linux-2.6.24-rc8.orig/include/linux/blkdev.h
+++ linux-2.6.24-rc8/include/linux/blkdev.h
@@ -162,8 +162,48 @@ enum {
 	 */
 	REQ_LB_OP_EJECT	= 0x40,		/* eject request */
 	REQ_LB_OP_FLUSH = 0x41,		/* flush device */
+	REQ_LB_OP_TRANSITION = 0x42,	/* failover/failback a device */
 };
 
+enum {
+	BLKERR_OK = 0,
+	/*
+	 * device errors
+	 */
+	BLKERR_DEV_FAILED,	/* generic device error */
+	BLKERR_DEV_TEMP_BUSY,
+	BLKERR_DEVICE_MAX,	/* max device blkerr definition */
+
+	/*
+	 * transport errors
+	 */
+	BLKERR_NOTCONN = BLKERR_DEVICE_MAX + 1,
+	BLKERR_CONN_FAILURE,
+	BLKERR_TRANSPORT_MAX,	/* max transport blkerr definition */
+
+	/*
+	 * driver and generic errors
+	 */
+	BLKERR_IO = BLKERR_TRANSPORT_MAX + 1,	/* generic error */
+	BLKERR_INVALID_IO,
+	BLKERR_RETRY,		/* retry the req, but not immediately */
+	BLKERR_IMM_RETRY,	/* immediately retry the req */
+	BLKERR_TIMED_OUT,
+	BLKERR_RES_TEMP_UNAVAIL,
+	BLKERR_DEV_OFFLINED,
+	BLKERR_NOSYS,
+	BLKERR_DRIVER_MAX,
+};
+
+#define blk_dev_err(_err) \
+	(_err > BLKERR_OK  && _err < BLKERR_DEVICE_MAX)
+
+ #define blkerr_transport_err(_err) \
+	(_err > BLKERR_DEVICE_MAX && _err < BLKERR_TRANSPORT_MAX)
+
+#define blkerr_driver_err(_err) \
+	(_err > BLKERR_TRANSPORT_MAX)
+
 /*
  * request type modified bits. first three bits match BIO_RW* bits, important
  */
@@ -521,6 +561,7 @@ enum {
 #define blk_pc_request(rq)	((rq)->cmd_type == REQ_TYPE_BLOCK_PC)
 #define blk_special_request(rq)	((rq)->cmd_type == REQ_TYPE_SPECIAL)
 #define blk_sense_request(rq)	((rq)->cmd_type == REQ_TYPE_SENSE)
+#define blk_linux_request(rq)	((rq)->cmd_type == REQ_TYPE_LINUX_BLOCK)
 
 #define blk_noretry_request(rq)	((rq)->cmd_flags & REQ_FAILFAST)
 #define blk_rq_started(rq)	((rq)->cmd_flags & REQ_STARTED)

-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------

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

* [PATCH 2/9] scsi_dh: change sd_prep_fn to call common code
  2008-01-24  0:30 [PATCH 0/9] scsi_dh: Move dm device handler to SCSI layer Chandra Seetharaman
  2008-01-24  0:30 ` [PATCH 1/9] scsi_dh: add REQ_LB_OP_TRANSITION and errors Chandra Seetharaman
@ 2008-01-24  0:30 ` Chandra Seetharaman
  2008-01-24  0:30 ` [PATCH 3/9] scsi_dh: scsi handling of REQ_LB_OP_TRANSITION Chandra Seetharaman
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 37+ messages in thread
From: Chandra Seetharaman @ 2008-01-24  0:30 UTC (permalink / raw)
  To: dm-devel, linux-scsi; +Cc: andmike, michaelc, Chandra Seetharaman, jens.axboe

Subject: scsi_dh: change sd_prep_fn to call common code

From: Mike Anderson <andmike@linux.vnet.ibm.com>

Have sd_prep_fn call common code if not REQ_TYPE_FS.

Signed-off-by: Mike Anderson <andmike@linux.vnet.ibm.com>
Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---

 drivers/scsi/scsi_lib.c    |    1 	1 +	0 -	0 !
 drivers/scsi/sd.c          |    9 	2 +	7 -	0 !
 include/scsi/scsi_driver.h |    1 	1 +	0 -	0 !
 3 files changed, 4 insertions(+), 7 deletions(-)

Index: linux-2.6.24-rc8/drivers/scsi/scsi_lib.c
===================================================================
--- linux-2.6.24-rc8.orig/drivers/scsi/scsi_lib.c
+++ linux-2.6.24-rc8/drivers/scsi/scsi_lib.c
@@ -1334,6 +1334,7 @@ int scsi_prep_fn(struct request_queue *q
 		ret = scsi_setup_blk_pc_cmnd(sdev, req);
 	return scsi_prep_return(q, req, ret);
 }
+EXPORT_SYMBOL(scsi_prep_fn);
 
 /*
  * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else
Index: linux-2.6.24-rc8/drivers/scsi/sd.c
===================================================================
--- linux-2.6.24-rc8.orig/drivers/scsi/sd.c
+++ linux-2.6.24-rc8/drivers/scsi/sd.c
@@ -354,13 +354,8 @@ static int sd_prep_fn(struct request_que
 	unsigned int timeout = sdp->timeout;
 	int ret;
 
-	if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
-		ret = scsi_setup_blk_pc_cmnd(sdp, rq);
-		goto out;
-	} else if (rq->cmd_type != REQ_TYPE_FS) {
-		ret = BLKPREP_KILL;
-		goto out;
-	}
+	if (rq->cmd_type != REQ_TYPE_FS)
+		return scsi_prep_fn(q, rq);
 	ret = scsi_setup_fs_cmnd(sdp, rq);
 	if (ret != BLKPREP_OK)
 		goto out;
Index: linux-2.6.24-rc8/include/scsi/scsi_driver.h
===================================================================
--- linux-2.6.24-rc8.orig/include/scsi/scsi_driver.h
+++ linux-2.6.24-rc8/include/scsi/scsi_driver.h
@@ -32,5 +32,6 @@ int scsi_setup_blk_pc_cmnd(struct scsi_d
 int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req);
 int scsi_prep_state_check(struct scsi_device *sdev, struct request *req);
 int scsi_prep_return(struct request_queue *q, struct request *req, int ret);
+int scsi_prep_fn(struct request_queue *q, struct request *req);
 
 #endif /* _SCSI_SCSI_DRIVER_H */

-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------

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

* [PATCH 3/9] scsi_dh: scsi handling of REQ_LB_OP_TRANSITION
  2008-01-24  0:30 [PATCH 0/9] scsi_dh: Move dm device handler to SCSI layer Chandra Seetharaman
  2008-01-24  0:30 ` [PATCH 1/9] scsi_dh: add REQ_LB_OP_TRANSITION and errors Chandra Seetharaman
  2008-01-24  0:30 ` [PATCH 2/9] scsi_dh: change sd_prep_fn to call common code Chandra Seetharaman
@ 2008-01-24  0:30 ` Chandra Seetharaman
  2008-02-01 20:00   ` Mike Christie
  2008-01-24  0:31 ` [PATCH 4/9] scsi_dh: add skeleton for SCSI Device Handlers Chandra Seetharaman
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 37+ messages in thread
From: Chandra Seetharaman @ 2008-01-24  0:30 UTC (permalink / raw)
  To: dm-devel, linux-scsi; +Cc: andmike, michaelc, Chandra Seetharaman, jens.axboe

Subject: scsi_dh: scsi handling of REQ_LB_OP_TRANSITION

From: Mike Christie <michaelc@cs.wisc.edu>

This patch adds a scsi handler for REQ_LB_OP_TRANSITION commands.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---

---
 drivers/scsi/scsi_lib.c    |  113 	111 +	2 -	0 !
 include/scsi/scsi_cmnd.h   |    1 	1 +	0 -	0 !
 include/scsi/scsi_device.h |   13 	13 +	0 -	0 !
 3 files changed, 125 insertions(+), 2 deletions(-)

Index: linux-2.6.24-rc8/drivers/scsi/scsi_lib.c
===================================================================
--- linux-2.6.24-rc8.orig/drivers/scsi/scsi_lib.c
+++ linux-2.6.24-rc8/drivers/scsi/scsi_lib.c
@@ -1163,6 +1163,38 @@ static struct scsi_cmnd *scsi_get_cmd_fr
 	return cmd;
 }
 
+static int scsi_setup_blk_linux_cmnd(struct scsi_device *sdev,
+				     struct request *rq)
+{
+	if (!get_device(&sdev->sdev_gendev)) {
+		rq->errors = BLKERR_DEV_OFFLINED;
+		return BLKPREP_KILL;
+	}
+
+	switch (rq->cmd[0]) {
+	case REQ_LB_OP_TRANSITION:
+		if (!sdev->sdev_dh || !sdev->sdev_dh->transition) {
+			/* set REQ_LB_OP_TRANSITION specific error */
+			rq->errors = BLKERR_NOSYS;
+			goto kill;
+		}
+		if (!try_module_get(sdev->sdev_dh->module)) {
+			rq->errors = BLKERR_DEV_OFFLINED;
+			goto kill;
+		}
+
+		break;
+	default:
+		rq->errors = BLKERR_INVALID_IO;
+		goto kill;
+	}
+	return BLKPREP_OK;
+
+kill:
+	put_device(&sdev->sdev_gendev);
+	return BLKPREP_KILL;
+}
+
 int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
 {
 	struct scsi_cmnd *cmd;
@@ -1332,6 +1364,8 @@ int scsi_prep_fn(struct request_queue *q
 
 	if (req->cmd_type == REQ_TYPE_BLOCK_PC)
 		ret = scsi_setup_blk_pc_cmnd(sdev, req);
+	else if (req->cmd_type == REQ_TYPE_LINUX_BLOCK)
+		ret = scsi_setup_blk_linux_cmnd(sdev, req);
 	return scsi_prep_return(q, req, ret);
 }
 EXPORT_SYMBOL(scsi_prep_fn);
@@ -1445,9 +1479,24 @@ static void scsi_kill_request(struct req
 static void scsi_softirq_done(struct request *rq)
 {
 	struct scsi_cmnd *cmd = rq->completion_data;
-	unsigned long wait_for = (cmd->allowed + 1) * cmd->timeout_per_command;
 	int disposition;
+	struct request_queue *q;
+	unsigned long wait_for, flags;
 
+	if (blk_linux_request(rq)) {
+		q = rq->q;
+		spin_lock_irqsave(q->queue_lock, flags);
+		/*
+		 * we always return 1 and the caller should
+		 * check rq->errors for the complete status
+		 */
+		end_that_request_last(rq, 1);
+		spin_unlock_irqrestore(q->queue_lock, flags);
+		return;
+	}
+
+
+	wait_for = (cmd->allowed + 1) * cmd->timeout_per_command;
 	INIT_LIST_HEAD(&cmd->eh_entry);
 
 	disposition = scsi_decide_disposition(cmd);
@@ -1477,6 +1526,50 @@ static void scsi_softirq_done(struct req
 	}
 }
 
+/**
+ * scsi_blk_linux_cmd_done - Complete a REQ_TYPE_LINUX_BLOCK request.
+ * @req: REQ_TYPE_LINUX_BLOCK request being processed
+ * @err: return value
+ *
+ * This function should be called by the REQ_TYPE_LINUX_BLOCK handler
+ * to return the request to its caller. This function queues the
+ * the completion to the blk softirq so the queue lock does not have
+ * to be held here.
+ */
+void scsi_blk_linux_cmd_done(struct request *rq, int err)
+{
+	struct scsi_device *sdev = rq->q->queuedata;
+
+	switch (rq->cmd[0]) {
+	case REQ_LB_OP_TRANSITION:
+		module_put(sdev->sdev_dh->module);
+		break;
+	}
+
+	put_device(&sdev->sdev_gendev);
+	rq->errors = err;
+	rq->completion_data = NULL;
+	blk_complete_request(rq);
+}
+EXPORT_SYMBOL_GPL(scsi_blk_linux_cmd_done);
+
+static void scsi_execute_blk_linux_cmd(struct request *rq)
+{
+	struct request_queue *q = rq->q;
+	struct scsi_device *sdev = q->queuedata;
+
+	switch (rq->cmd[0]) {
+	case REQ_LB_OP_TRANSITION:
+		spin_unlock_irq(q->queue_lock);
+		sdev->sdev_dh->transition(rq);
+		spin_lock_irq(q->queue_lock);
+		break;
+	default:
+		/* should have checked in scsi_prep_fn already */
+		BUG();
+	}
+}
+
 /*
  * Function:    scsi_request_fn()
  *
@@ -1519,7 +1612,23 @@ static void scsi_request_fn(struct reque
 		 * accept it.
 		 */
 		req = elv_next_request(q);
-		if (!req || !scsi_dev_queue_ready(q, sdev))
+		if (!req)
+			break;
+
+		/*
+		 * We do not account for linux blk req in the device
+		 * or host busy accounting because it is not necessarily
+		 * a scsi command that is sent to some object. The lower
+		 * level can translate it into a request/scsi_cmnd, if
+		 * necessary, and then queue that up using REQ_TYPE_BLOCK_PC.
+		 */
+		if (blk_linux_request(req)) {
+			blkdev_dequeue_request(req);
+			scsi_execute_blk_linux_cmd(req);
+			continue;
+		}
+
+		if (!scsi_dev_queue_ready(q, sdev))
 			break;
 
 		if (unlikely(!scsi_device_online(sdev))) {
Index: linux-2.6.24-rc8/include/scsi/scsi_cmnd.h
===================================================================
--- linux-2.6.24-rc8.orig/include/scsi/scsi_cmnd.h
+++ linux-2.6.24-rc8/include/scsi/scsi_cmnd.h
@@ -123,6 +123,7 @@ extern void __scsi_put_command(struct Sc
 			       struct device *);
 extern void scsi_finish_command(struct scsi_cmnd *cmd);
 extern void scsi_req_abort_cmd(struct scsi_cmnd *cmd);
+extern void scsi_blk_linux_cmd_done(struct request *req, int err);
 
 extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
 				 size_t *offset, size_t *len);
Index: linux-2.6.24-rc8/include/scsi/scsi_device.h
===================================================================
--- linux-2.6.24-rc8.orig/include/scsi/scsi_device.h
+++ linux-2.6.24-rc8/include/scsi/scsi_device.h
@@ -160,9 +160,22 @@ struct scsi_device {
 
 	struct execute_work	ew; /* used to get process context on put */
 
+	struct scsi_device_handler *sdev_dh;
+	void			*sdev_dh_data;
 	enum scsi_device_state sdev_state;
 	unsigned long		sdev_data[0];
 } __attribute__((aligned(sizeof(unsigned long))));
+
+struct scsi_device_handler {
+	struct module *module;
+	const char *name;
+
+	struct notifier_block nb;
+
+	int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *);
+	void (*transition)(struct request *);
+};
+
 #define	to_scsi_device(d)	\
 	container_of(d, struct scsi_device, sdev_gendev)
 #define	class_to_sdev(d)	\

-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------

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

* [PATCH 4/9] scsi_dh: add skeleton for SCSI Device Handlers
  2008-01-24  0:30 [PATCH 0/9] scsi_dh: Move dm device handler to SCSI layer Chandra Seetharaman
                   ` (2 preceding siblings ...)
  2008-01-24  0:30 ` [PATCH 3/9] scsi_dh: scsi handling of REQ_LB_OP_TRANSITION Chandra Seetharaman
@ 2008-01-24  0:31 ` Chandra Seetharaman
  2008-02-01 19:53   ` Mike Christie
  2008-01-24  0:31 ` [PATCH 5/9] scsi_dh: add EMC Clariion device handler Chandra Seetharaman
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 37+ messages in thread
From: Chandra Seetharaman @ 2008-01-24  0:31 UTC (permalink / raw)
  To: dm-devel, linux-scsi; +Cc: andmike, michaelc, Chandra Seetharaman, jens.axboe

Subject: scsi_dh: add skeleton for SCSI Device Handlers

From: Mike Anderson <andmike@linux.vnet.ibm.com>

Add base support to the SCSI subsystem for SCSI device handlers.

Signed-off-by: Mike Anderson <andmike@linux.vnet.ibm.com>
Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---

 drivers/scsi/Kconfig                 |    2 	2 +	0 -	0 !
 drivers/scsi/Makefile                |    1 	1 +	0 -	0 !
 drivers/scsi/device_handler/Kconfig  |   16 	16 +	0 -	0 !
 drivers/scsi/device_handler/Makefile |    3 	3 +	0 -	0 !
 drivers/scsi/scsi_error.c            |   10 	10 +	0 -	0 !
 drivers/scsi/scsi_sysfs.c            |   43 	43 +	0 -	0 !
 include/scsi/scsi_device.h           |    2 	2 +	0 -	0 !
 7 files changed, 77 insertions(+)

Index: linux-2.6.24-rc8/drivers/scsi/Kconfig
===================================================================
--- linux-2.6.24-rc8.orig/drivers/scsi/Kconfig
+++ linux-2.6.24-rc8/drivers/scsi/Kconfig
@@ -1822,4 +1822,6 @@ endif # SCSI_LOWLEVEL
 
 source "drivers/scsi/pcmcia/Kconfig"
 
+source "drivers/scsi/device_handler/Kconfig"
+
 endmenu
Index: linux-2.6.24-rc8/drivers/scsi/Makefile
===================================================================
--- linux-2.6.24-rc8.orig/drivers/scsi/Makefile
+++ linux-2.6.24-rc8/drivers/scsi/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_SCSI_ISCSI_ATTRS)	+= scsi_t
 obj-$(CONFIG_SCSI_SAS_ATTRS)	+= scsi_transport_sas.o
 obj-$(CONFIG_SCSI_SAS_LIBSAS)	+= libsas/
 obj-$(CONFIG_SCSI_SRP_ATTRS)	+= scsi_transport_srp.o
+obj-$(CONFIG_SCSI_DH)		+= device_handler/
 
 obj-$(CONFIG_ISCSI_TCP) 	+= libiscsi.o	iscsi_tcp.o
 obj-$(CONFIG_INFINIBAND_ISER) 	+= libiscsi.o
Index: linux-2.6.24-rc8/drivers/scsi/device_handler/Kconfig
===================================================================
--- /dev/null
+++ linux-2.6.24-rc8/drivers/scsi/device_handler/Kconfig
@@ -0,0 +1,16 @@
+#
+# SCSI Device Handler configuration
+#
+
+menuconfig SCSI_DH
+	bool "SCSI Device Handlers"
+	depends on SCSI!=n
+	default n
+	help
+	  SCSI Device Handlers provide device specific support for
+	  devices utilized in multipath configurations. Say Y here to
+	  select support for specific hardware.
+
+if SCSI_DH
+
+endif #SCSI_DH
Index: linux-2.6.24-rc8/drivers/scsi/device_handler/Makefile
===================================================================
--- /dev/null
+++ linux-2.6.24-rc8/drivers/scsi/device_handler/Makefile
@@ -0,0 +1,3 @@
+#
+# SCSI Device Handler
+#
Index: linux-2.6.24-rc8/drivers/scsi/scsi_error.c
===================================================================
--- linux-2.6.24-rc8.orig/drivers/scsi/scsi_error.c
+++ linux-2.6.24-rc8/drivers/scsi/scsi_error.c
@@ -298,6 +298,7 @@ static inline void scsi_eh_prt_fail_stat
  */
 static int scsi_check_sense(struct scsi_cmnd *scmd)
 {
+	struct scsi_device *sdev = scmd->device;
 	struct scsi_sense_hdr sshdr;
 
 	if (! scsi_command_normalize_sense(scmd, &sshdr))
@@ -306,6 +307,15 @@ static int scsi_check_sense(struct scsi_
 	if (scsi_sense_is_deferred(&sshdr))
 		return NEEDS_RETRY;
 
+	if (sdev->sdev_dh && sdev->sdev_dh->check_sense) {
+		int rc;
+
+		rc = sdev->sdev_dh->check_sense(sdev, &sshdr);
+		if (rc != SUCCESS)
+			return rc;
+		/* handler does not care. Drop down to default handling */
+	}
+
 	/*
 	 * Previous logic looked for FILEMARK, EOM or ILI which are
 	 * mainly associated with tapes and returned SUCCESS.
Index: linux-2.6.24-rc8/drivers/scsi/scsi_sysfs.c
===================================================================
--- linux-2.6.24-rc8.orig/drivers/scsi/scsi_sysfs.c
+++ linux-2.6.24-rc8/drivers/scsi/scsi_sysfs.c
@@ -951,6 +951,49 @@ int scsi_register_interface(struct class
 }
 EXPORT_SYMBOL(scsi_register_interface);
 
+static int scsi_dh_notifier_add(struct device *dev, void *data)
+{
+	struct scsi_device_handler *sdev_dh = data;
+
+	sdev_dh->nb.notifier_call(&sdev_dh->nb, BUS_NOTIFY_ADD_DEVICE, dev);
+
+	return 0;
+}
+
+int scsi_register_device_handler(struct scsi_device_handler *sdev_dh)
+{
+	int ret;
+
+	ret = bus_register_notifier(&scsi_bus_type, &sdev_dh->nb);
+
+	bus_for_each_dev(&scsi_bus_type, NULL, sdev_dh, scsi_dh_notifier_add);
+
+	return ret;
+}
+EXPORT_SYMBOL(scsi_register_device_handler);
+
+static int scsi_dh_notifier_remove(struct device *dev, void *data)
+{
+	struct scsi_device_handler *sdev_dh = data;
+
+	sdev_dh->nb.notifier_call(&sdev_dh->nb, BUS_NOTIFY_DEL_DEVICE, dev);
+
+	return 0;
+}
+
+int scsi_unregister_device_handler(struct scsi_device_handler *sdev_dh)
+{
+	int ret;
+
+	ret = bus_unregister_notifier(&scsi_bus_type, &sdev_dh->nb);
+
+	bus_for_each_dev(&scsi_bus_type, NULL, sdev_dh,
+					scsi_dh_notifier_remove);
+
+	return ret;
+}
+EXPORT_SYMBOL(scsi_unregister_device_handler);
+
 
 static struct class_device_attribute *class_attr_overridden(
 		struct class_device_attribute **attrs,
Index: linux-2.6.24-rc8/include/scsi/scsi_device.h
===================================================================
--- linux-2.6.24-rc8.orig/include/scsi/scsi_device.h
+++ linux-2.6.24-rc8/include/scsi/scsi_device.h
@@ -241,7 +241,9 @@ extern struct scsi_device *__scsi_add_de
 		uint, uint, uint, void *hostdata);
 extern int scsi_add_device(struct Scsi_Host *host, uint channel,
 			   uint target, uint lun);
+extern int scsi_register_device_handler(struct scsi_device_handler *sdev_dh);
 extern void scsi_remove_device(struct scsi_device *);
+extern int scsi_unregister_device_handler(struct scsi_device_handler *sdev_dh);
 
 extern int scsi_device_get(struct scsi_device *);
 extern void scsi_device_put(struct scsi_device *);

-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------

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

* [PATCH 5/9] scsi_dh: add EMC Clariion device handler
  2008-01-24  0:30 [PATCH 0/9] scsi_dh: Move dm device handler to SCSI layer Chandra Seetharaman
                   ` (3 preceding siblings ...)
  2008-01-24  0:31 ` [PATCH 4/9] scsi_dh: add skeleton for SCSI Device Handlers Chandra Seetharaman
@ 2008-01-24  0:31 ` Chandra Seetharaman
  2008-01-24  0:31 ` [PATCH 6/9] scsi_dh: add hp sw " Chandra Seetharaman
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 37+ messages in thread
From: Chandra Seetharaman @ 2008-01-24  0:31 UTC (permalink / raw)
  To: dm-devel, linux-scsi; +Cc: andmike, michaelc, Chandra Seetharaman, jens.axboe

Subject: scsi_dh: add EMC Clariion device handler

From: Mike Christie <michaelc@cs.wisc.edu>

This adds support for EMC Clariions. It is just a port of what is in
mainline. Ed's patches will be intergrated in a different patch which adds
more advanced functionality.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---

 drivers/scsi/device_handler/Kconfig       |    6 	6 +	0 -	0 !
 drivers/scsi/device_handler/Makefile      |    2 	2 +	0 -	0 !
 drivers/scsi/device_handler/scsi_dh_emc.c |  360 	360 +	0 -	0 !
 3 files changed, 368 insertions(+)

Index: linux-2.6.24-rc8/drivers/scsi/device_handler/Kconfig
===================================================================
--- linux-2.6.24-rc8.orig/drivers/scsi/device_handler/Kconfig
+++ linux-2.6.24-rc8/drivers/scsi/device_handler/Kconfig
@@ -13,4 +13,10 @@ menuconfig SCSI_DH
 
 if SCSI_DH
 
+config SCSI_DH_EMC
+	tristate "EMC CLARiiON Device Handler"
+	help
+	If you have a EMC CLARiiON select y. Otherwise, say N.
+
+
 endif #SCSI_DH
Index: linux-2.6.24-rc8/drivers/scsi/device_handler/Makefile
===================================================================
--- linux-2.6.24-rc8.orig/drivers/scsi/device_handler/Makefile
+++ linux-2.6.24-rc8/drivers/scsi/device_handler/Makefile
@@ -1,3 +1,5 @@
 #
 # SCSI Device Handler
 #
+
+obj-$(CONFIG_SCSI_DH_EMC)	+= scsi_dh_emc.o
Index: linux-2.6.24-rc8/drivers/scsi/device_handler/scsi_dh_emc.c
===================================================================
--- /dev/null
+++ linux-2.6.24-rc8/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -0,0 +1,360 @@
+/*
+ * Target driver for EMC CLARiiON AX/CX-series hardware.
+ * Based on code from Lars Marowsky-Bree <lmb@suse.de>
+ * and Ed Goggin <egoggin@emc.com>.
+ *
+ * Copyright (C) 2006 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2006 Mike Christie
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/blkdev.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_driver.h>
+
+#define CLARIION_NAME			"emc_clariion"
+
+#define CLARIION_TRESPASS_PAGE		0x22
+#define CLARIION_BUFFER_SIZE		0x80
+#define CLARIION_TIMEOUT		(60 * HZ)
+#define CLARIION_UNBOUND_LU		-1
+#define CLARIION_RETRIES		3
+
+struct clariion_dh_data {
+	/*
+	 * Use short trespass command (FC-series) or the long version
+	 * (default for AX/CX CLARiiON arrays).
+	 */
+	unsigned short_trespass;
+	/*
+	 * Whether or not (default) to honor SCSI reservations when
+	 * initiating a switch-over.
+	 */
+	unsigned hr;
+	/* I/O buffer for both MODE_SELECT and INQUIRY commands. */
+	char buffer[CLARIION_BUFFER_SIZE];
+	/*
+	 * SCSI sense buffer for commands -- assumes serial issuance
+	 * and completion sequence of all commands for same multipath.
+	 */
+	unsigned char sense[SCSI_SENSE_BUFFERSIZE];
+};
+
+static unsigned char long_trespass[] = {
+	0, 0, 0, 0,
+	CLARIION_TRESPASS_PAGE,	/* Page code */
+	0x09,			/* Page length - 2 */
+	0x81,			/* Trespass code + Honor reservation bit */
+	0xff, 0xff,		/* Trespass target */
+	0, 0, 0, 0, 0, 0	/* Reserved bytes / unknown */
+};
+
+static unsigned char long_trespass_hr[] = {
+	0, 0, 0, 0,
+	CLARIION_TRESPASS_PAGE,	/* Page code */
+	0x09,			/* Page length - 2 */
+	0x01,			/* Trespass code + Honor reservation bit */
+	0xff, 0xff,		/* Trespass target */
+	0, 0, 0, 0, 0, 0	/* Reserved bytes / unknown */
+};
+
+static unsigned char short_trespass[] = {
+	0, 0, 0, 0,
+	CLARIION_TRESPASS_PAGE,	/* Page code */
+	0x02,			/* Page length - 2 */
+	0x81,			/* Trespass code + Honor reservation bit */
+	0xff,			/* Trespass target */
+};
+
+static unsigned char short_trespass_hr[] = {
+	0, 0, 0, 0,
+	CLARIION_TRESPASS_PAGE,	/* Page code */
+	0x02,			/* Page length - 2 */
+	0x01,			/* Trespass code + Honor reservation bit */
+	0xff,			/* Trespass target */
+};
+
+/*
+ * Parse MODE_SELECT cmd reply.
+ */
+static int parse_trespass_rsp(struct scsi_device *sdev, char *sense,
+			       int result)
+{
+	struct scsi_sense_hdr sshdr;
+	int err = 0;
+
+	if (status_byte(result) == CHECK_CONDITION &&
+	    scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)) {
+		sdev_printk(KERN_ERR, sdev, "Found valid sense data 0x%2x, "
+			    "0x%2x, 0x%2x while sending CLARiiON trespass "
+			    "command.\n", sshdr.sense_key, sshdr.asc,
+			     sshdr.ascq);
+
+		if ((sshdr.sense_key == 0x05) && (sshdr.asc == 0x04) &&
+		     (sshdr.ascq == 0x00)) {
+			/*
+			 * Array based copy in progress -- do not send
+			 * pg_init or copy will be aborted mid-stream.
+			 */
+			sdev_printk(KERN_INFO, sdev, "Array Based Copy in "
+				    "progress while sending CLARiiON trespass "
+				    "command.\n");
+			err = BLKERR_DEV_TEMP_BUSY;
+		} else if ((sshdr.sense_key == 0x02) && (sshdr.asc == 0x04) &&
+			    (sshdr.ascq == 0x03)) {
+			/*
+			 * LUN Not Ready - Manual Intervention Required
+			 * indicates in-progress ucode upgrade (NDU).
+			 */
+			sdev_printk(KERN_INFO, sdev, "Detected in-progress "
+				    "ucode upgrade NDU operation while sending "
+				    "CLARiiON trespass command.\n");
+			err = BLKERR_DEV_TEMP_BUSY;
+		} else
+			err = BLKERR_DEV_FAILED;
+	} else if (result) {
+		sdev_printk(KERN_ERR, sdev, "Error 0x%x while sending "
+			    "CLARiiON trespass command.\n", result);
+		err = BLKERR_IO;
+	}
+
+	return err;
+}
+
+static void trespass_done(struct request *req, int uptodate)
+{
+	struct request *act_req = req->end_io_data;
+	struct scsi_device *sdev = req->q->queuedata;
+	int err_flags, result = req->errors;
+	char *sense = req->sense;
+
+	sdev_printk(KERN_NOTICE, sdev, "Trespass compeleted. Uptodate %d error "
+		    "%d.\n", uptodate, req->errors);
+
+	__blk_put_request(req->q, req);
+
+	err_flags = parse_trespass_rsp(sdev, sense, result);
+	if (err_flags) {
+		scsi_blk_linux_cmd_done(act_req, err_flags);
+		return;
+	}
+
+	scsi_blk_linux_cmd_done(act_req, BLKERR_OK);
+}
+
+static int execute_trespass(struct request *act_req)
+{
+	struct scsi_device *sdev = act_req->q->queuedata;
+	struct clariion_dh_data *csdev = sdev->sdev_dh_data;
+	struct request *req;
+	unsigned char *page22;
+	unsigned size;
+
+	if (csdev->short_trespass) {
+		page22 = csdev->hr ? short_trespass_hr : short_trespass;
+		size = sizeof(short_trespass);
+	} else {
+		page22 = csdev->hr ? long_trespass_hr : long_trespass;
+		size = sizeof(long_trespass);
+	}
+
+	req = blk_get_request(sdev->request_queue, 1, GFP_ATOMIC);
+	if (!req)
+		return BLKERR_RES_TEMP_UNAVAIL;
+
+	req->cmd_type = REQ_TYPE_BLOCK_PC;
+	req->cmd_flags |= REQ_FAILFAST;
+	req->timeout = CLARIION_TIMEOUT;
+	req->retries = CLARIION_RETRIES;
+	req->end_io_data = act_req;
+	req->sense = csdev->sense;
+	memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE);
+	req->sense_len = 0;
+
+	memset(req->cmd, 0, MAX_COMMAND_SIZE);
+	req->cmd[0] = MODE_SELECT;
+	req->cmd[1] = 0x10;
+	req->cmd[4] = size;
+	req->cmd_len = COMMAND_SIZE(MODE_SELECT);
+	memcpy(csdev->buffer, page22, size);
+
+	if (blk_rq_map_kern(sdev->request_queue, req, csdev->buffer,
+							size, GFP_ATOMIC)) {
+		__blk_put_request(req->q, req);
+		return BLKERR_RES_TEMP_UNAVAIL;
+	}
+
+	sdev_printk(KERN_NOTICE, sdev, "Failing over device\n.");
+	blk_execute_rq_nowait(req->q, NULL, req, 1, trespass_done);
+	return BLKERR_OK;
+}
+
+static void clariion_transition(struct request *req)
+{
+	int err;
+
+	err = execute_trespass(req);
+	if (err)
+		scsi_blk_linux_cmd_done(req, err);
+}
+
+static int clariion_check_sense(struct scsi_device *sdev,
+				struct scsi_sense_hdr *sense_hdr)
+{
+	switch (sense_hdr->sense_key) {
+	case NOT_READY:
+		if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x03)
+			/*
+			 * LUN Not Ready - Manual Intervention Required
+			 * indicates this is a passive path.
+			 *
+			 * FIXME: However, if this is seen and EVPD C0
+			 * indicates that this is due to a NDU in
+			 * progress, we should set FAIL_PATH too.
+			 * This indicates we might have to do a SCSI
+			 * inquiry in the end_io path. Ugh.
+			 *
+			 * Can return FAILED only when we want the error
+			 * recovery process to kick in.
+			 */
+			return SUCCESS;
+		break;
+	case ILLEGAL_REQUEST:
+		if (sense_hdr->asc == 0x25 && sense_hdr->ascq == 0x01)
+			/*
+			 * An array based copy is in progress. Do not
+			 * fail the path, do not bypass to another PG,
+			 * do not retry. Fail the IO immediately.
+			 * (Actually this is the same conclusion as in
+			 * the default handler, but lets make sure.)
+			 *
+			 * Can return FAILED only when we want the error
+			 * recovery process to kick in.
+			 */
+			return SUCCESS;
+		break;
+	case UNIT_ATTENTION:
+		if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00)
+			/*
+			 * Unit Attention Code. This is the first IO
+			 * to the new path, so just retry.
+			 */
+			return NEEDS_RETRY;
+		break;
+	}
+
+	/* success just means we do not care what scsi-ml does */
+	return SUCCESS;
+}
+
+static const struct {
+	char *vendor;
+	char *model;
+} clariion_dev_list[] = {
+	{"DGC", "RAID"},
+	{"DGC", "DISK"},
+	{NULL, NULL},
+};
+
+static int clariion_bus_notify(struct notifier_block *, unsigned long, void *);
+
+static struct scsi_device_handler clariion_dh = {
+	.name		= CLARIION_NAME,
+	.module		= THIS_MODULE,
+	.nb.notifier_call = clariion_bus_notify,
+	.check_sense	= clariion_check_sense,
+	.transition	= clariion_transition,
+};
+
+/*
+ * TODO: need some interface so we can set trespass values
+ */
+static int clariion_bus_notify(struct notifier_block *nb,
+				unsigned long action, void *data)
+{
+	struct device *dev = data;
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct clariion_dh_data *dh_data;
+	int i, found = 0;
+	unsigned long flags;
+
+	if (action == BUS_NOTIFY_ADD_DEVICE) {
+		for (i = 0; clariion_dev_list[i].vendor; i++) {
+			if (!strncmp(sdev->vendor, clariion_dev_list[i].vendor,
+				     strlen(clariion_dev_list[i].vendor)) &&
+			    !strncmp(sdev->model, clariion_dev_list[i].model,
+				     strlen(clariion_dev_list[i].model))) {
+				found = 1;
+				break;
+			}
+		}
+		if (!found)
+			goto out;
+
+		dh_data = kzalloc(sizeof(*dh_data), GFP_KERNEL);
+		if (!dh_data) {
+			sdev_printk(KERN_ERR, sdev, "Attach failed %s.\n",
+				    CLARIION_NAME);
+			goto out;
+		}
+
+		spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
+		sdev->sdev_dh_data = dh_data;
+		sdev->sdev_dh = &clariion_dh;
+		spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
+
+		sdev_printk(KERN_NOTICE, sdev, "Attached %s.\n",
+			    CLARIION_NAME);
+
+	} else if (action == BUS_NOTIFY_DEL_DEVICE) {
+		if (sdev->sdev_dh != &clariion_dh)
+			goto out;
+
+		spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
+		dh_data = sdev->sdev_dh_data;
+		sdev->sdev_dh_data = NULL;
+		sdev->sdev_dh = NULL;
+		spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
+
+		sdev_printk(KERN_NOTICE, sdev, "Dettached %s.\n",
+			    CLARIION_NAME);
+
+		kfree(dh_data);
+	}
+
+out:
+	return 0;
+}
+
+
+static int __init clariion_init(void)
+{
+	return scsi_register_device_handler(&clariion_dh);
+}
+
+static void __exit clariion_exit(void)
+{
+	scsi_unregister_device_handler(&clariion_dh);
+}
+
+module_init(clariion_init);
+module_exit(clariion_exit);
+
+MODULE_DESCRIPTION("EMC CX/AX/FC-family driver");
+MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu");
+MODULE_LICENSE("GPL");

-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------

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

* [PATCH 6/9] scsi_dh: add hp sw device handler
  2008-01-24  0:30 [PATCH 0/9] scsi_dh: Move dm device handler to SCSI layer Chandra Seetharaman
                   ` (4 preceding siblings ...)
  2008-01-24  0:31 ` [PATCH 5/9] scsi_dh: add EMC Clariion device handler Chandra Seetharaman
@ 2008-01-24  0:31 ` Chandra Seetharaman
  2008-01-24  0:32 ` [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE Chandra Seetharaman
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 37+ messages in thread
From: Chandra Seetharaman @ 2008-01-24  0:31 UTC (permalink / raw)
  To: dm-devel, linux-scsi; +Cc: andmike, michaelc, Chandra Seetharaman, jens.axboe

Subject: scsi_dh: add hp sw device handler

From: Mike Christie <michaelc@cs.wisc.edu>

This patch adds a very basic scsi device handler for older hp boxes which
cannot be upgraded.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---

 drivers/scsi/device_handler/Kconfig         |    6 	6 +	0 -	0 !
 drivers/scsi/device_handler/Makefile        |    1 	1 +	0 -	0 !
 drivers/scsi/device_handler/scsi_dh_hp_sw.c |  206 	206 +	0 -	0 !
 3 files changed, 213 insertions(+)

Index: linux-2.6.24-rc8/drivers/scsi/device_handler/Kconfig
===================================================================
--- linux-2.6.24-rc8.orig/drivers/scsi/device_handler/Kconfig
+++ linux-2.6.24-rc8/drivers/scsi/device_handler/Kconfig
@@ -18,5 +18,11 @@ config SCSI_DH_EMC
 	help
 	If you have a EMC CLARiiON select y. Otherwise, say N.
 
+config SCSI_DH_HP_SW
+	tristate "HP/COMPAQ MSA Device Handler"
+	help
+	If you have a HP/COMPAQ MSA device that requires START_STOP to
+	be sent to start it and cannot upgrade the firmware then select y.
+	Otherwise, say N.
 
 endif #SCSI_DH
Index: linux-2.6.24-rc8/drivers/scsi/device_handler/Makefile
===================================================================
--- linux-2.6.24-rc8.orig/drivers/scsi/device_handler/Makefile
+++ linux-2.6.24-rc8/drivers/scsi/device_handler/Makefile
@@ -3,3 +3,4 @@
 #
 
 obj-$(CONFIG_SCSI_DH_EMC)	+= scsi_dh_emc.o
+obj-$(CONFIG_SCSI_DH_HP_SW)	+= scsi_dh_hp_sw.o
Index: linux-2.6.24-rc8/drivers/scsi/device_handler/scsi_dh_hp_sw.c
===================================================================
--- /dev/null
+++ linux-2.6.24-rc8/drivers/scsi/device_handler/scsi_dh_hp_sw.c
@@ -0,0 +1,206 @@
+/*
+ * Basic HP/COMPAQ MSA 1000 support. This is only needed if your HW cannot be
+ * upgraded.
+ *
+ * Copyright (C) 2006 Red Hat, Inc.  All rights reserved.
+ * Copyright (C) 2006 Mike Christie
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/blkdev.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_dbg.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_driver.h>
+
+#define HP_SW_NAME	"hp_sw"
+
+#define HP_SW_TIMEOUT 30
+#define HP_SW_RETRIES 3
+
+struct hp_sw_dh_data {
+	unsigned char sense[SCSI_SENSE_BUFFERSIZE];
+	int retries;
+};
+
+static void hp_sw_done(struct request *req, int uptodate)
+{
+	struct request *act_req = req->end_io_data;
+	struct request_queue *q = req->q;
+	struct scsi_device *sdev = q->queuedata;
+	struct hp_sw_dh_data *hp_sw_dh_data = sdev->sdev_dh_data;
+	struct scsi_sense_hdr sshdr;
+	int rc = BLKERR_OK;
+
+	sdev_printk(KERN_INFO, sdev, "hp_sw_done %d\n", req->errors);
+
+	/*
+	 * This will at least get us going. Let Dave do the details.
+	 */
+	if (status_byte(req->errors) == CHECK_CONDITION &&
+	    scsi_normalize_sense(req->sense, req->sense_len, &sshdr)) {
+		/* tmp debug output */
+		__scsi_print_sense("hp_sw_done", req->sense, req->sense_len);
+
+		switch (sshdr.sense_key) {
+		case NOT_READY:
+			if ((sshdr.asc == 0x04) && (sshdr.ascq == 3)) {
+				rc = BLKERR_RETRY;
+				hp_sw_dh_data->retries++;
+				break;
+			}
+			/* fall through */
+		default:
+			hp_sw_dh_data->retries++;
+			rc = BLKERR_IMM_RETRY;
+		}
+	} else if (req->errors)
+		rc = BLKERR_IO;
+
+	if (rc == BLKERR_OK)
+		hp_sw_dh_data->retries = 0;
+	else if (hp_sw_dh_data->retries > HP_SW_RETRIES) {
+		hp_sw_dh_data->retries = 0;
+		rc = BLKERR_IO;
+	}
+
+	__blk_put_request(req->q, req);
+	scsi_blk_linux_cmd_done(act_req, rc);
+}
+
+static void hp_sw_transition(struct request *act_req)
+{
+	struct scsi_device *sdev = act_req->q->queuedata;
+	struct hp_sw_dh_data *hp_sw_dh_data = sdev->sdev_dh_data;
+	struct request *req;
+
+	sdev_printk(KERN_INFO, sdev, "hp_sw_done send START_STOP retries %d.\n",
+		   act_req->retries);
+
+	req = blk_get_request(sdev->request_queue, 0, GFP_ATOMIC);
+	if (!req) {
+		scsi_blk_linux_cmd_done(req, BLKERR_RES_TEMP_UNAVAIL);
+		return;
+	}
+
+	req->cmd_type = REQ_TYPE_BLOCK_PC;
+	req->cmd_flags |= REQ_FAILFAST;
+	req->cmd_len = COMMAND_SIZE(START_STOP);
+	memset(req->cmd, 0, MAX_COMMAND_SIZE);
+	req->cmd[0] = START_STOP;
+	req->cmd[4] = 1;	/* Start spin cycle */
+	req->timeout = HP_SW_TIMEOUT;
+	req->retries = HP_SW_RETRIES;
+	req->end_io_data = act_req;
+	req->sense = hp_sw_dh_data->sense;
+	memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE);
+	req->sense_len = 0;
+
+	blk_execute_rq_nowait(req->q, NULL, req, 1, hp_sw_done);
+}
+
+static const struct {
+	char *vendor;
+	char *model;
+} hp_sw_dh_data_list[] = {
+	{"COMPAQ", "MSA1000"},
+	{"HP", "HSV100"},
+	{NULL, NULL},
+};
+
+static int hp_sw_bus_notify(struct notifier_block *, unsigned long, void *);
+
+static struct scsi_device_handler hp_sw_dh = {
+	.name		= HP_SW_NAME,
+	.module		= THIS_MODULE,
+	.nb.notifier_call = hp_sw_bus_notify,
+	.transition	= hp_sw_transition,
+};
+
+static int hp_sw_bus_notify(struct notifier_block *nb,
+			    unsigned long action, void *data)
+{
+	struct device *dev = data;
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct hp_sw_dh_data *dh_data;
+	int i, found = 0;
+	unsigned long flags;
+
+	if (action == BUS_NOTIFY_ADD_DEVICE) {
+		for (i = 0; hp_sw_dh_data_list[i].vendor; i++) {
+			if (!strncmp(sdev->vendor, hp_sw_dh_data_list[i].vendor,
+				     strlen(hp_sw_dh_data_list[i].vendor)) &&
+			    !strncmp(sdev->model, hp_sw_dh_data_list[i].model,
+				     strlen(hp_sw_dh_data_list[i].model))) {
+				found = 1;
+				break;
+			}
+		}
+		if (!found)
+			goto out;
+
+		dh_data = kzalloc(sizeof(*dh_data), GFP_KERNEL);
+		if (!dh_data) {
+			sdev_printk(KERN_ERR, sdev, "Attach Failed %s.\n",
+				    HP_SW_NAME);
+			goto out;
+		}
+
+		spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
+		sdev->sdev_dh_data = dh_data;
+		sdev->sdev_dh = &hp_sw_dh;
+		spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
+
+		sdev_printk(KERN_NOTICE, sdev, "Attached %s.\n",
+			    HP_SW_NAME);
+	} else if (action == BUS_NOTIFY_DEL_DEVICE) {
+		if (sdev->sdev_dh != &hp_sw_dh)
+			goto out;
+
+		spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
+		dh_data = sdev->sdev_dh_data;
+		sdev->sdev_dh_data = NULL;
+		sdev->sdev_dh = NULL;
+		spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
+
+		sdev_printk(KERN_NOTICE, sdev, "Dettached %s.\n",
+			    HP_SW_NAME);
+
+		kfree(dh_data);
+	}
+
+out:
+	return 0;
+}
+
+static int __init hp_sw_init(void)
+{
+	return scsi_register_device_handler(&hp_sw_dh);
+}
+
+static void __exit hp_sw_exit(void)
+{
+	scsi_unregister_device_handler(&hp_sw_dh);
+}
+
+module_init(hp_sw_init);
+module_exit(hp_sw_exit);
+
+MODULE_DESCRIPTION("HP MSA 1000");
+MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu");
+MODULE_LICENSE("GPL");

-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------

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

* [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE
  2008-01-24  0:30 [PATCH 0/9] scsi_dh: Move dm device handler to SCSI layer Chandra Seetharaman
                   ` (5 preceding siblings ...)
  2008-01-24  0:31 ` [PATCH 6/9] scsi_dh: add hp sw " Chandra Seetharaman
@ 2008-01-24  0:32 ` Chandra Seetharaman
  2008-02-04 18:58   ` James Bottomley
  2008-01-24  0:32 ` [PATCH 8/9] scsi_dh: add lsi rdac device handler Chandra Seetharaman
  2008-01-24  0:32 ` [PATCH 9/9] scsi_dh: add scsi device handler to dm Chandra Seetharaman
  8 siblings, 1 reply; 37+ messages in thread
From: Chandra Seetharaman @ 2008-01-24  0:32 UTC (permalink / raw)
  To: dm-devel, linux-scsi; +Cc: andmike, michaelc, Chandra Seetharaman, jens.axboe

Subject: scsi_dh: Add support for SDEV_PASSIVE

From: Chandra Seetharaman <sekharan@us.ibm.com>

This patch adds a new device state SDEV_PASSIVE, to correspond to the
passive side access of an active/passive multipathed device.

Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---

---
 drivers/scsi/scsi_lib.c    |   14 	13 +	1 -	0 !
 include/scsi/scsi_device.h |    2 	2 +	0 -	0 !
 2 files changed, 15 insertions(+), 1 deletion(-)

Index: linux-2.6.24-rc8/drivers/scsi/scsi_lib.c
===================================================================
--- linux-2.6.24-rc8.orig/drivers/scsi/scsi_lib.c
+++ linux-2.6.24-rc8/drivers/scsi/scsi_lib.c
@@ -1310,6 +1310,14 @@ int scsi_prep_state_check(struct scsi_de
 			if (!(req->cmd_flags & REQ_PREEMPT))
 				ret = BLKPREP_DEFER;
 			break;
+		case SDEV_PASSIVE:
+			/*
+			 * If the device is passive, we refuse to
+			 * process any FS commands.
+			 */
+			if (req->cmd_type == REQ_TYPE_FS)
+				ret = BLKPREP_KILL;
+			break;
 		default:
 			/*
 			 * For any other not fully online state we only allow
@@ -2179,6 +2187,7 @@ scsi_device_set_state(struct scsi_device
 		case SDEV_OFFLINE:
 		case SDEV_QUIESCE:
 		case SDEV_BLOCK:
+		case SDEV_PASSIVE:
 			break;
 		default:
 			goto illegal;
@@ -2241,7 +2250,10 @@ scsi_device_set_state(struct scsi_device
 			goto illegal;
 		}
 		break;
-
+	case SDEV_PASSIVE:
+		if (oldstate != SDEV_RUNNING)
+			goto illegal;
+		break;
 	}
 	sdev->sdev_state = state;
 	return 0;
Index: linux-2.6.24-rc8/include/scsi/scsi_device.h
===================================================================
--- linux-2.6.24-rc8.orig/include/scsi/scsi_device.h
+++ linux-2.6.24-rc8/include/scsi/scsi_device.h
@@ -44,6 +44,8 @@ enum scsi_device_state {
 	SDEV_BLOCK,		/* Device blocked by scsi lld.  No scsi 
 				 * commands from user or midlayer should be issued
 				 * to the scsi lld. */
+	SDEV_PASSIVE,		/* Device is the passive side of a
+				 * active/passive multipath storage */
 };
 
 enum scsi_device_event {

-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------

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

* [PATCH 8/9] scsi_dh: add lsi rdac device handler
  2008-01-24  0:30 [PATCH 0/9] scsi_dh: Move dm device handler to SCSI layer Chandra Seetharaman
                   ` (6 preceding siblings ...)
  2008-01-24  0:32 ` [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE Chandra Seetharaman
@ 2008-01-24  0:32 ` Chandra Seetharaman
  2008-01-24  0:32 ` [PATCH 9/9] scsi_dh: add scsi device handler to dm Chandra Seetharaman
  8 siblings, 0 replies; 37+ messages in thread
From: Chandra Seetharaman @ 2008-01-24  0:32 UTC (permalink / raw)
  To: dm-devel, linux-scsi; +Cc: andmike, michaelc, Chandra Seetharaman, jens.axboe

Subject: scsi_dh: add lsi rdac device handler

From: Chandra Seetharaman <sekharan@us.ibm.com>

add LSI RDAC SCSI device handler

Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---

 drivers/scsi/device_handler/Kconfig            |    5 	5 +	0 -	0 !
 drivers/scsi/device_handler/Makefile           |    1 	1 +	0 -	0 !
 drivers/scsi/device_handler/scsi_dh_lsi_rdac.c |  766 	766 +	0 -	0 !
 3 files changed, 772 insertions(+)

Index: linux-2.6.24-rc8/drivers/scsi/device_handler/Kconfig
===================================================================
--- linux-2.6.24-rc8.orig/drivers/scsi/device_handler/Kconfig
+++ linux-2.6.24-rc8/drivers/scsi/device_handler/Kconfig
@@ -25,4 +25,9 @@ config SCSI_DH_HP_SW
 	be sent to start it and cannot upgrade the firmware then select y.
 	Otherwise, say N.
 
+config SCSI_DH_LSI_RDAC
+	tristate "LSI RDAC Device Handler"
+	help
+	If you have a LSI RDAC select y. Otherwise, say N.
+
 endif #SCSI_DH
Index: linux-2.6.24-rc8/drivers/scsi/device_handler/Makefile
===================================================================
--- linux-2.6.24-rc8.orig/drivers/scsi/device_handler/Makefile
+++ linux-2.6.24-rc8/drivers/scsi/device_handler/Makefile
@@ -4,3 +4,4 @@
 
 obj-$(CONFIG_SCSI_DH_EMC)	+= scsi_dh_emc.o
 obj-$(CONFIG_SCSI_DH_HP_SW)	+= scsi_dh_hp_sw.o
+obj-$(CONFIG_SCSI_DH_LSI_RDAC)	+= scsi_dh_lsi_rdac.o
Index: linux-2.6.24-rc8/drivers/scsi/device_handler/scsi_dh_lsi_rdac.c
===================================================================
--- /dev/null
+++ linux-2.6.24-rc8/drivers/scsi/device_handler/scsi_dh_lsi_rdac.c
@@ -0,0 +1,766 @@
+/*
+ * Engenio/LSI RDAC SCSI Device Handler
+ *
+ * Copyright (C) 2005 Mike Christie. All rights reserved.
+ * Copyright (C) Chandra Seetharaman, IBM Corp. 2007
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+#include <linux/blkdev.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_driver.h>
+
+#define RDAC_NAME "lsi_rdac"
+
+/*
+ * LSI mode page stuff
+ *
+ * These struct definitions and the forming of the
+ * mode page were taken from the LSI RDAC 2.4 GPL'd
+ * driver, and then converted to Linux conventions.
+ */
+#define RDAC_QUIESCENCE_TIME 20;
+/*
+ * Page Codes
+ */
+#define RDAC_PAGE_CODE_REDUNDANT_CONTROLLER 0x2c
+
+/*
+ * Controller modes definitions
+ */
+#define RDAC_MODE_TRANSFER_ALL_LUNS		0x01
+#define RDAC_MODE_TRANSFER_SPECIFIED_LUNS	0x02
+
+/*
+ * RDAC Options field
+ */
+#define RDAC_FORCED_QUIESENCE 0x02
+
+#define RDAC_TIMEOUT	(60 * HZ)
+#define RDAC_RETRIES	3
+
+struct rdac_mode_6_hdr {
+	u8	data_len;
+	u8	medium_type;
+	u8	device_params;
+	u8	block_desc_len;
+};
+
+struct rdac_mode_10_hdr {
+	u16	data_len;
+	u8	medium_type;
+	u8	device_params;
+	u16	reserved;
+	u16	block_desc_len;
+};
+
+struct rdac_mode_common {
+	u8	controller_serial[16];
+	u8	alt_controller_serial[16];
+	u8	rdac_mode[2];
+	u8	alt_rdac_mode[2];
+	u8	quiescence_timeout;
+	u8	rdac_options;
+};
+
+struct rdac_pg_legacy {
+	struct rdac_mode_6_hdr hdr;
+	u8	page_code;
+	u8	page_len;
+	struct rdac_mode_common common;
+#define MODE6_MAX_LUN	32
+	u8	lun_table[MODE6_MAX_LUN];
+	u8	reserved2[32];
+	u8	reserved3;
+	u8	reserved4;
+};
+
+struct rdac_pg_expanded {
+	struct rdac_mode_10_hdr hdr;
+	u8	page_code;
+	u8	subpage_code;
+	u8	page_len[2];
+	struct rdac_mode_common common;
+	u8	lun_table[256];
+	u8	reserved3;
+	u8	reserved4;
+};
+
+struct c9_inquiry {
+	u8	peripheral_info;
+	u8	page_code;	/* 0xC9 */
+	u8	reserved1;
+	u8	page_len;
+	u8	page_id[4];	/* "vace" */
+	u8	avte_cvp;
+	u8	path_prio;
+	u8	reserved2[38];
+};
+
+#define SUBSYS_ID_LEN	16
+#define SLOT_ID_LEN	2
+
+struct c4_inquiry {
+	u8	peripheral_info;
+	u8	page_code;	/* 0xC4 */
+	u8	reserved1;
+	u8	page_len;
+	u8	page_id[4];	/* "subs" */
+	u8	subsys_id[SUBSYS_ID_LEN];
+	u8	revision[4];
+	u8	slot_id[SLOT_ID_LEN];
+	u8	reserved[2];
+};
+
+struct rdac_controller {
+	u8			subsys_id[SUBSYS_ID_LEN];
+	u8			slot_id[SLOT_ID_LEN];
+	int			use_10_ms;
+	struct kref		kref;
+	struct list_head	node; /* list of all controllers */
+	spinlock_t		lock;
+	int			submitted;
+	struct list_head	cmd_list; /* list of commands to be submitted */
+	union			{
+		struct rdac_pg_legacy legacy;
+		struct rdac_pg_expanded expanded;
+	} mode_select;
+};
+struct c8_inquiry {
+	u8	peripheral_info;
+	u8	page_code; /* 0xC8 */
+	u8	reserved1;
+	u8	page_len;
+	u8	page_id[4]; /* "edid" */
+	u8	reserved2[3];
+	u8	vol_uniq_id_len;
+	u8	vol_uniq_id[16];
+	u8	vol_user_label_len;
+	u8	vol_user_label[60];
+	u8	array_uniq_id_len;
+	u8	array_unique_id[16];
+	u8	array_user_label_len;
+	u8	array_user_label[60];
+	u8	lun[8];
+};
+
+struct c2_inquiry {
+	u8	peripheral_info;
+	u8	page_code;	/* 0xC2 */
+	u8	reserved1;
+	u8	page_len;
+	u8	page_id[4];	/* "swr4" */
+	u8	sw_version[3];
+	u8	sw_date[3];
+	u8	features_enabled;
+	u8	max_lun_supported;
+	u8	partitions[239]; /* Total allocation length should be 0xFF */
+};
+
+struct rdac_dh_data {
+	struct list_head	entry; /* list waiting to submit MODE SELECT */
+	struct rdac_controller	*ctlr;
+#define UNINITIALIZED_LUN	(1 << 8)
+	unsigned		lun;
+	unsigned char		sense[SCSI_SENSE_BUFFERSIZE];
+	struct request		*act_req;
+	struct work_struct	work;
+#define	SEND_C2_INQUIRY		1
+#define	SEND_C4_INQUIRY		2
+#define	SEND_C8_INQUIRY		3
+#define	SEND_C9_INQUIRY		4
+#define	SEND_MODE_SELECT	5
+	int			cmd_to_send;
+	union			{
+		struct c2_inquiry c2;
+		struct c4_inquiry c4;
+		struct c8_inquiry c8;
+		struct c9_inquiry c9;
+	} inq;
+};
+
+static LIST_HEAD(ctlr_list);
+static DEFINE_SPINLOCK(list_lock);
+static struct workqueue_struct *rdac_wkqd;
+
+static inline int had_failures(int result)
+{
+	return (host_byte(result) != DID_OK ||
+			msg_byte(result) != COMMAND_COMPLETE);
+}
+
+static void rdac_resubmit_all(struct rdac_dh_data *h)
+{
+	struct rdac_controller *ctlr = h->ctlr;
+	struct rdac_dh_data *tmp, *h1;
+
+	spin_lock(&ctlr->lock);
+	list_for_each_entry_safe(h1, tmp, &ctlr->cmd_list, entry) {
+		h1->cmd_to_send = SEND_C9_INQUIRY;
+		queue_work(rdac_wkqd, &h1->work);
+		list_del(&h1->entry);
+	}
+	ctlr->submitted = 0;
+	spin_unlock(&ctlr->lock);
+}
+
+static void mode_select_endio(struct request *req, int uptodate)
+{
+	struct request *act_req = req->end_io_data;
+	struct scsi_device *sdev = req->q->queuedata;
+	struct scsi_sense_hdr sense_hdr;
+	int sense, err = BLKERR_OK, result = req->errors;
+
+	if (had_failures(result)) {
+		err = BLKERR_DEV_FAILED;
+		goto failed;
+	}
+
+	if (status_byte(result) == CHECK_CONDITION) {
+		scsi_normalize_sense(req->sense, SCSI_SENSE_BUFFERSIZE,
+				&sense_hdr);
+		sense = (sense_hdr.sense_key << 16) | (sense_hdr.asc << 8) |
+				sense_hdr.ascq;
+		/* If it is retryable failure, submit the c9 inquiry again */
+		if (sense == 0x59136 || sense == 0x68b02 || sense == 0xb8b02 ||
+				    sense == 0x62900) {
+			/* 0x59136    - Command lock contention
+			 * 0x[6b]8b02 - Quiesense in progress or achieved
+			 * 0x62900    - Power On, Reset, or Bus Device Reset
+			 */
+			err = BLKERR_DEV_TEMP_BUSY;
+		}
+		if (sense)
+			sdev_printk(KERN_INFO, sdev,
+				"MODE_SELECT failed with sense 0x%x", sense);
+	} else if (result) {
+		sdev_printk(KERN_ERR, sdev, "Error 0x%x while sending "
+			"MODE_SELECT.\n", result);
+		err = BLKERR_IO;
+	}
+
+	scsi_device_set_state(sdev, SDEV_RUNNING);
+failed:
+	scsi_blk_linux_cmd_done(act_req, err);
+	rdac_resubmit_all(sdev->sdev_dh_data);
+	__blk_put_request(req->q, req);
+}
+
+static struct request *get_rdac_req(struct request *act_req,
+			void *buffer, unsigned buflen, int rw)
+{
+	struct request *rq;
+	struct request_queue *q = act_req->q;
+	struct scsi_device *sdev = q->queuedata;
+	struct rdac_dh_data *h = sdev->sdev_dh_data;
+
+	rq = blk_get_request(q, rw, GFP_KERNEL);
+
+	if (!rq) {
+		sdev_printk(KERN_INFO, sdev,
+				"get_rdac_req: blk_get_request failed");
+		return NULL;
+	}
+
+	if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_KERNEL)) {
+		blk_put_request(rq);
+		sdev_printk(KERN_INFO, sdev,
+				"get_rdac_req: blk_rq_map_kern failed");
+		return NULL;
+	}
+
+	memset(&rq->cmd, 0, BLK_MAX_CDB);
+	rq->sense = h->sense;
+	memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
+	rq->sense_len = 0;
+
+	rq->cmd_type = REQ_TYPE_BLOCK_PC;
+	rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE;
+	rq->retries = RDAC_RETRIES;
+	rq->timeout = RDAC_TIMEOUT;
+	rq->end_io_data = act_req;
+
+	return rq;
+}
+
+static struct request *rdac_failover_get(struct request *act_req)
+{
+	struct request *rq;
+	struct rdac_mode_common *common;
+	unsigned data_size;
+	struct scsi_device *sdev = act_req->q->queuedata;
+	struct rdac_dh_data *h = sdev->sdev_dh_data;
+
+	if (h->ctlr->use_10_ms) {
+		struct rdac_pg_expanded *rdac_pg;
+
+		data_size = sizeof(struct rdac_pg_expanded);
+		rdac_pg = &h->ctlr->mode_select.expanded;
+		memset(rdac_pg, 0, data_size);
+		common = &rdac_pg->common;
+		rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER + 0x40;
+		rdac_pg->subpage_code = 0x1;
+		rdac_pg->page_len[0] = 0x01;
+		rdac_pg->page_len[1] = 0x28;
+		rdac_pg->lun_table[h->lun] = 0x81;
+	} else {
+		struct rdac_pg_legacy *rdac_pg;
+
+		data_size = sizeof(struct rdac_pg_legacy);
+		rdac_pg = &h->ctlr->mode_select.legacy;
+		memset(rdac_pg, 0, data_size);
+		common = &rdac_pg->common;
+		rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER;
+		rdac_pg->page_len = 0x68;
+		rdac_pg->lun_table[h->lun] = 0x81;
+	}
+	common->rdac_mode[1] = RDAC_MODE_TRANSFER_SPECIFIED_LUNS;
+	common->quiescence_timeout = RDAC_QUIESCENCE_TIME;
+	common->rdac_options = RDAC_FORCED_QUIESENCE;
+
+	/* get request for block layer packet command */
+	rq = get_rdac_req(act_req, &h->ctlr->mode_select, data_size, WRITE);
+	if (!rq)
+		return NULL;
+
+	/* Prepare the command. */
+	if (h->ctlr->use_10_ms) {
+		rq->cmd[0] = MODE_SELECT_10;
+		rq->cmd[7] = data_size >> 8;
+		rq->cmd[8] = data_size & 0xff;
+	} else {
+		rq->cmd[0] = MODE_SELECT;
+		rq->cmd[4] = data_size;
+	}
+	rq->cmd_len = COMMAND_SIZE(rq->cmd[0]);
+
+	return rq;
+}
+
+/* Acquires h->ctlr->lock */
+static void submit_mode_select(struct request *act_req)
+{
+	struct request *rq;
+	struct request_queue *q = act_req->q;
+	struct scsi_device *sdev = q->queuedata;
+	struct rdac_dh_data *h = sdev->sdev_dh_data;
+
+	spin_lock(&h->ctlr->lock);
+	if (h->ctlr->submitted) {
+		list_add(&h->entry, &h->ctlr->cmd_list);
+		goto drop_lock;
+	}
+
+	rq = rdac_failover_get(act_req);
+	if (!rq)
+		goto fail_path;
+
+	sdev_printk(KERN_INFO, sdev, "queueing MODE_SELECT command");
+
+	blk_execute_rq_nowait(q, NULL, rq, 1, mode_select_endio);
+	h->ctlr->submitted = 1;
+	goto drop_lock;
+fail_path:
+	scsi_blk_linux_cmd_done(act_req, BLKERR_RES_TEMP_UNAVAIL);
+drop_lock:
+	spin_unlock(&h->ctlr->lock);
+}
+
+static void release_ctlr(struct kref *kref)
+{
+	struct rdac_controller *ctlr;
+	ctlr = container_of(kref, struct rdac_controller, kref);
+
+	spin_lock(&list_lock);
+	list_del(&ctlr->node);
+	spin_unlock(&list_lock);
+	kfree(ctlr);
+}
+
+static struct rdac_controller *get_controller(u8 *subsys_id, u8 *slot_id)
+{
+	struct rdac_controller *ctlr, *tmp;
+
+	spin_lock(&list_lock);
+
+	list_for_each_entry(tmp, &ctlr_list, node) {
+		if ((memcmp(tmp->subsys_id, subsys_id, SUBSYS_ID_LEN) == 0) &&
+			  (memcmp(tmp->slot_id, slot_id, SLOT_ID_LEN) == 0)) {
+			kref_get(&tmp->kref);
+			spin_unlock(&list_lock);
+			return tmp;
+		}
+	}
+	ctlr = kmalloc(sizeof(*ctlr), GFP_ATOMIC);
+	if (!ctlr)
+		goto done;
+
+	/* initialize fields of controller */
+	memcpy(ctlr->subsys_id, subsys_id, SUBSYS_ID_LEN);
+	memcpy(ctlr->slot_id, slot_id, SLOT_ID_LEN);
+	kref_init(&ctlr->kref);
+	spin_lock_init(&ctlr->lock);
+	ctlr->submitted = 0;
+	ctlr->use_10_ms = -1;
+	INIT_LIST_HEAD(&ctlr->cmd_list);
+	list_add(&ctlr->node, &ctlr_list);
+done:
+	spin_unlock(&list_lock);
+	return ctlr;
+}
+
+static void c4_endio(struct request *req, int uptodate)
+{
+	struct request *act_req = req->end_io_data;
+	struct scsi_device *sdev = act_req->q->queuedata;
+	struct rdac_dh_data *h = sdev->sdev_dh_data;
+	struct c4_inquiry *sp;
+	int result = req->errors;
+
+	__blk_put_request(req->q, req);
+	if (had_failures(result)) {
+		scsi_blk_linux_cmd_done(act_req, BLKERR_IO);
+		return;
+	}
+
+	sp = &h->inq.c4;
+
+	h->ctlr = get_controller(sp->subsys_id, sp->slot_id);
+
+	if (h->ctlr) {
+		h->cmd_to_send = SEND_C9_INQUIRY;
+		queue_work(rdac_wkqd, &h->work);
+	} else
+		scsi_blk_linux_cmd_done(act_req, BLKERR_RES_TEMP_UNAVAIL);
+}
+
+static void c2_endio(struct request *req, int uptodate)
+{
+	struct request *act_req = req->end_io_data;
+	struct scsi_device *sdev = act_req->q->queuedata;
+	struct rdac_dh_data *h = sdev->sdev_dh_data;
+	struct c2_inquiry *sp;
+	int result = req->errors;
+
+	__blk_put_request(req->q, req);
+	if (had_failures(result)) {
+		scsi_blk_linux_cmd_done(act_req, BLKERR_IO);
+		return;
+	}
+
+	sp = &h->inq.c2;
+
+	/* If more than MODE6_MAX_LUN luns are supported, use mode select 10 */
+	if (sp->max_lun_supported >= MODE6_MAX_LUN)
+		h->ctlr->use_10_ms = 1;
+	else
+		h->ctlr->use_10_ms = 0;
+
+	h->cmd_to_send = SEND_MODE_SELECT;
+	queue_work(rdac_wkqd, &h->work);
+}
+
+static void c9_endio(struct request *req, int uptodate)
+{
+	struct request *act_req = req->end_io_data;
+	struct scsi_device *sdev = act_req->q->queuedata;
+	struct rdac_dh_data *h = sdev->sdev_dh_data;
+	struct c9_inquiry *sp;
+	int result = req->errors;
+
+	__blk_put_request(req->q, req);
+	if (had_failures(result)) {
+		scsi_blk_linux_cmd_done(act_req, BLKERR_IO);
+		return;
+	}
+
+	/* We need to look at the sense keys here to take clear action.
+	 * For now simple logic: If the host is in AVT mode or if controller
+	 * owns the lun, return dm_pg_init_complete(), otherwise submit
+	 * MODE SELECT.
+	 */
+	sp = &h->inq.c9;
+
+	/* If in AVT mode, return success */
+	if ((sp->avte_cvp >> 7) == 0x1) {
+		scsi_blk_linux_cmd_done(act_req, BLKERR_OK);
+		return;
+	}
+
+	/* If the controller on this path owns the LUN, return success */
+	if (sp->avte_cvp & 0x1) {
+		scsi_blk_linux_cmd_done(act_req, BLKERR_OK);
+		return;
+	}
+
+	if (h->ctlr) {
+		if (h->ctlr->use_10_ms == -1)
+			h->cmd_to_send = SEND_C2_INQUIRY;
+		else
+			h->cmd_to_send = SEND_MODE_SELECT;
+	} else
+		h->cmd_to_send = SEND_C4_INQUIRY;
+	queue_work(rdac_wkqd, &h->work);
+}
+
+static void c8_endio(struct request *req, int uptodate)
+{
+	struct request *act_req = req->end_io_data;
+	struct scsi_device *sdev = act_req->q->queuedata;
+	struct rdac_dh_data *h = sdev->sdev_dh_data;
+	struct c8_inquiry *sp;
+	int result = req->errors;
+
+	__blk_put_request(req->q, req);
+	if (had_failures(result)) {
+		scsi_blk_linux_cmd_done(act_req, BLKERR_IO);
+		return;
+	}
+
+	/* We need to look at the sense keys here to take clear action.
+	 * For now simple logic: Get the lun from the inquiry page.
+	 */
+	sp = &h->inq.c8;
+	h->lun = sp->lun[7]; /* currently it uses only one byte */
+	h->cmd_to_send = SEND_C9_INQUIRY;
+	queue_work(rdac_wkqd, &h->work);
+}
+
+static void submit_inquiry(struct request *act_req, int page_code,
+		unsigned int len, rq_end_io_fn endio)
+{
+	struct request *rq;
+	struct request_queue *q = act_req->q;
+	struct scsi_device *sdev = q->queuedata;
+	struct rdac_dh_data *h = sdev->sdev_dh_data;
+
+	rq = get_rdac_req(act_req, &h->inq, len, READ);
+	if (!rq)
+		goto fail_path;
+
+	/* Prepare the command. */
+	rq->cmd[0] = INQUIRY;
+	rq->cmd[1] = 1;
+	rq->cmd[2] = page_code;
+	rq->cmd[4] = len;
+	rq->cmd_len = COMMAND_SIZE(INQUIRY);
+	blk_execute_rq_nowait(q, NULL, rq, 1, endio);
+	return;
+
+fail_path:
+	scsi_blk_linux_cmd_done(act_req, BLKERR_IO);
+}
+
+static void service_wkq(struct work_struct *work)
+{
+	struct rdac_dh_data *h = container_of(work, struct rdac_dh_data, work);
+
+	switch (h->cmd_to_send) {
+	case SEND_C2_INQUIRY:
+		submit_inquiry(h->act_req, 0xC2,
+					sizeof(struct c2_inquiry), c2_endio);
+		break;
+	case SEND_C4_INQUIRY:
+		submit_inquiry(h->act_req, 0xC4,
+					sizeof(struct c4_inquiry), c4_endio);
+		break;
+	case SEND_C8_INQUIRY:
+		submit_inquiry(h->act_req, 0xC8,
+					sizeof(struct c8_inquiry), c8_endio);
+		break;
+	case SEND_C9_INQUIRY:
+		submit_inquiry(h->act_req, 0xC9,
+					sizeof(struct c9_inquiry), c9_endio);
+		break;
+	case SEND_MODE_SELECT:
+		submit_mode_select(h->act_req);
+		break;
+	default:
+		BUG();
+	}
+}
+
+static int rdac_check_sense(struct scsi_device *sdev,
+				struct scsi_sense_hdr *sense_hdr)
+{
+	switch (sense_hdr->sense_key) {
+	case NOT_READY:
+#if 0
+		if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x81)
+			/* LUN Not Ready - Storage firmware incompatible
+			 * Manual code synchonisation required.
+			 *
+			 * Nothing we can do here. Try to bypass the path.
+			 */
+			return SUCCESS;
+#endif
+		if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0xA1)
+			/* LUN Not Ready - Quiescense in progress
+			 *
+			 * Just retry and wait.
+			 */
+			return NEEDS_RETRY;
+		break;
+	case ILLEGAL_REQUEST:
+		if (sense_hdr->asc == 0x94 && sense_hdr->ascq == 0x01)
+			/* Invalid Request - Current Logical Unit Ownership.
+			 * Controller is not the current owner of the LUN,
+			 * Fail the path, so that the other path be used.
+			 */
+			scsi_device_set_state(sdev, SDEV_PASSIVE);
+		break;
+	case UNIT_ATTENTION:
+		if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00)
+			/*
+			 * Power On, Reset, or Bus Device Reset, just retry.
+			 */
+			return NEEDS_RETRY;
+		break;
+	}
+	/* success just means we do not care what scsi-ml does */
+	return SUCCESS;
+}
+
+static void rdac_transition(struct request *act_req)
+{
+	struct scsi_device *sdev = act_req->q->queuedata;
+	struct rdac_dh_data *h = sdev->sdev_dh_data;
+
+	h->act_req = act_req;
+	switch (h->lun) {
+	case UNINITIALIZED_LUN:
+		submit_inquiry(h->act_req, 0xC8, sizeof(struct c8_inquiry),
+								 c8_endio);
+		break;
+	default:
+		submit_inquiry(h->act_req, 0xC9, sizeof(struct c9_inquiry),
+								c9_endio);
+	}
+}
+
+static const struct {
+	char *vendor;
+	char *model;
+} rdac_dev_list[] = {
+	{"IBM", "1815"},
+	{NULL, NULL},
+};
+
+static int rdac_bus_notify(struct notifier_block *, unsigned long, void *);
+
+static struct scsi_device_handler rdac_dh = {
+	.name = RDAC_NAME,
+	.module = THIS_MODULE,
+	.nb.notifier_call = rdac_bus_notify,
+	.check_sense = rdac_check_sense,
+	.transition = rdac_transition,
+};
+
+/*
+ * TODO: need some interface so we can set trespass values
+ */
+static int rdac_bus_notify(struct notifier_block *nb,
+			    unsigned long action, void *data)
+{
+	struct device *dev = data;
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct rdac_dh_data *dh_data;
+	int i, found = 0;
+	unsigned long flags;
+
+	if (action == BUS_NOTIFY_ADD_DEVICE) {
+		for (i = 0; rdac_dev_list[i].vendor; i++) {
+			if (!strncmp(sdev->vendor, rdac_dev_list[i].vendor,
+				     strlen(rdac_dev_list[i].vendor)) &&
+			    !strncmp(sdev->model, rdac_dev_list[i].model,
+				     strlen(rdac_dev_list[i].model))) {
+				found = 1;
+				break;
+			}
+		}
+		if (!found)
+			goto out;
+
+		dh_data = kzalloc(sizeof(*dh_data), GFP_KERNEL);
+		if (!dh_data) {
+			sdev_printk(KERN_ERR, sdev, "Attach failed %s.\n",
+				    RDAC_NAME);
+			goto out;
+		}
+
+		dh_data->lun = UNINITIALIZED_LUN;
+		INIT_WORK(&dh_data->work, service_wkq);
+		spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
+		sdev->sdev_dh_data = dh_data;
+		sdev->sdev_dh = &rdac_dh;
+		spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
+
+		sdev_printk(KERN_NOTICE, sdev, "Attached %s.\n", RDAC_NAME);
+
+	} else if (action == BUS_NOTIFY_DEL_DEVICE) {
+		if (sdev->sdev_dh != &rdac_dh)
+			goto out;
+
+		spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
+		dh_data = sdev->sdev_dh_data;
+		sdev->sdev_dh_data = NULL;
+		sdev->sdev_dh = NULL;
+		spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
+
+		if (dh_data->ctlr)
+			kref_put(&dh_data->ctlr->kref, release_ctlr);
+		kfree(dh_data);
+		sdev_printk(KERN_NOTICE, sdev, "Dettached %s.\n",
+			    RDAC_NAME);
+	}
+
+out:
+	return 0;
+}
+
+static int __init rdac_init(void)
+{
+	int r;
+
+	rdac_wkqd = create_singlethread_workqueue("rdac_wkqd");
+	if (!rdac_wkqd) {
+		printk(KERN_ERR "Failed to create workqueue rdac_wkqd.");
+		return -ENOMEM;
+	}
+
+	r = scsi_register_device_handler(&rdac_dh);
+	if (r != 0) {
+		destroy_workqueue(rdac_wkqd);
+		printk(KERN_ERR "Failed to register scsi device handler.");
+	}
+	return r;
+}
+
+static void __exit rdac_exit(void)
+{
+	scsi_unregister_device_handler(&rdac_dh);
+	destroy_workqueue(rdac_wkqd);
+}
+
+module_init(rdac_init);
+module_exit(rdac_exit);
+
+MODULE_DESCRIPTION("Multipath LSI/Engenio RDAC driver");
+MODULE_AUTHOR("Mike Christie, Chandra Seetharaman");
+MODULE_LICENSE("GPL");

-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------

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

* [PATCH 9/9] scsi_dh: add scsi device handler to dm
  2008-01-24  0:30 [PATCH 0/9] scsi_dh: Move dm device handler to SCSI layer Chandra Seetharaman
                   ` (7 preceding siblings ...)
  2008-01-24  0:32 ` [PATCH 8/9] scsi_dh: add lsi rdac device handler Chandra Seetharaman
@ 2008-01-24  0:32 ` Chandra Seetharaman
  8 siblings, 0 replies; 37+ messages in thread
From: Chandra Seetharaman @ 2008-01-24  0:32 UTC (permalink / raw)
  To: dm-devel, linux-scsi; +Cc: andmike, michaelc, Chandra Seetharaman, jens.axboe

Subject: scsi_dh: add scsi device handler to dm

From: Mike Anderson <andmike@linux.vnet.ibm.com>

This patch adds a dm hardware handler that can control SCSI device
handlers.

SCSI Hardware handler for a specific device type can be invokes by using
this handler.

For example, to use the lsi_rdac SCSI hardware handler, one would specify
        hardware_handler        "2 scsi_dh lsi_rdac"
in the device section of /etc/multipath.conf.

Signed-off-by: Mike Anderson <andmike@linux.vnet.ibm.com>
Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com>
---

 drivers/md/Kconfig            |    6 	6 +	0 -	0 !
 drivers/md/Makefile           |    2 	2 +	0 -	0 !
 drivers/md/dm-mpath-scsi-dh.c |  185 	185 +	0 -	0 !
 3 files changed, 193 insertions(+)

Index: linux-2.6.24-rc8/drivers/md/Kconfig
===================================================================
--- linux-2.6.24-rc8.orig/drivers/md/Kconfig
+++ linux-2.6.24-rc8/drivers/md/Kconfig
@@ -273,6 +273,12 @@ config DM_MULTIPATH_HP
         ---help---
           Multipath support for HP MSA (Active/Passive) series hardware.
 
+config DM_MULTIPATH_SCSI_DH
+        tristate "SCSI Device Handler support (EXPERIMENTAL)"
+        depends on DM_MULTIPATH && BLK_DEV_DM && EXPERIMENTAL
+        ---help---
+          Multipath support for SCSI Device Handlers.
+
 config DM_DELAY
 	tristate "I/O delaying target (EXPERIMENTAL)"
 	depends on BLK_DEV_DM && EXPERIMENTAL
Index: linux-2.6.24-rc8/drivers/md/Makefile
===================================================================
--- linux-2.6.24-rc8.orig/drivers/md/Makefile
+++ linux-2.6.24-rc8/drivers/md/Makefile
@@ -9,6 +9,7 @@ dm-snapshot-objs := dm-snap.o dm-excepti
 dm-mirror-objs	:= dm-log.o dm-raid1.o
 dm-rdac-objs	:= dm-mpath-rdac.o
 dm-hp-sw-objs	:= dm-mpath-hp-sw.o
+dm-scsi-dh-objs := dm-mpath-scsi-dh.o
 md-mod-objs     := md.o bitmap.o
 raid456-objs	:= raid5.o raid6algos.o raid6recov.o raid6tables.o \
 		   raid6int1.o raid6int2.o raid6int4.o \
@@ -38,6 +39,7 @@ obj-$(CONFIG_DM_MULTIPATH)	+= dm-multipa
 obj-$(CONFIG_DM_MULTIPATH_EMC)	+= dm-emc.o
 obj-$(CONFIG_DM_MULTIPATH_HP)	+= dm-hp-sw.o
 obj-$(CONFIG_DM_MULTIPATH_RDAC)	+= dm-rdac.o
+obj-$(CONFIG_DM_MULTIPATH_SCSI_DH) += dm-scsi-dh.o
 obj-$(CONFIG_DM_SNAPSHOT)	+= dm-snapshot.o
 obj-$(CONFIG_DM_MIRROR)		+= dm-mirror.o
 obj-$(CONFIG_DM_ZERO)		+= dm-zero.o
Index: linux-2.6.24-rc8/drivers/md/dm-mpath-scsi-dh.c
===================================================================
--- /dev/null
+++ linux-2.6.24-rc8/drivers/md/dm-mpath-scsi-dh.c
@@ -0,0 +1,185 @@
+/*
+ * SCSI Device handler
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright IBM Corporation, 2007
+ * 	Author: Mike Anderson <andmike@linux.vnet.ibm.com>
+ */
+
+#define DM_MSG_PREFIX "multipath scsi_dh"
+
+#include "dm.h"
+#include "dm-hw-handler.h"
+
+struct scsi_dh_context {
+	char		*hw_handler_name;
+	struct dm_path	*path;
+};
+
+static int scsi_dh_create(struct hw_handler *hwh, unsigned argc, char **argv)
+{
+	struct scsi_dh_context *c;
+
+	c = kzalloc(sizeof(*c), GFP_KERNEL);
+	if (!c)
+		return -ENOMEM;
+	if (argc == 1) {
+		c->hw_handler_name = kstrdup(argv[0], GFP_KERNEL);
+		if (c->hw_handler_name)
+			request_module("scsi_dh_%s", c->hw_handler_name);
+	}
+
+	hwh->context = c;
+
+	return 0;
+}
+
+static void scsi_dh_destroy(struct hw_handler *hwh)
+{
+	struct scsi_dh_context *c = hwh->context;
+	kfree(c->hw_handler_name);
+	kfree(c);
+	hwh->context = NULL;
+	return;
+}
+
+static unsigned scsi_dh_error(struct hw_handler *hwh, struct bio *bio)
+{
+	/* Try default handler */
+	return dm_scsi_err_handler(hwh, bio);
+}
+
+
+static void pg_init_done(struct request *req, int err)
+{
+	struct scsi_dh_context *c = req->end_io_data;
+	int ret = 0;
+
+	if (blkerr_transport_err(req->errors)) {
+		/*
+		 * Old dm behavior had us fail a path on any error.
+		 * In future patches, since we have finer grained errors now,
+		 * we do not have to fail the path on the first transient
+		 * error.
+		 */
+		ret = MP_FAIL_PATH;
+		goto out;
+	}
+
+	/* device or driver problems */
+	switch (req->errors) {
+	case BLKERR_OK:
+		break;
+	case BLKERR_NOSYS:
+		if (!c->hw_handler_name)
+			break;
+		DMERR("Cannot failover device because hw-%s may not be "
+		      "loaded.", c->hw_handler_name);
+		/*
+		 * Fail path for now, so we do not ping poing
+		 */
+		ret = MP_FAIL_PATH;
+		break;
+	case BLKERR_DEV_TEMP_BUSY:
+		/*
+		 * Probably doing something like FW upgrade on the
+		 * controller so try the other pg.
+		 */
+		ret = MP_BYPASS_PG;
+		break;
+	/* TODO: For BLKERR_RETRY we should wait a couple seconds */
+	case BLKERR_RETRY:
+	case BLKERR_IMM_RETRY:
+	case BLKERR_RES_TEMP_UNAVAIL:
+		break;
+	default:
+		/*
+		 * We probably do not want to fail the path for a device
+		 * error, but this is what the old dm did. In future
+		 * patches we can do more advanced handling.
+		 */
+		ret = MP_FAIL_PATH;
+	}
+
+out:
+	dm_pg_init_complete(c->path, ret);
+	__blk_put_request(req->q, req);
+	return;
+}
+
+static void scsi_dh_pg_init(struct hw_handler *hwh, unsigned bypassed,
+			struct dm_path *path)
+{
+	struct scsi_dh_context *c = hwh->context;
+	struct request *req;
+
+	req = blk_get_request(bdev_get_queue(path->dev->bdev), 1, GFP_NOIO);
+	if (!req) {
+		/* FIXME: Add retry */
+		dm_pg_init_complete(path, MP_FAIL_PATH);
+		return;
+	}
+
+	req->cmd[0] = REQ_LB_OP_TRANSITION;
+	req->cmd_type = REQ_TYPE_LINUX_BLOCK;
+	c->path = path;
+	req->end_io_data = c;
+	/* TODO: does this need to be configurable or is it HW specific? */
+	req->retries = 5;
+	blk_execute_rq_nowait(req->q, NULL, req, 1, pg_init_done);
+}
+
+#define SCSI_DH_NAME "scsi_dh"
+#define SCSI_DH_VER "0.1"
+
+static struct hw_handler_type scsi_dh_handler = {
+	.name = SCSI_DH_NAME,
+	.module = THIS_MODULE,
+	.create = scsi_dh_create,
+	.destroy = scsi_dh_destroy,
+	.pg_init = scsi_dh_pg_init,
+	.error = scsi_dh_error,
+};
+
+static int __init scsi_dh_init(void)
+{
+	int r;
+
+	r = dm_register_hw_handler(&scsi_dh_handler);
+	if (r < 0) {
+		DMERR("%s: register failed %d", SCSI_DH_NAME, r);
+		return r;
+	}
+
+	DMINFO("%s: version %s loaded", SCSI_DH_NAME, SCSI_DH_VER);
+	return 0;
+}
+
+static void __exit scsi_dh_exit(void)
+{
+	int r = dm_unregister_hw_handler(&scsi_dh_handler);
+
+	if (r < 0)
+		DMERR("%s: unregister failed %d", SCSI_DH_NAME, r);
+}
+
+module_init(scsi_dh_init);
+module_exit(scsi_dh_exit);
+
+MODULE_DESCRIPTION("DM Multipath SCSI Device Handler support");
+MODULE_AUTHOR("Mike Anderson <andmike@linux.vnet.ibm.com");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(SCSI_DH_VER);

-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------

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

* Re: [PATCH 4/9] scsi_dh: add skeleton for SCSI Device Handlers
  2008-01-24  0:31 ` [PATCH 4/9] scsi_dh: add skeleton for SCSI Device Handlers Chandra Seetharaman
@ 2008-02-01 19:53   ` Mike Christie
  2008-02-01 20:27     ` Mike Anderson
  2008-02-04 18:54     ` Chandra Seetharaman
  0 siblings, 2 replies; 37+ messages in thread
From: Mike Christie @ 2008-02-01 19:53 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: andmike, dm-devel, linux-scsi, jens.axboe

Chandra Seetharaman wrote:
>  	 * mainly associated with tapes and returned SUCCESS.
> Index: linux-2.6.24-rc8/drivers/scsi/scsi_sysfs.c
> ===================================================================
> --- linux-2.6.24-rc8.orig/drivers/scsi/scsi_sysfs.c
> +++ linux-2.6.24-rc8/drivers/scsi/scsi_sysfs.c
> @@ -951,6 +951,49 @@ int scsi_register_interface(struct class
>  }
>  EXPORT_SYMBOL(scsi_register_interface);
>  
> +static int scsi_dh_notifier_add(struct device *dev, void *data)
> +{
> +	struct scsi_device_handler *sdev_dh = data;
> +
> +	sdev_dh->nb.notifier_call(&sdev_dh->nb, BUS_NOTIFY_ADD_DEVICE, dev);
> +
> +	return 0;
> +}
> +
> +int scsi_register_device_handler(struct scsi_device_handler *sdev_dh)
> +{
> +	int ret;
> +
> +	ret = bus_register_notifier(&scsi_bus_type, &sdev_dh->nb);
> +
> +	bus_for_each_dev(&scsi_bus_type, NULL, sdev_dh, scsi_dh_notifier_add);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(scsi_register_device_handler);
> +
> +static int scsi_dh_notifier_remove(struct device *dev, void *data)
> +{
> +	struct scsi_device_handler *sdev_dh = data;
> +
> +	sdev_dh->nb.notifier_call(&sdev_dh->nb, BUS_NOTIFY_DEL_DEVICE, dev);
> +
> +	return 0;
> +}
> +
> +int scsi_unregister_device_handler(struct scsi_device_handler *sdev_dh)
> +{
> +	int ret;
> +
> +	ret = bus_unregister_notifier(&scsi_bus_type, &sdev_dh->nb);
> +
> +	bus_for_each_dev(&scsi_bus_type, NULL, sdev_dh,
> +					scsi_dh_notifier_remove);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(scsi_unregister_device_handler);
> +

Did this end up solving the problem I was hitting where when using the 
other driver model stuff like is used with the SCSI upper layer drivers. 
The problem where the hw handler module had to be loaded before finding 
devices and had to be loaded before sd.c?

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

* Re: [PATCH 3/9] scsi_dh: scsi handling of REQ_LB_OP_TRANSITION
  2008-01-24  0:30 ` [PATCH 3/9] scsi_dh: scsi handling of REQ_LB_OP_TRANSITION Chandra Seetharaman
@ 2008-02-01 20:00   ` Mike Christie
  2008-02-04 18:59     ` Chandra Seetharaman
  2008-02-04 19:02     ` James Bottomley
  0 siblings, 2 replies; 37+ messages in thread
From: Mike Christie @ 2008-02-01 20:00 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: andmike, dm-devel, linux-scsi, jens.axboe

Chandra Seetharaman wrote:
> @@ -1445,9 +1479,24 @@ static void scsi_kill_request(struct req
>  static void scsi_softirq_done(struct request *rq)
>  {
>  	struct scsi_cmnd *cmd = rq->completion_data;
> -	unsigned long wait_for = (cmd->allowed + 1) * cmd->timeout_per_command;
>  	int disposition;
> +	struct request_queue *q;
> +	unsigned long wait_for, flags;
>  
> +	if (blk_linux_request(rq)) {
> +		q = rq->q;
> +		spin_lock_irqsave(q->queue_lock, flags);
> +		/*
> +		 * we always return 1 and the caller should
> +		 * check rq->errors for the complete status
> +		 */
> +		end_that_request_last(rq, 1);
> +		spin_unlock_irqrestore(q->queue_lock, flags);
> +		return;
> +	}
> +
> +
> +	wait_for = (cmd->allowed + 1) * cmd->timeout_per_command;
>  	INIT_LIST_HEAD(&cmd->eh_entry);
>  
.....

> +
>  /*
>   * Function:    scsi_request_fn()
>   *
> @@ -1519,7 +1612,23 @@ static void scsi_request_fn(struct reque
>  		 * accept it.
>  		 */
>  		req = elv_next_request(q);
> -		if (!req || !scsi_dev_queue_ready(q, sdev))
> +		if (!req)
> +			break;
> +
> +		/*
> +		 * We do not account for linux blk req in the device
> +		 * or host busy accounting because it is not necessarily
> +		 * a scsi command that is sent to some object. The lower
> +		 * level can translate it into a request/scsi_cmnd, if
> +		 * necessary, and then queue that up using REQ_TYPE_BLOCK_PC.
> +		 */
> +		if (blk_linux_request(req)) {
> +			blkdev_dequeue_request(req);
> +			scsi_execute_blk_linux_cmd(req);
> +			continue;
> +		}
> +
> +		if (!scsi_dev_queue_ready(q, sdev))
>  			break;

I think these two pieces are one of the reasons I have not pushed the 
patches. I thought the completion and execution pieces here are a little 
ugly and seem to just wedge themselves in where they want to be.

Is there any way to make the insertion of non-scsi commands more common? 
Do we have the code for being able to send requests directly to 
something like a fc rport done? Could we maybe inject these special 
commands to the hw handler using something similar to how bsg would send 
non scsi commands to weird objects (objects like rport, sessions, and 
not devices we traditionally associated with queues like scsi_devices). 
Just a thought with no code :) that is why the ugly code existed still :)

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

* Re: [PATCH 4/9] scsi_dh: add skeleton for SCSI Device Handlers
  2008-02-01 19:53   ` Mike Christie
@ 2008-02-01 20:27     ` Mike Anderson
  2008-02-04 18:54     ` Chandra Seetharaman
  1 sibling, 0 replies; 37+ messages in thread
From: Mike Anderson @ 2008-02-01 20:27 UTC (permalink / raw)
  To: Mike Christie; +Cc: Chandra Seetharaman, dm-devel, linux-scsi, jens.axboe

Mike Christie <michaelc@cs.wisc.edu> wrote:
> Chandra Seetharaman wrote:
>>  	 * mainly associated with tapes and returned SUCCESS.
>> Index: linux-2.6.24-rc8/drivers/scsi/scsi_sysfs.c
>> ===================================================================
>> --- linux-2.6.24-rc8.orig/drivers/scsi/scsi_sysfs.c
>> +++ linux-2.6.24-rc8/drivers/scsi/scsi_sysfs.c
>> @@ -951,6 +951,49 @@ int scsi_register_interface(struct class
>>  }
>>  EXPORT_SYMBOL(scsi_register_interface);
>>  +static int scsi_dh_notifier_add(struct device *dev, void *data)
>> +{
>> +	struct scsi_device_handler *sdev_dh = data;
>> +
>> +	sdev_dh->nb.notifier_call(&sdev_dh->nb, BUS_NOTIFY_ADD_DEVICE, dev);
>> +
>> +	return 0;
>> +}
>> +
>> +int scsi_register_device_handler(struct scsi_device_handler *sdev_dh)
>> +{
>> +	int ret;
>> +
>> +	ret = bus_register_notifier(&scsi_bus_type, &sdev_dh->nb);
>> +
>> +	bus_for_each_dev(&scsi_bus_type, NULL, sdev_dh, scsi_dh_notifier_add);
>> +
>> +	return ret;
>> +}
>> +EXPORT_SYMBOL(scsi_register_device_handler);
>> +
>> +static int scsi_dh_notifier_remove(struct device *dev, void *data)
>> +{
>> +	struct scsi_device_handler *sdev_dh = data;
>> +
>> +	sdev_dh->nb.notifier_call(&sdev_dh->nb, BUS_NOTIFY_DEL_DEVICE, dev);
>> +
>> +	return 0;
>> +}
>> +
>> +int scsi_unregister_device_handler(struct scsi_device_handler *sdev_dh)
>> +{
>> +	int ret;
>> +
>> +	ret = bus_unregister_notifier(&scsi_bus_type, &sdev_dh->nb);
>> +
>> +	bus_for_each_dev(&scsi_bus_type, NULL, sdev_dh,
>> +					scsi_dh_notifier_remove);
>> +
>> +	return ret;
>> +}
>> +EXPORT_SYMBOL(scsi_unregister_device_handler);
>> +
>
> Did this end up solving the problem I was hitting where when using the 
> other driver model stuff like is used with the SCSI upper layer drivers. 
> The problem where the hw handler module had to be loaded before finding 
> devices and had to be loaded before sd.c?

Yes this update was to have the handler add routine called prior to the
upper level drivers probe routine. In device_add
blocking_notifier_call_chain is called prior to bus_attach_device which
leads to the upper level drivers probe routine being called.

The bus_register_notifier will handle new devices showing up and the
bus_for_each_dev is used to sync up with already probed devices. Obviously
loading late will not be able to handle issues during the device probe
if a device needs that type of handling.

-andmike
--
Michael Anderson
andmike@linux.vnet.ibm.com

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

* Re: [PATCH 4/9] scsi_dh: add skeleton for SCSI Device Handlers
  2008-02-01 19:53   ` Mike Christie
  2008-02-01 20:27     ` Mike Anderson
@ 2008-02-04 18:54     ` Chandra Seetharaman
  1 sibling, 0 replies; 37+ messages in thread
From: Chandra Seetharaman @ 2008-02-04 18:54 UTC (permalink / raw)
  To: Mike Christie; +Cc: dm-devel, linux-scsi, Mike Anderson, jens.axboe

On Fri, 2008-02-01 at 13:53 -0600, Mike Christie wrote:
> Chandra Seetharaman wrote:
> >  	 * mainly associated with tapes and returned SUCCESS.
> > Index: linux-2.6.24-rc8/drivers/scsi/scsi_sysfs.c
> > ===================================================================
> > --- linux-2.6.24-rc8.orig/drivers/scsi/scsi_sysfs.c
> > +++ linux-2.6.24-rc8/drivers/scsi/scsi_sysfs.c
> > @@ -951,6 +951,49 @@ int scsi_register_interface(struct class
> >  }
> >  EXPORT_SYMBOL(scsi_register_interface);
> >  
> > +static int scsi_dh_notifier_add(struct device *dev, void *data)
> > +{
> > +	struct scsi_device_handler *sdev_dh = data;
> > +
> > +	sdev_dh->nb.notifier_call(&sdev_dh->nb, BUS_NOTIFY_ADD_DEVICE, dev);
> > +
> > +	return 0;
> > +}
> > +
> > +int scsi_register_device_handler(struct scsi_device_handler *sdev_dh)
> > +{
> > +	int ret;
> > +
> > +	ret = bus_register_notifier(&scsi_bus_type, &sdev_dh->nb);
> > +
> > +	bus_for_each_dev(&scsi_bus_type, NULL, sdev_dh, scsi_dh_notifier_add);
> > +
> > +	return ret;
> > +}
> > +EXPORT_SYMBOL(scsi_register_device_handler);
> > +
> > +static int scsi_dh_notifier_remove(struct device *dev, void *data)
> > +{
> > +	struct scsi_device_handler *sdev_dh = data;
> > +
> > +	sdev_dh->nb.notifier_call(&sdev_dh->nb, BUS_NOTIFY_DEL_DEVICE, dev);
> > +
> > +	return 0;
> > +}
> > +
> > +int scsi_unregister_device_handler(struct scsi_device_handler *sdev_dh)
> > +{
> > +	int ret;
> > +
> > +	ret = bus_unregister_notifier(&scsi_bus_type, &sdev_dh->nb);
> > +
> > +	bus_for_each_dev(&scsi_bus_type, NULL, sdev_dh,
> > +					scsi_dh_notifier_remove);
> > +
> > +	return ret;
> > +}
> > +EXPORT_SYMBOL(scsi_unregister_device_handler);
> > +
> 
> Did this end up solving the problem I was hitting where when using the 
> other driver model stuff like is used with the SCSI upper layer drivers. 
> The problem where the hw handler module had to be loaded before finding 
> devices and had to be loaded before sd.c?

Yes, As andmike pointed, it is coded and tested.

It works in both cases, module being inserted before sd is probed and
module inserted after sd.


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

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------



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

* Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE
  2008-01-24  0:32 ` [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE Chandra Seetharaman
@ 2008-02-04 18:58   ` James Bottomley
  2008-02-04 20:15     ` Chandra Seetharaman
  2008-02-04 20:26     ` [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE Mike Anderson
  0 siblings, 2 replies; 37+ messages in thread
From: James Bottomley @ 2008-02-04 18:58 UTC (permalink / raw)
  To: Chandra Seetharaman; +Cc: dm-devel, linux-scsi, andmike, michaelc, jens.axboe


On Wed, 2008-01-23 at 16:32 -0800, Chandra Seetharaman wrote:
> Subject: scsi_dh: Add support for SDEV_PASSIVE
> 
> From: Chandra Seetharaman <sekharan@us.ibm.com>
> 
> This patch adds a new device state SDEV_PASSIVE, to correspond to the
> passive side access of an active/passive multipathed device.

Really, no; this isn't right.  The state field of a SCSI device is for
the SCSI state model.  Passive might be a valid device mapper state, but
it's not a valid SCSI state.  If these patches can't work except by
mucking with the SCSI state model, there's some layering problem
elsewhere that needs sorting out.

James



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

* Re: [PATCH 3/9] scsi_dh: scsi handling of REQ_LB_OP_TRANSITION
  2008-02-01 20:00   ` Mike Christie
@ 2008-02-04 18:59     ` Chandra Seetharaman
  2008-02-04 19:02     ` James Bottomley
  1 sibling, 0 replies; 37+ messages in thread
From: Chandra Seetharaman @ 2008-02-04 18:59 UTC (permalink / raw)
  To: Mike Christie; +Cc: dm-devel, linux-scsi, Mike Anderson, jens.axboe

On Fri, 2008-02-01 at 14:00 -0600, Mike Christie wrote:
> Chandra Seetharaman wrote:
> > @@ -1445,9 +1479,24 @@ static void scsi_kill_request(struct req
> >  static void scsi_softirq_done(struct request *rq)
> >  {
> >  	struct scsi_cmnd *cmd = rq->completion_data;
> > -	unsigned long wait_for = (cmd->allowed + 1) * cmd->timeout_per_command;
> >  	int disposition;
> > +	struct request_queue *q;
> > +	unsigned long wait_for, flags;
> >  
> > +	if (blk_linux_request(rq)) {
> > +		q = rq->q;
> > +		spin_lock_irqsave(q->queue_lock, flags);
> > +		/*
> > +		 * we always return 1 and the caller should
> > +		 * check rq->errors for the complete status
> > +		 */
> > +		end_that_request_last(rq, 1);
> > +		spin_unlock_irqrestore(q->queue_lock, flags);
> > +		return;
> > +	}
> > +
> > +
> > +	wait_for = (cmd->allowed + 1) * cmd->timeout_per_command;
> >  	INIT_LIST_HEAD(&cmd->eh_entry);
> >  
> .....
> 
> > +
> >  /*
> >   * Function:    scsi_request_fn()
> >   *
> > @@ -1519,7 +1612,23 @@ static void scsi_request_fn(struct reque
> >  		 * accept it.
> >  		 */
> >  		req = elv_next_request(q);
> > -		if (!req || !scsi_dev_queue_ready(q, sdev))
> > +		if (!req)
> > +			break;
> > +
> > +		/*
> > +		 * We do not account for linux blk req in the device
> > +		 * or host busy accounting because it is not necessarily
> > +		 * a scsi command that is sent to some object. The lower
> > +		 * level can translate it into a request/scsi_cmnd, if
> > +		 * necessary, and then queue that up using REQ_TYPE_BLOCK_PC.
> > +		 */
> > +		if (blk_linux_request(req)) {
> > +			blkdev_dequeue_request(req);
> > +			scsi_execute_blk_linux_cmd(req);
> > +			continue;
> > +		}
> > +
> > +		if (!scsi_dev_queue_ready(q, sdev))
> >  			break;
> 
> I think these two pieces are one of the reasons I have not pushed the 
> patches. I thought the completion and execution pieces here are a little 
> ugly and seem to just wedge themselves in where they want to be.
> 
> Is there any way to make the insertion of non-scsi commands more common? 
> Do we have the code for being able to send requests directly to 
> something like a fc rport done? Could we maybe inject these special 
> commands to the hw handler using something similar to how bsg would send 
> non scsi commands to weird objects (objects like rport, sessions, and 
> not devices we traditionally associated with queues like scsi_devices). 
> Just a thought with no code :) that is why the ugly code existed still :)

Can't it be done with this code itself ?

If the underlying functionality is going to be provided by the hardware
handler, then can't we add additional commands (like transition) when we
need them ?

Or am I missing something ?

-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------



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

* Re: [PATCH 3/9] scsi_dh: scsi handling of REQ_LB_OP_TRANSITION
  2008-02-01 20:00   ` Mike Christie
  2008-02-04 18:59     ` Chandra Seetharaman
@ 2008-02-04 19:02     ` James Bottomley
  2008-02-06 19:00       ` Mike Anderson
  1 sibling, 1 reply; 37+ messages in thread
From: James Bottomley @ 2008-02-04 19:02 UTC (permalink / raw)
  To: Mike Christie
  Cc: Chandra Seetharaman, dm-devel, linux-scsi, andmike, jens.axboe


On Fri, 2008-02-01 at 14:00 -0600, Mike Christie wrote:
> Chandra Seetharaman wrote:
> > @@ -1445,9 +1479,24 @@ static void scsi_kill_request(struct req
> >  static void scsi_softirq_done(struct request *rq)
> >  {
> >  	struct scsi_cmnd *cmd = rq->completion_data;
> > -	unsigned long wait_for = (cmd->allowed + 1) * cmd->timeout_per_command;
> >  	int disposition;
> > +	struct request_queue *q;
> > +	unsigned long wait_for, flags;
> >  
> > +	if (blk_linux_request(rq)) {
> > +		q = rq->q;
> > +		spin_lock_irqsave(q->queue_lock, flags);
> > +		/*
> > +		 * we always return 1 and the caller should
> > +		 * check rq->errors for the complete status
> > +		 */
> > +		end_that_request_last(rq, 1);
> > +		spin_unlock_irqrestore(q->queue_lock, flags);
> > +		return;
> > +	}
> > +
> > +
> > +	wait_for = (cmd->allowed + 1) * cmd->timeout_per_command;
> >  	INIT_LIST_HEAD(&cmd->eh_entry);
> >  
> .....
> 
> > +
> >  /*
> >   * Function:    scsi_request_fn()
> >   *
> > @@ -1519,7 +1612,23 @@ static void scsi_request_fn(struct reque
> >  		 * accept it.
> >  		 */
> >  		req = elv_next_request(q);
> > -		if (!req || !scsi_dev_queue_ready(q, sdev))
> > +		if (!req)
> > +			break;
> > +
> > +		/*
> > +		 * We do not account for linux blk req in the device
> > +		 * or host busy accounting because it is not necessarily
> > +		 * a scsi command that is sent to some object. The lower
> > +		 * level can translate it into a request/scsi_cmnd, if
> > +		 * necessary, and then queue that up using REQ_TYPE_BLOCK_PC.
> > +		 */
> > +		if (blk_linux_request(req)) {
> > +			blkdev_dequeue_request(req);
> > +			scsi_execute_blk_linux_cmd(req);
> > +			continue;
> > +		}
> > +
> > +		if (!scsi_dev_queue_ready(q, sdev))
> >  			break;
> 
> I think these two pieces are one of the reasons I have not pushed the 
> patches. I thought the completion and execution pieces here are a little 
> ugly and seem to just wedge themselves in where they want to be.
> 
> Is there any way to make the insertion of non-scsi commands more common? 
> Do we have the code for being able to send requests directly to 
> something like a fc rport done? Could we maybe inject these special 
> commands to the hw handler using something similar to how bsg would send 
> non scsi commands to weird objects (objects like rport, sessions, and 
> not devices we traditionally associated with queues like scsi_devices). 
> Just a thought with no code :) that is why the ugly code existed still :)

We sort of do.  The bsg code in scsi_transport_sas to send SMP frames to
expander devices would be an example of non-scsi commands going via a
mechanism other than being encapsulated in SCSI.  I don't know if that's
the complete solution in this case, but you could investigate it.

James



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

* Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE
  2008-02-04 18:58   ` James Bottomley
@ 2008-02-04 20:15     ` Chandra Seetharaman
  2008-02-04 20:28       ` James Bottomley
  2008-02-04 20:26     ` [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE Mike Anderson
  1 sibling, 1 reply; 37+ messages in thread
From: Chandra Seetharaman @ 2008-02-04 20:15 UTC (permalink / raw)
  To: James Bottomley; +Cc: dm-devel, linux-scsi, Mike Anderson, michaelc, jens.axboe

On Mon, 2008-02-04 at 12:58 -0600, James Bottomley wrote:
> On Wed, 2008-01-23 at 16:32 -0800, Chandra Seetharaman wrote:
> > Subject: scsi_dh: Add support for SDEV_PASSIVE
> > 
> > From: Chandra Seetharaman <sekharan@us.ibm.com>
> > 
> > This patch adds a new device state SDEV_PASSIVE, to correspond to the
> > passive side access of an active/passive multipathed device.
> 
> Really, no; this isn't right.  The state field of a SCSI device is for
> the SCSI state model.  Passive might be a valid device mapper state, but

Hi James,

It is not the "device mapper state", it is the state of the device
itself. These devices have active/passive paths, the passive paths will
be represented by SDEV_PASSIVE device state in SCSI.

chandra
> it's not a valid SCSI state.  If these patches can't work except by
> mucking with the SCSI state model, there's some layering problem
> elsewhere that needs sorting out.
> 
> James
> 
> 
> -
> 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
-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------



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

* Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE
  2008-02-04 18:58   ` James Bottomley
  2008-02-04 20:15     ` Chandra Seetharaman
@ 2008-02-04 20:26     ` Mike Anderson
  1 sibling, 0 replies; 37+ messages in thread
From: Mike Anderson @ 2008-02-04 20:26 UTC (permalink / raw)
  To: James Bottomley; +Cc: michaelc, dm-devel, linux-scsi, jens.axboe

James Bottomley <James.Bottomley@HansenPartnership.com> wrote:
> 
> On Wed, 2008-01-23 at 16:32 -0800, Chandra Seetharaman wrote:
> > Subject: scsi_dh: Add support for SDEV_PASSIVE
> > 
> > From: Chandra Seetharaman <sekharan@us.ibm.com>
> > 
> > This patch adds a new device state SDEV_PASSIVE, to correspond to the
> > passive side access of an active/passive multipathed device.
> 
> Really, no; this isn't right.  The state field of a SCSI device is for
> the SCSI state model.  Passive might be a valid device mapper state, but
> it's not a valid SCSI state.  If these patches can't work except by
> mucking with the SCSI state model, there's some layering problem
> elsewhere that needs sorting out.
> 

It is actually a valid state for this device and a number of other
devices that have passive / active controller. There are differences in
response capability (i.e., media access commands) on certain sds until a
fail over command is given. The response behavior difference along with
all the partition scanning and other commands that get generated during
the probing of a device are what leads to the long boot times previously
mentioned by Chandra.

Since we have created a policy to remove the vendor specific multipath
drivers that handled the aggregation of the paths into a single device we
need some method to handle devices that are not fully capable, but are
still expose to the upper layers.

The patches are also addressing a long standing issue of sense data
processing, but that is not related to the SDEV_* state comment.

-andmike
--
Michael Anderson
andmike@linux.vnet.ibm.com

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

* Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE
  2008-02-04 20:15     ` Chandra Seetharaman
@ 2008-02-04 20:28       ` James Bottomley
  2008-02-04 21:19         ` Chandra Seetharaman
  2008-02-05 20:04         ` Mike Christie
  0 siblings, 2 replies; 37+ messages in thread
From: James Bottomley @ 2008-02-04 20:28 UTC (permalink / raw)
  To: sekharan; +Cc: dm-devel, linux-scsi, Mike Anderson, michaelc, jens.axboe


On Mon, 2008-02-04 at 12:15 -0800, Chandra Seetharaman wrote:
> On Mon, 2008-02-04 at 12:58 -0600, James Bottomley wrote:
> > On Wed, 2008-01-23 at 16:32 -0800, Chandra Seetharaman wrote:
> > > Subject: scsi_dh: Add support for SDEV_PASSIVE
> > > 
> > > From: Chandra Seetharaman <sekharan@us.ibm.com>
> > > 
> > > This patch adds a new device state SDEV_PASSIVE, to correspond to the
> > > passive side access of an active/passive multipathed device.
> > 
> > Really, no; this isn't right.  The state field of a SCSI device is for
> > the SCSI state model.  Passive might be a valid device mapper state, but
> 
> Hi James,
> 
> It is not the "device mapper state", it is the state of the device
> itself. These devices have active/passive paths, the passive paths will
> be represented by SDEV_PASSIVE device state in SCSI.

Yes, it is .. you're killing commands on the basis of being in this
state, which nothing in SCSI ever sets.

A proper return from a passive path is the SCSI standard NOT_READY
LOGICAL UNIT NOT READY, INITIALIZING COMMAND REQUIRED.  We expect to see
this, not the command being killed.

James



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

* Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE
  2008-02-04 20:28       ` James Bottomley
@ 2008-02-04 21:19         ` Chandra Seetharaman
  2008-02-09 12:45           ` Matthew Wilcox
  2008-02-05 20:04         ` Mike Christie
  1 sibling, 1 reply; 37+ messages in thread
From: Chandra Seetharaman @ 2008-02-04 21:19 UTC (permalink / raw)
  To: James Bottomley; +Cc: dm-devel, linux-scsi, Mike Anderson, michaelc, jens.axboe

On Mon, 2008-02-04 at 14:28 -0600, James Bottomley wrote:
> On Mon, 2008-02-04 at 12:15 -0800, Chandra Seetharaman wrote:
> > On Mon, 2008-02-04 at 12:58 -0600, James Bottomley wrote:
> > > On Wed, 2008-01-23 at 16:32 -0800, Chandra Seetharaman wrote:
> > > > Subject: scsi_dh: Add support for SDEV_PASSIVE
> > > > 
> > > > From: Chandra Seetharaman <sekharan@us.ibm.com>
> > > > 
> > > > This patch adds a new device state SDEV_PASSIVE, to correspond to the
> > > > passive side access of an active/passive multipathed device.
> > > 
> > > Really, no; this isn't right.  The state field of a SCSI device is for
> > > the SCSI state model.  Passive might be a valid device mapper state, but
> > 
> > Hi James,
> > 
> > It is not the "device mapper state", it is the state of the device
> > itself. These devices have active/passive paths, the passive paths will
> > be represented by SDEV_PASSIVE device state in SCSI.
> 
> Yes, it is .. you're killing commands on the basis of being in this
> state, which nothing in SCSI ever sets.
> 
> A proper return from a passive path is the SCSI standard NOT_READY
> LOGICAL UNIT NOT READY, INITIALIZING COMMAND REQUIRED.  We expect to see
> this, not the command being killed.

The device does send these error messages currently, but it takes some
time to get the check condition back, which adds up the time to boot
especially when the # of LUNS is huge.

For example, in my test configuration, I had 40 luns, and the time
difference (with this patch and without it) to boot is 171 seconds and
1426 seconds.

We thought we will get it short circuited so as to return the failure
back faster.

Also, we only short circuit REQ_TYPE_FS.


> 
> James
> 
> 
> -
> 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
-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------



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

* Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE
  2008-02-04 20:28       ` James Bottomley
  2008-02-04 21:19         ` Chandra Seetharaman
@ 2008-02-05 20:04         ` Mike Christie
  2008-02-05 21:56           ` Mike Anderson
  1 sibling, 1 reply; 37+ messages in thread
From: Mike Christie @ 2008-02-05 20:04 UTC (permalink / raw)
  To: James Bottomley; +Cc: Mike Anderson, dm-devel, linux-scsi, jens.axboe

James Bottomley wrote:
> On Mon, 2008-02-04 at 12:15 -0800, Chandra Seetharaman wrote:
>> On Mon, 2008-02-04 at 12:58 -0600, James Bottomley wrote:
>>> On Wed, 2008-01-23 at 16:32 -0800, Chandra Seetharaman wrote:
>>>> Subject: scsi_dh: Add support for SDEV_PASSIVE
>>>>
>>>> From: Chandra Seetharaman <sekharan@us.ibm.com>
>>>>
>>>> This patch adds a new device state SDEV_PASSIVE, to correspond to the
>>>> passive side access of an active/passive multipathed device.
>>> Really, no; this isn't right.  The state field of a SCSI device is for
>>> the SCSI state model.  Passive might be a valid device mapper state, but
>> Hi James,
>>
>> It is not the "device mapper state", it is the state of the device
>> itself. These devices have active/passive paths, the passive paths will
>> be represented by SDEV_PASSIVE device state in SCSI.
> 
> Yes, it is .. you're killing commands on the basis of being in this
> state, which nothing in SCSI ever sets.

SCSI does set this. See below.

> 
> A proper return from a passive path is the SCSI standard NOT_READY
> LOGICAL UNIT NOT READY, INITIALIZING COMMAND REQUIRED.  We expect to see
> this, not the command being killed.
> 

I think this part of the patch is trying to implement and detect the 
Target port asymetric access states from spc3 section 5.8.2.4 (it does 
not follow it exactly because devices like RDAC or old clarrions did not 
implement the spec), and then use that info to fail commands before they 
are even sent to the device to avoid start up delays from when programs 
like udev, hal, kernel partition scanning probe the device.

For the LSI patch it works like the following:

When IO is sent to a path that cannot execute IO optimally, the scsi hw 
handler hook for sense processing (see rdac_check_sense in "[PATCH 8/9] 
scsi_dh: add lsi rdac device handler" and the scsi_error.c hook in in 
"scsi_dh: add skeleton for SCSI Device Handlers") will detect this and 
set the state to passive so future IO is not execute on the path 
(SG_IO/passthrough is allowed).

I am not sure about alternatives. If we just exported the port access 
state in sysfs, but did not fail IO from scsi_prep_state_check, then the 
users could still check the state before sending IO. Would it be 
horrible to convert apps to do this?

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

* Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE
  2008-02-05 20:04         ` Mike Christie
@ 2008-02-05 21:56           ` Mike Anderson
  2008-02-06  0:46             ` Chandra Seetharaman
  2008-02-07 10:08             ` no INQUIRY from userspace please (was Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE) Stefan Richter
  0 siblings, 2 replies; 37+ messages in thread
From: Mike Anderson @ 2008-02-05 21:56 UTC (permalink / raw)
  To: Mike Christie; +Cc: James Bottomley, sekharan, dm-devel, linux-scsi, jens.axboe

Mike Christie <michaelc@cs.wisc.edu> wrote:
> When IO is sent to a path that cannot execute IO optimally, the scsi hw 
> handler hook for sense processing (see rdac_check_sense in "[PATCH 8/9] 
> scsi_dh: add lsi rdac device handler" and the scsi_error.c hook in in 
> "scsi_dh: add skeleton for SCSI Device Handlers") will detect this and set 
> the state to passive so future IO is not execute on the path 
> (SG_IO/passthrough is allowed).
>
> I am not sure about alternatives. If we just exported the port access state 
> in sysfs, but did not fail IO from scsi_prep_state_check, then the users 
> could still check the state before sending IO. Would it be horrible to 
> convert apps to do this?

The majority of the boot up delays is caused by the kernel partition
scanning and other kernel init code (Chandra please correct if that is not
true). Sysfs attributes would not help here. One option maybe to add
handling of the newer BLKERR_ codes in the generators of IO or some
similar solution with a rollout possibly focused at the top generators of
IO.

A number of user apps like lvm scanning that execute media access commands
already have filter capability to filter devices that one does not want to
scan. Another class of device scanners just use inquiries which are not
effected by the passive state (though some could probably use udevinfo and
reduce the amount of repeated SCSI inquiries execute on the system.

-andmike
--
Michael Anderson
andmike@linux.vnet.ibm.com

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

* Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE
  2008-02-05 21:56           ` Mike Anderson
@ 2008-02-06  0:46             ` Chandra Seetharaman
  2008-02-07 10:08             ` no INQUIRY from userspace please (was Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE) Stefan Richter
  1 sibling, 0 replies; 37+ messages in thread
From: Chandra Seetharaman @ 2008-02-06  0:46 UTC (permalink / raw)
  To: Mike Anderson
  Cc: Mike Christie, James Bottomley, dm-devel, linux-scsi, jens.axboe

On Tue, 2008-02-05 at 13:56 -0800, Mike Anderson wrote:
> Mike Christie <michaelc@cs.wisc.edu> wrote:
> > When IO is sent to a path that cannot execute IO optimally, the scsi hw 
> > handler hook for sense processing (see rdac_check_sense in "[PATCH 8/9] 
> > scsi_dh: add lsi rdac device handler" and the scsi_error.c hook in in 
> > "scsi_dh: add skeleton for SCSI Device Handlers") will detect this and set 
> > the state to passive so future IO is not execute on the path 
> > (SG_IO/passthrough is allowed).
> >
> > I am not sure about alternatives. If we just exported the port access state 
> > in sysfs, but did not fail IO from scsi_prep_state_check, then the users 
> > could still check the state before sending IO. Would it be horrible to 
> > convert apps to do this?
> 
> The majority of the boot up delays is caused by the kernel partition
> scanning and other kernel init code (Chandra please correct if that is not

Yes, this is the case.

Some level of scanning happens at the rc scripts level too. That can be
reduced by what Mikec is suggesting. But, as andmike is suggesting, it
won't be a complete solution.

> true). Sysfs attributes would not help here. One option maybe to add
> handling of the newer BLKERR_ codes in the generators of IO or some
> similar solution with a rollout possibly focused at the top generators of

are you suggesting the partition scanners (kernel) and lvm(user space
scanner) should stop sending I/Os to a passive device once they realize
that the device is passive (thru BLKERR_ return codes) ?

> IO.
> 
> A number of user apps like lvm scanning that execute media access commands
> already have filter capability to filter devices that one does not want to

Yes, it will help. But, it will lead to additional instructions to the
users which if they do not follow (due to not knowing it or some such)
will lead to a delayed boot.

IMO, It will be good if it works nicely out of the box.

> scan. Another class of device scanners just use inquiries which are not
> effected by the passive state (though some could probably use udevinfo and
> reduce the amount of repeated SCSI inquiries execute on the system.
> 
> -andmike
> --
> Michael Anderson
> andmike@linux.vnet.ibm.com
-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------



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

* Re: [PATCH 3/9] scsi_dh: scsi handling of REQ_LB_OP_TRANSITION
  2008-02-04 19:02     ` James Bottomley
@ 2008-02-06 19:00       ` Mike Anderson
  2008-02-06 20:52         ` James Bottomley
  0 siblings, 1 reply; 37+ messages in thread
From: Mike Anderson @ 2008-02-06 19:00 UTC (permalink / raw)
  To: James Bottomley
  Cc: Mike Christie, Chandra Seetharaman, dm-devel, linux-scsi, jens.axboe

James Bottomley <James.Bottomley@HansenPartnership.com> wrote:
> 
> On Fri, 2008-02-01 at 14:00 -0600, Mike Christie wrote:
> > Chandra Seetharaman wrote:
> > > @@ -1445,9 +1479,24 @@ static void scsi_kill_request(struct req
> > >  static void scsi_softirq_done(struct request *rq)
> > >  {
> > >  	struct scsi_cmnd *cmd = rq->completion_data;
> > > -	unsigned long wait_for = (cmd->allowed + 1) * cmd->timeout_per_command;
> > >  	int disposition;
> > > +	struct request_queue *q;
> > > +	unsigned long wait_for, flags;
> > >  
> > > +	if (blk_linux_request(rq)) {
> > > +		q = rq->q;
> > > +		spin_lock_irqsave(q->queue_lock, flags);
> > > +		/*
> > > +		 * we always return 1 and the caller should
> > > +		 * check rq->errors for the complete status
> > > +		 */
> > > +		end_that_request_last(rq, 1);
> > > +		spin_unlock_irqrestore(q->queue_lock, flags);
> > > +		return;
> > > +	}
> > > +
> > > +
> > > +	wait_for = (cmd->allowed + 1) * cmd->timeout_per_command;
> > >  	INIT_LIST_HEAD(&cmd->eh_entry);
> > >  
> > .....
> > 
> > > +
> > >  /*
> > >   * Function:    scsi_request_fn()
> > >   *
> > > @@ -1519,7 +1612,23 @@ static void scsi_request_fn(struct reque
> > >  		 * accept it.
> > >  		 */
> > >  		req = elv_next_request(q);
> > > -		if (!req || !scsi_dev_queue_ready(q, sdev))
> > > +		if (!req)
> > > +			break;
> > > +
> > > +		/*
> > > +		 * We do not account for linux blk req in the device
> > > +		 * or host busy accounting because it is not necessarily
> > > +		 * a scsi command that is sent to some object. The lower
> > > +		 * level can translate it into a request/scsi_cmnd, if
> > > +		 * necessary, and then queue that up using REQ_TYPE_BLOCK_PC.
> > > +		 */
> > > +		if (blk_linux_request(req)) {
> > > +			blkdev_dequeue_request(req);
> > > +			scsi_execute_blk_linux_cmd(req);
> > > +			continue;
> > > +		}
> > > +
> > > +		if (!scsi_dev_queue_ready(q, sdev))
> > >  			break;
> > 
> > I think these two pieces are one of the reasons I have not pushed the 
> > patches. I thought the completion and execution pieces here are a little 
> > ugly and seem to just wedge themselves in where they want to be.
> > 
> > Is there any way to make the insertion of non-scsi commands more common? 
> > Do we have the code for being able to send requests directly to 
> > something like a fc rport done? Could we maybe inject these special 
> > commands to the hw handler using something similar to how bsg would send 
> > non scsi commands to weird objects (objects like rport, sessions, and 
> > not devices we traditionally associated with queues like scsi_devices). 
> > Just a thought with no code :) that is why the ugly code existed still :)
> 
> We sort of do.  The bsg code in scsi_transport_sas to send SMP frames to
> expander devices would be an example of non-scsi commands going via a
> mechanism other than being encapsulated in SCSI.  I don't know if that's
> the complete solution in this case, but you could investigate it.

I looked at the bsg code in scsi_transport_sas and all I see it doing is
calling blk_init_queue to set the request_fn. The request_fn
(*smp_request) just processes one cmd_type. Is there code is another tree
that has more processing?

A idea to allow for more control / flexibility cmd_type handlers could be
added inside request_fn, prep_rq_fn, softirq_done_fn.

I thought about this being at a higher level in the block layer, but it
would be hard to handle the request_fn cleanly at the high level. The
localized change would reduce impact on users who do not want or need per
cmd_type handlers.

A SCSI example might be something like:

static void scsi_softirq_done(struct request *rq)
{
	...
	sdev->cmd_type_handler[rq->cmd_type]->softirq_done(rq)
	...
}

int scsi_prep_fn(struct request_queue *q, struct request *req)
{
	...
	sdev->cmd_type_handler[rq->cmd_type]->prep_fn(req)
	...
}

static void scsi_request_fn(struct request_queue *q)
{
	...
	sdev->cmd_type_handler[rq->cmd_type]->request_fn(req)
	...
}

This is just moving the code inside the cmd_type "if" checks, but it may
reduce the number of cmd_type "if" checks in some paths (if we make
multiple decisions based on cmd_type). On init of the sdev default
handlers would be installed.

-andmike
--
Michael Anderson
andmike@linux.vnet.ibm.com

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

* Re: [PATCH 3/9] scsi_dh: scsi handling of REQ_LB_OP_TRANSITION
  2008-02-06 19:00       ` Mike Anderson
@ 2008-02-06 20:52         ` James Bottomley
  0 siblings, 0 replies; 37+ messages in thread
From: James Bottomley @ 2008-02-06 20:52 UTC (permalink / raw)
  To: Mike Anderson
  Cc: Mike Christie, Chandra Seetharaman, dm-devel, linux-scsi, jens.axboe

On Wed, 2008-02-06 at 11:00 -0800, Mike Anderson wrote:
> James Bottomley <James.Bottomley@HansenPartnership.com> wrote:
> > 
> > On Fri, 2008-02-01 at 14:00 -0600, Mike Christie wrote:
> > > Chandra Seetharaman wrote:
> > > > @@ -1445,9 +1479,24 @@ static void scsi_kill_request(struct req
> > > >  static void scsi_softirq_done(struct request *rq)
> > > >  {
> > > >  	struct scsi_cmnd *cmd = rq->completion_data;
> > > > -	unsigned long wait_for = (cmd->allowed + 1) * cmd->timeout_per_command;
> > > >  	int disposition;
> > > > +	struct request_queue *q;
> > > > +	unsigned long wait_for, flags;
> > > >  
> > > > +	if (blk_linux_request(rq)) {
> > > > +		q = rq->q;
> > > > +		spin_lock_irqsave(q->queue_lock, flags);
> > > > +		/*
> > > > +		 * we always return 1 and the caller should
> > > > +		 * check rq->errors for the complete status
> > > > +		 */
> > > > +		end_that_request_last(rq, 1);
> > > > +		spin_unlock_irqrestore(q->queue_lock, flags);
> > > > +		return;
> > > > +	}
> > > > +
> > > > +
> > > > +	wait_for = (cmd->allowed + 1) * cmd->timeout_per_command;
> > > >  	INIT_LIST_HEAD(&cmd->eh_entry);
> > > >  
> > > .....
> > > 
> > > > +
> > > >  /*
> > > >   * Function:    scsi_request_fn()
> > > >   *
> > > > @@ -1519,7 +1612,23 @@ static void scsi_request_fn(struct reque
> > > >  		 * accept it.
> > > >  		 */
> > > >  		req = elv_next_request(q);
> > > > -		if (!req || !scsi_dev_queue_ready(q, sdev))
> > > > +		if (!req)
> > > > +			break;
> > > > +
> > > > +		/*
> > > > +		 * We do not account for linux blk req in the device
> > > > +		 * or host busy accounting because it is not necessarily
> > > > +		 * a scsi command that is sent to some object. The lower
> > > > +		 * level can translate it into a request/scsi_cmnd, if
> > > > +		 * necessary, and then queue that up using REQ_TYPE_BLOCK_PC.
> > > > +		 */
> > > > +		if (blk_linux_request(req)) {
> > > > +			blkdev_dequeue_request(req);
> > > > +			scsi_execute_blk_linux_cmd(req);
> > > > +			continue;
> > > > +		}
> > > > +
> > > > +		if (!scsi_dev_queue_ready(q, sdev))
> > > >  			break;
> > > 
> > > I think these two pieces are one of the reasons I have not pushed the 
> > > patches. I thought the completion and execution pieces here are a little 
> > > ugly and seem to just wedge themselves in where they want to be.
> > > 
> > > Is there any way to make the insertion of non-scsi commands more common? 
> > > Do we have the code for being able to send requests directly to 
> > > something like a fc rport done? Could we maybe inject these special 
> > > commands to the hw handler using something similar to how bsg would send 
> > > non scsi commands to weird objects (objects like rport, sessions, and 
> > > not devices we traditionally associated with queues like scsi_devices). 
> > > Just a thought with no code :) that is why the ugly code existed still :)
> > 
> > We sort of do.  The bsg code in scsi_transport_sas to send SMP frames to
> > expander devices would be an example of non-scsi commands going via a
> > mechanism other than being encapsulated in SCSI.  I don't know if that's
> > the complete solution in this case, but you could investigate it.
> 
> I looked at the bsg code in scsi_transport_sas and all I see it doing is
> calling blk_init_queue to set the request_fn. The request_fn
> (*smp_request) just processes one cmd_type. Is there code is another tree
> that has more processing?

No ... that's it.  It's designed to expose a frame driven SMP
communication channel to expanders via a block tap.

Part of the problem seems to be that your current code is very much
trying to do this in-band.  A block tap like the SMP handlers are
effectively out of band

> A idea to allow for more control / flexibility cmd_type handlers could be
> added inside request_fn, prep_rq_fn, softirq_done_fn.
> 
> I thought about this being at a higher level in the block layer, but it
> would be hard to handle the request_fn cleanly at the high level. The
> localized change would reduce impact on users who do not want or need per
> cmd_type handlers.

But this type of thinking does lead to a lot of apparent nastiness
inside your actual handlers.  Trying to do all of this in-band has you
doing a lot of callback driven async I/O stuff using
blk_execute_rq_nowait().  It might be a lot cleaner to do it out of band
on a thread using the standard waiting interfaces.

James



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

* no INQUIRY from userspace please (was Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE)
  2008-02-05 21:56           ` Mike Anderson
  2008-02-06  0:46             ` Chandra Seetharaman
@ 2008-02-07 10:08             ` Stefan Richter
  2008-02-07 15:01               ` James Bottomley
  1 sibling, 1 reply; 37+ messages in thread
From: Stefan Richter @ 2008-02-07 10:08 UTC (permalink / raw)
  To: Mike Anderson
  Cc: Mike Christie, James Bottomley, sekharan, dm-devel, linux-scsi,
	jens.axboe

Mike Anderson wrote:
> A number of user apps like lvm scanning that execute media access commands
> already have filter capability to filter devices that one does not want to
> scan. Another class of device scanners just use inquiries which are not
> effected by the passive state (though some could probably use udevinfo and
> reduce the amount of repeated SCSI inquiries execute on the system.

To expand on this:

At least on desktop systems and SOHO server systems, userspace should
_never_ issue INQUIRY.  There are too many broken firmwares out there
which assume that there will never be more than one INQUIRY sent.  They
start to return garbled data or crash if they get a second INQUIRY.
-- 
Stefan Richter
-=====-==--- --=- --===
http://arcgraph.de/sr/

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

* Re: no INQUIRY from userspace please (was Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE)
  2008-02-07 10:08             ` no INQUIRY from userspace please (was Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE) Stefan Richter
@ 2008-02-07 15:01               ` James Bottomley
  2008-02-07 17:05                 ` no INQUIRY from userspace please Stefan Richter
  2008-02-07 20:42                 ` no INQUIRY from userspace please (was Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE) Luben Tuikov
  0 siblings, 2 replies; 37+ messages in thread
From: James Bottomley @ 2008-02-07 15:01 UTC (permalink / raw)
  To: Stefan Richter
  Cc: Mike Anderson, Mike Christie, sekharan, dm-devel, linux-scsi, jens.axboe

On Thu, 2008-02-07 at 11:08 +0100, Stefan Richter wrote:
> Mike Anderson wrote:
> > A number of user apps like lvm scanning that execute media access commands
> > already have filter capability to filter devices that one does not want to
> > scan. Another class of device scanners just use inquiries which are not
> > effected by the passive state (though some could probably use udevinfo and
> > reduce the amount of repeated SCSI inquiries execute on the system.
> 
> To expand on this:
> 
> At least on desktop systems and SOHO server systems, userspace should
> _never_ issue INQUIRY.  There are too many broken firmwares out there
> which assume that there will never be more than one INQUIRY sent.  They
> start to return garbled data or crash if they get a second INQUIRY.

It's all very well to say this, but I think if you look at what udev
does, you'll find that it uses scsi_id to send a VPD inquiry to the
device so it can populate /dev/disk/by-id, so the point is already
conceded (and I think looking at a recent camera crash that seems to
have been precipitated by this, it's already causing us problems).

This is all a tradeoff.  If you want userspace *never* to issue raw SCSI
commands like INQUIRY, we're going to have to provide the needed
information from the kernel via sysfs ... including VPD strings.  This
is something we've always shovelled off into userspace before.

James



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

* Re: no INQUIRY from userspace please
  2008-02-07 15:01               ` James Bottomley
@ 2008-02-07 17:05                 ` Stefan Richter
  2008-02-07 17:13                   ` Stefan Richter
  2008-02-07 20:42                 ` no INQUIRY from userspace please (was Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE) Luben Tuikov
  1 sibling, 1 reply; 37+ messages in thread
From: Stefan Richter @ 2008-02-07 17:05 UTC (permalink / raw)
  To: James Bottomley
  Cc: Mike Anderson, Mike Christie, sekharan, dm-devel, linux-scsi,
	jens.axboe, linux-hotplug

(adding Cc linux-hotplug)

James Bottomley wrote:
> On Thu, 2008-02-07 at 11:08 +0100, Stefan Richter wrote:
>> Mike Anderson wrote:
>> > A number of user apps like lvm scanning that execute media access commands
>> > already have filter capability to filter devices that one does not want to
>> > scan. Another class of device scanners just use inquiries which are not
>> > effected by the passive state (though some could probably use udevinfo and
>> > reduce the amount of repeated SCSI inquiries execute on the system.
>> 
>> To expand on this:
>> 
>> At least on desktop systems and SOHO server systems, userspace should
>> _never_ issue INQUIRY.  There are too many broken firmwares out there
>> which assume that there will never be more than one INQUIRY sent.  They
>> start to return garbled data or crash if they get a second INQUIRY.
> 
> It's all very well to say this, but I think if you look at what udev
> does, you'll find that it uses scsi_id to send a VPD inquiry to the
> device so it can populate /dev/disk/by-id, so the point is already
> conceded (and I think looking at a recent camera crash that seems to
> have been precipitated by this, it's already causing us problems).
> 
> This is all a tradeoff.  If you want userspace *never* to issue raw SCSI
> commands like INQUIRY, we're going to have to provide the needed
> information from the kernel via sysfs ... including VPD strings.  This
> is something we've always shovelled off into userspace before.

Well, it's definitely awkward to have to deal with less than perfect
firmwares.

But there is still potential to optimize udev based on what we already
have in sysfs.  For example, on Gentoo I see calls of scsi_id and usb_id
for FireWire disks (by udev? by HAL? I don't know), even though udev
actually also reads the FireWire driver specific sysfs attribute with
the target port ID and LUN.  I.e. udev knows where to look but calls
pointless helpers anyway.

(BTW, how about sysfs attributes for the target port identifier and for
the logical unit identifier --- at transport independent sysfs paths ---
to simplify userspace's life?  What else?)
-- 
Stefan Richter
-=====-==--- --=- --===
http://arcgraph.de/sr/

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

* Re: no INQUIRY from userspace please
  2008-02-07 17:05                 ` no INQUIRY from userspace please Stefan Richter
@ 2008-02-07 17:13                   ` Stefan Richter
  2008-02-19 20:53                     ` Douglas Gilbert
  0 siblings, 1 reply; 37+ messages in thread
From: Stefan Richter @ 2008-02-07 17:13 UTC (permalink / raw)
  To: James Bottomley
  Cc: Mike Anderson, Mike Christie, sekharan, dm-devel, linux-scsi,
	jens.axboe, linux-hotplug

> James Bottomley wrote:
>> It's all very well to say this, but I think if you look at what udev
>> does, you'll find that it uses scsi_id to send a VPD inquiry to the
>> device so it can populate /dev/disk/by-id, so the point is already
>> conceded

PS:  Alas we don't have a practicable way to know how many of the
  - doesn't work with Linux but works to some degree with Windows,
  - doesn't work with a 2.6 based Linux distro but did work with a
    2.4 based distro
kinds of devices are those with this INQUIRY bug or similar bugs.

While non-udev distros slowly went out of fashion on the desktop, there
was a certain frequency of reports of the latter kind of FireWire
devices, but this was before I became aware of that kind of firmware
bug, therefore I don't have any data whether it played a role for these
cases.
-- 
Stefan Richter
-=====-==--- --=- --===
http://arcgraph.de/sr/

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

* Re: no INQUIRY from userspace please (was Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE)
  2008-02-07 15:01               ` James Bottomley
  2008-02-07 17:05                 ` no INQUIRY from userspace please Stefan Richter
@ 2008-02-07 20:42                 ` Luben Tuikov
  1 sibling, 0 replies; 37+ messages in thread
From: Luben Tuikov @ 2008-02-07 20:42 UTC (permalink / raw)
  To: Stefan Richter, James Bottomley
  Cc: Mike Anderson, Mike Christie, sekharan, dm-devel, linux-scsi, jens.axboe

--- On Thu, 2/7/08, James Bottomley <James.Bottomley@HansenPartnership.com> wrote:
> This is all a tradeoff.  If you want userspace *never* to
> issue raw SCSI
> commands like INQUIRY, we're going to have to provide
> the needed
> information from the kernel via sysfs ... including VPD
> strings.  This
> is something we've always shovelled off into userspace
> before.

What if a user-space application client _does_ send an INQUIRY to
a device anyway?

It would probably be better to preserve application client behaviour
and simulate/emulate n-th INQUIRY, after the 1st for such broken
device firmwares that break on any subsequent INQUIRY.  Possibly
in the LLDD or via blacklisting in the mid-layer.

   Luben


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

* Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE
  2008-02-04 21:19         ` Chandra Seetharaman
@ 2008-02-09 12:45           ` Matthew Wilcox
  2008-02-11 18:27             ` Chandra Seetharaman
  0 siblings, 1 reply; 37+ messages in thread
From: Matthew Wilcox @ 2008-02-09 12:45 UTC (permalink / raw)
  To: Chandra Seetharaman
  Cc: James Bottomley, dm-devel, linux-scsi, Mike Anderson, michaelc,
	jens.axboe

On Mon, Feb 04, 2008 at 01:19:30PM -0800, Chandra Seetharaman wrote:
> The device does send these error messages currently, but it takes some
> time to get the check condition back, which adds up the time to boot
> especially when the # of LUNS is huge.
> 
> For example, in my test configuration, I had 40 luns, and the time
> difference (with this patch and without it) to boot is 171 seconds and
> 1426 seconds.

Was that with sync or async SCSI bus scanning?

-- 
Intel are signing my paycheques ... these opinions are still mine
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours.  We can't possibly take such
a retrograde step."

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

* Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE
  2008-02-09 12:45           ` Matthew Wilcox
@ 2008-02-11 18:27             ` Chandra Seetharaman
  2008-02-11 19:18               ` Matthew Wilcox
  0 siblings, 1 reply; 37+ messages in thread
From: Chandra Seetharaman @ 2008-02-11 18:27 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Mike Anderson, michaelc, linux-scsi, James Bottomley, dm-devel,
	jens.axboe

On Sat, 2008-02-09 at 05:45 -0700, Matthew Wilcox wrote:
> On Mon, Feb 04, 2008 at 01:19:30PM -0800, Chandra Seetharaman wrote:
> > The device does send these error messages currently, but it takes some
> > time to get the check condition back, which adds up the time to boot
> > especially when the # of LUNS is huge.
> > 
> > For example, in my test configuration, I had 40 luns, and the time
> > difference (with this patch and without it) to boot is 171 seconds and
> > 1426 seconds.
> 
> Was that with sync or async SCSI bus scanning?

I didn't change anything, IOW, i did default scanning, which I would
guess sync ?!


> 
-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------

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

* Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE
  2008-02-11 18:27             ` Chandra Seetharaman
@ 2008-02-11 19:18               ` Matthew Wilcox
  2008-02-28  1:03                 ` Chandra Seetharaman
  0 siblings, 1 reply; 37+ messages in thread
From: Matthew Wilcox @ 2008-02-11 19:18 UTC (permalink / raw)
  To: Chandra Seetharaman
  Cc: James Bottomley, dm-devel, linux-scsi, Mike Anderson, michaelc,
	jens.axboe

On Mon, Feb 11, 2008 at 10:27:46AM -0800, Chandra Seetharaman wrote:
> On Sat, 2008-02-09 at 05:45 -0700, Matthew Wilcox wrote:
> > On Mon, Feb 04, 2008 at 01:19:30PM -0800, Chandra Seetharaman wrote:
> > > The device does send these error messages currently, but it takes some
> > > time to get the check condition back, which adds up the time to boot
> > > especially when the # of LUNS is huge.
> > > 
> > > For example, in my test configuration, I had 40 luns, and the time
> > > difference (with this patch and without it) to boot is 171 seconds and
> > > 1426 seconds.
> > 
> > Was that with sync or async SCSI bus scanning?
> 
> I didn't change anything, IOW, i did default scanning, which I would
> guess sync ?!

That would depend on your CONFIG_SCSI_SCAN_ASYNC setting.

Try booting with 'scsi_mod.scan=async' and without this patch, and see
how long it takes.

-- 
Intel are signing my paycheques ... these opinions are still mine
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours.  We can't possibly take such
a retrograde step."

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

* Re: no INQUIRY from userspace please
  2008-02-07 17:13                   ` Stefan Richter
@ 2008-02-19 20:53                     ` Douglas Gilbert
  2008-03-04  9:06                       ` Hannes Reinecke
  0 siblings, 1 reply; 37+ messages in thread
From: Douglas Gilbert @ 2008-02-19 20:53 UTC (permalink / raw)
  To: Stefan Richter
  Cc: James Bottomley, Mike Anderson, Mike Christie, sekharan,
	dm-devel, linux-scsi, jens.axboe, linux-hotplug

Stefan Richter wrote:
>> James Bottomley wrote:
>>> It's all very well to say this, but I think if you look at what udev
>>> does, you'll find that it uses scsi_id to send a VPD inquiry to the
>>> device so it can populate /dev/disk/by-id, so the point is already
>>> conceded
> 
> PS:  Alas we don't have a practicable way to know how many of the
>   - doesn't work with Linux but works to some degree with Windows,
>   - doesn't work with a 2.6 based Linux distro but did work with a
>     2.4 based distro
> kinds of devices are those with this INQUIRY bug or similar bugs.
> 
> While non-udev distros slowly went out of fashion on the desktop, there
> was a certain frequency of reports of the latter kind of FireWire
> devices, but this was before I became aware of that kind of firmware
> bug, therefore I don't have any data whether it played a role for these
> cases.

Just a small point here. To my knowledge all devices
that understand the SCSI command set will accept a
36 byte INQUIRY (i.e. an INQUIRY with an "allocation length"
of 36). That is a practical consideration since they would
crash on Windows otherwise.

Now scsi_id (and probably other programs of that ilk
(including some of mine)) get excited when they get a
response to a "36 byte" INQUIRY and go onto ask for
VPD page 0x80 (serial number) or page 0x83 (device id)
via an INQUIRY command with the EVPD bit set.
Now if they were clever they would make sure that
the "allocation length" of the _first_ such VPD inquiry
was 36! That way they could have a close look at the
response and if it wasn't valid for a VPD page
(e.g. requested_VPD_page_num != response[1]) then
they would leave the damn device alone **.

<<< Special case: removable media >>>
Since response[1] of a standard INQUIRY has RMB (removable
medium bit) set in its top bit and the rest of the byte
reserved, 0x80 is a possibility. That could give a
false positive when the serial number VPD page is
requested. So try looking for VPD page 0x83 (with
alloc_len=36) first.


** The logic here is that a brain dead SCSI target
interpreter doesn't look at the EVPD bit and can
only handle an "allocation length" of 36. So if
it receives an INQUIRY cdb with the EVPD bit set
it will just respond with its standard INQUIRY
response.

Doug Gilbert

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

* Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE
  2008-02-11 19:18               ` Matthew Wilcox
@ 2008-02-28  1:03                 ` Chandra Seetharaman
  0 siblings, 0 replies; 37+ messages in thread
From: Chandra Seetharaman @ 2008-02-28  1:03 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: James Bottomley, dm-devel, linux-scsi, Mike Anderson, michaelc,
	jens.axboe

On Mon, 2008-02-11 at 12:18 -0700, Matthew Wilcox wrote:
> On Mon, Feb 11, 2008 at 10:27:46AM -0800, Chandra Seetharaman wrote:
> > On Sat, 2008-02-09 at 05:45 -0700, Matthew Wilcox wrote:
> > > On Mon, Feb 04, 2008 at 01:19:30PM -0800, Chandra Seetharaman wrote:
> > > > The device does send these error messages currently, but it takes some
> > > > time to get the check condition back, which adds up the time to boot
> > > > especially when the # of LUNS is huge.
> > > > 
> > > > For example, in my test configuration, I had 40 luns, and the time
> > > > difference (with this patch and without it) to boot is 171 seconds and
> > > > 1426 seconds.
> > > 
> > > Was that with sync or async SCSI bus scanning?
> > 
> > I didn't change anything, IOW, i did default scanning, which I would
> > guess sync ?!
> 
> That would depend on your CONFIG_SCSI_SCAN_ASYNC setting.
> 
> Try booting with 'scsi_mod.scan=async' and without this patch, and see
> how long it takes.
Hi Matthew,

scanning in async mode did not help in reducing the boot time.

I even changed the configuration, such that 20 active luns and 20
passive luns are in each path, it still didn't change the time it took
to reboot.

regards,

chandra
> 
-- 

----------------------------------------------------------------------
    Chandra Seetharaman               | Be careful what you choose....
              - sekharan@us.ibm.com   |      .......you may get it.
----------------------------------------------------------------------



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

* Re: no INQUIRY from userspace please
  2008-02-19 20:53                     ` Douglas Gilbert
@ 2008-03-04  9:06                       ` Hannes Reinecke
  0 siblings, 0 replies; 37+ messages in thread
From: Hannes Reinecke @ 2008-03-04  9:06 UTC (permalink / raw)
  To: dougg
  Cc: Stefan Richter, James Bottomley, Mike Anderson, Mike Christie,
	sekharan, dm-devel, linux-scsi, jens.axboe, linux-hotplug

Hi Doug,

Douglas Gilbert wrote:
> Stefan Richter wrote:
>>> James Bottomley wrote:
>>>> It's all very well to say this, but I think if you look at what udev
>>>> does, you'll find that it uses scsi_id to send a VPD inquiry to the
>>>> device so it can populate /dev/disk/by-id, so the point is already
>>>> conceded
>>
>> PS:  Alas we don't have a practicable way to know how many of the
>>   - doesn't work with Linux but works to some degree with Windows,
>>   - doesn't work with a 2.6 based Linux distro but did work with a
>>     2.4 based distro
>> kinds of devices are those with this INQUIRY bug or similar bugs.
>>
>> While non-udev distros slowly went out of fashion on the desktop, there
>> was a certain frequency of reports of the latter kind of FireWire
>> devices, but this was before I became aware of that kind of firmware
>> bug, therefore I don't have any data whether it played a role for these
>> cases.
> 
> Just a small point here. To my knowledge all devices
> that understand the SCSI command set will accept a
> 36 byte INQUIRY (i.e. an INQUIRY with an "allocation length"
> of 36). That is a practical consideration since they would
> crash on Windows otherwise.
> 
> Now scsi_id (and probably other programs of that ilk
> (including some of mine)) get excited when they get a
> response to a "36 byte" INQUIRY and go onto ask for
> VPD page 0x80 (serial number) or page 0x83 (device id)
> via an INQUIRY command with the EVPD bit set.
> Now if they were clever they would make sure that
> the "allocation length" of the _first_ such VPD inquiry
> was 36! That way they could have a close look at the
> response and if it wasn't valid for a VPD page
> (e.g. requested_VPD_page_num != response[1]) then
> they would leave the damn device alone **.
> 
Oh, but of course we can do this. Actually not a bad idea.

> <<< Special case: removable media >>>
> Since response[1] of a standard INQUIRY has RMB (removable
> medium bit) set in its top bit and the rest of the byte
> reserved, 0x80 is a possibility. That could give a
> false positive when the serial number VPD page is
> requested. So try looking for VPD page 0x83 (with
> alloc_len=36) first.
> 
What we do is to query page 0x0 first (if no specific page
has been given), and then try 0x83 or, failing that, 0x80.
So we could easily modify the query to page 0x0 to get the
first 36 bytes only, that should catch these type of errors.

And we can check byte 4 of the response; according to SPC it
should always be 0 (as page 0 always has to be implemented).

Good idea. I'll do it.

> 
> ** The logic here is that a brain dead SCSI target
> interpreter doesn't look at the EVPD bit and can
> only handle an "allocation length" of 36. So if
> it receives an INQUIRY cdb with the EVPD bit set
> it will just respond with its standard INQUIRY
> response.
> 
Yes, but that's pretty much standard anyway.
So we're dealing with that already.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		      zSeries & Storage
hare@suse.de			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Markus Rex, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-hotplug" 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] 37+ messages in thread

end of thread, other threads:[~2008-03-04  9:06 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-01-24  0:30 [PATCH 0/9] scsi_dh: Move dm device handler to SCSI layer Chandra Seetharaman
2008-01-24  0:30 ` [PATCH 1/9] scsi_dh: add REQ_LB_OP_TRANSITION and errors Chandra Seetharaman
2008-01-24  0:30 ` [PATCH 2/9] scsi_dh: change sd_prep_fn to call common code Chandra Seetharaman
2008-01-24  0:30 ` [PATCH 3/9] scsi_dh: scsi handling of REQ_LB_OP_TRANSITION Chandra Seetharaman
2008-02-01 20:00   ` Mike Christie
2008-02-04 18:59     ` Chandra Seetharaman
2008-02-04 19:02     ` James Bottomley
2008-02-06 19:00       ` Mike Anderson
2008-02-06 20:52         ` James Bottomley
2008-01-24  0:31 ` [PATCH 4/9] scsi_dh: add skeleton for SCSI Device Handlers Chandra Seetharaman
2008-02-01 19:53   ` Mike Christie
2008-02-01 20:27     ` Mike Anderson
2008-02-04 18:54     ` Chandra Seetharaman
2008-01-24  0:31 ` [PATCH 5/9] scsi_dh: add EMC Clariion device handler Chandra Seetharaman
2008-01-24  0:31 ` [PATCH 6/9] scsi_dh: add hp sw " Chandra Seetharaman
2008-01-24  0:32 ` [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE Chandra Seetharaman
2008-02-04 18:58   ` James Bottomley
2008-02-04 20:15     ` Chandra Seetharaman
2008-02-04 20:28       ` James Bottomley
2008-02-04 21:19         ` Chandra Seetharaman
2008-02-09 12:45           ` Matthew Wilcox
2008-02-11 18:27             ` Chandra Seetharaman
2008-02-11 19:18               ` Matthew Wilcox
2008-02-28  1:03                 ` Chandra Seetharaman
2008-02-05 20:04         ` Mike Christie
2008-02-05 21:56           ` Mike Anderson
2008-02-06  0:46             ` Chandra Seetharaman
2008-02-07 10:08             ` no INQUIRY from userspace please (was Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE) Stefan Richter
2008-02-07 15:01               ` James Bottomley
2008-02-07 17:05                 ` no INQUIRY from userspace please Stefan Richter
2008-02-07 17:13                   ` Stefan Richter
2008-02-19 20:53                     ` Douglas Gilbert
2008-03-04  9:06                       ` Hannes Reinecke
2008-02-07 20:42                 ` no INQUIRY from userspace please (was Re: [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE) Luben Tuikov
2008-02-04 20:26     ` [PATCH 7/9] scsi_dh: Add support for SDEV_PASSIVE Mike Anderson
2008-01-24  0:32 ` [PATCH 8/9] scsi_dh: add lsi rdac device handler Chandra Seetharaman
2008-01-24  0:32 ` [PATCH 9/9] scsi_dh: add scsi device handler to dm Chandra Seetharaman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.