diff options
author | Anirban Chakraborty <anirban.chakraborty@qlogic.com> | 2009-12-02 13:36:55 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-12-10 09:54:19 -0500 |
commit | 3155754a6b7985a80c41d84dd06530ff543f52a8 (patch) | |
tree | ba11ce0747dbfad6ecdcb6d42d71ca8675122f63 /drivers/scsi | |
parent | c45dd30551c371cb1e7a742136b8b36f6aba63f8 (diff) |
[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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 12 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 11 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mid.c | 4 |
4 files changed, 27 insertions, 2 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 7a81e988fffe..384afda7dbe9 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2262,6 +2262,7 @@ struct qla_hw_data { | |||
2262 | uint32_t port0 :1; | 2262 | uint32_t port0 :1; |
2263 | uint32_t running_gold_fw :1; | 2263 | uint32_t running_gold_fw :1; |
2264 | uint32_t cpu_affinity_enabled :1; | 2264 | uint32_t cpu_affinity_enabled :1; |
2265 | uint32_t disable_msix_handshake :1; | ||
2265 | } flags; | 2266 | } flags; |
2266 | 2267 | ||
2267 | /* This spinlock is used to protect "io transactions", you must | 2268 | /* This spinlock is used to protect "io transactions", you must |
@@ -2384,6 +2385,7 @@ struct qla_hw_data { | |||
2384 | #define IS_QLA81XX(ha) (IS_QLA8001(ha)) | 2385 | #define IS_QLA81XX(ha) (IS_QLA8001(ha)) |
2385 | #define IS_QLA2XXX_MIDTYPE(ha) (IS_QLA24XX(ha) || IS_QLA84XX(ha) || \ | 2386 | #define IS_QLA2XXX_MIDTYPE(ha) (IS_QLA24XX(ha) || IS_QLA84XX(ha) || \ |
2386 | IS_QLA25XX(ha) || IS_QLA81XX(ha)) | 2387 | IS_QLA25XX(ha) || IS_QLA81XX(ha)) |
2388 | #define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha)) | ||
2387 | #define IS_NOPOLLING_TYPE(ha) ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && \ | 2389 | #define IS_NOPOLLING_TYPE(ha) ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && \ |
2388 | (ha)->flags.msix_enabled) | 2390 | (ha)->flags.msix_enabled) |
2389 | #define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha)) | 2391 | #define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha)) |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index b74924b279ef..73a793539d45 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -1442,7 +1442,17 @@ qla24xx_config_rings(struct scsi_qla_host *vha) | |||
1442 | icb->firmware_options_2 |= | 1442 | icb->firmware_options_2 |= |
1443 | __constant_cpu_to_le32(BIT_18); | 1443 | __constant_cpu_to_le32(BIT_18); |
1444 | 1444 | ||
1445 | icb->firmware_options_2 &= __constant_cpu_to_le32(~BIT_22); | 1445 | /* Use Disable MSIX Handshake mode for capable adapters */ |
1446 | if (IS_MSIX_NACK_CAPABLE(ha)) { | ||
1447 | icb->firmware_options_2 &= | ||
1448 | __constant_cpu_to_le32(~BIT_22); | ||
1449 | ha->flags.disable_msix_handshake = 1; | ||
1450 | qla_printk(KERN_INFO, ha, | ||
1451 | "MSIX Handshake Disable Mode turned on\n"); | ||
1452 | } else { | ||
1453 | icb->firmware_options_2 |= | ||
1454 | __constant_cpu_to_le32(BIT_22); | ||
1455 | } | ||
1446 | icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_23); | 1456 | icb->firmware_options_2 |= __constant_cpu_to_le32(BIT_23); |
1447 | 1457 | ||
1448 | WRT_REG_DWORD(®->isp25mq.req_q_in, 0); | 1458 | WRT_REG_DWORD(®->isp25mq.req_q_in, 0); |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index bc07d8392ac3..1692a883f4de 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -1928,7 +1928,7 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) | |||
1928 | 1928 | ||
1929 | vha = qla25xx_get_host(rsp); | 1929 | vha = qla25xx_get_host(rsp); |
1930 | qla24xx_process_response_queue(vha, rsp); | 1930 | qla24xx_process_response_queue(vha, rsp); |
1931 | if (!ha->mqenable) { | 1931 | if (!ha->flags.disable_msix_handshake) { |
1932 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1932 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1933 | RD_REG_DWORD_RELAXED(®->hccr); | 1933 | RD_REG_DWORD_RELAXED(®->hccr); |
1934 | } | 1934 | } |
@@ -1942,6 +1942,7 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) | |||
1942 | { | 1942 | { |
1943 | struct qla_hw_data *ha; | 1943 | struct qla_hw_data *ha; |
1944 | struct rsp_que *rsp; | 1944 | struct rsp_que *rsp; |
1945 | struct device_reg_24xx __iomem *reg; | ||
1945 | 1946 | ||
1946 | rsp = (struct rsp_que *) dev_id; | 1947 | rsp = (struct rsp_que *) dev_id; |
1947 | if (!rsp) { | 1948 | if (!rsp) { |
@@ -1951,6 +1952,14 @@ qla25xx_msix_rsp_q(int irq, void *dev_id) | |||
1951 | } | 1952 | } |
1952 | ha = rsp->hw; | 1953 | ha = rsp->hw; |
1953 | 1954 | ||
1955 | /* Clear the interrupt, if enabled, for this response queue */ | ||
1956 | if (rsp->options & ~BIT_6) { | ||
1957 | reg = &ha->iobase->isp24; | ||
1958 | spin_lock_irq(&ha->hardware_lock); | ||
1959 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | ||
1960 | RD_REG_DWORD_RELAXED(®->hccr); | ||
1961 | spin_unlock_irq(&ha->hardware_lock); | ||
1962 | } | ||
1954 | queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work); | 1963 | queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work); |
1955 | 1964 | ||
1956 | return IRQ_HANDLED; | 1965 | return IRQ_HANDLED; |
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index a47d34308a3a..2a4c7f4e7b69 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -696,6 +696,10 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, | |||
696 | /* Use alternate PCI devfn */ | 696 | /* Use alternate PCI devfn */ |
697 | if (LSB(rsp->rid)) | 697 | if (LSB(rsp->rid)) |
698 | options |= BIT_5; | 698 | options |= BIT_5; |
699 | /* Enable MSIX handshake mode on for uncapable adapters */ | ||
700 | if (!IS_MSIX_NACK_CAPABLE(ha)) | ||
701 | options |= BIT_6; | ||
702 | |||
699 | rsp->options = options; | 703 | rsp->options = options; |
700 | rsp->id = que_id; | 704 | rsp->id = que_id; |
701 | reg = ISP_QUE_REG(ha, que_id); | 705 | reg = ISP_QUE_REG(ha, que_id); |