Commit 7163ea81 authored by Anirban Chakraborty's avatar Anirban Chakraborty Committed by James Bottomley

[SCSI] qla2xxx: Fix to ensure driver works in sinlge queue mode if multiqueue fails

When the multiqueue mode fails to work, the driver falls back on single
queue mode. This ensures that the firmware is reinitialized with single
queue options and all the resources are readjusted accordingly.
Signed-off-by: default avatarAnirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 09ccbcc6
...@@ -1670,7 +1670,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) ...@@ -1670,7 +1670,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
qla24xx_vport_disable(fc_vport, disable); qla24xx_vport_disable(fc_vport, disable);
if (ql2xmultique_tag) { if (ha->flags.cpu_affinity_enabled) {
req = ha->req_q_map[1]; req = ha->req_q_map[1];
goto vport_queue; goto vport_queue;
} else if (ql2xmaxqueues == 1 || !ha->npiv_info) } else if (ql2xmaxqueues == 1 || !ha->npiv_info)
...@@ -1743,7 +1743,7 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) ...@@ -1743,7 +1743,7 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
vha->host_no, vha->vp_idx, vha)); vha->host_no, vha->vp_idx, vha));
} }
if (vha->req->id && !ql2xmultique_tag) { if (vha->req->id && !ha->flags.cpu_affinity_enabled) {
if (qla25xx_delete_req_que(vha, vha->req) != QLA_SUCCESS) if (qla25xx_delete_req_que(vha, vha->req) != QLA_SUCCESS)
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"Queue delete failed.\n"); "Queue delete failed.\n");
......
...@@ -2224,6 +2224,7 @@ struct qla_hw_data { ...@@ -2224,6 +2224,7 @@ struct qla_hw_data {
uint32_t chip_reset_done :1; uint32_t chip_reset_done :1;
uint32_t port0 :1; uint32_t port0 :1;
uint32_t running_gold_fw :1; uint32_t running_gold_fw :1;
uint32_t cpu_affinity_enabled :1;
} flags; } flags;
/* This spinlock is used to protect "io transactions", you must /* This spinlock is used to protect "io transactions", you must
......
...@@ -987,7 +987,6 @@ qla2x00_setup_chip(scsi_qla_host_t *vha) ...@@ -987,7 +987,6 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
ha->phy_version); ha->phy_version);
if (rval != QLA_SUCCESS) if (rval != QLA_SUCCESS)
goto failed; goto failed;
ha->flags.npiv_supported = 0; ha->flags.npiv_supported = 0;
if (IS_QLA2XXX_MIDTYPE(ha) && if (IS_QLA2XXX_MIDTYPE(ha) &&
(ha->fw_attributes & BIT_2)) { (ha->fw_attributes & BIT_2)) {
...@@ -3244,7 +3243,7 @@ qla2x00_loop_resync(scsi_qla_host_t *vha) ...@@ -3244,7 +3243,7 @@ qla2x00_loop_resync(scsi_qla_host_t *vha)
struct req_que *req; struct req_que *req;
struct rsp_que *rsp; struct rsp_que *rsp;
if (ql2xmultique_tag) if (vha->hw->flags.cpu_affinity_enabled)
req = vha->hw->req_q_map[0]; req = vha->hw->req_q_map[0];
else else
req = vha->req; req = vha->req;
...@@ -4264,7 +4263,7 @@ qla24xx_configure_vhba(scsi_qla_host_t *vha) ...@@ -4264,7 +4263,7 @@ qla24xx_configure_vhba(scsi_qla_host_t *vha)
return -EINVAL; return -EINVAL;
rval = qla2x00_fw_ready(base_vha); rval = qla2x00_fw_ready(base_vha);
if (ql2xmultique_tag) if (ha->flags.cpu_affinity_enabled)
req = ha->req_q_map[0]; req = ha->req_q_map[0];
else else
req = vha->req; req = vha->req;
......
...@@ -852,7 +852,7 @@ static void qla25xx_set_que(srb_t *sp, struct rsp_que **rsp) ...@@ -852,7 +852,7 @@ static void qla25xx_set_que(srb_t *sp, struct rsp_que **rsp)
struct qla_hw_data *ha = sp->fcport->vha->hw; struct qla_hw_data *ha = sp->fcport->vha->hw;
int affinity = cmd->request->cpu; int affinity = cmd->request->cpu;
if (ql2xmultique_tag && affinity >= 0 && if (ha->flags.cpu_affinity_enabled && affinity >= 0 &&
affinity < ha->max_rsp_queues - 1) affinity < ha->max_rsp_queues - 1)
*rsp = ha->rsp_q_map[affinity + 1]; *rsp = ha->rsp_q_map[affinity + 1];
else else
......
...@@ -1507,7 +1507,7 @@ qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain, ...@@ -1507,7 +1507,7 @@ qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no)); DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
if (ql2xmultique_tag) if (ha->flags.cpu_affinity_enabled)
req = ha->req_q_map[0]; req = ha->req_q_map[0];
else else
req = vha->req; req = vha->req;
...@@ -2324,7 +2324,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, ...@@ -2324,7 +2324,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
vha = fcport->vha; vha = fcport->vha;
ha = vha->hw; ha = vha->hw;
req = vha->req; req = vha->req;
if (ql2xmultique_tag) if (ha->flags.cpu_affinity_enabled)
rsp = ha->rsp_q_map[tag + 1]; rsp = ha->rsp_q_map[tag + 1];
else else
rsp = req->rsp; rsp = req->rsp;
......
...@@ -287,9 +287,12 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha) ...@@ -287,9 +287,12 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
int ques, req, ret; int ques, req, ret;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
if (!(ha->fw_attributes & BIT_6)) {
qla_printk(KERN_INFO, ha,
"Firmware is not multi-queue capable\n");
goto fail;
}
if (ql2xmultique_tag) { if (ql2xmultique_tag) {
/* CPU affinity mode */
ha->wq = create_workqueue("qla2xxx_wq");
/* create a request queue for IO */ /* create a request queue for IO */
options |= BIT_7; options |= BIT_7;
req = qla25xx_create_req_que(ha, options, 0, 0, -1, req = qla25xx_create_req_que(ha, options, 0, 0, -1,
...@@ -299,6 +302,7 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha) ...@@ -299,6 +302,7 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
"Can't create request queue\n"); "Can't create request queue\n");
goto fail; goto fail;
} }
ha->wq = create_workqueue("qla2xxx_wq");
vha->req = ha->req_q_map[req]; vha->req = ha->req_q_map[req];
options |= BIT_1; options |= BIT_1;
for (ques = 1; ques < ha->max_rsp_queues; ques++) { for (ques = 1; ques < ha->max_rsp_queues; ques++) {
...@@ -309,6 +313,8 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha) ...@@ -309,6 +313,8 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
goto fail2; goto fail2;
} }
} }
ha->flags.cpu_affinity_enabled = 1;
DEBUG2(qla_printk(KERN_INFO, ha, DEBUG2(qla_printk(KERN_INFO, ha,
"CPU affinity mode enabled, no. of response" "CPU affinity mode enabled, no. of response"
" queues:%d, no. of request queues:%d\n", " queues:%d, no. of request queues:%d\n",
...@@ -317,8 +323,13 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha) ...@@ -317,8 +323,13 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
return 0; return 0;
fail2: fail2:
qla25xx_delete_queues(vha); qla25xx_delete_queues(vha);
destroy_workqueue(ha->wq);
ha->wq = NULL;
fail: fail:
ha->mqenable = 0; ha->mqenable = 0;
kfree(ha->req_q_map);
kfree(ha->rsp_q_map);
ha->max_req_queues = ha->max_rsp_queues = 1;
return 1; return 1;
} }
...@@ -1923,6 +1934,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1923,6 +1934,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
if (ret) if (ret)
goto probe_init_failed; goto probe_init_failed;
/* Alloc arrays of request and response ring ptrs */ /* Alloc arrays of request and response ring ptrs */
que_init:
if (!qla2x00_alloc_queues(ha)) { if (!qla2x00_alloc_queues(ha)) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"[ERROR] Failed to allocate memory for queue" "[ERROR] Failed to allocate memory for queue"
...@@ -1959,11 +1971,14 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1959,11 +1971,14 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
goto probe_failed; goto probe_failed;
} }
if (ha->mqenable) if (ha->mqenable) {
if (qla25xx_setup_mode(base_vha)) if (qla25xx_setup_mode(base_vha)) {
qla_printk(KERN_WARNING, ha, qla_printk(KERN_WARNING, ha,
"Can't create queues, falling back to single" "Can't create queues, falling back to single"
" queue mode\n"); " queue mode\n");
goto que_init;
}
}
if (ha->flags.running_gold_fw) if (ha->flags.running_gold_fw)
goto skip_dpc; goto skip_dpc;
......
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