aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/device_handler/scsi_dh_rdac.c
diff options
context:
space:
mode:
authorChandra Seetharaman <sekharan@us.ibm.com>2011-07-27 14:22:56 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-07-28 03:38:47 -0400
commitd6857595394f1fa5c5752eae9bb6045c067fa41e (patch)
treec9723dd0fdf17843a431d2c79e9791682b70e109 /drivers/scsi/device_handler/scsi_dh_rdac.c
parentf170c684b55cb8d3bab55b1fb8fa812778d551f2 (diff)
[SCSI] dh_rdac: Associate HBA and storage in rdac_controller to support partitions in storage
rdac hardware handler assumes that there is one-to-one relation ship between the host and the controller w.r.t lun. IOW, it does not support "multiple storage partitions" within a storage. Example: HBA1 and HBA2 see lun 0 and 1 in storage A (1) HBA3 and HBA4 see lun 0 and 1 in storage A (2) HBA5 and HBA6 see lun 0 and 1 in storage A (3) luns 0 and 1 in (1), (2) and (3) are totally different. But, rdac handler treats the lun 0s (and lun 1s) as the same when sending a mode select to the controller, which is wrong. This patch makes the rdac hardware handler associate HBA and the storage w.r.t lun (and not the host itself). Signed-off-by: Chandra Seetharaman <sekharan@us.ibm.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/device_handler/scsi_dh_rdac.c')
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index f57009b348d6..27c9d65d54a9 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -158,6 +158,7 @@ struct rdac_controller {
158 } mode_select; 158 } mode_select;
159 u8 index; 159 u8 index;
160 u8 array_name[ARRAY_LABEL_LEN]; 160 u8 array_name[ARRAY_LABEL_LEN];
161 struct Scsi_Host *host;
161 spinlock_t ms_lock; 162 spinlock_t ms_lock;
162 int ms_queued; 163 int ms_queued;
163 struct work_struct ms_work; 164 struct work_struct ms_work;
@@ -370,7 +371,7 @@ static void release_controller(struct kref *kref)
370} 371}
371 372
372static struct rdac_controller *get_controller(int index, char *array_name, 373static struct rdac_controller *get_controller(int index, char *array_name,
373 u8 *array_id) 374 u8 *array_id, struct scsi_device *sdev)
374{ 375{
375 struct rdac_controller *ctlr, *tmp; 376 struct rdac_controller *ctlr, *tmp;
376 377
@@ -378,7 +379,8 @@ static struct rdac_controller *get_controller(int index, char *array_name,
378 379
379 list_for_each_entry(tmp, &ctlr_list, node) { 380 list_for_each_entry(tmp, &ctlr_list, node) {
380 if ((memcmp(tmp->array_id, array_id, UNIQUE_ID_LEN) == 0) && 381 if ((memcmp(tmp->array_id, array_id, UNIQUE_ID_LEN) == 0) &&
381 (tmp->index == index)) { 382 (tmp->index == index) &&
383 (tmp->host == sdev->host)) {
382 kref_get(&tmp->kref); 384 kref_get(&tmp->kref);
383 spin_unlock(&list_lock); 385 spin_unlock(&list_lock);
384 return tmp; 386 return tmp;
@@ -391,6 +393,7 @@ static struct rdac_controller *get_controller(int index, char *array_name,
391 /* initialize fields of controller */ 393 /* initialize fields of controller */
392 memcpy(ctlr->array_id, array_id, UNIQUE_ID_LEN); 394 memcpy(ctlr->array_id, array_id, UNIQUE_ID_LEN);
393 ctlr->index = index; 395 ctlr->index = index;
396 ctlr->host = sdev->host;
394 memcpy(ctlr->array_name, array_name, ARRAY_LABEL_LEN); 397 memcpy(ctlr->array_name, array_name, ARRAY_LABEL_LEN);
395 398
396 kref_init(&ctlr->kref); 399 kref_init(&ctlr->kref);
@@ -513,7 +516,7 @@ static int initialize_controller(struct scsi_device *sdev,
513 index = 0; 516 index = 0;
514 else 517 else
515 index = 1; 518 index = 1;
516 h->ctlr = get_controller(index, array_name, array_id); 519 h->ctlr = get_controller(index, array_name, array_id, sdev);
517 if (!h->ctlr) 520 if (!h->ctlr)
518 err = SCSI_DH_RES_TEMP_UNAVAIL; 521 err = SCSI_DH_RES_TEMP_UNAVAIL;
519 } 522 }