aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2010-03-05 22:37:09 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-03-07 02:32:14 -0500
commitf5713c5dfb4d61cd77debf61d3873eb36877ff1f (patch)
tree486b3ed74ad3584cf414be3997a5d3ba77712fd4 /drivers/scsi
parent816e49b8ed209e5e08d4c43359635cbca17e7196 (diff)
[SCSI] bfa: Fix Command Queue (CPE) full condition check and ack CPE interrupt.
Fixed the issue of not acknowledging the command queue full-to-non-full interrupt. Implemented separate acknowledging functions for different ASIC and interrupt mode. Fixed the case of missing CPE interrupt by always processing the pending requests in the completion path. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/bfa/bfa_hw_cb.c13
-rw-r--r--drivers/scsi/bfa/bfa_hw_ct.c9
-rw-r--r--drivers/scsi/bfa/bfa_intr.c71
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.c2
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.h3
5 files changed, 74 insertions, 24 deletions
diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c
index ede1438619e2..871a4e28575c 100644
--- a/drivers/scsi/bfa/bfa_hw_cb.c
+++ b/drivers/scsi/bfa/bfa_hw_cb.c
@@ -53,6 +53,18 @@ bfa_hwcb_reginit(struct bfa_s *bfa)
53} 53}
54 54
55void 55void
56bfa_hwcb_reqq_ack(struct bfa_s *bfa, int reqq)
57{
58}
59
60static void
61bfa_hwcb_reqq_ack_msix(struct bfa_s *bfa, int reqq)
62{
63 bfa_reg_write(bfa->iocfc.bfa_regs.intr_status,
64 __HFN_INT_CPE_Q0 << CPE_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), reqq));
65}
66
67void
56bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq) 68bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq)
57{ 69{
58} 70}
@@ -136,6 +148,7 @@ bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
136void 148void
137bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix) 149bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
138{ 150{
151 bfa->iocfc.hwif.hw_reqq_ack = bfa_hwcb_reqq_ack_msix;
139 bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix; 152 bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
140} 153}
141 154
diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c
index 51ae5740e6e9..76ceb9a4bf2f 100644
--- a/drivers/scsi/bfa/bfa_hw_ct.c
+++ b/drivers/scsi/bfa/bfa_hw_ct.c
@@ -85,6 +85,15 @@ bfa_hwct_reginit(struct bfa_s *bfa)
85} 85}
86 86
87void 87void
88bfa_hwct_reqq_ack(struct bfa_s *bfa, int reqq)
89{
90 u32 r32;
91
92 r32 = bfa_reg_read(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq]);
93 bfa_reg_write(bfa->iocfc.bfa_regs.cpe_q_ctrl[reqq], r32);
94}
95
96void
88bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq) 97bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq)
89{ 98{
90 u32 r32; 99 u32 r32;
diff --git a/drivers/scsi/bfa/bfa_intr.c b/drivers/scsi/bfa/bfa_intr.c
index c42254613f73..0eba3f930d5b 100644
--- a/drivers/scsi/bfa/bfa_intr.c
+++ b/drivers/scsi/bfa/bfa_intr.c
@@ -34,6 +34,26 @@ bfa_msix_lpu(struct bfa_s *bfa)
34 bfa_ioc_mbox_isr(&bfa->ioc); 34 bfa_ioc_mbox_isr(&bfa->ioc);
35} 35}
36 36
37static void
38bfa_reqq_resume(struct bfa_s *bfa, int qid)
39{
40 struct list_head *waitq, *qe, *qen;
41 struct bfa_reqq_wait_s *wqe;
42
43 waitq = bfa_reqq(bfa, qid);
44 list_for_each_safe(qe, qen, waitq) {
45 /**
46 * Callback only as long as there is room in request queue
47 */
48 if (bfa_reqq_full(bfa, qid))
49 break;
50
51 list_del(qe);
52 wqe = (struct bfa_reqq_wait_s *) qe;
53 wqe->qresume(wqe->cbarg);
54 }
55}
56
37void 57void
38bfa_msix_all(struct bfa_s *bfa, int vec) 58bfa_msix_all(struct bfa_s *bfa, int vec)
39{ 59{
@@ -128,23 +148,18 @@ bfa_isr_disable(struct bfa_s *bfa)
128void 148void
129bfa_msix_reqq(struct bfa_s *bfa, int qid) 149bfa_msix_reqq(struct bfa_s *bfa, int qid)
130{ 150{
131 struct list_head *waitq, *qe, *qen; 151 struct list_head *waitq;
132 struct bfa_reqq_wait_s *wqe;
133 152
134 qid &= (BFI_IOC_MAX_CQS - 1); 153 qid &= (BFI_IOC_MAX_CQS - 1);
135 154
136 waitq = bfa_reqq(bfa, qid); 155 bfa->iocfc.hwif.hw_reqq_ack(bfa, qid);
137 list_for_each_safe(qe, qen, waitq) {
138 /**
139 * Callback only as long as there is room in request queue
140 */
141 if (bfa_reqq_full(bfa, qid))
142 break;
143 156
144 list_del(qe); 157 /**
145 wqe = (struct bfa_reqq_wait_s *) qe; 158 * Resume any pending requests in the corresponding reqq.
146 wqe->qresume(wqe->cbarg); 159 */
147 } 160 waitq = bfa_reqq(bfa, qid);
161 if (!list_empty(waitq))
162 bfa_reqq_resume(bfa, qid);
148} 163}
149 164
150void 165void
@@ -158,26 +173,27 @@ bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m)
158} 173}
159 174
160void 175void
161bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid) 176bfa_msix_rspq(struct bfa_s *bfa, int qid)
162{ 177{
163 struct bfi_msg_s *m; 178 struct bfi_msg_s *m;
164 u32 pi, ci; 179 u32 pi, ci;
180 struct list_head *waitq;
165 181
166 bfa_trc_fp(bfa, rsp_qid); 182 bfa_trc_fp(bfa, qid);
167 183
168 rsp_qid &= (BFI_IOC_MAX_CQS - 1); 184 qid &= (BFI_IOC_MAX_CQS - 1);
169 185
170 bfa->iocfc.hwif.hw_rspq_ack(bfa, rsp_qid); 186 bfa->iocfc.hwif.hw_rspq_ack(bfa, qid);
171 187
172 ci = bfa_rspq_ci(bfa, rsp_qid); 188 ci = bfa_rspq_ci(bfa, qid);
173 pi = bfa_rspq_pi(bfa, rsp_qid); 189 pi = bfa_rspq_pi(bfa, qid);
174 190
175 bfa_trc_fp(bfa, ci); 191 bfa_trc_fp(bfa, ci);
176 bfa_trc_fp(bfa, pi); 192 bfa_trc_fp(bfa, pi);
177 193
178 if (bfa->rme_process) { 194 if (bfa->rme_process) {
179 while (ci != pi) { 195 while (ci != pi) {
180 m = bfa_rspq_elem(bfa, rsp_qid, ci); 196 m = bfa_rspq_elem(bfa, qid, ci);
181 bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX); 197 bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX);
182 198
183 bfa_isrs[m->mhdr.msg_class] (bfa, m); 199 bfa_isrs[m->mhdr.msg_class] (bfa, m);
@@ -189,9 +205,16 @@ bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid)
189 /** 205 /**
190 * update CI 206 * update CI
191 */ 207 */
192 bfa_rspq_ci(bfa, rsp_qid) = pi; 208 bfa_rspq_ci(bfa, qid) = pi;
193 bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[rsp_qid], pi); 209 bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[qid], pi);
194 bfa_os_mmiowb(); 210 bfa_os_mmiowb();
211
212 /**
213 * Resume any pending requests in the corresponding reqq.
214 */
215 waitq = bfa_reqq(bfa, qid);
216 if (!list_empty(waitq))
217 bfa_reqq_resume(bfa, qid);
195} 218}
196 219
197void 220void
diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c
index 137591c984d7..a5551db6dba6 100644
--- a/drivers/scsi/bfa/bfa_iocfc.c
+++ b/drivers/scsi/bfa/bfa_iocfc.c
@@ -172,6 +172,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
172 */ 172 */
173 if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) { 173 if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) {
174 iocfc->hwif.hw_reginit = bfa_hwct_reginit; 174 iocfc->hwif.hw_reginit = bfa_hwct_reginit;
175 iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack;
175 iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack; 176 iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack;
176 iocfc->hwif.hw_msix_init = bfa_hwct_msix_init; 177 iocfc->hwif.hw_msix_init = bfa_hwct_msix_init;
177 iocfc->hwif.hw_msix_install = bfa_hwct_msix_install; 178 iocfc->hwif.hw_msix_install = bfa_hwct_msix_install;
@@ -180,6 +181,7 @@ bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
180 iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs; 181 iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
181 } else { 182 } else {
182 iocfc->hwif.hw_reginit = bfa_hwcb_reginit; 183 iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
184 iocfc->hwif.hw_reqq_ack = bfa_hwcb_reqq_ack;
183 iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack; 185 iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
184 iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init; 186 iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
185 iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install; 187 iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install;
diff --git a/drivers/scsi/bfa/bfa_iocfc.h b/drivers/scsi/bfa/bfa_iocfc.h
index ce9a830a4207..fbb4bdc9d600 100644
--- a/drivers/scsi/bfa/bfa_iocfc.h
+++ b/drivers/scsi/bfa/bfa_iocfc.h
@@ -54,6 +54,7 @@ struct bfa_msix_s {
54 */ 54 */
55struct bfa_hwif_s { 55struct bfa_hwif_s {
56 void (*hw_reginit)(struct bfa_s *bfa); 56 void (*hw_reginit)(struct bfa_s *bfa);
57 void (*hw_reqq_ack)(struct bfa_s *bfa, int reqq);
57 void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq); 58 void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq);
58 void (*hw_msix_init)(struct bfa_s *bfa, int nvecs); 59 void (*hw_msix_init)(struct bfa_s *bfa, int nvecs);
59 void (*hw_msix_install)(struct bfa_s *bfa); 60 void (*hw_msix_install)(struct bfa_s *bfa);
@@ -143,6 +144,7 @@ void bfa_msix_rspq(struct bfa_s *bfa, int vec);
143void bfa_msix_lpu_err(struct bfa_s *bfa, int vec); 144void bfa_msix_lpu_err(struct bfa_s *bfa, int vec);
144 145
145void bfa_hwcb_reginit(struct bfa_s *bfa); 146void bfa_hwcb_reginit(struct bfa_s *bfa);
147void bfa_hwcb_reqq_ack(struct bfa_s *bfa, int rspq);
146void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq); 148void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq);
147void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs); 149void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs);
148void bfa_hwcb_msix_install(struct bfa_s *bfa); 150void bfa_hwcb_msix_install(struct bfa_s *bfa);
@@ -151,6 +153,7 @@ void bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix);
151void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap, 153void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap,
152 u32 *nvecs, u32 *maxvec); 154 u32 *nvecs, u32 *maxvec);
153void bfa_hwct_reginit(struct bfa_s *bfa); 155void bfa_hwct_reginit(struct bfa_s *bfa);
156void bfa_hwct_reqq_ack(struct bfa_s *bfa, int rspq);
154void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq); 157void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq);
155void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs); 158void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs);
156void bfa_hwct_msix_install(struct bfa_s *bfa); 159void bfa_hwct_msix_install(struct bfa_s *bfa);