summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa/bfa_hw_cb.c
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2011-07-20 17:00:45 -0700
committerJames Bottomley <JBottomley@Parallels.com>2011-07-27 14:44:48 +0400
commitca6e0ea71cd0f442875b05357dd51774bd84b418 (patch)
treed57fc05d9bd1141d1c8a340347bdb28ea20b8e45 /drivers/scsi/bfa/bfa_hw_cb.c
parent9afbcfab74d26051702862b57c0115f71477a3cc (diff)
downloadop-kernel-dev-ca6e0ea71cd0f442875b05357dd51774bd84b418.zip
op-kernel-dev-ca6e0ea71cd0f442875b05357dd51774bd84b418.tar.gz
[SCSI] bfa: Update RME interrupt handling.
- Made changes to always acknowledge RME interrupt and update consumer index (CI) when RME interrupt is generated. - Made changes to have ASIC specific hw_rspq_ack() handler. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa/bfa_hw_cb.c')
-rw-r--r--drivers/scsi/bfa/bfa_hw_cb.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c
index e7ffd82..ea24d4c 100644
--- a/drivers/scsi/bfa/bfa_hw_cb.c
+++ b/drivers/scsi/bfa/bfa_hw_cb.c
@@ -42,11 +42,36 @@ bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq)
bfa->iocfc.bfa_regs.intr_status);
}
+/*
+ * Actions to respond RME Interrupt for Crossbow ASIC:
+ * - Write 1 to Interrupt Status register
+ * INTX - done in bfa_intx()
+ * MSIX - done in bfa_hwcb_rspq_ack_msix()
+ * - Update CI (only if new CI)
+ */
static void
-bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq)
+bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq, u32 ci)
{
writel(__HFN_INT_RME_Q0 << RME_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), rspq),
- bfa->iocfc.bfa_regs.intr_status);
+ bfa->iocfc.bfa_regs.intr_status);
+
+ if (bfa_rspq_ci(bfa, rspq) == ci)
+ return;
+
+ bfa_rspq_ci(bfa, rspq) = ci;
+ writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
+ mmiowb();
+}
+
+void
+bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq, u32 ci)
+{
+ if (bfa_rspq_ci(bfa, rspq) == ci)
+ return;
+
+ bfa_rspq_ci(bfa, rspq) = ci;
+ writel(ci, bfa->iocfc.bfa_regs.rme_q_ci[rspq]);
+ mmiowb();
}
void
@@ -149,8 +174,13 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
void
bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
{
- bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix;
- bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
+ if (msix) {
+ bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix;
+ bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
+ } else {
+ bfa->iocfc.hwif.hw_reqq_ack = NULL;
+ bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
+ }
}
void
OpenPOWER on IntegriCloud