Hi, Christophe,

There some issues I need to look into, and I'm copying some
code from another source file, which is a bad thing.  I'll
look into those problems tomorrow.  I've not actually executed
this code yet.

If you have time to look this over before you leave for holiday,
that would be great.  Does it seem sensible to you?  Does it at least
try to do what's needed?  If you don't have time to review before
you leave, just let me know.  I'll look into the other code
duplication issues.  Another problem, I need to make sure there's
always a gen_disk and scsi_disk structure associated with these
block devices.

If I can make this approach work with dm-scsi-start.c, I might
look into re-writing dm-emc.c to see if we can remove some of the
bio and req management code.

Thanks!

Dave

diff -urN linux-2.6.11-rc3-udm2/drivers/md/dm-scsi-start.c linux-2.6.11-rc3-udm2-M/drivers/md/dm-scsi-start.c
--- linux-2.6.11-rc3-udm2/drivers/md/dm-scsi-start.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.11-rc3-udm2-M/drivers/md/dm-scsi-start.c	2005-03-03 22:02:17.000000000 -0800
@@ -0,0 +1,106 @@
+/*
+ * This file is released under the GPL.
+ *
+ * Multipath support for job disks.
+ */
+
+#include "dm.h"
+#include "dm-hw-handler.h"
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_ioctl.h>
+#include <linux/genhd.h>
+
+/*
+ * This struct scsi_disk and scsi_disk() macro are copied from sd.c.
+ * Think of a better way.  Probably need to work with linux-scsi.
+ * Just making the scsi_disk() macro be exported from sd.c would
+ * make it work.
+ */
+struct scsi_disk {
+        struct scsi_driver *driver;     /* always &sd_template */
+        struct scsi_device *device;
+        struct kref     kref;
+        struct gendisk  *disk;
+        unsigned int    openers;        /* protected by BKL for now, yuck */
+        sector_t        capacity;       /* size in 512-byte sectors */
+        u32             index;
+        u8              media_present;
+        u8              write_prot;
+        unsigned        WCE : 1;        /* state of disk WCE bit */
+        unsigned        RCD : 1;        /* state of disk RCD bit, unused */
+};
+
+
+static inline struct scsi_disk *scsi_disk(struct gendisk *disk)
+{
+        return container_of(disk->private_data, struct scsi_disk, driver);
+}
+
+static void sstart_pg_init(struct hw_handler *hwh, unsigned bypassed,
+			struct path *path)
+{
+	struct block_device *bdev = path->dev->bdev;
+	struct gendisk *disk = bdev->bd_disk;
+	struct scsi_device *sdev = scsi_disk(disk)->device;
+	int result;
+
+	result = scsi_ioctl(sdev, SCSI_IOCTL_START_UNIT, NULL);
+	dm_pg_init_complete(path, result?MP_FAIL_PATH:0);
+}
+
+static int sstart_ctr(struct hw_handler *hwh, unsigned argc, char **argv)
+{
+	hwh->context = NULL;
+	
+	return 0;
+}
+
+static void sstart_dtr(struct hw_handler *hwh)
+{
+}
+
+static unsigned sstart_err(struct hw_handler *hwh, struct bio *bio)
+{
+	/*
+	 * Try default handler
+	 * Is more needed here?
+	 */
+	return dm_scsi_err_handler(hwh, bio);
+}
+
+static struct hw_handler_type sstart_hwh = {
+	.name = "sstart",
+	.module = THIS_MODULE,
+	.ctr = sstart_ctr,
+	.dtr = sstart_dtr,
+	.pg_init = sstart_pg_init,
+	.err = sstart_err,
+};
+
+static int __init dm_sstart_init(void)
+{
+	int r = dm_register_hw_handler(&sstart_hwh);
+
+	if (r < 0)
+		DMERR("sstart: register failed %d", r);
+
+	DMINFO("dm-sstart version 0.0.3 loaded");
+
+	return r;
+}
+
+static void __exit dm_sstart_exit(void)
+{
+	int r = dm_unregister_hw_handler(&sstart_hwh);
+
+	if (r < 0)
+		DMERR("sstart: unregister failed %d", r);
+}
+
+module_init(dm_sstart_init);
+module_exit(dm_sstart_exit);
+
+MODULE_DESCRIPTION(DM_NAME "JBOD start/stop hardware handler");
+MODULE_AUTHOR("whoever finishes this");
+MODULE_LICENSE("GPL");
diff -urN linux-2.6.11-rc3-udm2/drivers/md/Kconfig linux-2.6.11-rc3-udm2-M/drivers/md/Kconfig
--- linux-2.6.11-rc3-udm2/drivers/md/Kconfig	2005-02-15 12:46:45.000000000 -0800
+++ linux-2.6.11-rc3-udm2-M/drivers/md/Kconfig	2005-03-03 20:17:36.000000000 -0800
@@ -239,6 +239,15 @@
 	---help---
 	  Multipath support for EMC CX/AX series hardware.
 
+config DM_MULTIPATH_SCSI_START
+	tristate "SCSI Start multipath support (EXPERIMENTAL)"
+	depends on DM_MULTIPATH && BLK_DEV_DM && EXPERIMENTAL
+	---help---
+	  Multipath support for array controllers that have
+	  active/passive ports, and that require a SCSI START
+	  command to switch to make the passive port active
+	  when the currently active port fails.
+
 config DM_FLAKEY
        tristate "Flakey target (EXPERIMENTAL)"
        depends on BLK_DEV_DM && EXPERIMENTAL
diff -urN linux-2.6.11-rc3-udm2/drivers/md/Makefile linux-2.6.11-rc3-udm2-M/drivers/md/Makefile
--- linux-2.6.11-rc3-udm2/drivers/md/Makefile	2005-02-15 12:46:45.000000000 -0800
+++ linux-2.6.11-rc3-udm2-M/drivers/md/Makefile	2005-03-03 20:18:47.000000000 -0800
@@ -33,6 +33,7 @@
 obj-$(CONFIG_DM_CRYPT)		+= dm-crypt.o
 obj-$(CONFIG_DM_MULTIPATH)	+= dm-multipath.o dm-round-robin.o
 obj-$(CONFIG_DM_MULTIPATH_EMC)	+= dm-emc.o
+obj-$(CONFIG_DM_MULTIPATH_SCSI_START) += dm-scsi-start.o
 obj-$(CONFIG_DM_SNAPSHOT)	+= dm-snapshot.o
 obj-$(CONFIG_DM_MIRROR)		+= dm-mirror.o
 obj-$(CONFIG_DM_FLAKEY)		+= dm-flakey.o