Commit 04b6e153 authored by Moger, Babu's avatar Moger, Babu Committed by James Bottomley

[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: default avatarBabu Moger <babu.moger@lsi.com>
Signed-off-by: default avatarSomasundaram Krishnasamy <Somasundaram.Krishnasamy@lsi.com>
Signed-off-by: default avatarYanling Qi <Yanling.Qi@lsi.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 3487735a
...@@ -281,11 +281,13 @@ static struct request *get_rdac_req(struct scsi_device *sdev, ...@@ -281,11 +281,13 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
} }
static struct request *rdac_failover_get(struct scsi_device *sdev, static struct request *rdac_failover_get(struct scsi_device *sdev,
struct rdac_dh_data *h) struct rdac_dh_data *h, struct list_head *list)
{ {
struct request *rq; struct request *rq;
struct rdac_mode_common *common; struct rdac_mode_common *common;
unsigned data_size; unsigned data_size;
struct rdac_queue_data *qdata;
u8 *lun_table;
if (h->ctlr->use_ms10) { if (h->ctlr->use_ms10) {
struct rdac_pg_expanded *rdac_pg; struct rdac_pg_expanded *rdac_pg;
...@@ -298,6 +300,7 @@ static struct request *rdac_failover_get(struct scsi_device *sdev, ...@@ -298,6 +300,7 @@ static struct request *rdac_failover_get(struct scsi_device *sdev,
rdac_pg->subpage_code = 0x1; rdac_pg->subpage_code = 0x1;
rdac_pg->page_len[0] = 0x01; rdac_pg->page_len[0] = 0x01;
rdac_pg->page_len[1] = 0x28; rdac_pg->page_len[1] = 0x28;
lun_table = rdac_pg->lun_table;
} else { } else {
struct rdac_pg_legacy *rdac_pg; struct rdac_pg_legacy *rdac_pg;
...@@ -307,11 +310,16 @@ static struct request *rdac_failover_get(struct scsi_device *sdev, ...@@ -307,11 +310,16 @@ static struct request *rdac_failover_get(struct scsi_device *sdev,
common = &rdac_pg->common; common = &rdac_pg->common;
rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER; rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER;
rdac_pg->page_len = 0x68; rdac_pg->page_len = 0x68;
lun_table = rdac_pg->lun_table;
} }
common->rdac_mode[1] = RDAC_MODE_TRANSFER_SPECIFIED_LUNS; common->rdac_mode[1] = RDAC_MODE_TRANSFER_SPECIFIED_LUNS;
common->quiescence_timeout = RDAC_QUIESCENCE_TIME; common->quiescence_timeout = RDAC_QUIESCENCE_TIME;
common->rdac_options = RDAC_FORCED_QUIESENCE; common->rdac_options = RDAC_FORCED_QUIESENCE;
list_for_each_entry(qdata, list, entry) {
lun_table[qdata->h->lun] = 0x81;
}
/* get request for block layer packet command */ /* get request for block layer packet command */
rq = get_rdac_req(sdev, &h->ctlr->mode_select, data_size, WRITE); rq = get_rdac_req(sdev, &h->ctlr->mode_select, data_size, WRITE);
if (!rq) if (!rq)
...@@ -565,7 +573,6 @@ static void send_mode_select(struct work_struct *work) ...@@ -565,7 +573,6 @@ static void send_mode_select(struct work_struct *work)
int err, retry_cnt = RDAC_RETRY_COUNT; int err, retry_cnt = RDAC_RETRY_COUNT;
struct rdac_queue_data *tmp, *qdata; struct rdac_queue_data *tmp, *qdata;
LIST_HEAD(list); LIST_HEAD(list);
u8 *lun_table;
spin_lock(&ctlr->ms_lock); spin_lock(&ctlr->ms_lock);
list_splice_init(&ctlr->ms_head, &list); list_splice_init(&ctlr->ms_head, &list);
...@@ -573,21 +580,12 @@ static void send_mode_select(struct work_struct *work) ...@@ -573,21 +580,12 @@ static void send_mode_select(struct work_struct *work)
ctlr->ms_sdev = NULL; ctlr->ms_sdev = NULL;
spin_unlock(&ctlr->ms_lock); spin_unlock(&ctlr->ms_lock);
if (ctlr->use_ms10)
lun_table = ctlr->mode_select.expanded.lun_table;
else
lun_table = ctlr->mode_select.legacy.lun_table;
retry: retry:
err = SCSI_DH_RES_TEMP_UNAVAIL; err = SCSI_DH_RES_TEMP_UNAVAIL;
rq = rdac_failover_get(sdev, h); rq = rdac_failover_get(sdev, h, &list);
if (!rq) if (!rq)
goto done; goto done;
list_for_each_entry(qdata, &list, entry) {
lun_table[qdata->h->lun] = 0x81;
}
RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, " RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, "
"%s MODE_SELECT command", "%s MODE_SELECT command",
(char *) h->ctlr->array_name, h->ctlr->index, (char *) h->ctlr->array_name, h->ctlr->index,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment