Skip to contentSkip to conversation

Add TGPS setting to scsi devices

PATCH New Hannes Reinecke 1 participant 1 message Nov 17, 2008 SCSI

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Add TGPS setting to scsi devices

Hi James,

this patch adds the TGPS setting to scsi devices. With this patch we can handle storage arrays running in compatible mode (ie supporting both the proprietary failover mode and ALUA mode) properly and we save us to keep a rather largish device table in the ALUA device handler.
And the correct hardware selection in multipath-tools will become a lot easier.

As usual, comments etc are welcome.

Cheers,

Hannes

Signature · 4 lines
Dr. Hannes Reinecke		      zSeries & Storage
[email protected]			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Markus Rex, HRB 16746 (AG Nürnberg)

Add TGPS setting to scsi devices

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.

drivers/scsi/device_handler/scsi_dh.c +7 -2
index a518f2e..872b80d 100644
@@ -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 *sdev)
 	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 scsi_device_handler *scsi_dh,
 		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_handler *scsi_dh,
 			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);
drivers/scsi/device_handler/scsi_dh_alua.c +9 -58

98 lines not on this page · raw message

drivers/scsi/device_handler/scsi_dh_emc.c +4 -4
index 0e572d2..ff2e653 100644
@@ -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);
drivers/scsi/device_handler/scsi_dh_hp_sw.c +5 -5
index 9aec4ca..ffd8a06 100644
@@ -283,11 +283,11 @@ static int hp_sw_activate(struct scsi_device *sdev)
 }
 
 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);
drivers/scsi/device_handler/scsi_dh_rdac.c +17 -17
index 6eae101..df5cb2e 100644
@@ -586,23 +586,23 @@ static int rdac_check_sense(struct scsi_device *sdev,
 }
 
 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);
drivers/scsi/scsi_scan.c +1 -0
index b14dc02..c586b71 100644
@@ -821,6 +821,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
 	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))
drivers/scsi/scsi_sysfs.c +2 -0
index 93c28f3..becc2fc 100644
@@ -560,6 +560,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?
@@ -745,6 +746,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,
include/scsi/scsi_device.h +3 -1
index a37a814..9e61a76 100644
@@ -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 {