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 +#include +#include +#include + +/* + * 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