aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/device_handler/scsi_dh_rdac.c
diff options
context:
space:
mode:
authorMoger, Babu <Babu.Moger@lsi.com>2011-02-11 17:14:08 -0500
committerJames Bottomley <James.Bottomley@suse.de>2011-02-12 15:05:08 -0500
commit04b6e153b64471ff43dde82b0122e67cf491f2f5 (patch)
treef58379ad7189750122033f71f7e4b8a6c0c6db5a /drivers/scsi/device_handler/scsi_dh_rdac.c
parent3487735aa54407565278a5a1288119c45210b86c (diff)
[SCSI] scsi_dh_rdac: fix for lun_table update for rdac device handler
During one of our testing, we noticed that mode select command sent from the host did not have the lun_table updated. Problem is root caused to the way lun table is updated. Lun table update was done after the call to blk_rq_map_kern is made. This was causing problem because kernel uses bounce buffer(bio_copy_kern) if the address is not aligned. The command buffer updated after the call(blk_rq_map_kern) was not going on the wire. Moved the code to update the lun_table before the call to fix the problem. Signed-off-by: Babu Moger <babu.moger@lsi.com> Signed-off-by: Somasundaram Krishnasamy <Somasundaram.Krishnasamy@lsi.com> Signed-off-by: Yanling Qi <Yanling.Qi@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/device_handler/scsi_dh_rdac.c')
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 5be3ae15cb7..7d83a84442a 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -281,11 +281,13 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
281} 281}
282 282
283static struct request *rdac_failover_get(struct scsi_device *sdev, 283static struct request *rdac_failover_get(struct scsi_device *sdev,
284 struct rdac_dh_data *h) 284 struct rdac_dh_data *h, struct list_head *list)
285{ 285{
286 struct request *rq; 286 struct request *rq;
287 struct rdac_mode_common *common; 287 struct rdac_mode_common *common;
288 unsigned data_size; 288 unsigned data_size;
289 struct rdac_queue_data *qdata;
290 u8 *lun_table;
289 291
290 if (h->ctlr->use_ms10) { 292 if (h->ctlr->use_ms10) {
291 struct rdac_pg_expanded *rdac_pg; 293 struct rdac_pg_expanded *rdac_pg;
@@ -298,6 +300,7 @@ static struct request *rdac_failover_get(struct scsi_device *sdev,
298 rdac_pg->subpage_code = 0x1; 300 rdac_pg->subpage_code = 0x1;
299 rdac_pg->page_len[0] = 0x01; 301 rdac_pg->page_len[0] = 0x01;
300 rdac_pg->page_len[1] = 0x28; 302 rdac_pg->page_len[1] = 0x28;
303 lun_table = rdac_pg->lun_table;
301 } else { 304 } else {
302 struct rdac_pg_legacy *rdac_pg; 305 struct rdac_pg_legacy *rdac_pg;
303 306
@@ -307,11 +310,16 @@ static struct request *rdac_failover_get(struct scsi_device *sdev,
307 common = &rdac_pg->common; 310 common = &rdac_pg->common;
308 rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER; 311 rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER;
309 rdac_pg->page_len = 0x68; 312 rdac_pg->page_len = 0x68;
313 lun_table = rdac_pg->lun_table;
310 } 314 }
311 common->rdac_mode[1] = RDAC_MODE_TRANSFER_SPECIFIED_LUNS; 315 common->rdac_mode[1] = RDAC_MODE_TRANSFER_SPECIFIED_LUNS;
312 common->quiescence_timeout = RDAC_QUIESCENCE_TIME; 316 common->quiescence_timeout = RDAC_QUIESCENCE_TIME;
313 common->rdac_options = RDAC_FORCED_QUIESENCE; 317 common->rdac_options = RDAC_FORCED_QUIESENCE;
314 318
319 list_for_each_entry(qdata, list, entry) {
320 lun_table[qdata->h->lun] = 0x81;
321 }
322
315 /* get request for block layer packet command */ 323 /* get request for block layer packet command */
316 rq = get_rdac_req(sdev, &h->ctlr->mode_select, data_size, WRITE); 324 rq = get_rdac_req(sdev, &h->ctlr->mode_select, data_size, WRITE);
317 if (!rq) 325 if (!rq)
@@ -565,7 +573,6 @@ static void send_mode_select(struct work_struct *work)
565 int err, retry_cnt = RDAC_RETRY_COUNT; 573 int err, retry_cnt = RDAC_RETRY_COUNT;
566 struct rdac_queue_data *tmp, *qdata; 574 struct rdac_queue_data *tmp, *qdata;
567 LIST_HEAD(list); 575 LIST_HEAD(list);
568 u8 *lun_table;
569 576
570 spin_lock(&ctlr->ms_lock); 577 spin_lock(&ctlr->ms_lock);
571 list_splice_init(&ctlr->ms_head, &list); 578 list_splice_init(&ctlr->ms_head, &list);
@@ -573,21 +580,12 @@ static void send_mode_select(struct work_struct *work)
573 ctlr->ms_sdev = NULL; 580 ctlr->ms_sdev = NULL;
574 spin_unlock(&ctlr->ms_lock); 581 spin_unlock(&ctlr->ms_lock);
575 582
576 if (ctlr->use_ms10)
577 lun_table = ctlr->mode_select.expanded.lun_table;
578 else
579 lun_table = ctlr->mode_select.legacy.lun_table;
580
581retry: 583retry:
582 err = SCSI_DH_RES_TEMP_UNAVAIL; 584 err = SCSI_DH_RES_TEMP_UNAVAIL;
583 rq = rdac_failover_get(sdev, h); 585 rq = rdac_failover_get(sdev, h, &list);
584 if (!rq) 586 if (!rq)
585 goto done; 587 goto done;
586 588
587 list_for_each_entry(qdata, &list, entry) {
588 lun_table[qdata->h->lun] = 0x81;
589 }
590
591 RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, " 589 RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
592 "%s MODE_SELECT command", 590 "%s MODE_SELECT command",
593 (char *) h->ctlr->array_name, h->ctlr->index, 591 (char *) h->ctlr->array_name, h->ctlr->index,