[SCSI] qla2xxx: fix for multiqueue in MISX disabled case
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>
This commit is contained in:

committed by
James Bottomley

parent
c45dd30551
commit
3155754a6b
@@ -2262,6 +2262,7 @@ struct qla_hw_data {
|
|||||||
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;
|
uint32_t cpu_affinity_enabled :1;
|
||||||
|
uint32_t disable_msix_handshake :1;
|
||||||
} flags;
|
} flags;
|
||||||
|
|
||||||
/* This spinlock is used to protect "io transactions", you must
|
/* 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_QLA81XX(ha) (IS_QLA8001(ha))
|
||||||
#define IS_QLA2XXX_MIDTYPE(ha) (IS_QLA24XX(ha) || IS_QLA84XX(ha) || \
|
#define IS_QLA2XXX_MIDTYPE(ha) (IS_QLA24XX(ha) || IS_QLA84XX(ha) || \
|
||||||
IS_QLA25XX(ha) || IS_QLA81XX(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)) && \
|
#define IS_NOPOLLING_TYPE(ha) ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && \
|
||||||
(ha)->flags.msix_enabled)
|
(ha)->flags.msix_enabled)
|
||||||
#define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha))
|
#define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha))
|
||||||
|
@@ -1442,7 +1442,17 @@ qla24xx_config_rings(struct scsi_qla_host *vha)
|
|||||||
icb->firmware_options_2 |=
|
icb->firmware_options_2 |=
|
||||||
__constant_cpu_to_le32(BIT_18);
|
__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);
|
icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_23);
|
||||||
|
|
||||||
WRT_REG_DWORD(®->isp25mq.req_q_in, 0);
|
WRT_REG_DWORD(®->isp25mq.req_q_in, 0);
|
||||||
|
@@ -1928,7 +1928,7 @@ qla24xx_msix_rsp_q(int irq, void *dev_id)
|
|||||||
|
|
||||||
vha = qla25xx_get_host(rsp);
|
vha = qla25xx_get_host(rsp);
|
||||||
qla24xx_process_response_queue(vha, rsp);
|
qla24xx_process_response_queue(vha, rsp);
|
||||||
if (!ha->mqenable) {
|
if (!ha->flags.disable_msix_handshake) {
|
||||||
WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT);
|
WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT);
|
||||||
RD_REG_DWORD_RELAXED(®->hccr);
|
RD_REG_DWORD_RELAXED(®->hccr);
|
||||||
}
|
}
|
||||||
@@ -1942,6 +1942,7 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
|
|||||||
{
|
{
|
||||||
struct qla_hw_data *ha;
|
struct qla_hw_data *ha;
|
||||||
struct rsp_que *rsp;
|
struct rsp_que *rsp;
|
||||||
|
struct device_reg_24xx __iomem *reg;
|
||||||
|
|
||||||
rsp = (struct rsp_que *) dev_id;
|
rsp = (struct rsp_que *) dev_id;
|
||||||
if (!rsp) {
|
if (!rsp) {
|
||||||
@@ -1951,6 +1952,14 @@ qla25xx_msix_rsp_q(int irq, void *dev_id)
|
|||||||
}
|
}
|
||||||
ha = rsp->hw;
|
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(®->hccr, HCCRX_CLR_RISC_INT);
|
||||||
|
RD_REG_DWORD_RELAXED(®->hccr);
|
||||||
|
spin_unlock_irq(&ha->hardware_lock);
|
||||||
|
}
|
||||||
queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work);
|
queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work);
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
@@ -696,6 +696,10 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
|
|||||||
/* Use alternate PCI devfn */
|
/* Use alternate PCI devfn */
|
||||||
if (LSB(rsp->rid))
|
if (LSB(rsp->rid))
|
||||||
options |= BIT_5;
|
options |= BIT_5;
|
||||||
|
/* Enable MSIX handshake mode on for uncapable adapters */
|
||||||
|
if (!IS_MSIX_NACK_CAPABLE(ha))
|
||||||
|
options |= BIT_6;
|
||||||
|
|
||||||
rsp->options = options;
|
rsp->options = options;
|
||||||
rsp->id = que_id;
|
rsp->id = que_id;
|
||||||
reg = ISP_QUE_REG(ha, que_id);
|
reg = ISP_QUE_REG(ha, que_id);
|
||||||
|
Reference in New Issue
Block a user