[SCSI] qla2xxx: fix for multiqueue in MISX disabled case
authorAnirban Chakraborty <anirban.chakraborty@qlogic.com>
Wed, 2 Dec 2009 18:36:55 +0000 (10:36 -0800)
committerJames Bottomley <James.Bottomley@suse.de>
Thu, 10 Dec 2009 14:54:19 +0000 (08:54 -0600)
 Fix to accommodate a hardware bug in multiqueue mode that does not
 work properly when acknowledgement of MSIX Interrupts is disabled.

Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mid.c

index 7a81e988fffe5d6235bb7e2924b348df0f7582a1..384afda7dbe942f2ade0f189be0da5e4e7d71685 100644 (file)
@@ -2262,6 +2262,7 @@ struct qla_hw_data {
                uint32_t        port0                   :1;
                uint32_t        running_gold_fw         :1;
                uint32_t        cpu_affinity_enabled    :1;
+               uint32_t        disable_msix_handshake  :1;
        } flags;
 
        /* This spinlock is used to protect "io transactions", you must
@@ -2384,6 +2385,7 @@ struct qla_hw_data {
 #define IS_QLA81XX(ha)         (IS_QLA8001(ha))
 #define IS_QLA2XXX_MIDTYPE(ha) (IS_QLA24XX(ha) || IS_QLA84XX(ha) || \
                                IS_QLA25XX(ha) || IS_QLA81XX(ha))
+#define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha))
 #define IS_NOPOLLING_TYPE(ha)  ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && \
                                (ha)->flags.msix_enabled)
 #define IS_FAC_REQUIRED(ha)    (IS_QLA81XX(ha))
index b74924b279ef2854cfc09e238cff4f5cfc950820..73a793539d4512ba0ac7a5921a6cd0783ffd4308 100644 (file)
@@ -1442,7 +1442,17 @@ qla24xx_config_rings(struct scsi_qla_host *vha)
                        icb->firmware_options_2 |=
                                __constant_cpu_to_le32(BIT_18);
 
-               icb->firmware_options_2 &= __constant_cpu_to_le32(~BIT_22);
+               /* Use Disable MSIX Handshake mode for capable adapters */
+               if (IS_MSIX_NACK_CAPABLE(ha)) {
+                       icb->firmware_options_2 &=
+                               __constant_cpu_to_le32(~BIT_22);
+                       ha->flags.disable_msix_handshake = 1;
+                       qla_printk(KERN_INFO, ha,
+                               "MSIX Handshake Disable Mode turned on\n");
+               } else {
+                       icb->firmware_options_2 |=
+                               __constant_cpu_to_le32(BIT_22);
+               }
                icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_23);
 
                WRT_REG_DWORD(&reg->isp25mq.req_q_in, 0);
index bc07d8392ac32a957dfc63600a245b374781e403..1692a883f4de837b7cd386bd6ea02e4de4c278ef 100644 (file)
@@ -1928,7 +1928,7 @@ qla24xx_msix_rsp_q(int irq, void *dev_id)
 
        vha = qla25xx_get_host(rsp);
        qla24xx_process_response_queue(vha, rsp);
-       if (!ha->mqenable) {
+       if (!ha->flags.disable_msix_handshake) {
                WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
                RD_REG_DWORD_RELAXED(&reg->hccr);
        }
@@ -1942,6 +1942,7 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
 {
        struct qla_hw_data *ha;
        struct rsp_que *rsp;
+       struct device_reg_24xx __iomem *reg;
 
        rsp = (struct rsp_que *) dev_id;
        if (!rsp) {
@@ -1951,6 +1952,14 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
        }
        ha = rsp->hw;
 
+       /* Clear the interrupt, if enabled, for this response queue */
+       if (rsp->options & ~BIT_6) {
+               reg = &ha->iobase->isp24;
+               spin_lock_irq(&ha->hardware_lock);
+               WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
+               RD_REG_DWORD_RELAXED(&reg->hccr);
+               spin_unlock_irq(&ha->hardware_lock);
+       }
        queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work);
 
        return IRQ_HANDLED;
index a47d34308a3a0fa050ec343085cef8d7d5ec7783..2a4c7f4e7b69b0a4fcaf13cf044044c60639a3f6 100644 (file)
@@ -696,6 +696,10 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
        /* Use alternate PCI devfn */
        if (LSB(rsp->rid))
                options |= BIT_5;
+       /* Enable MSIX handshake mode on for uncapable adapters */
+       if (!IS_MSIX_NACK_CAPABLE(ha))
+               options |= BIT_6;
+
        rsp->options = options;
        rsp->id = que_id;
        reg = ISP_QUE_REG(ha, que_id);