]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.fixes/scsi-add-tgps-setting
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.fixes / scsi-add-tgps-setting
CommitLineData
2cb7cef9
BS
1Subject: Add TGPS setting to scsi devices
2From: Hannes Reinecke <hare@suse.de>
3
4Some multipath-capable storage arrays are capable of running
5in compatible mode, ie supporting both the original vendor-specific
6failover mode and the SPC-3 compliant ALUA mode.
7This patch stores the TGPS setting in the sdev so that we can directly
8match onto it and select the correct device handler automatically.
9And we can save code in the ALUA device handler.
10
11Signed-off-by: Hannes Reinecke <hare@suse.de>
12
13---
14 drivers/scsi/device_handler/scsi_dh.c | 9 ++-
15 drivers/scsi/device_handler/scsi_dh_alua.c | 67 +++-------------------------
16 drivers/scsi/device_handler/scsi_dh_emc.c | 8 +--
17 drivers/scsi/device_handler/scsi_dh_hp_sw.c | 10 ++--
18 drivers/scsi/device_handler/scsi_dh_rdac.c | 34 +++++++-------
19 drivers/scsi/scsi_scan.c | 1
20 drivers/scsi/scsi_sysfs.c | 2
21 include/scsi/scsi_device.h | 4 +
22 8 files changed, 48 insertions(+), 87 deletions(-)
23
24--- a/drivers/scsi/device_handler/scsi_dh_alua.c
25+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
26@@ -118,43 +118,6 @@ static struct request *get_alua_req(stru
27 }
28
29 /*
30- * submit_std_inquiry - Issue a standard INQUIRY command
31- * @sdev: sdev the command should be send to
32- */
33-static int submit_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
34-{
35- struct request *rq;
36- int err = SCSI_DH_RES_TEMP_UNAVAIL;
37-
38- rq = get_alua_req(sdev, h->inq, ALUA_INQUIRY_SIZE, READ);
39- if (!rq)
40- goto done;
41-
42- /* Prepare the command. */
43- rq->cmd[0] = INQUIRY;
44- rq->cmd[1] = 0;
45- rq->cmd[2] = 0;
46- rq->cmd[4] = ALUA_INQUIRY_SIZE;
47- rq->cmd_len = COMMAND_SIZE(INQUIRY);
48-
49- rq->sense = h->sense;
50- memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE);
51- rq->sense_len = h->senselen = 0;
52-
53- err = blk_execute_rq(rq->q, NULL, rq, 1);
54- if (err == -EIO) {
55- sdev_printk(KERN_INFO, sdev,
56- "%s: std inquiry failed with %x\n",
57- ALUA_DH_NAME, rq->errors);
58- h->senselen = rq->sense_len;
59- err = SCSI_DH_IO;
60- }
61- blk_put_request(rq);
62-done:
63- return err;
64-}
65-
66-/*
67 * submit_vpd_inquiry - Issue an INQUIRY VPD page 0x83 command
68 * @sdev: sdev the command should be sent to
69 */
70@@ -281,23 +244,19 @@ done:
71 }
72
73 /*
74- * alua_std_inquiry - Evaluate standard INQUIRY command
75+ * alua_check_tgps - Evaluate TGPS setting
76 * @sdev: device to be checked
77 *
78- * Just extract the TPGS setting to find out if ALUA
79+ * Just examine the TPGS setting of the device to find out if ALUA
80 * is supported.
81 */
82-static int alua_std_inquiry(struct scsi_device *sdev, struct alua_dh_data *h)
83+static int alua_check_tgps(struct scsi_device *sdev, struct alua_dh_data *h)
84 {
85- int err;
86-
87- err = submit_std_inquiry(sdev, h);
88-
89- if (err != SCSI_DH_OK)
90- return err;
91+ int err = SCSI_DH_OK;
92
93 /* Check TPGS setting */
94- h->tpgs = (h->inq[5] >> 4) & 0x3;
95+ h->tpgs = sdev->tgps;
96+
97 switch (h->tpgs) {
98 case TPGS_MODE_EXPLICIT|TPGS_MODE_IMPLICIT:
99 sdev_printk(KERN_INFO, sdev,
100@@ -609,7 +568,7 @@ static int alua_initialize(struct scsi_d
101 {
102 int err;
103
104- err = alua_std_inquiry(sdev, h);
105+ err = alua_check_tgps(sdev, h);
106 if (err != SCSI_DH_OK)
107 goto out;
108
109@@ -674,16 +633,8 @@ static int alua_prep_fn(struct scsi_devi
110 }
111
112 static const struct scsi_dh_devlist alua_dev_list[] = {
113- {"HP", "MSA VOLUME" },
114- {"HP", "HSV101" },
115- {"HP", "HSV111" },
116- {"HP", "HSV200" },
117- {"HP", "HSV210" },
118- {"HP", "HSV300" },
119- {"IBM", "2107900" },
120- {"IBM", "2145" },
121- {"Pillar", "Axiom" },
122- {NULL, NULL}
123+ {"", "", 3 },
124+ {NULL, NULL, 0}
125 };
126
127 static int alua_bus_attach(struct scsi_device *sdev);
128--- a/drivers/scsi/device_handler/scsi_dh.c
129+++ b/drivers/scsi/device_handler/scsi_dh.c
130@@ -28,6 +28,7 @@ struct scsi_dh_devinfo_list {
131 struct list_head node;
132 char vendor[9];
133 char model[17];
134+ char tgps;
135 struct scsi_device_handler *handler;
136 };
137
138@@ -60,7 +61,8 @@ scsi_dh_cache_lookup(struct scsi_device
139 spin_lock(&list_lock);
140 list_for_each_entry(tmp, &scsi_dh_dev_list, node) {
141 if (!strncmp(sdev->vendor, tmp->vendor, strlen(tmp->vendor)) &&
142- !strncmp(sdev->model, tmp->model, strlen(tmp->model))) {
143+ !strncmp(sdev->model, tmp->model, strlen(tmp->model)) &&
144+ (!tmp->tgps || (sdev->tgps & tmp->tgps) != 0)) {
145 found_dh = tmp->handler;
146 break;
147 }
148@@ -79,7 +81,9 @@ static int scsi_dh_handler_lookup(struct
149 if (!strncmp(sdev->vendor, scsi_dh->devlist[i].vendor,
150 strlen(scsi_dh->devlist[i].vendor)) &&
151 !strncmp(sdev->model, scsi_dh->devlist[i].model,
152- strlen(scsi_dh->devlist[i].model))) {
153+ strlen(scsi_dh->devlist[i].model)) &&
154+ (!scsi_dh->devlist[i].tgps ||
155+ (sdev->tgps & scsi_dh->devlist[i].tgps) != 0)) {
156 found = 1;
157 break;
158 }
159@@ -128,6 +132,7 @@ device_handler_match(struct scsi_device_
160 strncpy(tmp->model, sdev->model, 16);
161 tmp->vendor[8] = '\0';
162 tmp->model[16] = '\0';
163+ tmp->tgps = sdev->tgps;
164 tmp->handler = found_dh;
165 spin_lock(&list_lock);
166 list_add(&tmp->node, &scsi_dh_dev_list);
167--- a/drivers/scsi/device_handler/scsi_dh_emc.c
168+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
169@@ -563,10 +563,10 @@ done:
170 }
171
172 static const struct scsi_dh_devlist clariion_dev_list[] = {
173- {"DGC", "RAID"},
174- {"DGC", "DISK"},
175- {"DGC", "VRAID"},
176- {NULL, NULL},
177+ {"DGC", "RAID", 0},
178+ {"DGC", "DISK", 0},
179+ {"DGC", "VRAID", 0},
180+ {NULL, NULL, 0},
181 };
182
183 static int clariion_bus_attach(struct scsi_device *sdev);
184--- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c
185+++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
186@@ -283,11 +283,11 @@ static int hp_sw_activate(struct scsi_de
187 }
188
189 static const struct scsi_dh_devlist hp_sw_dh_data_list[] = {
190- {"COMPAQ", "MSA1000 VOLUME"},
191- {"COMPAQ", "HSV110"},
192- {"HP", "HSV100"},
193- {"DEC", "HSG80"},
194- {NULL, NULL},
195+ {"COMPAQ", "MSA1000 VOLUME", 0},
196+ {"COMPAQ", "HSV110", 0},
197+ {"HP", "HSV100", 0},
198+ {"DEC", "HSG80", 0},
199+ {NULL, NULL, 0},
200 };
201
202 static int hp_sw_bus_attach(struct scsi_device *sdev);
203--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
204+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
205@@ -583,23 +583,23 @@ static int rdac_check_sense(struct scsi_
206 }
207
208 static const struct scsi_dh_devlist rdac_dev_list[] = {
209- {"IBM", "1722"},
210- {"IBM", "1724"},
211- {"IBM", "1726"},
212- {"IBM", "1742"},
213- {"IBM", "1814"},
214- {"IBM", "1815"},
215- {"IBM", "1818"},
216- {"IBM", "3526"},
217- {"SGI", "TP9400"},
218- {"SGI", "TP9500"},
219- {"SGI", "IS"},
220- {"STK", "OPENstorage D280"},
221- {"SUN", "CSM200_R"},
222- {"SUN", "LCSM100_F"},
223- {"DELL", "MD3000"},
224- {"DELL", "MD3000i"},
225- {NULL, NULL},
226+ {"IBM", "1722", 0},
227+ {"IBM", "1724", 0},
228+ {"IBM", "1726", 0},
229+ {"IBM", "1742", 0},
230+ {"IBM", "1814", 0},
231+ {"IBM", "1815", 0},
232+ {"IBM", "1818", 0},
233+ {"IBM", "3526", 0},
234+ {"SGI", "TP9400", 0},
235+ {"SGI", "TP9500", 0},
236+ {"SGI", "IS", 0},
237+ {"STK", "OPENstorage D280", 0},
238+ {"SUN", "CSM200_R", 0},
239+ {"SUN", "LCSM100_F", 0},
240+ {"DELL", "MD3000", 0},
241+ {"DELL", "MD3000i", 0},
242+ {NULL, NULL, 0},
243 };
244
245 static int rdac_bus_attach(struct scsi_device *sdev);
246--- a/drivers/scsi/scsi_scan.c
247+++ b/drivers/scsi/scsi_scan.c
248@@ -821,6 +821,7 @@ static int scsi_add_lun(struct scsi_devi
249 sdev->inq_periph_qual = (inq_result[0] >> 5) & 7;
250 sdev->lockable = sdev->removable;
251 sdev->soft_reset = (inq_result[7] & 1) && ((inq_result[3] & 7) == 2);
252+ sdev->tgps = (inq_result[5] >> 4) & 3;
253
254 if (sdev->scsi_level >= SCSI_3 ||
255 (sdev->inquiry_len > 56 && inq_result[56] & 0x04))
256--- a/drivers/scsi/scsi_sysfs.c
257+++ b/drivers/scsi/scsi_sysfs.c
258@@ -543,6 +543,7 @@ sdev_rd_attr (scsi_level, "%d\n");
259 sdev_rd_attr (vendor, "%.8s\n");
260 sdev_rd_attr (model, "%.16s\n");
261 sdev_rd_attr (rev, "%.4s\n");
262+sdev_rd_attr (tgps, "%d\n");
263
264 /*
265 * TODO: can we make these symlinks to the block layer ones?
266@@ -728,6 +729,7 @@ static struct attribute *scsi_sdev_attrs
267 &dev_attr_vendor.attr,
268 &dev_attr_model.attr,
269 &dev_attr_rev.attr,
270+ &dev_attr_tgps.attr,
271 &dev_attr_rescan.attr,
272 &dev_attr_delete.attr,
273 &dev_attr_state.attr,
274--- a/include/scsi/scsi_device.h
275+++ b/include/scsi/scsi_device.h
276@@ -96,7 +96,8 @@ struct scsi_device {
277 void *hostdata; /* available to low-level driver */
278 char type;
279 char scsi_level;
280- char inq_periph_qual; /* PQ from INQUIRY data */
281+ char inq_periph_qual; /* PQ from INQUIRY data */
282+ char tgps; /* Target port group support */
283 unsigned char inquiry_len; /* valid bytes in 'inquiry' */
284 unsigned char * inquiry; /* INQUIRY response data */
285 const char * vendor; /* [back_compat] point into 'inquiry' ... */
286@@ -174,6 +175,7 @@ struct scsi_device {
287 struct scsi_dh_devlist {
288 char *vendor;
289 char *model;
290+ char tgps;
291 };
292
293 struct scsi_device_handler {