aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/device_handler
diff options
context:
space:
mode:
authorChandra Seetharaman <sekharan@us.ibm.com>2011-07-20 17:18:56 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-07-27 06:29:44 -0400
commita53becc9a9dbe4f2961b2bba129b3b2624401021 (patch)
tree67351ddb63c352d8529f708cb3eb83a726b84f36 /drivers/scsi/device_handler
parente466e1c6e14e211e0ece86bdb0810b1b9c1a59a8 (diff)
[SCSI] dh_rdac: Use WWID from C8 page instead of Subsystem id from C4 page to identify storage
rdac hardware handler uses "Subsystem Identifier" from C4 inquiry page to uniquely identify a storage. The problem with that is that if any any of the bytes are non-ascii, subsys_id will all be spaces (hex 0x20). This creates lot of problems especially when there are multiple rdac storages are connected to the server. Use "Storage Array Unique Identifier" from C8 inquiry page, which is the world wide unique identifier for the storage array, to uniquely identify the storage. Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/device_handler')
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c79
1 files changed, 40 insertions, 39 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 2e7c136bb805..f57009b348d6 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -128,25 +128,7 @@ struct c4_inquiry {
128 u8 reserved[2]; 128 u8 reserved[2];
129}; 129};
130 130
131struct rdac_controller { 131#define UNIQUE_ID_LEN 16
132 u8 subsys_id[SUBSYS_ID_LEN];
133 u8 slot_id[SLOT_ID_LEN];
134 int use_ms10;
135 struct kref kref;
136 struct list_head node; /* list of all controllers */
137 union {
138 struct rdac_pg_legacy legacy;
139 struct rdac_pg_expanded expanded;
140 } mode_select;
141 u8 index;
142 u8 array_name[ARRAY_LABEL_LEN];
143 spinlock_t ms_lock;
144 int ms_queued;
145 struct work_struct ms_work;
146 struct scsi_device *ms_sdev;
147 struct list_head ms_head;
148};
149
150struct c8_inquiry { 132struct c8_inquiry {
151 u8 peripheral_info; 133 u8 peripheral_info;
152 u8 page_code; /* 0xC8 */ 134 u8 page_code; /* 0xC8 */
@@ -159,12 +141,30 @@ struct c8_inquiry {
159 u8 vol_user_label_len; 141 u8 vol_user_label_len;
160 u8 vol_user_label[60]; 142 u8 vol_user_label[60];
161 u8 array_uniq_id_len; 143 u8 array_uniq_id_len;
162 u8 array_unique_id[16]; 144 u8 array_unique_id[UNIQUE_ID_LEN];
163 u8 array_user_label_len; 145 u8 array_user_label_len;
164 u8 array_user_label[60]; 146 u8 array_user_label[60];
165 u8 lun[8]; 147 u8 lun[8];
166}; 148};
167 149
150struct rdac_controller {
151 u8 array_id[UNIQUE_ID_LEN];
152 int use_ms10;
153 struct kref kref;
154 struct list_head node; /* list of all controllers */
155 union {
156 struct rdac_pg_legacy legacy;
157 struct rdac_pg_expanded expanded;
158 } mode_select;
159 u8 index;
160 u8 array_name[ARRAY_LABEL_LEN];
161 spinlock_t ms_lock;
162 int ms_queued;
163 struct work_struct ms_work;
164 struct scsi_device *ms_sdev;
165 struct list_head ms_head;
166};
167
168struct c2_inquiry { 168struct c2_inquiry {
169 u8 peripheral_info; 169 u8 peripheral_info;
170 u8 page_code; /* 0xC2 */ 170 u8 page_code; /* 0xC2 */
@@ -369,16 +369,16 @@ static void release_controller(struct kref *kref)
369 kfree(ctlr); 369 kfree(ctlr);
370} 370}
371 371
372static struct rdac_controller *get_controller(u8 *subsys_id, u8 *slot_id, 372static struct rdac_controller *get_controller(int index, char *array_name,
373 char *array_name) 373 u8 *array_id)
374{ 374{
375 struct rdac_controller *ctlr, *tmp; 375 struct rdac_controller *ctlr, *tmp;
376 376
377 spin_lock(&list_lock); 377 spin_lock(&list_lock);
378 378
379 list_for_each_entry(tmp, &ctlr_list, node) { 379 list_for_each_entry(tmp, &ctlr_list, node) {
380 if ((memcmp(tmp->subsys_id, subsys_id, SUBSYS_ID_LEN) == 0) && 380 if ((memcmp(tmp->array_id, array_id, UNIQUE_ID_LEN) == 0) &&
381 (memcmp(tmp->slot_id, slot_id, SLOT_ID_LEN) == 0)) { 381 (tmp->index == index)) {
382 kref_get(&tmp->kref); 382 kref_get(&tmp->kref);
383 spin_unlock(&list_lock); 383 spin_unlock(&list_lock);
384 return tmp; 384 return tmp;
@@ -389,16 +389,10 @@ static struct rdac_controller *get_controller(u8 *subsys_id, u8 *slot_id,
389 goto done; 389 goto done;
390 390
391 /* initialize fields of controller */ 391 /* initialize fields of controller */
392 memcpy(ctlr->subsys_id, subsys_id, SUBSYS_ID_LEN); 392 memcpy(ctlr->array_id, array_id, UNIQUE_ID_LEN);
393 memcpy(ctlr->slot_id, slot_id, SLOT_ID_LEN); 393 ctlr->index = index;
394 memcpy(ctlr->array_name, array_name, ARRAY_LABEL_LEN); 394 memcpy(ctlr->array_name, array_name, ARRAY_LABEL_LEN);
395 395
396 /* update the controller index */
397 if (slot_id[1] == 0x31)
398 ctlr->index = 0;
399 else
400 ctlr->index = 1;
401
402 kref_init(&ctlr->kref); 396 kref_init(&ctlr->kref);
403 ctlr->use_ms10 = -1; 397 ctlr->use_ms10 = -1;
404 ctlr->ms_queued = 0; 398 ctlr->ms_queued = 0;
@@ -444,7 +438,7 @@ done:
444} 438}
445 439
446static int get_lun_info(struct scsi_device *sdev, struct rdac_dh_data *h, 440static int get_lun_info(struct scsi_device *sdev, struct rdac_dh_data *h,
447 char *array_name) 441 char *array_name, u8 *array_id)
448{ 442{
449 int err, i; 443 int err, i;
450 struct c8_inquiry *inqp; 444 struct c8_inquiry *inqp;
@@ -463,6 +457,8 @@ static int get_lun_info(struct scsi_device *sdev, struct rdac_dh_data *h,
463 *(array_name+i) = inqp->array_user_label[(2*i)+1]; 457 *(array_name+i) = inqp->array_user_label[(2*i)+1];
464 458
465 *(array_name+ARRAY_LABEL_LEN-1) = '\0'; 459 *(array_name+ARRAY_LABEL_LEN-1) = '\0';
460 memset(array_id, 0, UNIQUE_ID_LEN);
461 memcpy(array_id, inqp->array_unique_id, inqp->array_uniq_id_len);
466 } 462 }
467 return err; 463 return err;
468} 464}
@@ -504,16 +500,20 @@ static int check_ownership(struct scsi_device *sdev, struct rdac_dh_data *h)
504} 500}
505 501
506static int initialize_controller(struct scsi_device *sdev, 502static int initialize_controller(struct scsi_device *sdev,
507 struct rdac_dh_data *h, char *array_name) 503 struct rdac_dh_data *h, char *array_name, u8 *array_id)
508{ 504{
509 int err; 505 int err, index;
510 struct c4_inquiry *inqp; 506 struct c4_inquiry *inqp;
511 507
512 err = submit_inquiry(sdev, 0xC4, sizeof(struct c4_inquiry), h); 508 err = submit_inquiry(sdev, 0xC4, sizeof(struct c4_inquiry), h);
513 if (err == SCSI_DH_OK) { 509 if (err == SCSI_DH_OK) {
514 inqp = &h->inq.c4; 510 inqp = &h->inq.c4;
515 h->ctlr = get_controller(inqp->subsys_id, inqp->slot_id, 511 /* get the controller index */
516 array_name); 512 if (inqp->slot_id[1] == 0x31)
513 index = 0;
514 else
515 index = 1;
516 h->ctlr = get_controller(index, array_name, array_id);
517 if (!h->ctlr) 517 if (!h->ctlr)
518 err = SCSI_DH_RES_TEMP_UNAVAIL; 518 err = SCSI_DH_RES_TEMP_UNAVAIL;
519 } 519 }
@@ -835,6 +835,7 @@ static int rdac_bus_attach(struct scsi_device *sdev)
835 unsigned long flags; 835 unsigned long flags;
836 int err; 836 int err;
837 char array_name[ARRAY_LABEL_LEN]; 837 char array_name[ARRAY_LABEL_LEN];
838 char array_id[UNIQUE_ID_LEN];
838 839
839 scsi_dh_data = kzalloc(sizeof(*scsi_dh_data) 840 scsi_dh_data = kzalloc(sizeof(*scsi_dh_data)
840 + sizeof(*h) , GFP_KERNEL); 841 + sizeof(*h) , GFP_KERNEL);
@@ -849,11 +850,11 @@ static int rdac_bus_attach(struct scsi_device *sdev)
849 h->lun = UNINITIALIZED_LUN; 850 h->lun = UNINITIALIZED_LUN;
850 h->state = RDAC_STATE_ACTIVE; 851 h->state = RDAC_STATE_ACTIVE;
851 852
852 err = get_lun_info(sdev, h, array_name); 853 err = get_lun_info(sdev, h, array_name, array_id);
853 if (err != SCSI_DH_OK) 854 if (err != SCSI_DH_OK)
854 goto failed; 855 goto failed;
855 856
856 err = initialize_controller(sdev, h, array_name); 857 err = initialize_controller(sdev, h, array_name, array_id);
857 if (err != SCSI_DH_OK) 858 if (err != SCSI_DH_OK)
858 goto failed; 859 goto failed;
859 860