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_cb_ioim_macros.h>
21 BFA_TRC_FILE(HAL
, TSKIM
);
24 * task management completion handling
26 #define bfa_tskim_qcomp(__tskim, __cbfn) do { \
27 bfa_cb_queue((__tskim)->bfa, &(__tskim)->hcb_qe, \
29 bfa_tskim_notify_comp(__tskim); \
32 #define bfa_tskim_notify_comp(__tskim) do { \
33 if ((__tskim)->notify) \
34 bfa_itnim_tskdone((__tskim)->itnim); \
38 * forward declarations
40 static void __bfa_cb_tskim_done(void *cbarg
, bfa_boolean_t complete
);
41 static void __bfa_cb_tskim_failed(void *cbarg
, bfa_boolean_t complete
);
42 static bfa_boolean_t
bfa_tskim_match_scope(struct bfa_tskim_s
*tskim
,
44 static void bfa_tskim_gather_ios(struct bfa_tskim_s
*tskim
);
45 static void bfa_tskim_cleanp_comp(void *tskim_cbarg
);
46 static void bfa_tskim_cleanup_ios(struct bfa_tskim_s
*tskim
);
47 static bfa_boolean_t
bfa_tskim_send(struct bfa_tskim_s
*tskim
);
48 static bfa_boolean_t
bfa_tskim_send_abort(struct bfa_tskim_s
*tskim
);
49 static void bfa_tskim_iocdisable_ios(struct bfa_tskim_s
*tskim
);
55 enum bfa_tskim_event
{
56 BFA_TSKIM_SM_START
= 1, /* TM command start */
57 BFA_TSKIM_SM_DONE
= 2, /* TM completion */
58 BFA_TSKIM_SM_QRESUME
= 3, /* resume after qfull */
59 BFA_TSKIM_SM_HWFAIL
= 5, /* IOC h/w failure event */
60 BFA_TSKIM_SM_HCB
= 6, /* BFA callback completion */
61 BFA_TSKIM_SM_IOS_DONE
= 7, /* IO and sub TM completions */
62 BFA_TSKIM_SM_CLEANUP
= 8, /* TM cleanup on ITN offline */
63 BFA_TSKIM_SM_CLEANUP_DONE
= 9, /* TM abort completion */
66 static void bfa_tskim_sm_uninit(struct bfa_tskim_s
*tskim
,
67 enum bfa_tskim_event event
);
68 static void bfa_tskim_sm_active(struct bfa_tskim_s
*tskim
,
69 enum bfa_tskim_event event
);
70 static void bfa_tskim_sm_cleanup(struct bfa_tskim_s
*tskim
,
71 enum bfa_tskim_event event
);
72 static void bfa_tskim_sm_iocleanup(struct bfa_tskim_s
*tskim
,
73 enum bfa_tskim_event event
);
74 static void bfa_tskim_sm_qfull(struct bfa_tskim_s
*tskim
,
75 enum bfa_tskim_event event
);
76 static void bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s
*tskim
,
77 enum bfa_tskim_event event
);
78 static void bfa_tskim_sm_hcb(struct bfa_tskim_s
*tskim
,
79 enum bfa_tskim_event event
);
82 * Task management command beginning state.
85 bfa_tskim_sm_uninit(struct bfa_tskim_s
*tskim
, enum bfa_tskim_event event
)
87 bfa_trc(tskim
->bfa
, event
);
90 case BFA_TSKIM_SM_START
:
91 bfa_sm_set_state(tskim
, bfa_tskim_sm_active
);
92 bfa_tskim_gather_ios(tskim
);
95 * If device is offline, do not send TM on wire. Just cleanup
96 * any pending IO requests and complete TM request.
98 if (!bfa_itnim_is_online(tskim
->itnim
)) {
99 bfa_sm_set_state(tskim
, bfa_tskim_sm_iocleanup
);
100 tskim
->tsk_status
= BFI_TSKIM_STS_OK
;
101 bfa_tskim_cleanup_ios(tskim
);
105 if (!bfa_tskim_send(tskim
)) {
106 bfa_sm_set_state(tskim
, bfa_tskim_sm_qfull
);
107 bfa_reqq_wait(tskim
->bfa
, tskim
->itnim
->reqq
,
113 bfa_sm_fault(tskim
->bfa
, event
);
119 * TM command is active, awaiting completion from firmware to
120 * cleanup IO requests in TM scope.
123 bfa_tskim_sm_active(struct bfa_tskim_s
*tskim
, enum bfa_tskim_event event
)
125 bfa_trc(tskim
->bfa
, event
);
128 case BFA_TSKIM_SM_DONE
:
129 bfa_sm_set_state(tskim
, bfa_tskim_sm_iocleanup
);
130 bfa_tskim_cleanup_ios(tskim
);
133 case BFA_TSKIM_SM_CLEANUP
:
134 bfa_sm_set_state(tskim
, bfa_tskim_sm_cleanup
);
135 if (!bfa_tskim_send_abort(tskim
)) {
136 bfa_sm_set_state(tskim
, bfa_tskim_sm_cleanup_qfull
);
137 bfa_reqq_wait(tskim
->bfa
, tskim
->itnim
->reqq
,
142 case BFA_TSKIM_SM_HWFAIL
:
143 bfa_sm_set_state(tskim
, bfa_tskim_sm_hcb
);
144 bfa_tskim_iocdisable_ios(tskim
);
145 bfa_tskim_qcomp(tskim
, __bfa_cb_tskim_failed
);
149 bfa_sm_fault(tskim
->bfa
, event
);
154 * An active TM is being cleaned up since ITN is offline. Awaiting cleanup
155 * completion event from firmware.
158 bfa_tskim_sm_cleanup(struct bfa_tskim_s
*tskim
, enum bfa_tskim_event event
)
160 bfa_trc(tskim
->bfa
, event
);
163 case BFA_TSKIM_SM_DONE
:
165 * Ignore and wait for ABORT completion from firmware.
169 case BFA_TSKIM_SM_CLEANUP_DONE
:
170 bfa_sm_set_state(tskim
, bfa_tskim_sm_iocleanup
);
171 bfa_tskim_cleanup_ios(tskim
);
174 case BFA_TSKIM_SM_HWFAIL
:
175 bfa_sm_set_state(tskim
, bfa_tskim_sm_hcb
);
176 bfa_tskim_iocdisable_ios(tskim
);
177 bfa_tskim_qcomp(tskim
, __bfa_cb_tskim_failed
);
181 bfa_sm_fault(tskim
->bfa
, event
);
186 bfa_tskim_sm_iocleanup(struct bfa_tskim_s
*tskim
, enum bfa_tskim_event event
)
188 bfa_trc(tskim
->bfa
, event
);
191 case BFA_TSKIM_SM_IOS_DONE
:
192 bfa_sm_set_state(tskim
, bfa_tskim_sm_hcb
);
193 bfa_tskim_qcomp(tskim
, __bfa_cb_tskim_done
);
196 case BFA_TSKIM_SM_CLEANUP
:
198 * Ignore, TM command completed on wire.
199 * Notify TM conmpletion on IO cleanup completion.
203 case BFA_TSKIM_SM_HWFAIL
:
204 bfa_sm_set_state(tskim
, bfa_tskim_sm_hcb
);
205 bfa_tskim_iocdisable_ios(tskim
);
206 bfa_tskim_qcomp(tskim
, __bfa_cb_tskim_failed
);
210 bfa_sm_fault(tskim
->bfa
, event
);
215 * Task management command is waiting for room in request CQ
218 bfa_tskim_sm_qfull(struct bfa_tskim_s
*tskim
, enum bfa_tskim_event event
)
220 bfa_trc(tskim
->bfa
, event
);
223 case BFA_TSKIM_SM_QRESUME
:
224 bfa_sm_set_state(tskim
, bfa_tskim_sm_active
);
225 bfa_tskim_send(tskim
);
228 case BFA_TSKIM_SM_CLEANUP
:
230 * No need to send TM on wire since ITN is offline.
232 bfa_sm_set_state(tskim
, bfa_tskim_sm_iocleanup
);
233 bfa_reqq_wcancel(&tskim
->reqq_wait
);
234 bfa_tskim_cleanup_ios(tskim
);
237 case BFA_TSKIM_SM_HWFAIL
:
238 bfa_sm_set_state(tskim
, bfa_tskim_sm_hcb
);
239 bfa_reqq_wcancel(&tskim
->reqq_wait
);
240 bfa_tskim_iocdisable_ios(tskim
);
241 bfa_tskim_qcomp(tskim
, __bfa_cb_tskim_failed
);
245 bfa_sm_fault(tskim
->bfa
, event
);
250 * Task management command is active, awaiting for room in request CQ
251 * to send clean up request.
254 bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s
*tskim
,
255 enum bfa_tskim_event event
)
257 bfa_trc(tskim
->bfa
, event
);
260 case BFA_TSKIM_SM_DONE
:
261 bfa_reqq_wcancel(&tskim
->reqq_wait
);
267 case BFA_TSKIM_SM_QRESUME
:
268 bfa_sm_set_state(tskim
, bfa_tskim_sm_cleanup
);
269 bfa_tskim_send_abort(tskim
);
272 case BFA_TSKIM_SM_HWFAIL
:
273 bfa_sm_set_state(tskim
, bfa_tskim_sm_hcb
);
274 bfa_reqq_wcancel(&tskim
->reqq_wait
);
275 bfa_tskim_iocdisable_ios(tskim
);
276 bfa_tskim_qcomp(tskim
, __bfa_cb_tskim_failed
);
280 bfa_sm_fault(tskim
->bfa
, event
);
285 * BFA callback is pending
288 bfa_tskim_sm_hcb(struct bfa_tskim_s
*tskim
, enum bfa_tskim_event event
)
290 bfa_trc(tskim
->bfa
, event
);
293 case BFA_TSKIM_SM_HCB
:
294 bfa_sm_set_state(tskim
, bfa_tskim_sm_uninit
);
295 bfa_tskim_free(tskim
);
298 case BFA_TSKIM_SM_CLEANUP
:
299 bfa_tskim_notify_comp(tskim
);
302 case BFA_TSKIM_SM_HWFAIL
:
306 bfa_sm_fault(tskim
->bfa
, event
);
317 __bfa_cb_tskim_done(void *cbarg
, bfa_boolean_t complete
)
319 struct bfa_tskim_s
*tskim
= cbarg
;
322 bfa_sm_send_event(tskim
, BFA_TSKIM_SM_HCB
);
326 bfa_stats(tskim
->itnim
, tm_success
);
327 bfa_cb_tskim_done(tskim
->bfa
->bfad
, tskim
->dtsk
, tskim
->tsk_status
);
331 __bfa_cb_tskim_failed(void *cbarg
, bfa_boolean_t complete
)
333 struct bfa_tskim_s
*tskim
= cbarg
;
336 bfa_sm_send_event(tskim
, BFA_TSKIM_SM_HCB
);
340 bfa_stats(tskim
->itnim
, tm_failures
);
341 bfa_cb_tskim_done(tskim
->bfa
->bfad
, tskim
->dtsk
,
342 BFI_TSKIM_STS_FAILED
);
346 bfa_tskim_match_scope(struct bfa_tskim_s
*tskim
, lun_t lun
)
348 switch (tskim
->tm_cmnd
) {
349 case FCP_TM_TARGET_RESET
:
352 case FCP_TM_ABORT_TASK_SET
:
353 case FCP_TM_CLEAR_TASK_SET
:
354 case FCP_TM_LUN_RESET
:
355 case FCP_TM_CLEAR_ACA
:
356 return (tskim
->lun
== lun
);
366 * Gather affected IO requests and task management commands.
369 bfa_tskim_gather_ios(struct bfa_tskim_s
*tskim
)
371 struct bfa_itnim_s
*itnim
= tskim
->itnim
;
372 struct bfa_ioim_s
*ioim
;
373 struct list_head
*qe
, *qen
;
375 INIT_LIST_HEAD(&tskim
->io_q
);
378 * Gather any active IO requests first.
380 list_for_each_safe(qe
, qen
, &itnim
->io_q
) {
381 ioim
= (struct bfa_ioim_s
*) qe
;
382 if (bfa_tskim_match_scope
383 (tskim
, bfa_cb_ioim_get_lun(ioim
->dio
))) {
385 list_add_tail(&ioim
->qe
, &tskim
->io_q
);
390 * Failback any pending IO requests immediately.
392 list_for_each_safe(qe
, qen
, &itnim
->pending_q
) {
393 ioim
= (struct bfa_ioim_s
*) qe
;
394 if (bfa_tskim_match_scope
395 (tskim
, bfa_cb_ioim_get_lun(ioim
->dio
))) {
397 list_add_tail(&ioim
->qe
, &ioim
->fcpim
->ioim_comp_q
);
404 * IO cleanup completion
407 bfa_tskim_cleanp_comp(void *tskim_cbarg
)
409 struct bfa_tskim_s
*tskim
= tskim_cbarg
;
411 bfa_stats(tskim
->itnim
, tm_io_comps
);
412 bfa_sm_send_event(tskim
, BFA_TSKIM_SM_IOS_DONE
);
416 * Gather affected IO requests and task management commands.
419 bfa_tskim_cleanup_ios(struct bfa_tskim_s
*tskim
)
421 struct bfa_ioim_s
*ioim
;
422 struct list_head
*qe
, *qen
;
424 bfa_wc_init(&tskim
->wc
, bfa_tskim_cleanp_comp
, tskim
);
426 list_for_each_safe(qe
, qen
, &tskim
->io_q
) {
427 ioim
= (struct bfa_ioim_s
*) qe
;
428 bfa_wc_up(&tskim
->wc
);
429 bfa_ioim_cleanup_tm(ioim
, tskim
);
432 bfa_wc_wait(&tskim
->wc
);
436 * Send task management request to firmware.
439 bfa_tskim_send(struct bfa_tskim_s
*tskim
)
441 struct bfa_itnim_s
*itnim
= tskim
->itnim
;
442 struct bfi_tskim_req_s
*m
;
445 * check for room in queue to send request now
447 m
= bfa_reqq_next(tskim
->bfa
, itnim
->reqq
);
452 * build i/o request message next
454 bfi_h2i_set(m
->mh
, BFI_MC_TSKIM
, BFI_TSKIM_H2I_TM_REQ
,
455 bfa_lpuid(tskim
->bfa
));
457 m
->tsk_tag
= bfa_os_htons(tskim
->tsk_tag
);
458 m
->itn_fhdl
= tskim
->itnim
->rport
->fw_handle
;
459 m
->t_secs
= tskim
->tsecs
;
461 m
->tm_flags
= tskim
->tm_cmnd
;
464 * queue I/O message to firmware
466 bfa_reqq_produce(tskim
->bfa
, itnim
->reqq
);
471 * Send abort request to cleanup an active TM to firmware.
474 bfa_tskim_send_abort(struct bfa_tskim_s
*tskim
)
476 struct bfa_itnim_s
*itnim
= tskim
->itnim
;
477 struct bfi_tskim_abortreq_s
*m
;
480 * check for room in queue to send request now
482 m
= bfa_reqq_next(tskim
->bfa
, itnim
->reqq
);
487 * build i/o request message next
489 bfi_h2i_set(m
->mh
, BFI_MC_TSKIM
, BFI_TSKIM_H2I_ABORT_REQ
,
490 bfa_lpuid(tskim
->bfa
));
492 m
->tsk_tag
= bfa_os_htons(tskim
->tsk_tag
);
495 * queue I/O message to firmware
497 bfa_reqq_produce(tskim
->bfa
, itnim
->reqq
);
502 * Call to resume task management cmnd waiting for room in request queue.
505 bfa_tskim_qresume(void *cbarg
)
507 struct bfa_tskim_s
*tskim
= cbarg
;
509 bfa_fcpim_stats(tskim
->fcpim
, qresumes
);
510 bfa_stats(tskim
->itnim
, tm_qresumes
);
511 bfa_sm_send_event(tskim
, BFA_TSKIM_SM_QRESUME
);
515 * Cleanup IOs associated with a task mangement command on IOC failures.
518 bfa_tskim_iocdisable_ios(struct bfa_tskim_s
*tskim
)
520 struct bfa_ioim_s
*ioim
;
521 struct list_head
*qe
, *qen
;
523 list_for_each_safe(qe
, qen
, &tskim
->io_q
) {
524 ioim
= (struct bfa_ioim_s
*) qe
;
525 bfa_ioim_iocdisable(ioim
);
536 * Notification on completions from related ioim.
539 bfa_tskim_iodone(struct bfa_tskim_s
*tskim
)
541 bfa_wc_down(&tskim
->wc
);
545 * Handle IOC h/w failure notification from itnim.
548 bfa_tskim_iocdisable(struct bfa_tskim_s
*tskim
)
550 tskim
->notify
= BFA_FALSE
;
551 bfa_stats(tskim
->itnim
, tm_iocdowns
);
552 bfa_sm_send_event(tskim
, BFA_TSKIM_SM_HWFAIL
);
556 * Cleanup TM command and associated IOs as part of ITNIM offline.
559 bfa_tskim_cleanup(struct bfa_tskim_s
*tskim
)
561 tskim
->notify
= BFA_TRUE
;
562 bfa_stats(tskim
->itnim
, tm_cleanups
);
563 bfa_sm_send_event(tskim
, BFA_TSKIM_SM_CLEANUP
);
567 * Memory allocation and initialization.
570 bfa_tskim_attach(struct bfa_fcpim_mod_s
*fcpim
, struct bfa_meminfo_s
*minfo
)
572 struct bfa_tskim_s
*tskim
;
575 INIT_LIST_HEAD(&fcpim
->tskim_free_q
);
577 tskim
= (struct bfa_tskim_s
*) bfa_meminfo_kva(minfo
);
578 fcpim
->tskim_arr
= tskim
;
580 for (i
= 0; i
< fcpim
->num_tskim_reqs
; i
++, tskim
++) {
584 bfa_os_memset(tskim
, 0, sizeof(struct bfa_tskim_s
));
586 tskim
->bfa
= fcpim
->bfa
;
587 tskim
->fcpim
= fcpim
;
588 tskim
->notify
= BFA_FALSE
;
589 bfa_reqq_winit(&tskim
->reqq_wait
, bfa_tskim_qresume
,
591 bfa_sm_set_state(tskim
, bfa_tskim_sm_uninit
);
593 list_add_tail(&tskim
->qe
, &fcpim
->tskim_free_q
);
596 bfa_meminfo_kva(minfo
) = (u8
*) tskim
;
600 bfa_tskim_detach(struct bfa_fcpim_mod_s
*fcpim
)
608 bfa_tskim_isr(struct bfa_s
*bfa
, struct bfi_msg_s
*m
)
610 struct bfa_fcpim_mod_s
*fcpim
= BFA_FCPIM_MOD(bfa
);
611 struct bfi_tskim_rsp_s
*rsp
= (struct bfi_tskim_rsp_s
*) m
;
612 struct bfa_tskim_s
*tskim
;
613 u16 tsk_tag
= bfa_os_ntohs(rsp
->tsk_tag
);
615 tskim
= BFA_TSKIM_FROM_TAG(fcpim
, tsk_tag
);
616 bfa_assert(tskim
->tsk_tag
== tsk_tag
);
618 tskim
->tsk_status
= rsp
->tsk_status
;
621 * Firmware sends BFI_TSKIM_STS_ABORTED status for abort
622 * requests. All other statuses are for normal completions.
624 if (rsp
->tsk_status
== BFI_TSKIM_STS_ABORTED
) {
625 bfa_stats(tskim
->itnim
, tm_cleanup_comps
);
626 bfa_sm_send_event(tskim
, BFA_TSKIM_SM_CLEANUP_DONE
);
628 bfa_stats(tskim
->itnim
, tm_fw_rsps
);
629 bfa_sm_send_event(tskim
, BFA_TSKIM_SM_DONE
);
641 bfa_tskim_alloc(struct bfa_s
*bfa
, struct bfad_tskim_s
*dtsk
)
643 struct bfa_fcpim_mod_s
*fcpim
= BFA_FCPIM_MOD(bfa
);
644 struct bfa_tskim_s
*tskim
;
646 bfa_q_deq(&fcpim
->tskim_free_q
, &tskim
);
649 bfa_fcpim_stats(fcpim
, no_tskims
);
657 bfa_tskim_free(struct bfa_tskim_s
*tskim
)
659 bfa_assert(bfa_q_is_on_q_func(&tskim
->itnim
->tsk_q
, &tskim
->qe
));
660 list_del(&tskim
->qe
);
661 list_add_tail(&tskim
->qe
, &tskim
->fcpim
->tskim_free_q
);
665 * Start a task management command.
667 * @param[in] tskim BFA task management command instance
668 * @param[in] itnim i-t nexus for the task management command
669 * @param[in] lun lun, if applicable
670 * @param[in] tm_cmnd Task management command code.
671 * @param[in] t_secs Timeout in seconds
676 bfa_tskim_start(struct bfa_tskim_s
*tskim
, struct bfa_itnim_s
*itnim
, lun_t lun
,
677 enum fcp_tm_cmnd tm_cmnd
, u8 tsecs
)
679 tskim
->itnim
= itnim
;
681 tskim
->tm_cmnd
= tm_cmnd
;
682 tskim
->tsecs
= tsecs
;
683 tskim
->notify
= BFA_FALSE
;
684 bfa_stats(itnim
, tm_cmnds
);
686 list_add_tail(&tskim
->qe
, &itnim
->tsk_q
);
687 bfa_sm_send_event(tskim
, BFA_TSKIM_SM_START
);