2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
19 #include <bfa_fcpim.h>
20 #include "bfa_fcpim_priv.h"
22 BFA_TRC_FILE(HAL
, ITNIM
);
24 #define BFA_ITNIM_FROM_TAG(_fcpim, _tag) \
25 ((_fcpim)->itnim_arr + ((_tag) & ((_fcpim)->num_itnims - 1)))
27 #define bfa_fcpim_additn(__itnim) \
28 list_add_tail(&(__itnim)->qe, &(__itnim)->fcpim->itnim_q)
29 #define bfa_fcpim_delitn(__itnim) do { \
30 bfa_assert(bfa_q_is_on_q(&(__itnim)->fcpim->itnim_q, __itnim)); \
31 list_del(&(__itnim)->qe); \
32 bfa_assert(list_empty(&(__itnim)->io_q)); \
33 bfa_assert(list_empty(&(__itnim)->io_cleanup_q)); \
34 bfa_assert(list_empty(&(__itnim)->pending_q)); \
37 #define bfa_itnim_online_cb(__itnim) do { \
38 if ((__itnim)->bfa->fcs) \
39 bfa_cb_itnim_online((__itnim)->ditn); \
41 bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \
42 __bfa_cb_itnim_online, (__itnim)); \
46 #define bfa_itnim_offline_cb(__itnim) do { \
47 if ((__itnim)->bfa->fcs) \
48 bfa_cb_itnim_offline((__itnim)->ditn); \
50 bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \
51 __bfa_cb_itnim_offline, (__itnim)); \
55 #define bfa_itnim_sler_cb(__itnim) do { \
56 if ((__itnim)->bfa->fcs) \
57 bfa_cb_itnim_sler((__itnim)->ditn); \
59 bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \
60 __bfa_cb_itnim_sler, (__itnim)); \
65 * forward declarations
67 static void bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s
*itnim
);
68 static bfa_boolean_t
bfa_itnim_send_fwcreate(struct bfa_itnim_s
*itnim
);
69 static bfa_boolean_t
bfa_itnim_send_fwdelete(struct bfa_itnim_s
*itnim
);
70 static void bfa_itnim_cleanp_comp(void *itnim_cbarg
);
71 static void bfa_itnim_cleanup(struct bfa_itnim_s
*itnim
);
72 static void __bfa_cb_itnim_online(void *cbarg
, bfa_boolean_t complete
);
73 static void __bfa_cb_itnim_offline(void *cbarg
, bfa_boolean_t complete
);
74 static void __bfa_cb_itnim_sler(void *cbarg
, bfa_boolean_t complete
);
75 static void bfa_itnim_iotov_online(struct bfa_itnim_s
*itnim
);
76 static void bfa_itnim_iotov_cleanup(struct bfa_itnim_s
*itnim
);
77 static void bfa_itnim_iotov(void *itnim_arg
);
78 static void bfa_itnim_iotov_start(struct bfa_itnim_s
*itnim
);
79 static void bfa_itnim_iotov_stop(struct bfa_itnim_s
*itnim
);
80 static void bfa_itnim_iotov_delete(struct bfa_itnim_s
*itnim
);
83 * bfa_itnim_sm BFA itnim state machine
87 enum bfa_itnim_event
{
88 BFA_ITNIM_SM_CREATE
= 1, /* itnim is created */
89 BFA_ITNIM_SM_ONLINE
= 2, /* itnim is online */
90 BFA_ITNIM_SM_OFFLINE
= 3, /* itnim is offline */
91 BFA_ITNIM_SM_FWRSP
= 4, /* firmware response */
92 BFA_ITNIM_SM_DELETE
= 5, /* deleting an existing itnim */
93 BFA_ITNIM_SM_CLEANUP
= 6, /* IO cleanup completion */
94 BFA_ITNIM_SM_SLER
= 7, /* second level error recovery */
95 BFA_ITNIM_SM_HWFAIL
= 8, /* IOC h/w failure event */
96 BFA_ITNIM_SM_QRESUME
= 9, /* queue space available */
99 static void bfa_itnim_sm_uninit(struct bfa_itnim_s
*itnim
,
100 enum bfa_itnim_event event
);
101 static void bfa_itnim_sm_created(struct bfa_itnim_s
*itnim
,
102 enum bfa_itnim_event event
);
103 static void bfa_itnim_sm_fwcreate(struct bfa_itnim_s
*itnim
,
104 enum bfa_itnim_event event
);
105 static void bfa_itnim_sm_delete_pending(struct bfa_itnim_s
*itnim
,
106 enum bfa_itnim_event event
);
107 static void bfa_itnim_sm_online(struct bfa_itnim_s
*itnim
,
108 enum bfa_itnim_event event
);
109 static void bfa_itnim_sm_sler(struct bfa_itnim_s
*itnim
,
110 enum bfa_itnim_event event
);
111 static void bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s
*itnim
,
112 enum bfa_itnim_event event
);
113 static void bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s
*itnim
,
114 enum bfa_itnim_event event
);
115 static void bfa_itnim_sm_fwdelete(struct bfa_itnim_s
*itnim
,
116 enum bfa_itnim_event event
);
117 static void bfa_itnim_sm_offline(struct bfa_itnim_s
*itnim
,
118 enum bfa_itnim_event event
);
119 static void bfa_itnim_sm_iocdisable(struct bfa_itnim_s
*itnim
,
120 enum bfa_itnim_event event
);
121 static void bfa_itnim_sm_deleting(struct bfa_itnim_s
*itnim
,
122 enum bfa_itnim_event event
);
123 static void bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s
*itnim
,
124 enum bfa_itnim_event event
);
125 static void bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s
*itnim
,
126 enum bfa_itnim_event event
);
127 static void bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s
*itnim
,
128 enum bfa_itnim_event event
);
131 * Beginning/unallocated state - no events expected.
134 bfa_itnim_sm_uninit(struct bfa_itnim_s
*itnim
, enum bfa_itnim_event event
)
136 bfa_trc(itnim
->bfa
, itnim
->rport
->rport_tag
);
137 bfa_trc(itnim
->bfa
, event
);
140 case BFA_ITNIM_SM_CREATE
:
141 bfa_sm_set_state(itnim
, bfa_itnim_sm_created
);
142 itnim
->is_online
= BFA_FALSE
;
143 bfa_fcpim_additn(itnim
);
147 bfa_sm_fault(itnim
->bfa
, event
);
152 * Beginning state, only online event expected.
155 bfa_itnim_sm_created(struct bfa_itnim_s
*itnim
, enum bfa_itnim_event event
)
157 bfa_trc(itnim
->bfa
, itnim
->rport
->rport_tag
);
158 bfa_trc(itnim
->bfa
, event
);
161 case BFA_ITNIM_SM_ONLINE
:
162 if (bfa_itnim_send_fwcreate(itnim
))
163 bfa_sm_set_state(itnim
, bfa_itnim_sm_fwcreate
);
165 bfa_sm_set_state(itnim
, bfa_itnim_sm_fwcreate_qfull
);
168 case BFA_ITNIM_SM_DELETE
:
169 bfa_sm_set_state(itnim
, bfa_itnim_sm_uninit
);
170 bfa_fcpim_delitn(itnim
);
173 case BFA_ITNIM_SM_HWFAIL
:
174 bfa_sm_set_state(itnim
, bfa_itnim_sm_iocdisable
);
178 bfa_sm_fault(itnim
->bfa
, event
);
183 * Waiting for itnim create response from firmware.
186 bfa_itnim_sm_fwcreate(struct bfa_itnim_s
*itnim
, enum bfa_itnim_event event
)
188 bfa_trc(itnim
->bfa
, itnim
->rport
->rport_tag
);
189 bfa_trc(itnim
->bfa
, event
);
192 case BFA_ITNIM_SM_FWRSP
:
193 bfa_sm_set_state(itnim
, bfa_itnim_sm_online
);
194 itnim
->is_online
= BFA_TRUE
;
195 bfa_itnim_iotov_online(itnim
);
196 bfa_itnim_online_cb(itnim
);
199 case BFA_ITNIM_SM_DELETE
:
200 bfa_sm_set_state(itnim
, bfa_itnim_sm_delete_pending
);
203 case BFA_ITNIM_SM_OFFLINE
:
204 if (bfa_itnim_send_fwdelete(itnim
))
205 bfa_sm_set_state(itnim
, bfa_itnim_sm_fwdelete
);
207 bfa_sm_set_state(itnim
, bfa_itnim_sm_fwdelete_qfull
);
210 case BFA_ITNIM_SM_HWFAIL
:
211 bfa_sm_set_state(itnim
, bfa_itnim_sm_iocdisable
);
215 bfa_sm_fault(itnim
->bfa
, event
);
220 bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s
*itnim
,
221 enum bfa_itnim_event event
)
223 bfa_trc(itnim
->bfa
, itnim
->rport
->rport_tag
);
224 bfa_trc(itnim
->bfa
, event
);
227 case BFA_ITNIM_SM_QRESUME
:
228 bfa_sm_set_state(itnim
, bfa_itnim_sm_fwcreate
);
229 bfa_itnim_send_fwcreate(itnim
);
232 case BFA_ITNIM_SM_DELETE
:
233 bfa_sm_set_state(itnim
, bfa_itnim_sm_uninit
);
234 bfa_reqq_wcancel(&itnim
->reqq_wait
);
235 bfa_fcpim_delitn(itnim
);
238 case BFA_ITNIM_SM_OFFLINE
:
239 bfa_sm_set_state(itnim
, bfa_itnim_sm_offline
);
240 bfa_reqq_wcancel(&itnim
->reqq_wait
);
241 bfa_itnim_offline_cb(itnim
);
244 case BFA_ITNIM_SM_HWFAIL
:
245 bfa_sm_set_state(itnim
, bfa_itnim_sm_iocdisable
);
246 bfa_reqq_wcancel(&itnim
->reqq_wait
);
250 bfa_sm_fault(itnim
->bfa
, event
);
255 * Waiting for itnim create response from firmware, a delete is pending.
258 bfa_itnim_sm_delete_pending(struct bfa_itnim_s
*itnim
,
259 enum bfa_itnim_event event
)
261 bfa_trc(itnim
->bfa
, itnim
->rport
->rport_tag
);
262 bfa_trc(itnim
->bfa
, event
);
265 case BFA_ITNIM_SM_FWRSP
:
266 if (bfa_itnim_send_fwdelete(itnim
))
267 bfa_sm_set_state(itnim
, bfa_itnim_sm_deleting
);
269 bfa_sm_set_state(itnim
, bfa_itnim_sm_deleting_qfull
);
272 case BFA_ITNIM_SM_HWFAIL
:
273 bfa_sm_set_state(itnim
, bfa_itnim_sm_uninit
);
274 bfa_fcpim_delitn(itnim
);
278 bfa_sm_fault(itnim
->bfa
, event
);
283 * Online state - normal parking state.
286 bfa_itnim_sm_online(struct bfa_itnim_s
*itnim
, enum bfa_itnim_event event
)
288 bfa_trc(itnim
->bfa
, itnim
->rport
->rport_tag
);
289 bfa_trc(itnim
->bfa
, event
);
292 case BFA_ITNIM_SM_OFFLINE
:
293 bfa_sm_set_state(itnim
, bfa_itnim_sm_cleanup_offline
);
294 itnim
->is_online
= BFA_FALSE
;
295 bfa_itnim_iotov_start(itnim
);
296 bfa_itnim_cleanup(itnim
);
299 case BFA_ITNIM_SM_DELETE
:
300 bfa_sm_set_state(itnim
, bfa_itnim_sm_cleanup_delete
);
301 itnim
->is_online
= BFA_FALSE
;
302 bfa_itnim_cleanup(itnim
);
305 case BFA_ITNIM_SM_SLER
:
306 bfa_sm_set_state(itnim
, bfa_itnim_sm_sler
);
307 itnim
->is_online
= BFA_FALSE
;
308 bfa_itnim_iotov_start(itnim
);
309 bfa_itnim_sler_cb(itnim
);
312 case BFA_ITNIM_SM_HWFAIL
:
313 bfa_sm_set_state(itnim
, bfa_itnim_sm_iocdisable
);
314 itnim
->is_online
= BFA_FALSE
;
315 bfa_itnim_iotov_start(itnim
);
316 bfa_itnim_iocdisable_cleanup(itnim
);
320 bfa_sm_fault(itnim
->bfa
, event
);
325 * Second level error recovery need.
328 bfa_itnim_sm_sler(struct bfa_itnim_s
*itnim
, enum bfa_itnim_event event
)
330 bfa_trc(itnim
->bfa
, itnim
->rport
->rport_tag
);
331 bfa_trc(itnim
->bfa
, event
);
334 case BFA_ITNIM_SM_OFFLINE
:
335 bfa_sm_set_state(itnim
, bfa_itnim_sm_cleanup_offline
);
336 bfa_itnim_cleanup(itnim
);
339 case BFA_ITNIM_SM_DELETE
:
340 bfa_sm_set_state(itnim
, bfa_itnim_sm_cleanup_delete
);
341 bfa_itnim_cleanup(itnim
);
342 bfa_itnim_iotov_delete(itnim
);
345 case BFA_ITNIM_SM_HWFAIL
:
346 bfa_sm_set_state(itnim
, bfa_itnim_sm_iocdisable
);
347 bfa_itnim_iocdisable_cleanup(itnim
);
351 bfa_sm_fault(itnim
->bfa
, event
);
356 * Going offline. Waiting for active IO cleanup.
359 bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s
*itnim
,
360 enum bfa_itnim_event event
)
362 bfa_trc(itnim
->bfa
, itnim
->rport
->rport_tag
);
363 bfa_trc(itnim
->bfa
, event
);
366 case BFA_ITNIM_SM_CLEANUP
:
367 if (bfa_itnim_send_fwdelete(itnim
))
368 bfa_sm_set_state(itnim
, bfa_itnim_sm_fwdelete
);
370 bfa_sm_set_state(itnim
, bfa_itnim_sm_fwdelete_qfull
);
373 case BFA_ITNIM_SM_DELETE
:
374 bfa_sm_set_state(itnim
, bfa_itnim_sm_cleanup_delete
);
375 bfa_itnim_iotov_delete(itnim
);
378 case BFA_ITNIM_SM_HWFAIL
:
379 bfa_sm_set_state(itnim
, bfa_itnim_sm_iocdisable
);
380 bfa_itnim_iocdisable_cleanup(itnim
);
381 bfa_itnim_offline_cb(itnim
);
384 case BFA_ITNIM_SM_SLER
:
388 bfa_sm_fault(itnim
->bfa
, event
);
393 * Deleting itnim. Waiting for active IO cleanup.
396 bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s
*itnim
,
397 enum bfa_itnim_event event
)
399 bfa_trc(itnim
->bfa
, itnim
->rport
->rport_tag
);
400 bfa_trc(itnim
->bfa
, event
);
403 case BFA_ITNIM_SM_CLEANUP
:
404 if (bfa_itnim_send_fwdelete(itnim
))
405 bfa_sm_set_state(itnim
, bfa_itnim_sm_deleting
);
407 bfa_sm_set_state(itnim
, bfa_itnim_sm_deleting_qfull
);
410 case BFA_ITNIM_SM_HWFAIL
:
411 bfa_sm_set_state(itnim
, bfa_itnim_sm_iocdisable
);
412 bfa_itnim_iocdisable_cleanup(itnim
);
416 bfa_sm_fault(itnim
->bfa
, event
);
421 * Rport offline. Fimrware itnim is being deleted - awaiting f/w response.
424 bfa_itnim_sm_fwdelete(struct bfa_itnim_s
*itnim
, enum bfa_itnim_event event
)
426 bfa_trc(itnim
->bfa
, itnim
->rport
->rport_tag
);
427 bfa_trc(itnim
->bfa
, event
);
430 case BFA_ITNIM_SM_FWRSP
:
431 bfa_sm_set_state(itnim
, bfa_itnim_sm_offline
);
432 bfa_itnim_offline_cb(itnim
);
435 case BFA_ITNIM_SM_DELETE
:
436 bfa_sm_set_state(itnim
, bfa_itnim_sm_deleting
);
439 case BFA_ITNIM_SM_HWFAIL
:
440 bfa_sm_set_state(itnim
, bfa_itnim_sm_iocdisable
);
441 bfa_itnim_offline_cb(itnim
);
445 bfa_sm_fault(itnim
->bfa
, event
);
450 bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s
*itnim
,
451 enum bfa_itnim_event event
)
453 bfa_trc(itnim
->bfa
, itnim
->rport
->rport_tag
);
454 bfa_trc(itnim
->bfa
, event
);
457 case BFA_ITNIM_SM_QRESUME
:
458 bfa_sm_set_state(itnim
, bfa_itnim_sm_fwdelete
);
459 bfa_itnim_send_fwdelete(itnim
);
462 case BFA_ITNIM_SM_DELETE
:
463 bfa_sm_set_state(itnim
, bfa_itnim_sm_deleting_qfull
);
466 case BFA_ITNIM_SM_HWFAIL
:
467 bfa_sm_set_state(itnim
, bfa_itnim_sm_iocdisable
);
468 bfa_reqq_wcancel(&itnim
->reqq_wait
);
469 bfa_itnim_offline_cb(itnim
);
473 bfa_sm_fault(itnim
->bfa
, event
);
481 bfa_itnim_sm_offline(struct bfa_itnim_s
*itnim
, enum bfa_itnim_event event
)
483 bfa_trc(itnim
->bfa
, itnim
->rport
->rport_tag
);
484 bfa_trc(itnim
->bfa
, event
);
487 case BFA_ITNIM_SM_DELETE
:
488 bfa_sm_set_state(itnim
, bfa_itnim_sm_uninit
);
489 bfa_itnim_iotov_delete(itnim
);
490 bfa_fcpim_delitn(itnim
);
493 case BFA_ITNIM_SM_ONLINE
:
494 if (bfa_itnim_send_fwcreate(itnim
))
495 bfa_sm_set_state(itnim
, bfa_itnim_sm_fwcreate
);
497 bfa_sm_set_state(itnim
, bfa_itnim_sm_fwcreate_qfull
);
500 case BFA_ITNIM_SM_HWFAIL
:
501 bfa_sm_set_state(itnim
, bfa_itnim_sm_iocdisable
);
505 bfa_sm_fault(itnim
->bfa
, event
);
510 * IOC h/w failed state.
513 bfa_itnim_sm_iocdisable(struct bfa_itnim_s
*itnim
,
514 enum bfa_itnim_event event
)
516 bfa_trc(itnim
->bfa
, itnim
->rport
->rport_tag
);
517 bfa_trc(itnim
->bfa
, event
);
520 case BFA_ITNIM_SM_DELETE
:
521 bfa_sm_set_state(itnim
, bfa_itnim_sm_uninit
);
522 bfa_itnim_iotov_delete(itnim
);
523 bfa_fcpim_delitn(itnim
);
526 case BFA_ITNIM_SM_OFFLINE
:
527 bfa_itnim_offline_cb(itnim
);
530 case BFA_ITNIM_SM_ONLINE
:
531 if (bfa_itnim_send_fwcreate(itnim
))
532 bfa_sm_set_state(itnim
, bfa_itnim_sm_fwcreate
);
534 bfa_sm_set_state(itnim
, bfa_itnim_sm_fwcreate_qfull
);
537 case BFA_ITNIM_SM_HWFAIL
:
541 bfa_sm_fault(itnim
->bfa
, event
);
546 * Itnim is deleted, waiting for firmware response to delete.
549 bfa_itnim_sm_deleting(struct bfa_itnim_s
*itnim
, enum bfa_itnim_event event
)
551 bfa_trc(itnim
->bfa
, itnim
->rport
->rport_tag
);
552 bfa_trc(itnim
->bfa
, event
);
555 case BFA_ITNIM_SM_FWRSP
:
556 case BFA_ITNIM_SM_HWFAIL
:
557 bfa_sm_set_state(itnim
, bfa_itnim_sm_uninit
);
558 bfa_fcpim_delitn(itnim
);
562 bfa_sm_fault(itnim
->bfa
, event
);
567 bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s
*itnim
,
568 enum bfa_itnim_event event
)
570 bfa_trc(itnim
->bfa
, itnim
->rport
->rport_tag
);
571 bfa_trc(itnim
->bfa
, event
);
574 case BFA_ITNIM_SM_QRESUME
:
575 bfa_sm_set_state(itnim
, bfa_itnim_sm_deleting
);
576 bfa_itnim_send_fwdelete(itnim
);
579 case BFA_ITNIM_SM_HWFAIL
:
580 bfa_sm_set_state(itnim
, bfa_itnim_sm_uninit
);
581 bfa_reqq_wcancel(&itnim
->reqq_wait
);
582 bfa_fcpim_delitn(itnim
);
586 bfa_sm_fault(itnim
->bfa
, event
);
597 * Initiate cleanup of all IOs on an IOC failure.
600 bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s
*itnim
)
602 struct bfa_tskim_s
*tskim
;
603 struct bfa_ioim_s
*ioim
;
604 struct list_head
*qe
, *qen
;
606 list_for_each_safe(qe
, qen
, &itnim
->tsk_q
) {
607 tskim
= (struct bfa_tskim_s
*) qe
;
608 bfa_tskim_iocdisable(tskim
);
611 list_for_each_safe(qe
, qen
, &itnim
->io_q
) {
612 ioim
= (struct bfa_ioim_s
*) qe
;
613 bfa_ioim_iocdisable(ioim
);
617 * For IO request in pending queue, we pretend an early timeout.
619 list_for_each_safe(qe
, qen
, &itnim
->pending_q
) {
620 ioim
= (struct bfa_ioim_s
*) qe
;
624 list_for_each_safe(qe
, qen
, &itnim
->io_cleanup_q
) {
625 ioim
= (struct bfa_ioim_s
*) qe
;
626 bfa_ioim_iocdisable(ioim
);
631 * IO cleanup completion
634 bfa_itnim_cleanp_comp(void *itnim_cbarg
)
636 struct bfa_itnim_s
*itnim
= itnim_cbarg
;
638 bfa_stats(itnim
, cleanup_comps
);
639 bfa_sm_send_event(itnim
, BFA_ITNIM_SM_CLEANUP
);
643 * Initiate cleanup of all IOs.
646 bfa_itnim_cleanup(struct bfa_itnim_s
*itnim
)
648 struct bfa_ioim_s
*ioim
;
649 struct bfa_tskim_s
*tskim
;
650 struct list_head
*qe
, *qen
;
652 bfa_wc_init(&itnim
->wc
, bfa_itnim_cleanp_comp
, itnim
);
654 list_for_each_safe(qe
, qen
, &itnim
->io_q
) {
655 ioim
= (struct bfa_ioim_s
*) qe
;
658 * Move IO to a cleanup queue from active queue so that a later
659 * TM will not pickup this IO.
662 list_add_tail(&ioim
->qe
, &itnim
->io_cleanup_q
);
664 bfa_wc_up(&itnim
->wc
);
665 bfa_ioim_cleanup(ioim
);
668 list_for_each_safe(qe
, qen
, &itnim
->tsk_q
) {
669 tskim
= (struct bfa_tskim_s
*) qe
;
670 bfa_wc_up(&itnim
->wc
);
671 bfa_tskim_cleanup(tskim
);
674 bfa_wc_wait(&itnim
->wc
);
678 __bfa_cb_itnim_online(void *cbarg
, bfa_boolean_t complete
)
680 struct bfa_itnim_s
*itnim
= cbarg
;
683 bfa_cb_itnim_online(itnim
->ditn
);
687 __bfa_cb_itnim_offline(void *cbarg
, bfa_boolean_t complete
)
689 struct bfa_itnim_s
*itnim
= cbarg
;
692 bfa_cb_itnim_offline(itnim
->ditn
);
696 __bfa_cb_itnim_sler(void *cbarg
, bfa_boolean_t complete
)
698 struct bfa_itnim_s
*itnim
= cbarg
;
701 bfa_cb_itnim_sler(itnim
->ditn
);
705 * Call to resume any I/O requests waiting for room in request queue.
708 bfa_itnim_qresume(void *cbarg
)
710 struct bfa_itnim_s
*itnim
= cbarg
;
712 bfa_sm_send_event(itnim
, BFA_ITNIM_SM_QRESUME
);
723 bfa_itnim_iodone(struct bfa_itnim_s
*itnim
)
725 bfa_wc_down(&itnim
->wc
);
729 bfa_itnim_tskdone(struct bfa_itnim_s
*itnim
)
731 bfa_wc_down(&itnim
->wc
);
735 bfa_itnim_meminfo(struct bfa_iocfc_cfg_s
*cfg
, u32
*km_len
,
741 *km_len
+= cfg
->fwcfg
.num_rports
* sizeof(struct bfa_itnim_s
);
745 bfa_itnim_attach(struct bfa_fcpim_mod_s
*fcpim
, struct bfa_meminfo_s
*minfo
)
747 struct bfa_s
*bfa
= fcpim
->bfa
;
748 struct bfa_itnim_s
*itnim
;
751 INIT_LIST_HEAD(&fcpim
->itnim_q
);
753 itnim
= (struct bfa_itnim_s
*) bfa_meminfo_kva(minfo
);
754 fcpim
->itnim_arr
= itnim
;
756 for (i
= 0; i
< fcpim
->num_itnims
; i
++, itnim
++) {
757 bfa_os_memset(itnim
, 0, sizeof(struct bfa_itnim_s
));
759 itnim
->fcpim
= fcpim
;
760 itnim
->reqq
= BFA_REQQ_QOS_LO
;
761 itnim
->rport
= BFA_RPORT_FROM_TAG(bfa
, i
);
762 itnim
->iotov_active
= BFA_FALSE
;
763 bfa_reqq_winit(&itnim
->reqq_wait
, bfa_itnim_qresume
, itnim
);
765 INIT_LIST_HEAD(&itnim
->io_q
);
766 INIT_LIST_HEAD(&itnim
->io_cleanup_q
);
767 INIT_LIST_HEAD(&itnim
->pending_q
);
768 INIT_LIST_HEAD(&itnim
->tsk_q
);
769 INIT_LIST_HEAD(&itnim
->delay_comp_q
);
770 bfa_sm_set_state(itnim
, bfa_itnim_sm_uninit
);
773 bfa_meminfo_kva(minfo
) = (u8
*) itnim
;
777 bfa_itnim_iocdisable(struct bfa_itnim_s
*itnim
)
779 bfa_stats(itnim
, ioc_disabled
);
780 bfa_sm_send_event(itnim
, BFA_ITNIM_SM_HWFAIL
);
784 bfa_itnim_send_fwcreate(struct bfa_itnim_s
*itnim
)
786 struct bfi_itnim_create_req_s
*m
;
791 * check for room in queue to send request now
793 m
= bfa_reqq_next(itnim
->bfa
, itnim
->reqq
);
795 bfa_reqq_wait(itnim
->bfa
, itnim
->reqq
, &itnim
->reqq_wait
);
799 bfi_h2i_set(m
->mh
, BFI_MC_ITNIM
, BFI_ITNIM_H2I_CREATE_REQ
,
800 bfa_lpuid(itnim
->bfa
));
801 m
->fw_handle
= itnim
->rport
->fw_handle
;
802 m
->class = FC_CLASS_3
;
803 m
->seq_rec
= itnim
->seq_rec
;
804 m
->msg_no
= itnim
->msg_no
;
807 * queue I/O message to firmware
809 bfa_reqq_produce(itnim
->bfa
, itnim
->reqq
);
814 bfa_itnim_send_fwdelete(struct bfa_itnim_s
*itnim
)
816 struct bfi_itnim_delete_req_s
*m
;
819 * check for room in queue to send request now
821 m
= bfa_reqq_next(itnim
->bfa
, itnim
->reqq
);
823 bfa_reqq_wait(itnim
->bfa
, itnim
->reqq
, &itnim
->reqq_wait
);
827 bfi_h2i_set(m
->mh
, BFI_MC_ITNIM
, BFI_ITNIM_H2I_DELETE_REQ
,
828 bfa_lpuid(itnim
->bfa
));
829 m
->fw_handle
= itnim
->rport
->fw_handle
;
832 * queue I/O message to firmware
834 bfa_reqq_produce(itnim
->bfa
, itnim
->reqq
);
839 * Cleanup all pending failed inflight requests.
842 bfa_itnim_delayed_comp(struct bfa_itnim_s
*itnim
, bfa_boolean_t iotov
)
844 struct bfa_ioim_s
*ioim
;
845 struct list_head
*qe
, *qen
;
847 list_for_each_safe(qe
, qen
, &itnim
->delay_comp_q
) {
848 ioim
= (struct bfa_ioim_s
*)qe
;
849 bfa_ioim_delayed_comp(ioim
, iotov
);
854 * Start all pending IO requests.
857 bfa_itnim_iotov_online(struct bfa_itnim_s
*itnim
)
859 struct bfa_ioim_s
*ioim
;
861 bfa_itnim_iotov_stop(itnim
);
864 * Abort all inflight IO requests in the queue
866 bfa_itnim_delayed_comp(itnim
, BFA_FALSE
);
869 * Start all pending IO requests.
871 while (!list_empty(&itnim
->pending_q
)) {
872 bfa_q_deq(&itnim
->pending_q
, &ioim
);
873 list_add_tail(&ioim
->qe
, &itnim
->io_q
);
874 bfa_ioim_start(ioim
);
879 * Fail all pending IO requests
882 bfa_itnim_iotov_cleanup(struct bfa_itnim_s
*itnim
)
884 struct bfa_ioim_s
*ioim
;
887 * Fail all inflight IO requests in the queue
889 bfa_itnim_delayed_comp(itnim
, BFA_TRUE
);
892 * Fail any pending IO requests.
894 while (!list_empty(&itnim
->pending_q
)) {
895 bfa_q_deq(&itnim
->pending_q
, &ioim
);
896 list_add_tail(&ioim
->qe
, &ioim
->fcpim
->ioim_comp_q
);
902 * IO TOV timer callback. Fail any pending IO requests.
905 bfa_itnim_iotov(void *itnim_arg
)
907 struct bfa_itnim_s
*itnim
= itnim_arg
;
909 itnim
->iotov_active
= BFA_FALSE
;
911 bfa_cb_itnim_tov_begin(itnim
->ditn
);
912 bfa_itnim_iotov_cleanup(itnim
);
913 bfa_cb_itnim_tov(itnim
->ditn
);
917 * Start IO TOV timer for failing back pending IO requests in offline state.
920 bfa_itnim_iotov_start(struct bfa_itnim_s
*itnim
)
922 if (itnim
->fcpim
->path_tov
> 0) {
924 itnim
->iotov_active
= BFA_TRUE
;
925 bfa_assert(bfa_itnim_hold_io(itnim
));
926 bfa_timer_start(itnim
->bfa
, &itnim
->timer
,
927 bfa_itnim_iotov
, itnim
, itnim
->fcpim
->path_tov
);
935 bfa_itnim_iotov_stop(struct bfa_itnim_s
*itnim
)
937 if (itnim
->iotov_active
) {
938 itnim
->iotov_active
= BFA_FALSE
;
939 bfa_timer_stop(&itnim
->timer
);
947 bfa_itnim_iotov_delete(struct bfa_itnim_s
*itnim
)
949 bfa_boolean_t pathtov_active
= BFA_FALSE
;
951 if (itnim
->iotov_active
)
952 pathtov_active
= BFA_TRUE
;
954 bfa_itnim_iotov_stop(itnim
);
956 bfa_cb_itnim_tov_begin(itnim
->ditn
);
957 bfa_itnim_iotov_cleanup(itnim
);
959 bfa_cb_itnim_tov(itnim
->ditn
);
969 * Itnim interrupt processing.
972 bfa_itnim_isr(struct bfa_s
*bfa
, struct bfi_msg_s
*m
)
974 struct bfa_fcpim_mod_s
*fcpim
= BFA_FCPIM_MOD(bfa
);
975 union bfi_itnim_i2h_msg_u msg
;
976 struct bfa_itnim_s
*itnim
;
978 bfa_trc(bfa
, m
->mhdr
.msg_id
);
982 switch (m
->mhdr
.msg_id
) {
983 case BFI_ITNIM_I2H_CREATE_RSP
:
984 itnim
= BFA_ITNIM_FROM_TAG(fcpim
,
985 msg
.create_rsp
->bfa_handle
);
986 bfa_assert(msg
.create_rsp
->status
== BFA_STATUS_OK
);
987 bfa_stats(itnim
, create_comps
);
988 bfa_sm_send_event(itnim
, BFA_ITNIM_SM_FWRSP
);
991 case BFI_ITNIM_I2H_DELETE_RSP
:
992 itnim
= BFA_ITNIM_FROM_TAG(fcpim
,
993 msg
.delete_rsp
->bfa_handle
);
994 bfa_assert(msg
.delete_rsp
->status
== BFA_STATUS_OK
);
995 bfa_stats(itnim
, delete_comps
);
996 bfa_sm_send_event(itnim
, BFA_ITNIM_SM_FWRSP
);
999 case BFI_ITNIM_I2H_SLER_EVENT
:
1000 itnim
= BFA_ITNIM_FROM_TAG(fcpim
,
1001 msg
.sler_event
->bfa_handle
);
1002 bfa_stats(itnim
, sler_events
);
1003 bfa_sm_send_event(itnim
, BFA_ITNIM_SM_SLER
);
1007 bfa_trc(bfa
, m
->mhdr
.msg_id
);
1018 struct bfa_itnim_s
*
1019 bfa_itnim_create(struct bfa_s
*bfa
, struct bfa_rport_s
*rport
, void *ditn
)
1021 struct bfa_fcpim_mod_s
*fcpim
= BFA_FCPIM_MOD(bfa
);
1022 struct bfa_itnim_s
*itnim
;
1024 itnim
= BFA_ITNIM_FROM_TAG(fcpim
, rport
->rport_tag
);
1025 bfa_assert(itnim
->rport
== rport
);
1029 bfa_stats(itnim
, creates
);
1030 bfa_sm_send_event(itnim
, BFA_ITNIM_SM_CREATE
);
1036 bfa_itnim_delete(struct bfa_itnim_s
*itnim
)
1038 bfa_stats(itnim
, deletes
);
1039 bfa_sm_send_event(itnim
, BFA_ITNIM_SM_DELETE
);
1043 bfa_itnim_online(struct bfa_itnim_s
*itnim
, bfa_boolean_t seq_rec
)
1045 itnim
->seq_rec
= seq_rec
;
1046 bfa_stats(itnim
, onlines
);
1047 bfa_sm_send_event(itnim
, BFA_ITNIM_SM_ONLINE
);
1051 bfa_itnim_offline(struct bfa_itnim_s
*itnim
)
1053 bfa_stats(itnim
, offlines
);
1054 bfa_sm_send_event(itnim
, BFA_ITNIM_SM_OFFLINE
);
1058 * Return true if itnim is considered offline for holding off IO request.
1059 * IO is not held if itnim is being deleted.
1062 bfa_itnim_hold_io(struct bfa_itnim_s
*itnim
)
1065 itnim
->fcpim
->path_tov
&& itnim
->iotov_active
&&
1066 (bfa_sm_cmp_state(itnim
, bfa_itnim_sm_fwcreate
) ||
1067 bfa_sm_cmp_state(itnim
, bfa_itnim_sm_sler
) ||
1068 bfa_sm_cmp_state(itnim
, bfa_itnim_sm_cleanup_offline
) ||
1069 bfa_sm_cmp_state(itnim
, bfa_itnim_sm_fwdelete
) ||
1070 bfa_sm_cmp_state(itnim
, bfa_itnim_sm_offline
) ||
1071 bfa_sm_cmp_state(itnim
, bfa_itnim_sm_iocdisable
))
1076 bfa_itnim_get_stats(struct bfa_itnim_s
*itnim
,
1077 struct bfa_itnim_hal_stats_s
*stats
)
1079 *stats
= itnim
->stats
;
1083 bfa_itnim_clear_stats(struct bfa_itnim_s
*itnim
)
1085 bfa_os_memset(&itnim
->stats
, 0, sizeof(itnim
->stats
));