]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
[SCSI] qla2xxx: Fix to ensure driver works in sinlge queue mode if multiqueue fails
authorAnirban Chakraborty <anirban.chakraborty@qlogic.com>
Wed, 5 Aug 2009 16:18:40 +0000 (09:18 -0700)
committerJames Bottomley <James.Bottomley@suse.de>
Sat, 22 Aug 2009 22:52:20 +0000 (17:52 -0500)
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: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_iocb.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c

index 0f8796201504c25a9f736f38f4ec8094b2578640..5b0a222241bbe24ac18f1269d2004c29af7898c8 100644 (file)
@@ -1670,7 +1670,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
 
        qla24xx_vport_disable(fc_vport, disable);
 
-       if (ql2xmultique_tag) {
+       if (ha->flags.cpu_affinity_enabled) {
                req = ha->req_q_map[1];
                goto vport_queue;
        } else if (ql2xmaxqueues == 1 || !ha->npiv_info)
@@ -1743,7 +1743,7 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
                    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)
                        qla_printk(KERN_WARNING, ha,
                                "Queue delete failed.\n");
index 9fde8bfe7607f3721e7f4b8e18d1895afbb7acc9..68ab28c8152b2ab58741413c70be9f9cfefec1c6 100644 (file)
@@ -2224,6 +2224,7 @@ struct qla_hw_data {
                uint32_t        chip_reset_done         :1;
                uint32_t        port0                   :1;
                uint32_t        running_gold_fw         :1;
+               uint32_t        cpu_affinity_enabled    :1;
        } flags;
 
        /* This spinlock is used to protect "io transactions", you must
index f2ce8e3cc91bc661d91f23a699cc68894530030e..0cbe39e92506e7854a220202d6ca9db2a411f503 100644 (file)
@@ -987,7 +987,6 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
                                    ha->phy_version);
                                if (rval != QLA_SUCCESS)
                                        goto failed;
-
                                ha->flags.npiv_supported = 0;
                                if (IS_QLA2XXX_MIDTYPE(ha) &&
                                         (ha->fw_attributes & BIT_2)) {
@@ -3244,7 +3243,7 @@ qla2x00_loop_resync(scsi_qla_host_t *vha)
        struct req_que *req;
        struct rsp_que *rsp;
 
-       if (ql2xmultique_tag)
+       if (vha->hw->flags.cpu_affinity_enabled)
                req = vha->hw->req_q_map[0];
        else
                req = vha->req;
@@ -4264,7 +4263,7 @@ qla24xx_configure_vhba(scsi_qla_host_t *vha)
                return -EINVAL;
 
        rval = qla2x00_fw_ready(base_vha);
-       if (ql2xmultique_tag)
+       if (ha->flags.cpu_affinity_enabled)
                req = ha->req_q_map[0];
        else
                req = vha->req;
index 13396beae2cedcde63b00c6156b44696168e6cc0..c0ba370b23cf780b11379c2b955036812d624b3c 100644 (file)
@@ -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;
        int affinity = cmd->request->cpu;
 
-       if (ql2xmultique_tag && affinity >= 0 &&
+       if (ha->flags.cpu_affinity_enabled && affinity >= 0 &&
                affinity < ha->max_rsp_queues - 1)
                *rsp = ha->rsp_q_map[affinity + 1];
         else
index 8fcd99eeec00093860e718ae814c333d94963cfc..b6202fe118ac4abeed182f631e67b33f38b623e9 100644 (file)
@@ -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));
 
-       if (ql2xmultique_tag)
+       if (ha->flags.cpu_affinity_enabled)
                req = ha->req_q_map[0];
        else
                req = vha->req;
@@ -2324,7 +2324,7 @@ __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
        vha = fcport->vha;
        ha = vha->hw;
        req = vha->req;
-       if (ql2xmultique_tag)
+       if (ha->flags.cpu_affinity_enabled)
                rsp = ha->rsp_q_map[tag + 1];
        else
                rsp = req->rsp;
index f0396e79b6fa159a4a02226ba23ae171a7516652..d7b271339a5cc24fd4f33b91fc3ce688bd469925 100644 (file)
@@ -287,9 +287,12 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
        int ques, req, ret;
        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) {
-               /* CPU affinity mode */
-               ha->wq = create_workqueue("qla2xxx_wq");
                /* create a request queue for IO */
                options |= BIT_7;
                req = qla25xx_create_req_que(ha, options, 0, 0, -1,
@@ -299,6 +302,7 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
                                "Can't create request queue\n");
                        goto fail;
                }
+               ha->wq = create_workqueue("qla2xxx_wq");
                vha->req = ha->req_q_map[req];
                options |= BIT_1;
                for (ques = 1; ques < ha->max_rsp_queues; ques++) {
@@ -309,6 +313,8 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
                                goto fail2;
                        }
                }
+               ha->flags.cpu_affinity_enabled = 1;
+
                DEBUG2(qla_printk(KERN_INFO, ha,
                        "CPU affinity mode enabled, no. of response"
                        " queues:%d, no. of request queues:%d\n",
@@ -317,8 +323,13 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
        return 0;
 fail2:
        qla25xx_delete_queues(vha);
+       destroy_workqueue(ha->wq);
+       ha->wq = NULL;
 fail:
        ha->mqenable = 0;
+       kfree(ha->req_q_map);
+       kfree(ha->rsp_q_map);
+       ha->max_req_queues = ha->max_rsp_queues = 1;
        return 1;
 }
 
@@ -1923,6 +1934,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        if (ret)
                goto probe_init_failed;
        /* Alloc arrays of request and response ring ptrs */
+que_init:
        if (!qla2x00_alloc_queues(ha)) {
                qla_printk(KERN_WARNING, ha,
                "[ERROR] Failed to allocate memory for queue"
@@ -1959,11 +1971,14 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
                goto probe_failed;
        }
 
-       if (ha->mqenable)
-               if (qla25xx_setup_mode(base_vha))
+       if (ha->mqenable) {
+               if (qla25xx_setup_mode(base_vha)) {
                        qla_printk(KERN_WARNING, ha,
                                "Can't create queues, falling back to single"
                                " queue mode\n");
+                       goto que_init;
+               }
+       }
 
        if (ha->flags.running_gold_fw)
                goto skip_dpc;