aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2016-05-06 04:34:35 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2016-05-10 21:31:17 -0400
commitfe8b9534a0a0356f8a76467e2c561194bdb53c84 (patch)
tree9b0d7a6c26db4ea494e82e5b1da0f16646f87780
parent1b37bd606deef0a787bdbbab6ff51dbebdeb9d3d (diff)
scsi_dh_alua: do not fail for unknown VPD identification
Not every device will return a useable VPD identification, but still might support ALUA. Rather than disable ALUA support we should be allowing the device identification to be empty and attach individual ALUA device handler to each devices. [mkp: Fixed typo reported by Bart] Reported-by: Paul Mackerras <paulus@ozlabs.org> Signed-off-by: Hannes Reinecke <hare@suse.com> Tested-by: Paul Mackerras <paulus@ozlabs.org> Reviewed-by: Bart Van Assche <bart.vanassche@sandisk.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index e034f12c1418..b2244eb90776 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -195,10 +195,13 @@ static struct alua_port_group *alua_find_get_pg(char *id_str, size_t id_size,
195{ 195{
196 struct alua_port_group *pg; 196 struct alua_port_group *pg;
197 197
198 if (!id_str || !id_size || !strlen(id_str))
199 return NULL;
200
198 list_for_each_entry(pg, &port_group_list, node) { 201 list_for_each_entry(pg, &port_group_list, node) {
199 if (pg->group_id != group_id) 202 if (pg->group_id != group_id)
200 continue; 203 continue;
201 if (pg->device_id_len != id_size) 204 if (!pg->device_id_len || pg->device_id_len != id_size)
202 continue; 205 continue;
203 if (strncmp(pg->device_id_str, id_str, id_size)) 206 if (strncmp(pg->device_id_str, id_str, id_size))
204 continue; 207 continue;
@@ -232,14 +235,14 @@ static struct alua_port_group *alua_alloc_pg(struct scsi_device *sdev,
232 sizeof(pg->device_id_str)); 235 sizeof(pg->device_id_str));
233 if (pg->device_id_len <= 0) { 236 if (pg->device_id_len <= 0) {
234 /* 237 /*
235 * Internal error: TPGS supported but no device 238 * TPGS supported but no device identification found.
236 * identifcation found. Disable ALUA support. 239 * Generate private device identification.
237 */ 240 */
238 kfree(pg);
239 sdev_printk(KERN_INFO, sdev, 241 sdev_printk(KERN_INFO, sdev,
240 "%s: No device descriptors found\n", 242 "%s: No device descriptors found\n",
241 ALUA_DH_NAME); 243 ALUA_DH_NAME);
242 return ERR_PTR(-ENXIO); 244 pg->device_id_str[0] = '\0';
245 pg->device_id_len = 0;
243 } 246 }
244 pg->group_id = group_id; 247 pg->group_id = group_id;
245 pg->tpgs = tpgs; 248 pg->tpgs = tpgs;
@@ -354,9 +357,15 @@ static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h,
354 return SCSI_DH_NOMEM; 357 return SCSI_DH_NOMEM;
355 return SCSI_DH_DEV_UNSUPP; 358 return SCSI_DH_DEV_UNSUPP;
356 } 359 }
357 sdev_printk(KERN_INFO, sdev, 360 if (pg->device_id_len)
358 "%s: device %s port group %x rel port %x\n", 361 sdev_printk(KERN_INFO, sdev,
359 ALUA_DH_NAME, pg->device_id_str, group_id, rel_port); 362 "%s: device %s port group %x rel port %x\n",
363 ALUA_DH_NAME, pg->device_id_str,
364 group_id, rel_port);
365 else
366 sdev_printk(KERN_INFO, sdev,
367 "%s: port group %x rel port %x\n",
368 ALUA_DH_NAME, group_id, rel_port);
360 369
361 /* Check for existing port group references */ 370 /* Check for existing port group references */
362 spin_lock(&h->pg_lock); 371 spin_lock(&h->pg_lock);