]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.25/patches.fixes/scsi-add-tgps-setting
Revert "Move xen patchset to new version's subdir."
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.fixes / scsi-add-tgps-setting
diff --git a/src/patches/suse-2.6.27.25/patches.fixes/scsi-add-tgps-setting b/src/patches/suse-2.6.27.25/patches.fixes/scsi-add-tgps-setting
new file mode 100644 (file)
index 0000000..1c9a3ed
--- /dev/null
@@ -0,0 +1,293 @@
+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 {