+++ /dev/null
-Subject: Add TGPS setting to scsi devices
-From: Hannes Reinecke <hare@suse.de>
-
-Some multipath-capable storage arrays are capable of running
-in compatible mode, ie supporting both the original vendor-specific
-failover mode and the SPC-3 compliant ALUA mode.
-This patch stores the TGPS setting in the sdev so that we can directly
-match onto it and select the correct device handler automatically.
-And we can save code in the ALUA device handler.
-
-Signed-off-by: Hannes Reinecke <hare@suse.de>
-
----
- drivers/scsi/device_handler/scsi_dh.c | 9 ++-
- drivers/scsi/device_handler/scsi_dh_alua.c | 67 +++-------------------------
- drivers/scsi/device_handler/scsi_dh_emc.c | 8 +--
- drivers/scsi/device_handler/scsi_dh_hp_sw.c | 10 ++--
- drivers/scsi/device_handler/scsi_dh_rdac.c | 34 +++++++-------
- drivers/scsi/scsi_scan.c | 1
- drivers/scsi/scsi_sysfs.c | 2
- include/scsi/scsi_device.h | 4 +
- 8 files changed, 48 insertions(+), 87 deletions(-)
-
---- a/drivers/scsi/device_handler/scsi_dh_alua.c
-+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
-@@ -118,43 +118,6 @@ static struct request *get_alua_req(stru
- }
-
- /*
-- * submit_std_inquiry - Issue a standard INQUIRY command
-- * @sdev: sdev the command should be send to
-- */
--static int submit_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
--{
-- struct request *rq;
-- int err = SCSI_DH_RES_TEMP_UNAVAIL;
--
-- rq = get_alua_req(sdev, h->inq, ALUA_INQUIRY_SIZE, READ);
-- if (!rq)
-- goto done;
--
-- /* Prepare the command. */
-- rq->cmd[0] = INQUIRY;
-- rq->cmd[1] = 0;
-- rq->cmd[2] = 0;
-- rq->cmd[4] = ALUA_INQUIRY_SIZE;
-- rq->cmd_len = COMMAND_SIZE(INQUIRY);
--
-- rq->sense = h->sense;
-- memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
-- rq->sense_len = h->senselen = 0;
--
-- err = blk_execute_rq(rq->q, NULL, rq, 1);
-- if (err == -EIO) {
-- sdev_printk(KERN_INFO, sdev,
-- "%s: std inquiry failed with %x\n",
-- ALUA_DH_NAME, rq->errors);
-- h->senselen = rq->sense_len;
-- err = SCSI_DH_IO;
-- }
-- blk_put_request(rq);
--done:
-- return err;
--}
--
--/*
- * submit_vpd_inquiry - Issue an INQUIRY VPD page 0x83 command
- * @sdev: sdev the command should be sent to
- */
-@@ -281,23 +244,19 @@ done:
- }
-
- /*
-- * alua_std_inquiry - Evaluate standard INQUIRY command
-+ * alua_check_tgps - Evaluate TGPS setting
- * @sdev: device to be checked
- *
-- * Just extract the TPGS setting to find out if ALUA
-+ * Just examine the TPGS setting of the device to find out if ALUA
- * is supported.
- */
--static int alua_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
-+static int alua_check_tgps(struct scsi_device *sdev, struct alua_dh_data *h)
- {
-- int err;
--
-- err = submit_std_inquiry(sdev, h);
--
-- if (err != SCSI_DH_OK)
-- return err;
-+ int err = SCSI_DH_OK;
-
- /* Check TPGS setting */
-- h->tpgs = (h->inq[5] >> 4) & 0x3;
-+ h->tpgs = sdev->tgps;
-+
- switch (h->tpgs) {
- case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT:
- sdev_printk(KERN_INFO, sdev,
-@@ -609,7 +568,7 @@ static int alua_initialize(struct scsi_d
- {
- int err;
-
-- err = alua_std_inquiry(sdev, h);
-+ err = alua_check_tgps(sdev, h);
- if (err != SCSI_DH_OK)
- goto out;
-
-@@ -674,16 +633,8 @@ static int alua_prep_fn(struct scsi_devi
- }
-
- static const struct scsi_dh_devlist alua_dev_list[] = {
-- {"HP", "MSA VOLUME" },
-- {"HP", "HSV101" },
-- {"HP", "HSV111" },
-- {"HP", "HSV200" },
-- {"HP", "HSV210" },
-- {"HP", "HSV300" },
-- {"IBM", "2107900" },
-- {"IBM", "2145" },
-- {"Pillar", "Axiom" },
-- {NULL, NULL}
-+ {"", "", 3 },
-+ {NULL, NULL, 0}
- };
-
- static int alua_bus_attach(struct scsi_device *sdev);
---- a/drivers/scsi/device_handler/scsi_dh.c
-+++ b/drivers/scsi/device_handler/scsi_dh.c
-@@ -28,6 +28,7 @@ struct scsi_dh_devinfo_list {
- struct list_head node;
- char vendor[9];
- char model[17];
-+ char tgps;
- struct scsi_device_handler *handler;
- };
-
-@@ -60,7 +61,8 @@ scsi_dh_cache_lookup(struct scsi_device
- spin_lock(&list_lock);
- list_for_each_entry(tmp, &scsi_dh_dev_list, node) {
- if (!strncmp(sdev->vendor, tmp->vendor, strlen(tmp->vendor)) &&
-- !strncmp(sdev->model, tmp->model, strlen(tmp->model))) {
-+ !strncmp(sdev->model, tmp->model, strlen(tmp->model)) &&
-+ (!tmp->tgps || (sdev->tgps & tmp->tgps) != 0)) {
- found_dh = tmp->handler;
- break;
- }
-@@ -79,7 +81,9 @@ static int scsi_dh_handler_lookup(struct
- if (!strncmp(sdev->vendor, scsi_dh->devlist[i].vendor,
- strlen(scsi_dh->devlist[i].vendor)) &&
- !strncmp(sdev->model, scsi_dh->devlist[i].model,
-- strlen(scsi_dh->devlist[i].model))) {
-+ strlen(scsi_dh->devlist[i].model)) &&
-+ (!scsi_dh->devlist[i].tgps ||
-+ (sdev->tgps & scsi_dh->devlist[i].tgps) != 0)) {
- found = 1;
- break;
- }
-@@ -128,6 +132,7 @@ device_handler_match(struct scsi_device_
- strncpy(tmp->model, sdev->model, 16);
- tmp->vendor[8] = '\0';
- tmp->model[16] = '\0';
-+ tmp->tgps = sdev->tgps;
- tmp->handler = found_dh;
- spin_lock(&list_lock);
- list_add(&tmp->node, &scsi_dh_dev_list);
---- a/drivers/scsi/device_handler/scsi_dh_emc.c
-+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
-@@ -563,10 +563,10 @@ done:
- }
-
- static const struct scsi_dh_devlist clariion_dev_list[] = {
-- {"DGC", "RAID"},
-- {"DGC", "DISK"},
-- {"DGC", "VRAID"},
-- {NULL, NULL},
-+ {"DGC", "RAID", 0},
-+ {"DGC", "DISK", 0},
-+ {"DGC", "VRAID", 0},
-+ {NULL, NULL, 0},
- };
-
- static int clariion_bus_attach(struct scsi_device *sdev);
---- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c
-+++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
-@@ -283,11 +283,11 @@ static int hp_sw_activate(struct scsi_de
- }
-
- static const struct scsi_dh_devlist hp_sw_dh_data_list[] = {
-- {"COMPAQ", "MSA1000 VOLUME"},
-- {"COMPAQ", "HSV110"},
-- {"HP", "HSV100"},
-- {"DEC", "HSG80"},
-- {NULL, NULL},
-+ {"COMPAQ", "MSA1000 VOLUME", 0},
-+ {"COMPAQ", "HSV110", 0},
-+ {"HP", "HSV100", 0},
-+ {"DEC", "HSG80", 0},
-+ {NULL, NULL, 0},
- };
-
- static int hp_sw_bus_attach(struct scsi_device *sdev);
---- a/drivers/scsi/device_handler/scsi_dh_rdac.c
-+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
-@@ -583,23 +583,23 @@ static int rdac_check_sense(struct scsi_
- }
-
- static const struct scsi_dh_devlist rdac_dev_list[] = {
-- {"IBM", "1722"},
-- {"IBM", "1724"},
-- {"IBM", "1726"},
-- {"IBM", "1742"},
-- {"IBM", "1814"},
-- {"IBM", "1815"},
-- {"IBM", "1818"},
-- {"IBM", "3526"},
-- {"SGI", "TP9400"},
-- {"SGI", "TP9500"},
-- {"SGI", "IS"},
-- {"STK", "OPENstorage D280"},
-- {"SUN", "CSM200_R"},
-- {"SUN", "LCSM100_F"},
-- {"DELL", "MD3000"},
-- {"DELL", "MD3000i"},
-- {NULL, NULL},
-+ {"IBM", "1722", 0},
-+ {"IBM", "1724", 0},
-+ {"IBM", "1726", 0},
-+ {"IBM", "1742", 0},
-+ {"IBM", "1814", 0},
-+ {"IBM", "1815", 0},
-+ {"IBM", "1818", 0},
-+ {"IBM", "3526", 0},
-+ {"SGI", "TP9400", 0},
-+ {"SGI", "TP9500", 0},
-+ {"SGI", "IS", 0},
-+ {"STK", "OPENstorage D280", 0},
-+ {"SUN", "CSM200_R", 0},
-+ {"SUN", "LCSM100_F", 0},
-+ {"DELL", "MD3000", 0},
-+ {"DELL", "MD3000i", 0},
-+ {NULL, NULL, 0},
- };
-
- static int rdac_bus_attach(struct scsi_device *sdev);
---- a/drivers/scsi/scsi_scan.c
-+++ b/drivers/scsi/scsi_scan.c
-@@ -821,6 +821,7 @@ static int scsi_add_lun(struct scsi_devi
- sdev->inq_periph_qual = (inq_result[0] >> 5) & 7;
- sdev->lockable = sdev->removable;
- sdev->soft_reset = (inq_result[7] & 1) && ((inq_result[3] & 7) == 2);
-+ sdev->tgps = (inq_result[5] >> 4) & 3;
-
- if (sdev->scsi_level >= SCSI_3 ||
- (sdev->inquiry_len > 56 && inq_result[56] & 0x04))
---- a/drivers/scsi/scsi_sysfs.c
-+++ b/drivers/scsi/scsi_sysfs.c
-@@ -543,6 +543,7 @@ sdev_rd_attr (scsi_level, "%d\n");
- sdev_rd_attr (vendor, "%.8s\n");
- sdev_rd_attr (model, "%.16s\n");
- sdev_rd_attr (rev, "%.4s\n");
-+sdev_rd_attr (tgps, "%d\n");
-
- /*
- * TODO: can we make these symlinks to the block layer ones?
-@@ -728,6 +729,7 @@ static struct attribute *scsi_sdev_attrs
- &dev_attr_vendor.attr,
- &dev_attr_model.attr,
- &dev_attr_rev.attr,
-+ &dev_attr_tgps.attr,
- &dev_attr_rescan.attr,
- &dev_attr_delete.attr,
- &dev_attr_state.attr,
---- a/include/scsi/scsi_device.h
-+++ b/include/scsi/scsi_device.h
-@@ -96,7 +96,8 @@ struct scsi_device {
- void *hostdata; /* available to low-level driver */
- char type;
- char scsi_level;
-- char inq_periph_qual; /* PQ from INQUIRY data */
-+ char inq_periph_qual; /* PQ from INQUIRY data */
-+ char tgps; /* Target port group support */
- unsigned char inquiry_len; /* valid bytes in 'inquiry' */
- unsigned char * inquiry; /* INQUIRY response data */
- const char * vendor; /* [back_compat] point into 'inquiry' ... */
-@@ -174,6 +175,7 @@ struct scsi_device {
- struct scsi_dh_devlist {
- char *vendor;
- char *model;
-+ char tgps;
- };
-
- struct scsi_device_handler {