Merge branch 'master' into for-next
[linux-flexiantxendom0-natty.git] / drivers / scsi / bfa / bfa_fcpim.c
1 /*
2  * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
3  * All rights reserved
4  * www.brocade.com
5  *
6  * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7  *
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
11  *
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.
16  */
17
18 #include "bfa_modules.h"
19 #include "bfa_cb_ioim.h"
20
21 BFA_TRC_FILE(HAL, FCPIM);
22 BFA_MODULE(fcpim);
23
24
25 #define bfa_fcpim_add_iostats(__l, __r, __stats)        \
26         (__l->__stats += __r->__stats)
27
28
29 /*
30  *  BFA ITNIM Related definitions
31  */
32 static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim);
33
34 #define BFA_ITNIM_FROM_TAG(_fcpim, _tag)                                \
35         (((_fcpim)->itnim_arr + ((_tag) & ((_fcpim)->num_itnims - 1))))
36
37 #define bfa_fcpim_additn(__itnim)                                       \
38         list_add_tail(&(__itnim)->qe, &(__itnim)->fcpim->itnim_q)
39 #define bfa_fcpim_delitn(__itnim)       do {                            \
40         bfa_assert(bfa_q_is_on_q(&(__itnim)->fcpim->itnim_q, __itnim));      \
41         bfa_itnim_update_del_itn_stats(__itnim);      \
42         list_del(&(__itnim)->qe);      \
43         bfa_assert(list_empty(&(__itnim)->io_q));      \
44         bfa_assert(list_empty(&(__itnim)->io_cleanup_q));      \
45         bfa_assert(list_empty(&(__itnim)->pending_q));      \
46 } while (0)
47
48 #define bfa_itnim_online_cb(__itnim) do {                               \
49         if ((__itnim)->bfa->fcs)                                        \
50                 bfa_cb_itnim_online((__itnim)->ditn);      \
51         else {                                                          \
52                 bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe,        \
53                 __bfa_cb_itnim_online, (__itnim));      \
54         }                                                               \
55 } while (0)
56
57 #define bfa_itnim_offline_cb(__itnim) do {                              \
58         if ((__itnim)->bfa->fcs)                                        \
59                 bfa_cb_itnim_offline((__itnim)->ditn);      \
60         else {                                                          \
61                 bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe,        \
62                 __bfa_cb_itnim_offline, (__itnim));      \
63         }                                                               \
64 } while (0)
65
66 #define bfa_itnim_sler_cb(__itnim) do {                                 \
67         if ((__itnim)->bfa->fcs)                                        \
68                 bfa_cb_itnim_sler((__itnim)->ditn);      \
69         else {                                                          \
70                 bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe,        \
71                 __bfa_cb_itnim_sler, (__itnim));      \
72         }                                                               \
73 } while (0)
74
75 /*
76  *  bfa_itnim_sm BFA itnim state machine
77  */
78
79
80 enum bfa_itnim_event {
81         BFA_ITNIM_SM_CREATE = 1,        /*  itnim is created */
82         BFA_ITNIM_SM_ONLINE = 2,        /*  itnim is online */
83         BFA_ITNIM_SM_OFFLINE = 3,       /*  itnim is offline */
84         BFA_ITNIM_SM_FWRSP = 4,         /*  firmware response */
85         BFA_ITNIM_SM_DELETE = 5,        /*  deleting an existing itnim */
86         BFA_ITNIM_SM_CLEANUP = 6,       /*  IO cleanup completion */
87         BFA_ITNIM_SM_SLER = 7,          /*  second level error recovery */
88         BFA_ITNIM_SM_HWFAIL = 8,        /*  IOC h/w failure event */
89         BFA_ITNIM_SM_QRESUME = 9,       /*  queue space available */
90 };
91
92 /*
93  *  BFA IOIM related definitions
94  */
95 #define bfa_ioim_move_to_comp_q(__ioim) do {                            \
96         list_del(&(__ioim)->qe);                                        \
97         list_add_tail(&(__ioim)->qe, &(__ioim)->fcpim->ioim_comp_q);    \
98 } while (0)
99
100
101 #define bfa_ioim_cb_profile_comp(__fcpim, __ioim) do {                  \
102         if ((__fcpim)->profile_comp)                                    \
103                 (__fcpim)->profile_comp(__ioim);                        \
104 } while (0)
105
106 #define bfa_ioim_cb_profile_start(__fcpim, __ioim) do {                 \
107         if ((__fcpim)->profile_start)                                   \
108                 (__fcpim)->profile_start(__ioim);                       \
109 } while (0)
110 /*
111  *  hal_ioim_sm
112  */
113
114 /*
115  * IO state machine events
116  */
117 enum bfa_ioim_event {
118         BFA_IOIM_SM_START       = 1,    /*  io start request from host */
119         BFA_IOIM_SM_COMP_GOOD   = 2,    /*  io good comp, resource free */
120         BFA_IOIM_SM_COMP        = 3,    /*  io comp, resource is free */
121         BFA_IOIM_SM_COMP_UTAG   = 4,    /*  io comp, resource is free */
122         BFA_IOIM_SM_DONE        = 5,    /*  io comp, resource not free */
123         BFA_IOIM_SM_FREE        = 6,    /*  io resource is freed */
124         BFA_IOIM_SM_ABORT       = 7,    /*  abort request from scsi stack */
125         BFA_IOIM_SM_ABORT_COMP  = 8,    /*  abort from f/w */
126         BFA_IOIM_SM_ABORT_DONE  = 9,    /*  abort completion from f/w */
127         BFA_IOIM_SM_QRESUME     = 10,   /*  CQ space available to queue IO */
128         BFA_IOIM_SM_SGALLOCED   = 11,   /*  SG page allocation successful */
129         BFA_IOIM_SM_SQRETRY     = 12,   /*  sequence recovery retry */
130         BFA_IOIM_SM_HCB         = 13,   /*  bfa callback complete */
131         BFA_IOIM_SM_CLEANUP     = 14,   /*  IO cleanup from itnim */
132         BFA_IOIM_SM_TMSTART     = 15,   /*  IO cleanup from tskim */
133         BFA_IOIM_SM_TMDONE      = 16,   /*  IO cleanup from tskim */
134         BFA_IOIM_SM_HWFAIL      = 17,   /*  IOC h/w failure event */
135         BFA_IOIM_SM_IOTOV       = 18,   /*  ITN offline TOV */
136 };
137
138
139 /*
140  *  BFA TSKIM related definitions
141  */
142
143 /*
144  * task management completion handling
145  */
146 #define bfa_tskim_qcomp(__tskim, __cbfn) do {                           \
147         bfa_cb_queue((__tskim)->bfa, &(__tskim)->hcb_qe, __cbfn, (__tskim));\
148         bfa_tskim_notify_comp(__tskim);      \
149 } while (0)
150
151 #define bfa_tskim_notify_comp(__tskim) do {                             \
152         if ((__tskim)->notify)                                          \
153                 bfa_itnim_tskdone((__tskim)->itnim);      \
154 } while (0)
155
156
157 enum bfa_tskim_event {
158         BFA_TSKIM_SM_START      = 1,    /*  TM command start            */
159         BFA_TSKIM_SM_DONE       = 2,    /*  TM completion               */
160         BFA_TSKIM_SM_QRESUME    = 3,    /*  resume after qfull          */
161         BFA_TSKIM_SM_HWFAIL     = 5,    /*  IOC h/w failure event       */
162         BFA_TSKIM_SM_HCB        = 6,    /*  BFA callback completion     */
163         BFA_TSKIM_SM_IOS_DONE   = 7,    /*  IO and sub TM completions   */
164         BFA_TSKIM_SM_CLEANUP    = 8,    /*  TM cleanup on ITN offline   */
165         BFA_TSKIM_SM_CLEANUP_DONE = 9,  /*  TM abort completion */
166 };
167
168 /*
169  * forward declaration for BFA ITNIM functions
170  */
171 static void     bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim);
172 static bfa_boolean_t bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim);
173 static bfa_boolean_t bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim);
174 static void     bfa_itnim_cleanp_comp(void *itnim_cbarg);
175 static void     bfa_itnim_cleanup(struct bfa_itnim_s *itnim);
176 static void     __bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete);
177 static void     __bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete);
178 static void     __bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete);
179 static void     bfa_itnim_iotov_online(struct bfa_itnim_s *itnim);
180 static void     bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim);
181 static void     bfa_itnim_iotov(void *itnim_arg);
182 static void     bfa_itnim_iotov_start(struct bfa_itnim_s *itnim);
183 static void     bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim);
184 static void     bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim);
185
186 /*
187  * forward declaration of ITNIM state machine
188  */
189 static void     bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim,
190                                         enum bfa_itnim_event event);
191 static void     bfa_itnim_sm_created(struct bfa_itnim_s *itnim,
192                                         enum bfa_itnim_event event);
193 static void     bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim,
194                                         enum bfa_itnim_event event);
195 static void     bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
196                                         enum bfa_itnim_event event);
197 static void     bfa_itnim_sm_online(struct bfa_itnim_s *itnim,
198                                         enum bfa_itnim_event event);
199 static void     bfa_itnim_sm_sler(struct bfa_itnim_s *itnim,
200                                         enum bfa_itnim_event event);
201 static void     bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
202                                         enum bfa_itnim_event event);
203 static void     bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
204                                         enum bfa_itnim_event event);
205 static void     bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim,
206                                         enum bfa_itnim_event event);
207 static void     bfa_itnim_sm_offline(struct bfa_itnim_s *itnim,
208                                         enum bfa_itnim_event event);
209 static void     bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
210                                         enum bfa_itnim_event event);
211 static void     bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim,
212                                         enum bfa_itnim_event event);
213 static void     bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
214                                         enum bfa_itnim_event event);
215 static void     bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
216                                         enum bfa_itnim_event event);
217 static void     bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
218                                         enum bfa_itnim_event event);
219
220 /*
221  * forward declaration for BFA IOIM functions
222  */
223 static bfa_boolean_t    bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim);
224 static bfa_boolean_t    bfa_ioim_sge_setup(struct bfa_ioim_s *ioim);
225 static void             bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim);
226 static bfa_boolean_t    bfa_ioim_send_abort(struct bfa_ioim_s *ioim);
227 static void             bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim);
228 static void __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete);
229 static void __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete);
230 static void __bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete);
231 static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete);
232 static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete);
233 static bfa_boolean_t    bfa_ioim_is_abortable(struct bfa_ioim_s *ioim);
234
235
236 /*
237  * forward declaration of BFA IO state machine
238  */
239 static void     bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim,
240                                         enum bfa_ioim_event event);
241 static void     bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim,
242                                         enum bfa_ioim_event event);
243 static void     bfa_ioim_sm_active(struct bfa_ioim_s *ioim,
244                                         enum bfa_ioim_event event);
245 static void     bfa_ioim_sm_abort(struct bfa_ioim_s *ioim,
246                                         enum bfa_ioim_event event);
247 static void     bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim,
248                                         enum bfa_ioim_event event);
249 static void     bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim,
250                                         enum bfa_ioim_event event);
251 static void     bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim,
252                                         enum bfa_ioim_event event);
253 static void     bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim,
254                                         enum bfa_ioim_event event);
255 static void     bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim,
256                                         enum bfa_ioim_event event);
257 static void     bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim,
258                                         enum bfa_ioim_event event);
259 static void     bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim,
260                                         enum bfa_ioim_event event);
261 static void     bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim,
262                                         enum bfa_ioim_event event);
263
264 /*
265  * forward declaration for BFA TSKIM functions
266  */
267 static void     __bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete);
268 static void     __bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete);
269 static bfa_boolean_t bfa_tskim_match_scope(struct bfa_tskim_s *tskim,
270                                         lun_t lun);
271 static void     bfa_tskim_gather_ios(struct bfa_tskim_s *tskim);
272 static void     bfa_tskim_cleanp_comp(void *tskim_cbarg);
273 static void     bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim);
274 static bfa_boolean_t bfa_tskim_send(struct bfa_tskim_s *tskim);
275 static bfa_boolean_t bfa_tskim_send_abort(struct bfa_tskim_s *tskim);
276 static void     bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim);
277
278
279 /*
280  * forward declaration of BFA TSKIM state machine
281  */
282 static void     bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim,
283                                         enum bfa_tskim_event event);
284 static void     bfa_tskim_sm_active(struct bfa_tskim_s *tskim,
285                                         enum bfa_tskim_event event);
286 static void     bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim,
287                                         enum bfa_tskim_event event);
288 static void     bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim,
289                                         enum bfa_tskim_event event);
290 static void     bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim,
291                                         enum bfa_tskim_event event);
292 static void     bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
293                                         enum bfa_tskim_event event);
294 static void     bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim,
295                                         enum bfa_tskim_event event);
296
297 /*
298  *  hal_fcpim_mod BFA FCP Initiator Mode module
299  */
300
301 /*
302  *      Compute and return memory needed by FCP(im) module.
303  */
304 static void
305 bfa_fcpim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
306                 u32 *dm_len)
307 {
308         bfa_itnim_meminfo(cfg, km_len, dm_len);
309
310         /*
311          * IO memory
312          */
313         if (cfg->fwcfg.num_ioim_reqs < BFA_IOIM_MIN)
314                 cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN;
315         else if (cfg->fwcfg.num_ioim_reqs > BFA_IOIM_MAX)
316                 cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MAX;
317
318         *km_len += cfg->fwcfg.num_ioim_reqs *
319           (sizeof(struct bfa_ioim_s) + sizeof(struct bfa_ioim_sp_s));
320
321         *dm_len += cfg->fwcfg.num_ioim_reqs * BFI_IOIM_SNSLEN;
322
323         /*
324          * task management command memory
325          */
326         if (cfg->fwcfg.num_tskim_reqs < BFA_TSKIM_MIN)
327                 cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN;
328         *km_len += cfg->fwcfg.num_tskim_reqs * sizeof(struct bfa_tskim_s);
329 }
330
331
332 static void
333 bfa_fcpim_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
334                 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
335 {
336         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
337
338         bfa_trc(bfa, cfg->drvcfg.path_tov);
339         bfa_trc(bfa, cfg->fwcfg.num_rports);
340         bfa_trc(bfa, cfg->fwcfg.num_ioim_reqs);
341         bfa_trc(bfa, cfg->fwcfg.num_tskim_reqs);
342
343         fcpim->bfa              = bfa;
344         fcpim->num_itnims       = cfg->fwcfg.num_rports;
345         fcpim->num_ioim_reqs  = cfg->fwcfg.num_ioim_reqs;
346         fcpim->num_tskim_reqs = cfg->fwcfg.num_tskim_reqs;
347         fcpim->path_tov         = cfg->drvcfg.path_tov;
348         fcpim->delay_comp       = cfg->drvcfg.delay_comp;
349         fcpim->profile_comp = NULL;
350         fcpim->profile_start = NULL;
351
352         bfa_itnim_attach(fcpim, meminfo);
353         bfa_tskim_attach(fcpim, meminfo);
354         bfa_ioim_attach(fcpim, meminfo);
355 }
356
357 static void
358 bfa_fcpim_detach(struct bfa_s *bfa)
359 {
360         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
361
362         bfa_ioim_detach(fcpim);
363         bfa_tskim_detach(fcpim);
364 }
365
366 static void
367 bfa_fcpim_start(struct bfa_s *bfa)
368 {
369 }
370
371 static void
372 bfa_fcpim_stop(struct bfa_s *bfa)
373 {
374 }
375
376 static void
377 bfa_fcpim_iocdisable(struct bfa_s *bfa)
378 {
379         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
380         struct bfa_itnim_s *itnim;
381         struct list_head *qe, *qen;
382
383         list_for_each_safe(qe, qen, &fcpim->itnim_q) {
384                 itnim = (struct bfa_itnim_s *) qe;
385                 bfa_itnim_iocdisable(itnim);
386         }
387 }
388
389 void
390 bfa_fcpim_add_stats(struct bfa_itnim_iostats_s *lstats,
391                 struct bfa_itnim_iostats_s *rstats)
392 {
393         bfa_fcpim_add_iostats(lstats, rstats, total_ios);
394         bfa_fcpim_add_iostats(lstats, rstats, qresumes);
395         bfa_fcpim_add_iostats(lstats, rstats, no_iotags);
396         bfa_fcpim_add_iostats(lstats, rstats, io_aborts);
397         bfa_fcpim_add_iostats(lstats, rstats, no_tskims);
398         bfa_fcpim_add_iostats(lstats, rstats, iocomp_ok);
399         bfa_fcpim_add_iostats(lstats, rstats, iocomp_underrun);
400         bfa_fcpim_add_iostats(lstats, rstats, iocomp_overrun);
401         bfa_fcpim_add_iostats(lstats, rstats, iocomp_aborted);
402         bfa_fcpim_add_iostats(lstats, rstats, iocomp_timedout);
403         bfa_fcpim_add_iostats(lstats, rstats, iocom_nexus_abort);
404         bfa_fcpim_add_iostats(lstats, rstats, iocom_proto_err);
405         bfa_fcpim_add_iostats(lstats, rstats, iocom_dif_err);
406         bfa_fcpim_add_iostats(lstats, rstats, iocom_sqer_needed);
407         bfa_fcpim_add_iostats(lstats, rstats, iocom_res_free);
408         bfa_fcpim_add_iostats(lstats, rstats, iocom_hostabrts);
409         bfa_fcpim_add_iostats(lstats, rstats, iocom_utags);
410         bfa_fcpim_add_iostats(lstats, rstats, io_cleanups);
411         bfa_fcpim_add_iostats(lstats, rstats, io_tmaborts);
412         bfa_fcpim_add_iostats(lstats, rstats, onlines);
413         bfa_fcpim_add_iostats(lstats, rstats, offlines);
414         bfa_fcpim_add_iostats(lstats, rstats, creates);
415         bfa_fcpim_add_iostats(lstats, rstats, deletes);
416         bfa_fcpim_add_iostats(lstats, rstats, create_comps);
417         bfa_fcpim_add_iostats(lstats, rstats, delete_comps);
418         bfa_fcpim_add_iostats(lstats, rstats, sler_events);
419         bfa_fcpim_add_iostats(lstats, rstats, fw_create);
420         bfa_fcpim_add_iostats(lstats, rstats, fw_delete);
421         bfa_fcpim_add_iostats(lstats, rstats, ioc_disabled);
422         bfa_fcpim_add_iostats(lstats, rstats, cleanup_comps);
423         bfa_fcpim_add_iostats(lstats, rstats, tm_cmnds);
424         bfa_fcpim_add_iostats(lstats, rstats, tm_fw_rsps);
425         bfa_fcpim_add_iostats(lstats, rstats, tm_success);
426         bfa_fcpim_add_iostats(lstats, rstats, tm_failures);
427         bfa_fcpim_add_iostats(lstats, rstats, tm_io_comps);
428         bfa_fcpim_add_iostats(lstats, rstats, tm_qresumes);
429         bfa_fcpim_add_iostats(lstats, rstats, tm_iocdowns);
430         bfa_fcpim_add_iostats(lstats, rstats, tm_cleanups);
431         bfa_fcpim_add_iostats(lstats, rstats, tm_cleanup_comps);
432         bfa_fcpim_add_iostats(lstats, rstats, io_comps);
433         bfa_fcpim_add_iostats(lstats, rstats, input_reqs);
434         bfa_fcpim_add_iostats(lstats, rstats, output_reqs);
435         bfa_fcpim_add_iostats(lstats, rstats, rd_throughput);
436         bfa_fcpim_add_iostats(lstats, rstats, wr_throughput);
437 }
438
439 void
440 bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov)
441 {
442         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
443
444         fcpim->path_tov = path_tov * 1000;
445         if (fcpim->path_tov > BFA_FCPIM_PATHTOV_MAX)
446                 fcpim->path_tov = BFA_FCPIM_PATHTOV_MAX;
447 }
448
449 u16
450 bfa_fcpim_path_tov_get(struct bfa_s *bfa)
451 {
452         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
453
454         return fcpim->path_tov / 1000;
455 }
456
457 bfa_status_t
458 bfa_fcpim_port_iostats(struct bfa_s *bfa, struct bfa_itnim_iostats_s *stats,
459         u8 lp_tag)
460 {
461         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
462         struct list_head *qe, *qen;
463         struct bfa_itnim_s *itnim;
464
465         /* accumulate IO stats from itnim */
466         memset(stats, 0, sizeof(struct bfa_itnim_iostats_s));
467         list_for_each_safe(qe, qen, &fcpim->itnim_q) {
468                 itnim = (struct bfa_itnim_s *) qe;
469                 if (itnim->rport->rport_info.lp_tag != lp_tag)
470                         continue;
471                 bfa_fcpim_add_stats(stats, &(itnim->stats));
472         }
473         return BFA_STATUS_OK;
474 }
475 bfa_status_t
476 bfa_fcpim_get_modstats(struct bfa_s *bfa, struct bfa_itnim_iostats_s *modstats)
477 {
478         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
479         struct list_head *qe, *qen;
480         struct bfa_itnim_s *itnim;
481
482         /* accumulate IO stats from itnim */
483         memset(modstats, 0, sizeof(struct bfa_itnim_iostats_s));
484         list_for_each_safe(qe, qen, &fcpim->itnim_q) {
485                 itnim = (struct bfa_itnim_s *) qe;
486                 bfa_fcpim_add_stats(modstats, &(itnim->stats));
487         }
488         return BFA_STATUS_OK;
489 }
490
491 bfa_status_t
492 bfa_fcpim_get_del_itn_stats(struct bfa_s *bfa,
493          struct bfa_fcpim_del_itn_stats_s *modstats)
494 {
495         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
496
497         *modstats = fcpim->del_itn_stats;
498
499         return BFA_STATUS_OK;
500 }
501
502
503 bfa_status_t
504 bfa_fcpim_profile_on(struct bfa_s *bfa, u32 time)
505 {
506         struct bfa_itnim_s *itnim;
507         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
508         struct list_head *qe, *qen;
509
510         /* accumulate IO stats from itnim */
511         list_for_each_safe(qe, qen, &fcpim->itnim_q) {
512                 itnim = (struct bfa_itnim_s *) qe;
513                 bfa_itnim_clear_stats(itnim);
514         }
515         fcpim->io_profile = BFA_TRUE;
516         fcpim->io_profile_start_time = time;
517         fcpim->profile_comp = bfa_ioim_profile_comp;
518         fcpim->profile_start = bfa_ioim_profile_start;
519
520         return BFA_STATUS_OK;
521 }
522 bfa_status_t
523 bfa_fcpim_profile_off(struct bfa_s *bfa)
524 {
525         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
526         fcpim->io_profile = BFA_FALSE;
527         fcpim->io_profile_start_time = 0;
528         fcpim->profile_comp = NULL;
529         fcpim->profile_start = NULL;
530         return BFA_STATUS_OK;
531 }
532
533 bfa_status_t
534 bfa_fcpim_port_clear_iostats(struct bfa_s *bfa, u8 lp_tag)
535 {
536         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
537         struct list_head *qe, *qen;
538         struct bfa_itnim_s *itnim;
539
540         /* clear IO stats from all active itnims */
541         list_for_each_safe(qe, qen, &fcpim->itnim_q) {
542                 itnim = (struct bfa_itnim_s *) qe;
543                 if (itnim->rport->rport_info.lp_tag != lp_tag)
544                         continue;
545                 bfa_itnim_clear_stats(itnim);
546         }
547         return BFA_STATUS_OK;
548
549 }
550
551 bfa_status_t
552 bfa_fcpim_clr_modstats(struct bfa_s *bfa)
553 {
554         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
555         struct list_head *qe, *qen;
556         struct bfa_itnim_s *itnim;
557
558         /* clear IO stats from all active itnims */
559         list_for_each_safe(qe, qen, &fcpim->itnim_q) {
560                 itnim = (struct bfa_itnim_s *) qe;
561                 bfa_itnim_clear_stats(itnim);
562         }
563         memset(&fcpim->del_itn_stats, 0,
564                 sizeof(struct bfa_fcpim_del_itn_stats_s));
565
566         return BFA_STATUS_OK;
567 }
568
569 void
570 bfa_fcpim_qdepth_set(struct bfa_s *bfa, u16 q_depth)
571 {
572         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
573
574         bfa_assert(q_depth <= BFA_IOCFC_QDEPTH_MAX);
575
576         fcpim->q_depth = q_depth;
577 }
578
579 u16
580 bfa_fcpim_qdepth_get(struct bfa_s *bfa)
581 {
582         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
583
584         return fcpim->q_depth;
585 }
586
587 void
588 bfa_fcpim_update_ioredirect(struct bfa_s *bfa)
589 {
590         bfa_boolean_t ioredirect;
591
592         /*
593          * IO redirection is turned off when QoS is enabled and vice versa
594          */
595         ioredirect = bfa_fcport_is_qos_enabled(bfa) ? BFA_FALSE : BFA_TRUE;
596 }
597
598 void
599 bfa_fcpim_set_ioredirect(struct bfa_s *bfa, bfa_boolean_t state)
600 {
601         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
602         fcpim->ioredirect = state;
603 }
604
605
606
607 /*
608  *  BFA ITNIM module state machine functions
609  */
610
611 /*
612  *      Beginning/unallocated state - no events expected.
613  */
614 static void
615 bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
616 {
617         bfa_trc(itnim->bfa, itnim->rport->rport_tag);
618         bfa_trc(itnim->bfa, event);
619
620         switch (event) {
621         case BFA_ITNIM_SM_CREATE:
622                 bfa_sm_set_state(itnim, bfa_itnim_sm_created);
623                 itnim->is_online = BFA_FALSE;
624                 bfa_fcpim_additn(itnim);
625                 break;
626
627         default:
628                 bfa_sm_fault(itnim->bfa, event);
629         }
630 }
631
632 /*
633  *      Beginning state, only online event expected.
634  */
635 static void
636 bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
637 {
638         bfa_trc(itnim->bfa, itnim->rport->rport_tag);
639         bfa_trc(itnim->bfa, event);
640
641         switch (event) {
642         case BFA_ITNIM_SM_ONLINE:
643                 if (bfa_itnim_send_fwcreate(itnim))
644                         bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
645                 else
646                         bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
647                 break;
648
649         case BFA_ITNIM_SM_DELETE:
650                 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
651                 bfa_fcpim_delitn(itnim);
652                 break;
653
654         case BFA_ITNIM_SM_HWFAIL:
655                 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
656                 break;
657
658         default:
659                 bfa_sm_fault(itnim->bfa, event);
660         }
661 }
662
663 /*
664  *      Waiting for itnim create response from firmware.
665  */
666 static void
667 bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
668 {
669         bfa_trc(itnim->bfa, itnim->rport->rport_tag);
670         bfa_trc(itnim->bfa, event);
671
672         switch (event) {
673         case BFA_ITNIM_SM_FWRSP:
674                 bfa_sm_set_state(itnim, bfa_itnim_sm_online);
675                 itnim->is_online = BFA_TRUE;
676                 bfa_itnim_iotov_online(itnim);
677                 bfa_itnim_online_cb(itnim);
678                 break;
679
680         case BFA_ITNIM_SM_DELETE:
681                 bfa_sm_set_state(itnim, bfa_itnim_sm_delete_pending);
682                 break;
683
684         case BFA_ITNIM_SM_OFFLINE:
685                 if (bfa_itnim_send_fwdelete(itnim))
686                         bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
687                 else
688                         bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull);
689                 break;
690
691         case BFA_ITNIM_SM_HWFAIL:
692                 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
693                 break;
694
695         default:
696                 bfa_sm_fault(itnim->bfa, event);
697         }
698 }
699
700 static void
701 bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
702                         enum bfa_itnim_event event)
703 {
704         bfa_trc(itnim->bfa, itnim->rport->rport_tag);
705         bfa_trc(itnim->bfa, event);
706
707         switch (event) {
708         case BFA_ITNIM_SM_QRESUME:
709                 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
710                 bfa_itnim_send_fwcreate(itnim);
711                 break;
712
713         case BFA_ITNIM_SM_DELETE:
714                 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
715                 bfa_reqq_wcancel(&itnim->reqq_wait);
716                 bfa_fcpim_delitn(itnim);
717                 break;
718
719         case BFA_ITNIM_SM_OFFLINE:
720                 bfa_sm_set_state(itnim, bfa_itnim_sm_offline);
721                 bfa_reqq_wcancel(&itnim->reqq_wait);
722                 bfa_itnim_offline_cb(itnim);
723                 break;
724
725         case BFA_ITNIM_SM_HWFAIL:
726                 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
727                 bfa_reqq_wcancel(&itnim->reqq_wait);
728                 break;
729
730         default:
731                 bfa_sm_fault(itnim->bfa, event);
732         }
733 }
734
735 /*
736  *      Waiting for itnim create response from firmware, a delete is pending.
737  */
738 static void
739 bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
740                                 enum bfa_itnim_event event)
741 {
742         bfa_trc(itnim->bfa, itnim->rport->rport_tag);
743         bfa_trc(itnim->bfa, event);
744
745         switch (event) {
746         case BFA_ITNIM_SM_FWRSP:
747                 if (bfa_itnim_send_fwdelete(itnim))
748                         bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
749                 else
750                         bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
751                 break;
752
753         case BFA_ITNIM_SM_HWFAIL:
754                 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
755                 bfa_fcpim_delitn(itnim);
756                 break;
757
758         default:
759                 bfa_sm_fault(itnim->bfa, event);
760         }
761 }
762
763 /*
764  *      Online state - normal parking state.
765  */
766 static void
767 bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
768 {
769         bfa_trc(itnim->bfa, itnim->rport->rport_tag);
770         bfa_trc(itnim->bfa, event);
771
772         switch (event) {
773         case BFA_ITNIM_SM_OFFLINE:
774                 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline);
775                 itnim->is_online = BFA_FALSE;
776                 bfa_itnim_iotov_start(itnim);
777                 bfa_itnim_cleanup(itnim);
778                 break;
779
780         case BFA_ITNIM_SM_DELETE:
781                 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
782                 itnim->is_online = BFA_FALSE;
783                 bfa_itnim_cleanup(itnim);
784                 break;
785
786         case BFA_ITNIM_SM_SLER:
787                 bfa_sm_set_state(itnim, bfa_itnim_sm_sler);
788                 itnim->is_online = BFA_FALSE;
789                 bfa_itnim_iotov_start(itnim);
790                 bfa_itnim_sler_cb(itnim);
791                 break;
792
793         case BFA_ITNIM_SM_HWFAIL:
794                 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
795                 itnim->is_online = BFA_FALSE;
796                 bfa_itnim_iotov_start(itnim);
797                 bfa_itnim_iocdisable_cleanup(itnim);
798                 break;
799
800         default:
801                 bfa_sm_fault(itnim->bfa, event);
802         }
803 }
804
805 /*
806  *      Second level error recovery need.
807  */
808 static void
809 bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
810 {
811         bfa_trc(itnim->bfa, itnim->rport->rport_tag);
812         bfa_trc(itnim->bfa, event);
813
814         switch (event) {
815         case BFA_ITNIM_SM_OFFLINE:
816                 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline);
817                 bfa_itnim_cleanup(itnim);
818                 break;
819
820         case BFA_ITNIM_SM_DELETE:
821                 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
822                 bfa_itnim_cleanup(itnim);
823                 bfa_itnim_iotov_delete(itnim);
824                 break;
825
826         case BFA_ITNIM_SM_HWFAIL:
827                 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
828                 bfa_itnim_iocdisable_cleanup(itnim);
829                 break;
830
831         default:
832                 bfa_sm_fault(itnim->bfa, event);
833         }
834 }
835
836 /*
837  *      Going offline. Waiting for active IO cleanup.
838  */
839 static void
840 bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
841                                  enum bfa_itnim_event event)
842 {
843         bfa_trc(itnim->bfa, itnim->rport->rport_tag);
844         bfa_trc(itnim->bfa, event);
845
846         switch (event) {
847         case BFA_ITNIM_SM_CLEANUP:
848                 if (bfa_itnim_send_fwdelete(itnim))
849                         bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
850                 else
851                         bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull);
852                 break;
853
854         case BFA_ITNIM_SM_DELETE:
855                 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
856                 bfa_itnim_iotov_delete(itnim);
857                 break;
858
859         case BFA_ITNIM_SM_HWFAIL:
860                 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
861                 bfa_itnim_iocdisable_cleanup(itnim);
862                 bfa_itnim_offline_cb(itnim);
863                 break;
864
865         case BFA_ITNIM_SM_SLER:
866                 break;
867
868         default:
869                 bfa_sm_fault(itnim->bfa, event);
870         }
871 }
872
873 /*
874  *      Deleting itnim. Waiting for active IO cleanup.
875  */
876 static void
877 bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
878                                 enum bfa_itnim_event event)
879 {
880         bfa_trc(itnim->bfa, itnim->rport->rport_tag);
881         bfa_trc(itnim->bfa, event);
882
883         switch (event) {
884         case BFA_ITNIM_SM_CLEANUP:
885                 if (bfa_itnim_send_fwdelete(itnim))
886                         bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
887                 else
888                         bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
889                 break;
890
891         case BFA_ITNIM_SM_HWFAIL:
892                 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
893                 bfa_itnim_iocdisable_cleanup(itnim);
894                 break;
895
896         default:
897                 bfa_sm_fault(itnim->bfa, event);
898         }
899 }
900
901 /*
902  * Rport offline. Fimrware itnim is being deleted - awaiting f/w response.
903  */
904 static void
905 bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
906 {
907         bfa_trc(itnim->bfa, itnim->rport->rport_tag);
908         bfa_trc(itnim->bfa, event);
909
910         switch (event) {
911         case BFA_ITNIM_SM_FWRSP:
912                 bfa_sm_set_state(itnim, bfa_itnim_sm_offline);
913                 bfa_itnim_offline_cb(itnim);
914                 break;
915
916         case BFA_ITNIM_SM_DELETE:
917                 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
918                 break;
919
920         case BFA_ITNIM_SM_HWFAIL:
921                 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
922                 bfa_itnim_offline_cb(itnim);
923                 break;
924
925         default:
926                 bfa_sm_fault(itnim->bfa, event);
927         }
928 }
929
930 static void
931 bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
932                         enum bfa_itnim_event event)
933 {
934         bfa_trc(itnim->bfa, itnim->rport->rport_tag);
935         bfa_trc(itnim->bfa, event);
936
937         switch (event) {
938         case BFA_ITNIM_SM_QRESUME:
939                 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
940                 bfa_itnim_send_fwdelete(itnim);
941                 break;
942
943         case BFA_ITNIM_SM_DELETE:
944                 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
945                 break;
946
947         case BFA_ITNIM_SM_HWFAIL:
948                 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
949                 bfa_reqq_wcancel(&itnim->reqq_wait);
950                 bfa_itnim_offline_cb(itnim);
951                 break;
952
953         default:
954                 bfa_sm_fault(itnim->bfa, event);
955         }
956 }
957
958 /*
959  *      Offline state.
960  */
961 static void
962 bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
963 {
964         bfa_trc(itnim->bfa, itnim->rport->rport_tag);
965         bfa_trc(itnim->bfa, event);
966
967         switch (event) {
968         case BFA_ITNIM_SM_DELETE:
969                 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
970                 bfa_itnim_iotov_delete(itnim);
971                 bfa_fcpim_delitn(itnim);
972                 break;
973
974         case BFA_ITNIM_SM_ONLINE:
975                 if (bfa_itnim_send_fwcreate(itnim))
976                         bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
977                 else
978                         bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
979                 break;
980
981         case BFA_ITNIM_SM_HWFAIL:
982                 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
983                 break;
984
985         default:
986                 bfa_sm_fault(itnim->bfa, event);
987         }
988 }
989
990 /*
991  *      IOC h/w failed state.
992  */
993 static void
994 bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
995                                 enum bfa_itnim_event event)
996 {
997         bfa_trc(itnim->bfa, itnim->rport->rport_tag);
998         bfa_trc(itnim->bfa, event);
999
1000         switch (event) {
1001         case BFA_ITNIM_SM_DELETE:
1002                 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
1003                 bfa_itnim_iotov_delete(itnim);
1004                 bfa_fcpim_delitn(itnim);
1005                 break;
1006
1007         case BFA_ITNIM_SM_OFFLINE:
1008                 bfa_itnim_offline_cb(itnim);
1009                 break;
1010
1011         case BFA_ITNIM_SM_ONLINE:
1012                 if (bfa_itnim_send_fwcreate(itnim))
1013                         bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
1014                 else
1015                         bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
1016                 break;
1017
1018         case BFA_ITNIM_SM_HWFAIL:
1019                 break;
1020
1021         default:
1022                 bfa_sm_fault(itnim->bfa, event);
1023         }
1024 }
1025
1026 /*
1027  *      Itnim is deleted, waiting for firmware response to delete.
1028  */
1029 static void
1030 bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
1031 {
1032         bfa_trc(itnim->bfa, itnim->rport->rport_tag);
1033         bfa_trc(itnim->bfa, event);
1034
1035         switch (event) {
1036         case BFA_ITNIM_SM_FWRSP:
1037         case BFA_ITNIM_SM_HWFAIL:
1038                 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
1039                 bfa_fcpim_delitn(itnim);
1040                 break;
1041
1042         default:
1043                 bfa_sm_fault(itnim->bfa, event);
1044         }
1045 }
1046
1047 static void
1048 bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
1049                 enum bfa_itnim_event event)
1050 {
1051         bfa_trc(itnim->bfa, itnim->rport->rport_tag);
1052         bfa_trc(itnim->bfa, event);
1053
1054         switch (event) {
1055         case BFA_ITNIM_SM_QRESUME:
1056                 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
1057                 bfa_itnim_send_fwdelete(itnim);
1058                 break;
1059
1060         case BFA_ITNIM_SM_HWFAIL:
1061                 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
1062                 bfa_reqq_wcancel(&itnim->reqq_wait);
1063                 bfa_fcpim_delitn(itnim);
1064                 break;
1065
1066         default:
1067                 bfa_sm_fault(itnim->bfa, event);
1068         }
1069 }
1070
1071 /*
1072  *      Initiate cleanup of all IOs on an IOC failure.
1073  */
1074 static void
1075 bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim)
1076 {
1077         struct bfa_tskim_s *tskim;
1078         struct bfa_ioim_s *ioim;
1079         struct list_head        *qe, *qen;
1080
1081         list_for_each_safe(qe, qen, &itnim->tsk_q) {
1082                 tskim = (struct bfa_tskim_s *) qe;
1083                 bfa_tskim_iocdisable(tskim);
1084         }
1085
1086         list_for_each_safe(qe, qen, &itnim->io_q) {
1087                 ioim = (struct bfa_ioim_s *) qe;
1088                 bfa_ioim_iocdisable(ioim);
1089         }
1090
1091         /*
1092          * For IO request in pending queue, we pretend an early timeout.
1093          */
1094         list_for_each_safe(qe, qen, &itnim->pending_q) {
1095                 ioim = (struct bfa_ioim_s *) qe;
1096                 bfa_ioim_tov(ioim);
1097         }
1098
1099         list_for_each_safe(qe, qen, &itnim->io_cleanup_q) {
1100                 ioim = (struct bfa_ioim_s *) qe;
1101                 bfa_ioim_iocdisable(ioim);
1102         }
1103 }
1104
1105 /*
1106  *      IO cleanup completion
1107  */
1108 static void
1109 bfa_itnim_cleanp_comp(void *itnim_cbarg)
1110 {
1111         struct bfa_itnim_s *itnim = itnim_cbarg;
1112
1113         bfa_stats(itnim, cleanup_comps);
1114         bfa_sm_send_event(itnim, BFA_ITNIM_SM_CLEANUP);
1115 }
1116
1117 /*
1118  *      Initiate cleanup of all IOs.
1119  */
1120 static void
1121 bfa_itnim_cleanup(struct bfa_itnim_s *itnim)
1122 {
1123         struct bfa_ioim_s  *ioim;
1124         struct bfa_tskim_s *tskim;
1125         struct list_head        *qe, *qen;
1126
1127         bfa_wc_init(&itnim->wc, bfa_itnim_cleanp_comp, itnim);
1128
1129         list_for_each_safe(qe, qen, &itnim->io_q) {
1130                 ioim = (struct bfa_ioim_s *) qe;
1131
1132                 /*
1133                  * Move IO to a cleanup queue from active queue so that a later
1134                  * TM will not pickup this IO.
1135                  */
1136                 list_del(&ioim->qe);
1137                 list_add_tail(&ioim->qe, &itnim->io_cleanup_q);
1138
1139                 bfa_wc_up(&itnim->wc);
1140                 bfa_ioim_cleanup(ioim);
1141         }
1142
1143         list_for_each_safe(qe, qen, &itnim->tsk_q) {
1144                 tskim = (struct bfa_tskim_s *) qe;
1145                 bfa_wc_up(&itnim->wc);
1146                 bfa_tskim_cleanup(tskim);
1147         }
1148
1149         bfa_wc_wait(&itnim->wc);
1150 }
1151
1152 static void
1153 __bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete)
1154 {
1155         struct bfa_itnim_s *itnim = cbarg;
1156
1157         if (complete)
1158                 bfa_cb_itnim_online(itnim->ditn);
1159 }
1160
1161 static void
1162 __bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete)
1163 {
1164         struct bfa_itnim_s *itnim = cbarg;
1165
1166         if (complete)
1167                 bfa_cb_itnim_offline(itnim->ditn);
1168 }
1169
1170 static void
1171 __bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete)
1172 {
1173         struct bfa_itnim_s *itnim = cbarg;
1174
1175         if (complete)
1176                 bfa_cb_itnim_sler(itnim->ditn);
1177 }
1178
1179 /*
1180  * Call to resume any I/O requests waiting for room in request queue.
1181  */
1182 static void
1183 bfa_itnim_qresume(void *cbarg)
1184 {
1185         struct bfa_itnim_s *itnim = cbarg;
1186
1187         bfa_sm_send_event(itnim, BFA_ITNIM_SM_QRESUME);
1188 }
1189
1190
1191
1192
1193 /*
1194  *  bfa_itnim_public
1195  */
1196
1197 void
1198 bfa_itnim_iodone(struct bfa_itnim_s *itnim)
1199 {
1200         bfa_wc_down(&itnim->wc);
1201 }
1202
1203 void
1204 bfa_itnim_tskdone(struct bfa_itnim_s *itnim)
1205 {
1206         bfa_wc_down(&itnim->wc);
1207 }
1208
1209 void
1210 bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
1211                 u32 *dm_len)
1212 {
1213         /*
1214          * ITN memory
1215          */
1216         *km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_itnim_s);
1217 }
1218
1219 void
1220 bfa_itnim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
1221 {
1222         struct bfa_s    *bfa = fcpim->bfa;
1223         struct bfa_itnim_s *itnim;
1224         int     i, j;
1225
1226         INIT_LIST_HEAD(&fcpim->itnim_q);
1227
1228         itnim = (struct bfa_itnim_s *) bfa_meminfo_kva(minfo);
1229         fcpim->itnim_arr = itnim;
1230
1231         for (i = 0; i < fcpim->num_itnims; i++, itnim++) {
1232                 memset(itnim, 0, sizeof(struct bfa_itnim_s));
1233                 itnim->bfa = bfa;
1234                 itnim->fcpim = fcpim;
1235                 itnim->reqq = BFA_REQQ_QOS_LO;
1236                 itnim->rport = BFA_RPORT_FROM_TAG(bfa, i);
1237                 itnim->iotov_active = BFA_FALSE;
1238                 bfa_reqq_winit(&itnim->reqq_wait, bfa_itnim_qresume, itnim);
1239
1240                 INIT_LIST_HEAD(&itnim->io_q);
1241                 INIT_LIST_HEAD(&itnim->io_cleanup_q);
1242                 INIT_LIST_HEAD(&itnim->pending_q);
1243                 INIT_LIST_HEAD(&itnim->tsk_q);
1244                 INIT_LIST_HEAD(&itnim->delay_comp_q);
1245                 for (j = 0; j < BFA_IOBUCKET_MAX; j++)
1246                         itnim->ioprofile.io_latency.min[j] = ~0;
1247                 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
1248         }
1249
1250         bfa_meminfo_kva(minfo) = (u8 *) itnim;
1251 }
1252
1253 void
1254 bfa_itnim_iocdisable(struct bfa_itnim_s *itnim)
1255 {
1256         bfa_stats(itnim, ioc_disabled);
1257         bfa_sm_send_event(itnim, BFA_ITNIM_SM_HWFAIL);
1258 }
1259
1260 static bfa_boolean_t
1261 bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim)
1262 {
1263         struct bfi_itnim_create_req_s *m;
1264
1265         itnim->msg_no++;
1266
1267         /*
1268          * check for room in queue to send request now
1269          */
1270         m = bfa_reqq_next(itnim->bfa, itnim->reqq);
1271         if (!m) {
1272                 bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait);
1273                 return BFA_FALSE;
1274         }
1275
1276         bfi_h2i_set(m->mh, BFI_MC_ITNIM, BFI_ITNIM_H2I_CREATE_REQ,
1277                         bfa_lpuid(itnim->bfa));
1278         m->fw_handle = itnim->rport->fw_handle;
1279         m->class = FC_CLASS_3;
1280         m->seq_rec = itnim->seq_rec;
1281         m->msg_no = itnim->msg_no;
1282         bfa_stats(itnim, fw_create);
1283
1284         /*
1285          * queue I/O message to firmware
1286          */
1287         bfa_reqq_produce(itnim->bfa, itnim->reqq);
1288         return BFA_TRUE;
1289 }
1290
1291 static bfa_boolean_t
1292 bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim)
1293 {
1294         struct bfi_itnim_delete_req_s *m;
1295
1296         /*
1297          * check for room in queue to send request now
1298          */
1299         m = bfa_reqq_next(itnim->bfa, itnim->reqq);
1300         if (!m) {
1301                 bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait);
1302                 return BFA_FALSE;
1303         }
1304
1305         bfi_h2i_set(m->mh, BFI_MC_ITNIM, BFI_ITNIM_H2I_DELETE_REQ,
1306                         bfa_lpuid(itnim->bfa));
1307         m->fw_handle = itnim->rport->fw_handle;
1308         bfa_stats(itnim, fw_delete);
1309
1310         /*
1311          * queue I/O message to firmware
1312          */
1313         bfa_reqq_produce(itnim->bfa, itnim->reqq);
1314         return BFA_TRUE;
1315 }
1316
1317 /*
1318  * Cleanup all pending failed inflight requests.
1319  */
1320 static void
1321 bfa_itnim_delayed_comp(struct bfa_itnim_s *itnim, bfa_boolean_t iotov)
1322 {
1323         struct bfa_ioim_s *ioim;
1324         struct list_head *qe, *qen;
1325
1326         list_for_each_safe(qe, qen, &itnim->delay_comp_q) {
1327                 ioim = (struct bfa_ioim_s *)qe;
1328                 bfa_ioim_delayed_comp(ioim, iotov);
1329         }
1330 }
1331
1332 /*
1333  * Start all pending IO requests.
1334  */
1335 static void
1336 bfa_itnim_iotov_online(struct bfa_itnim_s *itnim)
1337 {
1338         struct bfa_ioim_s *ioim;
1339
1340         bfa_itnim_iotov_stop(itnim);
1341
1342         /*
1343          * Abort all inflight IO requests in the queue
1344          */
1345         bfa_itnim_delayed_comp(itnim, BFA_FALSE);
1346
1347         /*
1348          * Start all pending IO requests.
1349          */
1350         while (!list_empty(&itnim->pending_q)) {
1351                 bfa_q_deq(&itnim->pending_q, &ioim);
1352                 list_add_tail(&ioim->qe, &itnim->io_q);
1353                 bfa_ioim_start(ioim);
1354         }
1355 }
1356
1357 /*
1358  * Fail all pending IO requests
1359  */
1360 static void
1361 bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim)
1362 {
1363         struct bfa_ioim_s *ioim;
1364
1365         /*
1366          * Fail all inflight IO requests in the queue
1367          */
1368         bfa_itnim_delayed_comp(itnim, BFA_TRUE);
1369
1370         /*
1371          * Fail any pending IO requests.
1372          */
1373         while (!list_empty(&itnim->pending_q)) {
1374                 bfa_q_deq(&itnim->pending_q, &ioim);
1375                 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
1376                 bfa_ioim_tov(ioim);
1377         }
1378 }
1379
1380 /*
1381  * IO TOV timer callback. Fail any pending IO requests.
1382  */
1383 static void
1384 bfa_itnim_iotov(void *itnim_arg)
1385 {
1386         struct bfa_itnim_s *itnim = itnim_arg;
1387
1388         itnim->iotov_active = BFA_FALSE;
1389
1390         bfa_cb_itnim_tov_begin(itnim->ditn);
1391         bfa_itnim_iotov_cleanup(itnim);
1392         bfa_cb_itnim_tov(itnim->ditn);
1393 }
1394
1395 /*
1396  * Start IO TOV timer for failing back pending IO requests in offline state.
1397  */
1398 static void
1399 bfa_itnim_iotov_start(struct bfa_itnim_s *itnim)
1400 {
1401         if (itnim->fcpim->path_tov > 0) {
1402
1403                 itnim->iotov_active = BFA_TRUE;
1404                 bfa_assert(bfa_itnim_hold_io(itnim));
1405                 bfa_timer_start(itnim->bfa, &itnim->timer,
1406                         bfa_itnim_iotov, itnim, itnim->fcpim->path_tov);
1407         }
1408 }
1409
1410 /*
1411  * Stop IO TOV timer.
1412  */
1413 static void
1414 bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim)
1415 {
1416         if (itnim->iotov_active) {
1417                 itnim->iotov_active = BFA_FALSE;
1418                 bfa_timer_stop(&itnim->timer);
1419         }
1420 }
1421
1422 /*
1423  * Stop IO TOV timer.
1424  */
1425 static void
1426 bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim)
1427 {
1428         bfa_boolean_t pathtov_active = BFA_FALSE;
1429
1430         if (itnim->iotov_active)
1431                 pathtov_active = BFA_TRUE;
1432
1433         bfa_itnim_iotov_stop(itnim);
1434         if (pathtov_active)
1435                 bfa_cb_itnim_tov_begin(itnim->ditn);
1436         bfa_itnim_iotov_cleanup(itnim);
1437         if (pathtov_active)
1438                 bfa_cb_itnim_tov(itnim->ditn);
1439 }
1440
1441 static void
1442 bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim)
1443 {
1444         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(itnim->bfa);
1445         fcpim->del_itn_stats.del_itn_iocomp_aborted +=
1446                 itnim->stats.iocomp_aborted;
1447         fcpim->del_itn_stats.del_itn_iocomp_timedout +=
1448                 itnim->stats.iocomp_timedout;
1449         fcpim->del_itn_stats.del_itn_iocom_sqer_needed +=
1450                 itnim->stats.iocom_sqer_needed;
1451         fcpim->del_itn_stats.del_itn_iocom_res_free +=
1452                 itnim->stats.iocom_res_free;
1453         fcpim->del_itn_stats.del_itn_iocom_hostabrts +=
1454                 itnim->stats.iocom_hostabrts;
1455         fcpim->del_itn_stats.del_itn_total_ios += itnim->stats.total_ios;
1456         fcpim->del_itn_stats.del_io_iocdowns += itnim->stats.io_iocdowns;
1457         fcpim->del_itn_stats.del_tm_iocdowns += itnim->stats.tm_iocdowns;
1458 }
1459
1460
1461
1462 /*
1463  *  bfa_itnim_public
1464  */
1465
1466 /*
1467  *      Itnim interrupt processing.
1468  */
1469 void
1470 bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
1471 {
1472         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
1473         union bfi_itnim_i2h_msg_u msg;
1474         struct bfa_itnim_s *itnim;
1475
1476         bfa_trc(bfa, m->mhdr.msg_id);
1477
1478         msg.msg = m;
1479
1480         switch (m->mhdr.msg_id) {
1481         case BFI_ITNIM_I2H_CREATE_RSP:
1482                 itnim = BFA_ITNIM_FROM_TAG(fcpim,
1483                                                 msg.create_rsp->bfa_handle);
1484                 bfa_assert(msg.create_rsp->status == BFA_STATUS_OK);
1485                 bfa_stats(itnim, create_comps);
1486                 bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP);
1487                 break;
1488
1489         case BFI_ITNIM_I2H_DELETE_RSP:
1490                 itnim = BFA_ITNIM_FROM_TAG(fcpim,
1491                                                 msg.delete_rsp->bfa_handle);
1492                 bfa_assert(msg.delete_rsp->status == BFA_STATUS_OK);
1493                 bfa_stats(itnim, delete_comps);
1494                 bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP);
1495                 break;
1496
1497         case BFI_ITNIM_I2H_SLER_EVENT:
1498                 itnim = BFA_ITNIM_FROM_TAG(fcpim,
1499                                                 msg.sler_event->bfa_handle);
1500                 bfa_stats(itnim, sler_events);
1501                 bfa_sm_send_event(itnim, BFA_ITNIM_SM_SLER);
1502                 break;
1503
1504         default:
1505                 bfa_trc(bfa, m->mhdr.msg_id);
1506                 bfa_assert(0);
1507         }
1508 }
1509
1510
1511
1512 /*
1513  *  bfa_itnim_api
1514  */
1515
1516 struct bfa_itnim_s *
1517 bfa_itnim_create(struct bfa_s *bfa, struct bfa_rport_s *rport, void *ditn)
1518 {
1519         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
1520         struct bfa_itnim_s *itnim;
1521
1522         itnim = BFA_ITNIM_FROM_TAG(fcpim, rport->rport_tag);
1523         bfa_assert(itnim->rport == rport);
1524
1525         itnim->ditn = ditn;
1526
1527         bfa_stats(itnim, creates);
1528         bfa_sm_send_event(itnim, BFA_ITNIM_SM_CREATE);
1529
1530         return itnim;
1531 }
1532
1533 void
1534 bfa_itnim_delete(struct bfa_itnim_s *itnim)
1535 {
1536         bfa_stats(itnim, deletes);
1537         bfa_sm_send_event(itnim, BFA_ITNIM_SM_DELETE);
1538 }
1539
1540 void
1541 bfa_itnim_online(struct bfa_itnim_s *itnim, bfa_boolean_t seq_rec)
1542 {
1543         itnim->seq_rec = seq_rec;
1544         bfa_stats(itnim, onlines);
1545         bfa_sm_send_event(itnim, BFA_ITNIM_SM_ONLINE);
1546 }
1547
1548 void
1549 bfa_itnim_offline(struct bfa_itnim_s *itnim)
1550 {
1551         bfa_stats(itnim, offlines);
1552         bfa_sm_send_event(itnim, BFA_ITNIM_SM_OFFLINE);
1553 }
1554
1555 /*
1556  * Return true if itnim is considered offline for holding off IO request.
1557  * IO is not held if itnim is being deleted.
1558  */
1559 bfa_boolean_t
1560 bfa_itnim_hold_io(struct bfa_itnim_s *itnim)
1561 {
1562         return itnim->fcpim->path_tov && itnim->iotov_active &&
1563                 (bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwcreate) ||
1564                  bfa_sm_cmp_state(itnim, bfa_itnim_sm_sler) ||
1565                  bfa_sm_cmp_state(itnim, bfa_itnim_sm_cleanup_offline) ||
1566                  bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwdelete) ||
1567                  bfa_sm_cmp_state(itnim, bfa_itnim_sm_offline) ||
1568                  bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable));
1569 }
1570
1571 bfa_status_t
1572 bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim,
1573                 struct bfa_itnim_ioprofile_s *ioprofile)
1574 {
1575         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(itnim->bfa);
1576         if (!fcpim->io_profile)
1577                 return BFA_STATUS_IOPROFILE_OFF;
1578
1579         itnim->ioprofile.index = BFA_IOBUCKET_MAX;
1580         itnim->ioprofile.io_profile_start_time =
1581                 bfa_io_profile_start_time(itnim->bfa);
1582         itnim->ioprofile.clock_res_mul = bfa_io_lat_clock_res_mul;
1583         itnim->ioprofile.clock_res_div = bfa_io_lat_clock_res_div;
1584         *ioprofile = itnim->ioprofile;
1585
1586         return BFA_STATUS_OK;
1587 }
1588
1589 void
1590 bfa_itnim_get_stats(struct bfa_itnim_s *itnim,
1591         struct bfa_itnim_iostats_s *stats)
1592 {
1593         *stats = itnim->stats;
1594 }
1595
1596 void
1597 bfa_itnim_clear_stats(struct bfa_itnim_s *itnim)
1598 {
1599         int j;
1600         memset(&itnim->stats, 0, sizeof(itnim->stats));
1601         memset(&itnim->ioprofile, 0, sizeof(itnim->ioprofile));
1602         for (j = 0; j < BFA_IOBUCKET_MAX; j++)
1603                 itnim->ioprofile.io_latency.min[j] = ~0;
1604 }
1605
1606 /*
1607  *  BFA IO module state machine functions
1608  */
1609
1610 /*
1611  *      IO is not started (unallocated).
1612  */
1613 static void
1614 bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1615 {
1616         bfa_trc_fp(ioim->bfa, ioim->iotag);
1617         bfa_trc_fp(ioim->bfa, event);
1618
1619         switch (event) {
1620         case BFA_IOIM_SM_START:
1621                 if (!bfa_itnim_is_online(ioim->itnim)) {
1622                         if (!bfa_itnim_hold_io(ioim->itnim)) {
1623                                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1624                                 list_del(&ioim->qe);
1625                                 list_add_tail(&ioim->qe,
1626                                         &ioim->fcpim->ioim_comp_q);
1627                                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1628                                                 __bfa_cb_ioim_pathtov, ioim);
1629                         } else {
1630                                 list_del(&ioim->qe);
1631                                 list_add_tail(&ioim->qe,
1632                                         &ioim->itnim->pending_q);
1633                         }
1634                         break;
1635                 }
1636
1637                 if (ioim->nsges > BFI_SGE_INLINE) {
1638                         if (!bfa_ioim_sge_setup(ioim)) {
1639                                 bfa_sm_set_state(ioim, bfa_ioim_sm_sgalloc);
1640                                 return;
1641                         }
1642                 }
1643
1644                 if (!bfa_ioim_send_ioreq(ioim)) {
1645                         bfa_sm_set_state(ioim, bfa_ioim_sm_qfull);
1646                         break;
1647                 }
1648
1649                 bfa_sm_set_state(ioim, bfa_ioim_sm_active);
1650                 break;
1651
1652         case BFA_IOIM_SM_IOTOV:
1653                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1654                 bfa_ioim_move_to_comp_q(ioim);
1655                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1656                                 __bfa_cb_ioim_pathtov, ioim);
1657                 break;
1658
1659         case BFA_IOIM_SM_ABORT:
1660                 /*
1661                  * IO in pending queue can get abort requests. Complete abort
1662                  * requests immediately.
1663                  */
1664                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1665                 bfa_assert(bfa_q_is_on_q(&ioim->itnim->pending_q, ioim));
1666                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1667                                 __bfa_cb_ioim_abort, ioim);
1668                 break;
1669
1670         default:
1671                 bfa_sm_fault(ioim->bfa, event);
1672         }
1673 }
1674
1675 /*
1676  *      IO is waiting for SG pages.
1677  */
1678 static void
1679 bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1680 {
1681         bfa_trc(ioim->bfa, ioim->iotag);
1682         bfa_trc(ioim->bfa, event);
1683
1684         switch (event) {
1685         case BFA_IOIM_SM_SGALLOCED:
1686                 if (!bfa_ioim_send_ioreq(ioim)) {
1687                         bfa_sm_set_state(ioim, bfa_ioim_sm_qfull);
1688                         break;
1689                 }
1690                 bfa_sm_set_state(ioim, bfa_ioim_sm_active);
1691                 break;
1692
1693         case BFA_IOIM_SM_CLEANUP:
1694                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1695                 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
1696                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1697                               ioim);
1698                 bfa_ioim_notify_cleanup(ioim);
1699                 break;
1700
1701         case BFA_IOIM_SM_ABORT:
1702                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1703                 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
1704                 bfa_ioim_move_to_comp_q(ioim);
1705                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1706                               ioim);
1707                 break;
1708
1709         case BFA_IOIM_SM_HWFAIL:
1710                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1711                 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
1712                 bfa_ioim_move_to_comp_q(ioim);
1713                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1714                               ioim);
1715                 break;
1716
1717         default:
1718                 bfa_sm_fault(ioim->bfa, event);
1719         }
1720 }
1721
1722 /*
1723  *      IO is active.
1724  */
1725 static void
1726 bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1727 {
1728         bfa_trc_fp(ioim->bfa, ioim->iotag);
1729         bfa_trc_fp(ioim->bfa, event);
1730
1731         switch (event) {
1732         case BFA_IOIM_SM_COMP_GOOD:
1733                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1734                 bfa_ioim_move_to_comp_q(ioim);
1735                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1736                               __bfa_cb_ioim_good_comp, ioim);
1737                 break;
1738
1739         case BFA_IOIM_SM_COMP:
1740                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1741                 bfa_ioim_move_to_comp_q(ioim);
1742                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp,
1743                               ioim);
1744                 break;
1745
1746         case BFA_IOIM_SM_DONE:
1747                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1748                 bfa_ioim_move_to_comp_q(ioim);
1749                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp,
1750                               ioim);
1751                 break;
1752
1753         case BFA_IOIM_SM_ABORT:
1754                 ioim->iosp->abort_explicit = BFA_TRUE;
1755                 ioim->io_cbfn = __bfa_cb_ioim_abort;
1756
1757                 if (bfa_ioim_send_abort(ioim))
1758                         bfa_sm_set_state(ioim, bfa_ioim_sm_abort);
1759                 else {
1760                         bfa_sm_set_state(ioim, bfa_ioim_sm_abort_qfull);
1761                         bfa_stats(ioim->itnim, qwait);
1762                         bfa_reqq_wait(ioim->bfa, ioim->reqq,
1763                                           &ioim->iosp->reqq_wait);
1764                 }
1765                 break;
1766
1767         case BFA_IOIM_SM_CLEANUP:
1768                 ioim->iosp->abort_explicit = BFA_FALSE;
1769                 ioim->io_cbfn = __bfa_cb_ioim_failed;
1770
1771                 if (bfa_ioim_send_abort(ioim))
1772                         bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
1773                 else {
1774                         bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
1775                         bfa_stats(ioim->itnim, qwait);
1776                         bfa_reqq_wait(ioim->bfa, ioim->reqq,
1777                                           &ioim->iosp->reqq_wait);
1778                 }
1779                 break;
1780
1781         case BFA_IOIM_SM_HWFAIL:
1782                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1783                 bfa_ioim_move_to_comp_q(ioim);
1784                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1785                               ioim);
1786                 break;
1787
1788         case BFA_IOIM_SM_SQRETRY:
1789                 if (bfa_ioim_get_iotag(ioim) != BFA_TRUE) {
1790                         /* max retry completed free IO */
1791                         bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1792                         bfa_ioim_move_to_comp_q(ioim);
1793                         bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1794                                         __bfa_cb_ioim_failed, ioim);
1795                         break;
1796                 }
1797                 /* waiting for IO tag resource free */
1798                 bfa_sm_set_state(ioim, bfa_ioim_sm_cmnd_retry);
1799                 break;
1800
1801         default:
1802                 bfa_sm_fault(ioim->bfa, event);
1803         }
1804 }
1805
1806 /*
1807 *       IO is retried with new tag.
1808 */
1809 static void
1810 bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1811 {
1812         bfa_trc_fp(ioim->bfa, ioim->iotag);
1813         bfa_trc_fp(ioim->bfa, event);
1814
1815         switch (event) {
1816         case BFA_IOIM_SM_FREE:
1817                 /* abts and rrq done. Now retry the IO with new tag */
1818                 if (!bfa_ioim_send_ioreq(ioim)) {
1819                         bfa_sm_set_state(ioim, bfa_ioim_sm_qfull);
1820                         break;
1821                 }
1822                 bfa_sm_set_state(ioim, bfa_ioim_sm_active);
1823         break;
1824
1825         case BFA_IOIM_SM_CLEANUP:
1826                 ioim->iosp->abort_explicit = BFA_FALSE;
1827                 ioim->io_cbfn = __bfa_cb_ioim_failed;
1828
1829                 if (bfa_ioim_send_abort(ioim))
1830                         bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
1831                 else {
1832                         bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
1833                         bfa_stats(ioim->itnim, qwait);
1834                         bfa_reqq_wait(ioim->bfa, ioim->reqq,
1835                                           &ioim->iosp->reqq_wait);
1836                 }
1837         break;
1838
1839         case BFA_IOIM_SM_HWFAIL:
1840                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1841                 bfa_ioim_move_to_comp_q(ioim);
1842                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
1843                          __bfa_cb_ioim_failed, ioim);
1844                 break;
1845
1846         case BFA_IOIM_SM_ABORT:
1847                 /* in this state IO abort is done.
1848                  * Waiting for IO tag resource free.
1849                  */
1850                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1851                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1852                               ioim);
1853                 break;
1854
1855         default:
1856                 bfa_sm_fault(ioim->bfa, event);
1857         }
1858 }
1859
1860 /*
1861  *      IO is being aborted, waiting for completion from firmware.
1862  */
1863 static void
1864 bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1865 {
1866         bfa_trc(ioim->bfa, ioim->iotag);
1867         bfa_trc(ioim->bfa, event);
1868
1869         switch (event) {
1870         case BFA_IOIM_SM_COMP_GOOD:
1871         case BFA_IOIM_SM_COMP:
1872         case BFA_IOIM_SM_DONE:
1873         case BFA_IOIM_SM_FREE:
1874                 break;
1875
1876         case BFA_IOIM_SM_ABORT_DONE:
1877                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1878                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1879                               ioim);
1880                 break;
1881
1882         case BFA_IOIM_SM_ABORT_COMP:
1883                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1884                 bfa_ioim_move_to_comp_q(ioim);
1885                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1886                               ioim);
1887                 break;
1888
1889         case BFA_IOIM_SM_COMP_UTAG:
1890                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1891                 bfa_ioim_move_to_comp_q(ioim);
1892                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
1893                               ioim);
1894                 break;
1895
1896         case BFA_IOIM_SM_CLEANUP:
1897                 bfa_assert(ioim->iosp->abort_explicit == BFA_TRUE);
1898                 ioim->iosp->abort_explicit = BFA_FALSE;
1899
1900                 if (bfa_ioim_send_abort(ioim))
1901                         bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
1902                 else {
1903                         bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
1904                         bfa_stats(ioim->itnim, qwait);
1905                         bfa_reqq_wait(ioim->bfa, ioim->reqq,
1906                                           &ioim->iosp->reqq_wait);
1907                 }
1908                 break;
1909
1910         case BFA_IOIM_SM_HWFAIL:
1911                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1912                 bfa_ioim_move_to_comp_q(ioim);
1913                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1914                               ioim);
1915                 break;
1916
1917         default:
1918                 bfa_sm_fault(ioim->bfa, event);
1919         }
1920 }
1921
1922 /*
1923  * IO is being cleaned up (implicit abort), waiting for completion from
1924  * firmware.
1925  */
1926 static void
1927 bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1928 {
1929         bfa_trc(ioim->bfa, ioim->iotag);
1930         bfa_trc(ioim->bfa, event);
1931
1932         switch (event) {
1933         case BFA_IOIM_SM_COMP_GOOD:
1934         case BFA_IOIM_SM_COMP:
1935         case BFA_IOIM_SM_DONE:
1936         case BFA_IOIM_SM_FREE:
1937                 break;
1938
1939         case BFA_IOIM_SM_ABORT:
1940                 /*
1941                  * IO is already being aborted implicitly
1942                  */
1943                 ioim->io_cbfn = __bfa_cb_ioim_abort;
1944                 break;
1945
1946         case BFA_IOIM_SM_ABORT_DONE:
1947                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
1948                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
1949                 bfa_ioim_notify_cleanup(ioim);
1950                 break;
1951
1952         case BFA_IOIM_SM_ABORT_COMP:
1953                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1954                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
1955                 bfa_ioim_notify_cleanup(ioim);
1956                 break;
1957
1958         case BFA_IOIM_SM_COMP_UTAG:
1959                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1960                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
1961                 bfa_ioim_notify_cleanup(ioim);
1962                 break;
1963
1964         case BFA_IOIM_SM_HWFAIL:
1965                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
1966                 bfa_ioim_move_to_comp_q(ioim);
1967                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
1968                               ioim);
1969                 break;
1970
1971         case BFA_IOIM_SM_CLEANUP:
1972                 /*
1973                  * IO can be in cleanup state already due to TM command.
1974                  * 2nd cleanup request comes from ITN offline event.
1975                  */
1976                 break;
1977
1978         default:
1979                 bfa_sm_fault(ioim->bfa, event);
1980         }
1981 }
1982
1983 /*
1984  *      IO is waiting for room in request CQ
1985  */
1986 static void
1987 bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
1988 {
1989         bfa_trc(ioim->bfa, ioim->iotag);
1990         bfa_trc(ioim->bfa, event);
1991
1992         switch (event) {
1993         case BFA_IOIM_SM_QRESUME:
1994                 bfa_sm_set_state(ioim, bfa_ioim_sm_active);
1995                 bfa_ioim_send_ioreq(ioim);
1996                 break;
1997
1998         case BFA_IOIM_SM_ABORT:
1999                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
2000                 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
2001                 bfa_ioim_move_to_comp_q(ioim);
2002                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
2003                               ioim);
2004                 break;
2005
2006         case BFA_IOIM_SM_CLEANUP:
2007                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
2008                 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
2009                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
2010                               ioim);
2011                 bfa_ioim_notify_cleanup(ioim);
2012                 break;
2013
2014         case BFA_IOIM_SM_HWFAIL:
2015                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
2016                 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
2017                 bfa_ioim_move_to_comp_q(ioim);
2018                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
2019                               ioim);
2020                 break;
2021
2022         default:
2023                 bfa_sm_fault(ioim->bfa, event);
2024         }
2025 }
2026
2027 /*
2028  *      Active IO is being aborted, waiting for room in request CQ.
2029  */
2030 static void
2031 bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
2032 {
2033         bfa_trc(ioim->bfa, ioim->iotag);
2034         bfa_trc(ioim->bfa, event);
2035
2036         switch (event) {
2037         case BFA_IOIM_SM_QRESUME:
2038                 bfa_sm_set_state(ioim, bfa_ioim_sm_abort);
2039                 bfa_ioim_send_abort(ioim);
2040                 break;
2041
2042         case BFA_IOIM_SM_CLEANUP:
2043                 bfa_assert(ioim->iosp->abort_explicit == BFA_TRUE);
2044                 ioim->iosp->abort_explicit = BFA_FALSE;
2045                 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
2046                 break;
2047
2048         case BFA_IOIM_SM_COMP_GOOD:
2049         case BFA_IOIM_SM_COMP:
2050                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
2051                 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
2052                 bfa_ioim_move_to_comp_q(ioim);
2053                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
2054                               ioim);
2055                 break;
2056
2057         case BFA_IOIM_SM_DONE:
2058                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
2059                 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
2060                 bfa_ioim_move_to_comp_q(ioim);
2061                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
2062                               ioim);
2063                 break;
2064
2065         case BFA_IOIM_SM_HWFAIL:
2066                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
2067                 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
2068                 bfa_ioim_move_to_comp_q(ioim);
2069                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
2070                               ioim);
2071                 break;
2072
2073         default:
2074                 bfa_sm_fault(ioim->bfa, event);
2075         }
2076 }
2077
2078 /*
2079  *      Active IO is being cleaned up, waiting for room in request CQ.
2080  */
2081 static void
2082 bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
2083 {
2084         bfa_trc(ioim->bfa, ioim->iotag);
2085         bfa_trc(ioim->bfa, event);
2086
2087         switch (event) {
2088         case BFA_IOIM_SM_QRESUME:
2089                 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
2090                 bfa_ioim_send_abort(ioim);
2091                 break;
2092
2093         case BFA_IOIM_SM_ABORT:
2094                 /*
2095                  * IO is already being cleaned up implicitly
2096                  */
2097                 ioim->io_cbfn = __bfa_cb_ioim_abort;
2098                 break;
2099
2100         case BFA_IOIM_SM_COMP_GOOD:
2101         case BFA_IOIM_SM_COMP:
2102                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
2103                 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
2104                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
2105                 bfa_ioim_notify_cleanup(ioim);
2106                 break;
2107
2108         case BFA_IOIM_SM_DONE:
2109                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
2110                 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
2111                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
2112                 bfa_ioim_notify_cleanup(ioim);
2113                 break;
2114
2115         case BFA_IOIM_SM_HWFAIL:
2116                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
2117                 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
2118                 bfa_ioim_move_to_comp_q(ioim);
2119                 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
2120                               ioim);
2121                 break;
2122
2123         default:
2124                 bfa_sm_fault(ioim->bfa, event);
2125         }
2126 }
2127
2128 /*
2129  * IO bfa callback is pending.
2130  */
2131 static void
2132 bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
2133 {
2134         bfa_trc_fp(ioim->bfa, ioim->iotag);
2135         bfa_trc_fp(ioim->bfa, event);
2136
2137         switch (event) {
2138         case BFA_IOIM_SM_HCB:
2139                 bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
2140                 bfa_ioim_free(ioim);
2141                 break;
2142
2143         case BFA_IOIM_SM_CLEANUP:
2144                 bfa_ioim_notify_cleanup(ioim);
2145                 break;
2146
2147         case BFA_IOIM_SM_HWFAIL:
2148                 break;
2149
2150         default:
2151                 bfa_sm_fault(ioim->bfa, event);
2152         }
2153 }
2154
2155 /*
2156  * IO bfa callback is pending. IO resource cannot be freed.
2157  */
2158 static void
2159 bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
2160 {
2161         bfa_trc(ioim->bfa, ioim->iotag);
2162         bfa_trc(ioim->bfa, event);
2163
2164         switch (event) {
2165         case BFA_IOIM_SM_HCB:
2166                 bfa_sm_set_state(ioim, bfa_ioim_sm_resfree);
2167                 list_del(&ioim->qe);
2168                 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_resfree_q);
2169                 break;
2170
2171         case BFA_IOIM_SM_FREE:
2172                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
2173                 break;
2174
2175         case BFA_IOIM_SM_CLEANUP:
2176                 bfa_ioim_notify_cleanup(ioim);
2177                 break;
2178
2179         case BFA_IOIM_SM_HWFAIL:
2180                 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
2181                 break;
2182
2183         default:
2184                 bfa_sm_fault(ioim->bfa, event);
2185         }
2186 }
2187
2188 /*
2189  * IO is completed, waiting resource free from firmware.
2190  */
2191 static void
2192 bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
2193 {
2194         bfa_trc(ioim->bfa, ioim->iotag);
2195         bfa_trc(ioim->bfa, event);
2196
2197         switch (event) {
2198         case BFA_IOIM_SM_FREE:
2199                 bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
2200                 bfa_ioim_free(ioim);
2201                 break;
2202
2203         case BFA_IOIM_SM_CLEANUP:
2204                 bfa_ioim_notify_cleanup(ioim);
2205                 break;
2206
2207         case BFA_IOIM_SM_HWFAIL:
2208                 break;
2209
2210         default:
2211                 bfa_sm_fault(ioim->bfa, event);
2212         }
2213 }
2214
2215
2216
2217 /*
2218  *  hal_ioim_private
2219  */
2220
2221 static void
2222 __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete)
2223 {
2224         struct bfa_ioim_s *ioim = cbarg;
2225
2226         if (!complete) {
2227                 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2228                 return;
2229         }
2230
2231         bfa_cb_ioim_good_comp(ioim->bfa->bfad, ioim->dio);
2232 }
2233
2234 static void
2235 __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete)
2236 {
2237         struct bfa_ioim_s       *ioim = cbarg;
2238         struct bfi_ioim_rsp_s *m;
2239         u8      *snsinfo = NULL;
2240         u8      sns_len = 0;
2241         s32     residue = 0;
2242
2243         if (!complete) {
2244                 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2245                 return;
2246         }
2247
2248         m = (struct bfi_ioim_rsp_s *) &ioim->iosp->comp_rspmsg;
2249         if (m->io_status == BFI_IOIM_STS_OK) {
2250                 /*
2251                  * setup sense information, if present
2252                  */
2253                 if ((m->scsi_status == SCSI_STATUS_CHECK_CONDITION) &&
2254                                         m->sns_len) {
2255                         sns_len = m->sns_len;
2256                         snsinfo = ioim->iosp->snsinfo;
2257                 }
2258
2259                 /*
2260                  * setup residue value correctly for normal completions
2261                  */
2262                 if (m->resid_flags == FCP_RESID_UNDER) {
2263                         residue = be32_to_cpu(m->residue);
2264                         bfa_stats(ioim->itnim, iocomp_underrun);
2265                 }
2266                 if (m->resid_flags == FCP_RESID_OVER) {
2267                         residue = be32_to_cpu(m->residue);
2268                         residue = -residue;
2269                         bfa_stats(ioim->itnim, iocomp_overrun);
2270                 }
2271         }
2272
2273         bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, m->io_status,
2274                           m->scsi_status, sns_len, snsinfo, residue);
2275 }
2276
2277 static void
2278 __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete)
2279 {
2280         struct bfa_ioim_s *ioim = cbarg;
2281
2282         if (!complete) {
2283                 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2284                 return;
2285         }
2286
2287         bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_ABORTED,
2288                           0, 0, NULL, 0);
2289 }
2290
2291 static void
2292 __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete)
2293 {
2294         struct bfa_ioim_s *ioim = cbarg;
2295
2296         bfa_stats(ioim->itnim, path_tov_expired);
2297         if (!complete) {
2298                 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2299                 return;
2300         }
2301
2302         bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_PATHTOV,
2303                           0, 0, NULL, 0);
2304 }
2305
2306 static void
2307 __bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete)
2308 {
2309         struct bfa_ioim_s *ioim = cbarg;
2310
2311         if (!complete) {
2312                 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
2313                 return;
2314         }
2315
2316         bfa_cb_ioim_abort(ioim->bfa->bfad, ioim->dio);
2317 }
2318
2319 static void
2320 bfa_ioim_sgpg_alloced(void *cbarg)
2321 {
2322         struct bfa_ioim_s *ioim = cbarg;
2323
2324         ioim->nsgpgs = BFA_SGPG_NPAGE(ioim->nsges);
2325         list_splice_tail_init(&ioim->iosp->sgpg_wqe.sgpg_q, &ioim->sgpg_q);
2326         bfa_ioim_sgpg_setup(ioim);
2327         bfa_sm_send_event(ioim, BFA_IOIM_SM_SGALLOCED);
2328 }
2329
2330 /*
2331  * Send I/O request to firmware.
2332  */
2333 static  bfa_boolean_t
2334 bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
2335 {
2336         struct bfa_itnim_s *itnim = ioim->itnim;
2337         struct bfi_ioim_req_s *m;
2338         static struct fcp_cmnd_s cmnd_z0 = { 0 };
2339         struct bfi_sge_s      *sge;
2340         u32     pgdlen = 0;
2341         u32     fcp_dl;
2342         u64 addr;
2343         struct scatterlist *sg;
2344         struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio;
2345
2346         /*
2347          * check for room in queue to send request now
2348          */
2349         m = bfa_reqq_next(ioim->bfa, ioim->reqq);
2350         if (!m) {
2351                 bfa_stats(ioim->itnim, qwait);
2352                 bfa_reqq_wait(ioim->bfa, ioim->reqq,
2353                                   &ioim->iosp->reqq_wait);
2354                 return BFA_FALSE;
2355         }
2356
2357         /*
2358          * build i/o request message next
2359          */
2360         m->io_tag = cpu_to_be16(ioim->iotag);
2361         m->rport_hdl = ioim->itnim->rport->fw_handle;
2362         m->io_timeout = bfa_cb_ioim_get_timeout(ioim->dio);
2363
2364         /*
2365          * build inline IO SG element here
2366          */
2367         sge = &m->sges[0];
2368         if (ioim->nsges) {
2369                 sg = (struct scatterlist *)scsi_sglist(cmnd);
2370                 addr = bfa_os_sgaddr(sg_dma_address(sg));
2371                 sge->sga = *(union bfi_addr_u *) &addr;
2372                 pgdlen = sg_dma_len(sg);
2373                 sge->sg_len = pgdlen;
2374                 sge->flags = (ioim->nsges > BFI_SGE_INLINE) ?
2375                                         BFI_SGE_DATA_CPL : BFI_SGE_DATA_LAST;
2376                 bfa_sge_to_be(sge);
2377                 sge++;
2378         }
2379
2380         if (ioim->nsges > BFI_SGE_INLINE) {
2381                 sge->sga = ioim->sgpg->sgpg_pa;
2382         } else {
2383                 sge->sga.a32.addr_lo = 0;
2384                 sge->sga.a32.addr_hi = 0;
2385         }
2386         sge->sg_len = pgdlen;
2387         sge->flags = BFI_SGE_PGDLEN;
2388         bfa_sge_to_be(sge);
2389
2390         /*
2391          * set up I/O command parameters
2392          */
2393         m->cmnd = cmnd_z0;
2394         m->cmnd.lun = bfa_cb_ioim_get_lun(ioim->dio);
2395         m->cmnd.iodir = bfa_cb_ioim_get_iodir(ioim->dio);
2396         m->cmnd.cdb = *(scsi_cdb_t *)bfa_cb_ioim_get_cdb(ioim->dio);
2397         fcp_dl = bfa_cb_ioim_get_size(ioim->dio);
2398         m->cmnd.fcp_dl = cpu_to_be32(fcp_dl);
2399
2400         /*
2401          * set up I/O message header
2402          */
2403         switch (m->cmnd.iodir) {
2404         case FCP_IODIR_READ:
2405                 bfi_h2i_set(m->mh, BFI_MC_IOIM_READ, 0, bfa_lpuid(ioim->bfa));
2406                 bfa_stats(itnim, input_reqs);
2407                 ioim->itnim->stats.rd_throughput += fcp_dl;
2408                 break;
2409         case FCP_IODIR_WRITE:
2410                 bfi_h2i_set(m->mh, BFI_MC_IOIM_WRITE, 0, bfa_lpuid(ioim->bfa));
2411                 bfa_stats(itnim, output_reqs);
2412                 ioim->itnim->stats.wr_throughput += fcp_dl;
2413                 break;
2414         case FCP_IODIR_RW:
2415                 bfa_stats(itnim, input_reqs);
2416                 bfa_stats(itnim, output_reqs);
2417         default:
2418                 bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa));
2419         }
2420         if (itnim->seq_rec ||
2421             (bfa_cb_ioim_get_size(ioim->dio) & (sizeof(u32) - 1)))
2422                 bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa));
2423
2424 #ifdef IOIM_ADVANCED
2425         m->cmnd.crn = bfa_cb_ioim_get_crn(ioim->dio);
2426         m->cmnd.priority = bfa_cb_ioim_get_priority(ioim->dio);
2427         m->cmnd.taskattr = bfa_cb_ioim_get_taskattr(ioim->dio);
2428
2429         /*
2430          * Handle large CDB (>16 bytes).
2431          */
2432         m->cmnd.addl_cdb_len = (bfa_cb_ioim_get_cdblen(ioim->dio) -
2433                                         FCP_CMND_CDB_LEN) / sizeof(u32);
2434         if (m->cmnd.addl_cdb_len) {
2435                 memcpy(&m->cmnd.cdb + 1, (scsi_cdb_t *)
2436                                 bfa_cb_ioim_get_cdb(ioim->dio) + 1,
2437                                 m->cmnd.addl_cdb_len * sizeof(u32));
2438                 fcp_cmnd_fcpdl(&m->cmnd) =
2439                                 cpu_to_be32(bfa_cb_ioim_get_size(ioim->dio));
2440         }
2441 #endif
2442
2443         /*
2444          * queue I/O message to firmware
2445          */
2446         bfa_reqq_produce(ioim->bfa, ioim->reqq);
2447         return BFA_TRUE;
2448 }
2449
2450 /*
2451  * Setup any additional SG pages needed.Inline SG element is setup
2452  * at queuing time.
2453  */
2454 static bfa_boolean_t
2455 bfa_ioim_sge_setup(struct bfa_ioim_s *ioim)
2456 {
2457         u16     nsgpgs;
2458
2459         bfa_assert(ioim->nsges > BFI_SGE_INLINE);
2460
2461         /*
2462          * allocate SG pages needed
2463          */
2464         nsgpgs = BFA_SGPG_NPAGE(ioim->nsges);
2465         if (!nsgpgs)
2466                 return BFA_TRUE;
2467
2468         if (bfa_sgpg_malloc(ioim->bfa, &ioim->sgpg_q, nsgpgs)
2469             != BFA_STATUS_OK) {
2470                 bfa_sgpg_wait(ioim->bfa, &ioim->iosp->sgpg_wqe, nsgpgs);
2471                 return BFA_FALSE;
2472         }
2473
2474         ioim->nsgpgs = nsgpgs;
2475         bfa_ioim_sgpg_setup(ioim);
2476
2477         return BFA_TRUE;
2478 }
2479
2480 static void
2481 bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim)
2482 {
2483         int             sgeid, nsges, i;
2484         struct bfi_sge_s      *sge;
2485         struct bfa_sgpg_s *sgpg;
2486         u32     pgcumsz;
2487         u64        addr;
2488         struct scatterlist *sg;
2489         struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio;
2490
2491         sgeid = BFI_SGE_INLINE;
2492         ioim->sgpg = sgpg = bfa_q_first(&ioim->sgpg_q);
2493
2494         sg = scsi_sglist(cmnd);
2495         sg = sg_next(sg);
2496
2497         do {
2498                 sge = sgpg->sgpg->sges;
2499                 nsges = ioim->nsges - sgeid;
2500                 if (nsges > BFI_SGPG_DATA_SGES)
2501                         nsges = BFI_SGPG_DATA_SGES;
2502
2503                 pgcumsz = 0;
2504                 for (i = 0; i < nsges; i++, sge++, sgeid++, sg = sg_next(sg)) {
2505                         addr = bfa_os_sgaddr(sg_dma_address(sg));
2506                         sge->sga = *(union bfi_addr_u *) &addr;
2507                         sge->sg_len = sg_dma_len(sg);
2508                         pgcumsz += sge->sg_len;
2509
2510                         /*
2511                          * set flags
2512                          */
2513                         if (i < (nsges - 1))
2514                                 sge->flags = BFI_SGE_DATA;
2515                         else if (sgeid < (ioim->nsges - 1))
2516                                 sge->flags = BFI_SGE_DATA_CPL;
2517                         else
2518                                 sge->flags = BFI_SGE_DATA_LAST;
2519
2520                         bfa_sge_to_le(sge);
2521                 }
2522
2523                 sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg);
2524
2525                 /*
2526                  * set the link element of each page
2527                  */
2528                 if (sgeid == ioim->nsges) {
2529                         sge->flags = BFI_SGE_PGDLEN;
2530                         sge->sga.a32.addr_lo = 0;
2531                         sge->sga.a32.addr_hi = 0;
2532                 } else {
2533                         sge->flags = BFI_SGE_LINK;
2534                         sge->sga = sgpg->sgpg_pa;
2535                 }
2536                 sge->sg_len = pgcumsz;
2537
2538                 bfa_sge_to_le(sge);
2539         } while (sgeid < ioim->nsges);
2540 }
2541
2542 /*
2543  * Send I/O abort request to firmware.
2544  */
2545 static  bfa_boolean_t
2546 bfa_ioim_send_abort(struct bfa_ioim_s *ioim)
2547 {
2548         struct bfi_ioim_abort_req_s *m;
2549         enum bfi_ioim_h2i       msgop;
2550
2551         /*
2552          * check for room in queue to send request now
2553          */
2554         m = bfa_reqq_next(ioim->bfa, ioim->reqq);
2555         if (!m)
2556                 return BFA_FALSE;
2557
2558         /*
2559          * build i/o request message next
2560          */
2561         if (ioim->iosp->abort_explicit)
2562                 msgop = BFI_IOIM_H2I_IOABORT_REQ;
2563         else
2564                 msgop = BFI_IOIM_H2I_IOCLEANUP_REQ;
2565
2566         bfi_h2i_set(m->mh, BFI_MC_IOIM, msgop, bfa_lpuid(ioim->bfa));
2567         m->io_tag    = cpu_to_be16(ioim->iotag);
2568         m->abort_tag = ++ioim->abort_tag;
2569
2570         /*
2571          * queue I/O message to firmware
2572          */
2573         bfa_reqq_produce(ioim->bfa, ioim->reqq);
2574         return BFA_TRUE;
2575 }
2576
2577 /*
2578  * Call to resume any I/O requests waiting for room in request queue.
2579  */
2580 static void
2581 bfa_ioim_qresume(void *cbarg)
2582 {
2583         struct bfa_ioim_s *ioim = cbarg;
2584
2585         bfa_stats(ioim->itnim, qresumes);
2586         bfa_sm_send_event(ioim, BFA_IOIM_SM_QRESUME);
2587 }
2588
2589
2590 static void
2591 bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim)
2592 {
2593         /*
2594          * Move IO from itnim queue to fcpim global queue since itnim will be
2595          * freed.
2596          */
2597         list_del(&ioim->qe);
2598         list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
2599
2600         if (!ioim->iosp->tskim) {
2601                 if (ioim->fcpim->delay_comp && ioim->itnim->iotov_active) {
2602                         bfa_cb_dequeue(&ioim->hcb_qe);
2603                         list_del(&ioim->qe);
2604                         list_add_tail(&ioim->qe, &ioim->itnim->delay_comp_q);
2605                 }
2606                 bfa_itnim_iodone(ioim->itnim);
2607         } else
2608                 bfa_tskim_iodone(ioim->iosp->tskim);
2609 }
2610
2611 static bfa_boolean_t
2612 bfa_ioim_is_abortable(struct bfa_ioim_s *ioim)
2613 {
2614         if ((bfa_sm_cmp_state(ioim, bfa_ioim_sm_uninit) &&
2615             (!bfa_q_is_on_q(&ioim->itnim->pending_q, ioim)))    ||
2616             (bfa_sm_cmp_state(ioim, bfa_ioim_sm_abort))         ||
2617             (bfa_sm_cmp_state(ioim, bfa_ioim_sm_abort_qfull))   ||
2618             (bfa_sm_cmp_state(ioim, bfa_ioim_sm_hcb))           ||
2619             (bfa_sm_cmp_state(ioim, bfa_ioim_sm_hcb_free))      ||
2620             (bfa_sm_cmp_state(ioim, bfa_ioim_sm_resfree)))
2621                 return BFA_FALSE;
2622
2623         return BFA_TRUE;
2624 }
2625
2626 /*
2627  *      or after the link comes back.
2628  */
2629 void
2630 bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim, bfa_boolean_t iotov)
2631 {
2632         /*
2633          * If path tov timer expired, failback with PATHTOV status - these
2634          * IO requests are not normally retried by IO stack.
2635          *
2636          * Otherwise device cameback online and fail it with normal failed
2637          * status so that IO stack retries these failed IO requests.
2638          */
2639         if (iotov)
2640                 ioim->io_cbfn = __bfa_cb_ioim_pathtov;
2641         else {
2642                 ioim->io_cbfn = __bfa_cb_ioim_failed;
2643                 bfa_stats(ioim->itnim, iocom_nexus_abort);
2644         }
2645         bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
2646
2647         /*
2648          * Move IO to fcpim global queue since itnim will be
2649          * freed.
2650          */
2651         list_del(&ioim->qe);
2652         list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
2653 }
2654
2655
2656
2657 /*
2658  *  hal_ioim_friend
2659  */
2660
2661 /*
2662  * Memory allocation and initialization.
2663  */
2664 void
2665 bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
2666 {
2667         struct bfa_ioim_s               *ioim;
2668         struct bfa_ioim_sp_s    *iosp;
2669         u16             i;
2670         u8                      *snsinfo;
2671         u32             snsbufsz;
2672
2673         /*
2674          * claim memory first
2675          */
2676         ioim = (struct bfa_ioim_s *) bfa_meminfo_kva(minfo);
2677         fcpim->ioim_arr = ioim;
2678         bfa_meminfo_kva(minfo) = (u8 *) (ioim + fcpim->num_ioim_reqs);
2679
2680         iosp = (struct bfa_ioim_sp_s *) bfa_meminfo_kva(minfo);
2681         fcpim->ioim_sp_arr = iosp;
2682         bfa_meminfo_kva(minfo) = (u8 *) (iosp + fcpim->num_ioim_reqs);
2683
2684         /*
2685          * Claim DMA memory for per IO sense data.
2686          */
2687         snsbufsz = fcpim->num_ioim_reqs * BFI_IOIM_SNSLEN;
2688         fcpim->snsbase.pa  = bfa_meminfo_dma_phys(minfo);
2689         bfa_meminfo_dma_phys(minfo) += snsbufsz;
2690
2691         fcpim->snsbase.kva = bfa_meminfo_dma_virt(minfo);
2692         bfa_meminfo_dma_virt(minfo) += snsbufsz;
2693         snsinfo = fcpim->snsbase.kva;
2694         bfa_iocfc_set_snsbase(fcpim->bfa, fcpim->snsbase.pa);
2695
2696         /*
2697          * Initialize ioim free queues
2698          */
2699         INIT_LIST_HEAD(&fcpim->ioim_free_q);
2700         INIT_LIST_HEAD(&fcpim->ioim_resfree_q);
2701         INIT_LIST_HEAD(&fcpim->ioim_comp_q);
2702
2703         for (i = 0; i < fcpim->num_ioim_reqs;
2704              i++, ioim++, iosp++, snsinfo += BFI_IOIM_SNSLEN) {
2705                 /*
2706                  * initialize IOIM
2707                  */
2708                 memset(ioim, 0, sizeof(struct bfa_ioim_s));
2709                 ioim->iotag   = i;
2710                 ioim->bfa     = fcpim->bfa;
2711                 ioim->fcpim   = fcpim;
2712                 ioim->iosp    = iosp;
2713                 iosp->snsinfo = snsinfo;
2714                 INIT_LIST_HEAD(&ioim->sgpg_q);
2715                 bfa_reqq_winit(&ioim->iosp->reqq_wait,
2716                                    bfa_ioim_qresume, ioim);
2717                 bfa_sgpg_winit(&ioim->iosp->sgpg_wqe,
2718                                    bfa_ioim_sgpg_alloced, ioim);
2719                 bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
2720
2721                 list_add_tail(&ioim->qe, &fcpim->ioim_free_q);
2722         }
2723 }
2724
2725 /*
2726  * Driver detach time call.
2727  */
2728 void
2729 bfa_ioim_detach(struct bfa_fcpim_mod_s *fcpim)
2730 {
2731 }
2732
2733 void
2734 bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
2735 {
2736         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
2737         struct bfi_ioim_rsp_s *rsp = (struct bfi_ioim_rsp_s *) m;
2738         struct bfa_ioim_s *ioim;
2739         u16     iotag;
2740         enum bfa_ioim_event evt = BFA_IOIM_SM_COMP;
2741
2742         iotag = be16_to_cpu(rsp->io_tag);
2743
2744         ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
2745         bfa_assert(ioim->iotag == iotag);
2746
2747         bfa_trc(ioim->bfa, ioim->iotag);
2748         bfa_trc(ioim->bfa, rsp->io_status);
2749         bfa_trc(ioim->bfa, rsp->reuse_io_tag);
2750
2751         if (bfa_sm_cmp_state(ioim, bfa_ioim_sm_active))
2752                 ioim->iosp->comp_rspmsg = *m;
2753
2754         switch (rsp->io_status) {
2755         case BFI_IOIM_STS_OK:
2756                 bfa_stats(ioim->itnim, iocomp_ok);
2757                 if (rsp->reuse_io_tag == 0)
2758                         evt = BFA_IOIM_SM_DONE;
2759                 else
2760                         evt = BFA_IOIM_SM_COMP;
2761                 break;
2762
2763         case BFI_IOIM_STS_TIMEDOUT:
2764                 bfa_stats(ioim->itnim, iocomp_timedout);
2765         case BFI_IOIM_STS_ABORTED:
2766                 rsp->io_status = BFI_IOIM_STS_ABORTED;
2767                 bfa_stats(ioim->itnim, iocomp_aborted);
2768                 if (rsp->reuse_io_tag == 0)
2769                         evt = BFA_IOIM_SM_DONE;
2770                 else
2771                         evt = BFA_IOIM_SM_COMP;
2772                 break;
2773
2774         case BFI_IOIM_STS_PROTO_ERR:
2775                 bfa_stats(ioim->itnim, iocom_proto_err);
2776                 bfa_assert(rsp->reuse_io_tag);
2777                 evt = BFA_IOIM_SM_COMP;
2778                 break;
2779
2780         case BFI_IOIM_STS_SQER_NEEDED:
2781                 bfa_stats(ioim->itnim, iocom_sqer_needed);
2782                 bfa_assert(rsp->reuse_io_tag == 0);
2783                 evt = BFA_IOIM_SM_SQRETRY;
2784                 break;
2785
2786         case BFI_IOIM_STS_RES_FREE:
2787                 bfa_stats(ioim->itnim, iocom_res_free);
2788                 evt = BFA_IOIM_SM_FREE;
2789                 break;
2790
2791         case BFI_IOIM_STS_HOST_ABORTED:
2792                 bfa_stats(ioim->itnim, iocom_hostabrts);
2793                 if (rsp->abort_tag != ioim->abort_tag) {
2794                         bfa_trc(ioim->bfa, rsp->abort_tag);
2795                         bfa_trc(ioim->bfa, ioim->abort_tag);
2796                         return;
2797                 }
2798
2799                 if (rsp->reuse_io_tag)
2800                         evt = BFA_IOIM_SM_ABORT_COMP;
2801                 else
2802                         evt = BFA_IOIM_SM_ABORT_DONE;
2803                 break;
2804
2805         case BFI_IOIM_STS_UTAG:
2806                 bfa_stats(ioim->itnim, iocom_utags);
2807                 evt = BFA_IOIM_SM_COMP_UTAG;
2808                 break;
2809
2810         default:
2811                 bfa_assert(0);
2812         }
2813
2814         bfa_sm_send_event(ioim, evt);
2815 }
2816
2817 void
2818 bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
2819 {
2820         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
2821         struct bfi_ioim_rsp_s *rsp = (struct bfi_ioim_rsp_s *) m;
2822         struct bfa_ioim_s *ioim;
2823         u16     iotag;
2824
2825         iotag = be16_to_cpu(rsp->io_tag);
2826
2827         ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
2828         bfa_assert(ioim->iotag == iotag);
2829
2830         bfa_trc_fp(ioim->bfa, ioim->iotag);
2831         bfa_ioim_cb_profile_comp(fcpim, ioim);
2832
2833         bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD);
2834 }
2835
2836 void
2837 bfa_ioim_profile_start(struct bfa_ioim_s *ioim)
2838 {
2839         ioim->start_time = jiffies;
2840 }
2841
2842 void
2843 bfa_ioim_profile_comp(struct bfa_ioim_s *ioim)
2844 {
2845         u32 fcp_dl = bfa_cb_ioim_get_size(ioim->dio);
2846         u32 index = bfa_ioim_get_index(fcp_dl);
2847         u64 end_time = jiffies;
2848         struct bfa_itnim_latency_s *io_lat =
2849                         &(ioim->itnim->ioprofile.io_latency);
2850         u32 val = (u32)(end_time - ioim->start_time);
2851
2852         bfa_itnim_ioprofile_update(ioim->itnim, index);
2853
2854         io_lat->count[index]++;
2855         io_lat->min[index] = (io_lat->min[index] < val) ?
2856                 io_lat->min[index] : val;
2857         io_lat->max[index] = (io_lat->max[index] > val) ?
2858                 io_lat->max[index] : val;
2859         io_lat->avg[index] += val;
2860 }
2861 /*
2862  * Called by itnim to clean up IO while going offline.
2863  */
2864 void
2865 bfa_ioim_cleanup(struct bfa_ioim_s *ioim)
2866 {
2867         bfa_trc(ioim->bfa, ioim->iotag);
2868         bfa_stats(ioim->itnim, io_cleanups);
2869
2870         ioim->iosp->tskim = NULL;
2871         bfa_sm_send_event(ioim, BFA_IOIM_SM_CLEANUP);
2872 }
2873
2874 void
2875 bfa_ioim_cleanup_tm(struct bfa_ioim_s *ioim, struct bfa_tskim_s *tskim)
2876 {
2877         bfa_trc(ioim->bfa, ioim->iotag);
2878         bfa_stats(ioim->itnim, io_tmaborts);
2879
2880         ioim->iosp->tskim = tskim;
2881         bfa_sm_send_event(ioim, BFA_IOIM_SM_CLEANUP);
2882 }
2883
2884 /*
2885  * IOC failure handling.
2886  */
2887 void
2888 bfa_ioim_iocdisable(struct bfa_ioim_s *ioim)
2889 {
2890         bfa_trc(ioim->bfa, ioim->iotag);
2891         bfa_stats(ioim->itnim, io_iocdowns);
2892         bfa_sm_send_event(ioim, BFA_IOIM_SM_HWFAIL);
2893 }
2894
2895 /*
2896  * IO offline TOV popped. Fail the pending IO.
2897  */
2898 void
2899 bfa_ioim_tov(struct bfa_ioim_s *ioim)
2900 {
2901         bfa_trc(ioim->bfa, ioim->iotag);
2902         bfa_sm_send_event(ioim, BFA_IOIM_SM_IOTOV);
2903 }
2904
2905
2906
2907 /*
2908  *  hal_ioim_api
2909  */
2910
2911 /*
2912  * Allocate IOIM resource for initiator mode I/O request.
2913  */
2914 struct bfa_ioim_s *
2915 bfa_ioim_alloc(struct bfa_s *bfa, struct bfad_ioim_s *dio,
2916                 struct bfa_itnim_s *itnim, u16 nsges)
2917 {
2918         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
2919         struct bfa_ioim_s *ioim;
2920
2921         /*
2922          * alocate IOIM resource
2923          */
2924         bfa_q_deq(&fcpim->ioim_free_q, &ioim);
2925         if (!ioim) {
2926                 bfa_stats(itnim, no_iotags);
2927                 return NULL;
2928         }
2929
2930         ioim->dio = dio;
2931         ioim->itnim = itnim;
2932         ioim->nsges = nsges;
2933         ioim->nsgpgs = 0;
2934
2935         bfa_stats(itnim, total_ios);
2936         fcpim->ios_active++;
2937
2938         list_add_tail(&ioim->qe, &itnim->io_q);
2939         bfa_trc_fp(ioim->bfa, ioim->iotag);
2940
2941         return ioim;
2942 }
2943
2944 void
2945 bfa_ioim_free(struct bfa_ioim_s *ioim)
2946 {
2947         struct bfa_fcpim_mod_s *fcpim = ioim->fcpim;
2948
2949         bfa_trc_fp(ioim->bfa, ioim->iotag);
2950         bfa_assert_fp(bfa_sm_cmp_state(ioim, bfa_ioim_sm_uninit));
2951
2952         bfa_assert_fp(list_empty(&ioim->sgpg_q) ||
2953                         (ioim->nsges > BFI_SGE_INLINE));
2954
2955         if (ioim->nsgpgs > 0)
2956                 bfa_sgpg_mfree(ioim->bfa, &ioim->sgpg_q, ioim->nsgpgs);
2957
2958         bfa_stats(ioim->itnim, io_comps);
2959         fcpim->ios_active--;
2960
2961         list_del(&ioim->qe);
2962         list_add_tail(&ioim->qe, &fcpim->ioim_free_q);
2963 }
2964
2965 void
2966 bfa_ioim_start(struct bfa_ioim_s *ioim)
2967 {
2968         bfa_trc_fp(ioim->bfa, ioim->iotag);
2969
2970         bfa_ioim_cb_profile_start(ioim->fcpim, ioim);
2971
2972         /*
2973          * Obtain the queue over which this request has to be issued
2974          */
2975         ioim->reqq = bfa_fcpim_ioredirect_enabled(ioim->bfa) ?
2976                         bfa_cb_ioim_get_reqq(ioim->dio) :
2977                         bfa_itnim_get_reqq(ioim);
2978
2979         bfa_sm_send_event(ioim, BFA_IOIM_SM_START);
2980 }
2981
2982 /*
2983  * Driver I/O abort request.
2984  */
2985 bfa_status_t
2986 bfa_ioim_abort(struct bfa_ioim_s *ioim)
2987 {
2988
2989         bfa_trc(ioim->bfa, ioim->iotag);
2990
2991         if (!bfa_ioim_is_abortable(ioim))
2992                 return BFA_STATUS_FAILED;
2993
2994         bfa_stats(ioim->itnim, io_aborts);
2995         bfa_sm_send_event(ioim, BFA_IOIM_SM_ABORT);
2996
2997         return BFA_STATUS_OK;
2998 }
2999
3000
3001 /*
3002  *  BFA TSKIM state machine functions
3003  */
3004
3005 /*
3006  *      Task management command beginning state.
3007  */
3008 static void
3009 bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3010 {
3011         bfa_trc(tskim->bfa, event);
3012
3013         switch (event) {
3014         case BFA_TSKIM_SM_START:
3015                 bfa_sm_set_state(tskim, bfa_tskim_sm_active);
3016                 bfa_tskim_gather_ios(tskim);
3017
3018                 /*
3019                  * If device is offline, do not send TM on wire. Just cleanup
3020                  * any pending IO requests and complete TM request.
3021                  */
3022                 if (!bfa_itnim_is_online(tskim->itnim)) {
3023                         bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
3024                         tskim->tsk_status = BFI_TSKIM_STS_OK;
3025                         bfa_tskim_cleanup_ios(tskim);
3026                         return;
3027                 }
3028
3029                 if (!bfa_tskim_send(tskim)) {
3030                         bfa_sm_set_state(tskim, bfa_tskim_sm_qfull);
3031                         bfa_stats(tskim->itnim, tm_qwait);
3032                         bfa_reqq_wait(tskim->bfa, tskim->itnim->reqq,
3033                                           &tskim->reqq_wait);
3034                 }
3035                 break;
3036
3037         default:
3038                 bfa_sm_fault(tskim->bfa, event);
3039         }
3040 }
3041
3042 /*
3043  * brief
3044  *      TM command is active, awaiting completion from firmware to
3045  *      cleanup IO requests in TM scope.
3046  */
3047 static void
3048 bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3049 {
3050         bfa_trc(tskim->bfa, event);
3051
3052         switch (event) {
3053         case BFA_TSKIM_SM_DONE:
3054                 bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
3055                 bfa_tskim_cleanup_ios(tskim);
3056                 break;
3057
3058         case BFA_TSKIM_SM_CLEANUP:
3059                 bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup);
3060                 if (!bfa_tskim_send_abort(tskim)) {
3061                         bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup_qfull);
3062                         bfa_stats(tskim->itnim, tm_qwait);
3063                         bfa_reqq_wait(tskim->bfa, tskim->itnim->reqq,
3064                                 &tskim->reqq_wait);
3065                 }
3066                 break;
3067
3068         case BFA_TSKIM_SM_HWFAIL:
3069                 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3070                 bfa_tskim_iocdisable_ios(tskim);
3071                 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
3072                 break;
3073
3074         default:
3075                 bfa_sm_fault(tskim->bfa, event);
3076         }
3077 }
3078
3079 /*
3080  *      An active TM is being cleaned up since ITN is offline. Awaiting cleanup
3081  *      completion event from firmware.
3082  */
3083 static void
3084 bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3085 {
3086         bfa_trc(tskim->bfa, event);
3087
3088         switch (event) {
3089         case BFA_TSKIM_SM_DONE:
3090                 /*
3091                  * Ignore and wait for ABORT completion from firmware.
3092                  */
3093                 break;
3094
3095         case BFA_TSKIM_SM_CLEANUP_DONE:
3096                 bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
3097                 bfa_tskim_cleanup_ios(tskim);
3098                 break;
3099
3100         case BFA_TSKIM_SM_HWFAIL:
3101                 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3102                 bfa_tskim_iocdisable_ios(tskim);
3103                 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
3104                 break;
3105
3106         default:
3107                 bfa_sm_fault(tskim->bfa, event);
3108         }
3109 }
3110
3111 static void
3112 bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3113 {
3114         bfa_trc(tskim->bfa, event);
3115
3116         switch (event) {
3117         case BFA_TSKIM_SM_IOS_DONE:
3118                 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3119                 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_done);
3120                 break;
3121
3122         case BFA_TSKIM_SM_CLEANUP:
3123                 /*
3124                  * Ignore, TM command completed on wire.
3125                  * Notify TM conmpletion on IO cleanup completion.
3126                  */
3127                 break;
3128
3129         case BFA_TSKIM_SM_HWFAIL:
3130                 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3131                 bfa_tskim_iocdisable_ios(tskim);
3132                 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
3133                 break;
3134
3135         default:
3136                 bfa_sm_fault(tskim->bfa, event);
3137         }
3138 }
3139
3140 /*
3141  *      Task management command is waiting for room in request CQ
3142  */
3143 static void
3144 bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3145 {
3146         bfa_trc(tskim->bfa, event);
3147
3148         switch (event) {
3149         case BFA_TSKIM_SM_QRESUME:
3150                 bfa_sm_set_state(tskim, bfa_tskim_sm_active);
3151                 bfa_tskim_send(tskim);
3152                 break;
3153
3154         case BFA_TSKIM_SM_CLEANUP:
3155                 /*
3156                  * No need to send TM on wire since ITN is offline.
3157                  */
3158                 bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
3159                 bfa_reqq_wcancel(&tskim->reqq_wait);
3160                 bfa_tskim_cleanup_ios(tskim);
3161                 break;
3162
3163         case BFA_TSKIM_SM_HWFAIL:
3164                 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3165                 bfa_reqq_wcancel(&tskim->reqq_wait);
3166                 bfa_tskim_iocdisable_ios(tskim);
3167                 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
3168                 break;
3169
3170         default:
3171                 bfa_sm_fault(tskim->bfa, event);
3172         }
3173 }
3174
3175 /*
3176  *      Task management command is active, awaiting for room in request CQ
3177  *      to send clean up request.
3178  */
3179 static void
3180 bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
3181                 enum bfa_tskim_event event)
3182 {
3183         bfa_trc(tskim->bfa, event);
3184
3185         switch (event) {
3186         case BFA_TSKIM_SM_DONE:
3187                 bfa_reqq_wcancel(&tskim->reqq_wait);
3188                 /*
3189                  *
3190                  * Fall through !!!
3191                  */
3192
3193         case BFA_TSKIM_SM_QRESUME:
3194                 bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup);
3195                 bfa_tskim_send_abort(tskim);
3196                 break;
3197
3198         case BFA_TSKIM_SM_HWFAIL:
3199                 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
3200                 bfa_reqq_wcancel(&tskim->reqq_wait);
3201                 bfa_tskim_iocdisable_ios(tskim);
3202                 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
3203                 break;
3204
3205         default:
3206                 bfa_sm_fault(tskim->bfa, event);
3207         }
3208 }
3209
3210 /*
3211  *      BFA callback is pending
3212  */
3213 static void
3214 bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
3215 {
3216         bfa_trc(tskim->bfa, event);
3217
3218         switch (event) {
3219         case BFA_TSKIM_SM_HCB:
3220                 bfa_sm_set_state(tskim, bfa_tskim_sm_uninit);
3221                 bfa_tskim_free(tskim);
3222                 break;
3223
3224         case BFA_TSKIM_SM_CLEANUP:
3225                 bfa_tskim_notify_comp(tskim);
3226                 break;
3227
3228         case BFA_TSKIM_SM_HWFAIL:
3229                 break;
3230
3231         default:
3232                 bfa_sm_fault(tskim->bfa, event);
3233         }
3234 }
3235
3236
3237
3238 /*
3239  *  hal_tskim_private
3240  */
3241
3242 static void
3243 __bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete)
3244 {
3245         struct bfa_tskim_s *tskim = cbarg;
3246
3247         if (!complete) {
3248                 bfa_sm_send_event(tskim, BFA_TSKIM_SM_HCB);
3249                 return;
3250         }
3251
3252         bfa_stats(tskim->itnim, tm_success);
3253         bfa_cb_tskim_done(tskim->bfa->bfad, tskim->dtsk, tskim->tsk_status);
3254 }
3255
3256 static void
3257 __bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete)
3258 {
3259         struct bfa_tskim_s *tskim = cbarg;
3260
3261         if (!complete) {
3262                 bfa_sm_send_event(tskim, BFA_TSKIM_SM_HCB);
3263                 return;
3264         }
3265
3266         bfa_stats(tskim->itnim, tm_failures);
3267         bfa_cb_tskim_done(tskim->bfa->bfad, tskim->dtsk,
3268                                 BFI_TSKIM_STS_FAILED);
3269 }
3270
3271 static  bfa_boolean_t
3272 bfa_tskim_match_scope(struct bfa_tskim_s *tskim, lun_t lun)
3273 {
3274         switch (tskim->tm_cmnd) {
3275         case FCP_TM_TARGET_RESET:
3276                 return BFA_TRUE;
3277
3278         case FCP_TM_ABORT_TASK_SET:
3279         case FCP_TM_CLEAR_TASK_SET:
3280         case FCP_TM_LUN_RESET:
3281         case FCP_TM_CLEAR_ACA:
3282                 return (tskim->lun == lun);
3283
3284         default:
3285                 bfa_assert(0);
3286         }
3287
3288         return BFA_FALSE;
3289 }
3290
3291 /*
3292  *      Gather affected IO requests and task management commands.
3293  */
3294 static void
3295 bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
3296 {
3297         struct bfa_itnim_s *itnim = tskim->itnim;
3298         struct bfa_ioim_s *ioim;
3299         struct list_head        *qe, *qen;
3300
3301         INIT_LIST_HEAD(&tskim->io_q);
3302
3303         /*
3304          * Gather any active IO requests first.
3305          */
3306         list_for_each_safe(qe, qen, &itnim->io_q) {
3307                 ioim = (struct bfa_ioim_s *) qe;
3308                 if (bfa_tskim_match_scope
3309                         (tskim, bfa_cb_ioim_get_lun(ioim->dio))) {
3310                         list_del(&ioim->qe);
3311                         list_add_tail(&ioim->qe, &tskim->io_q);
3312                 }
3313         }
3314
3315         /*
3316          * Failback any pending IO requests immediately.
3317          */
3318         list_for_each_safe(qe, qen, &itnim->pending_q) {
3319                 ioim = (struct bfa_ioim_s *) qe;
3320                 if (bfa_tskim_match_scope
3321                         (tskim, bfa_cb_ioim_get_lun(ioim->dio))) {
3322                         list_del(&ioim->qe);
3323                         list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
3324                         bfa_ioim_tov(ioim);
3325                 }
3326         }
3327 }
3328
3329 /*
3330  *      IO cleanup completion
3331  */
3332 static void
3333 bfa_tskim_cleanp_comp(void *tskim_cbarg)
3334 {
3335         struct bfa_tskim_s *tskim = tskim_cbarg;
3336
3337         bfa_stats(tskim->itnim, tm_io_comps);
3338         bfa_sm_send_event(tskim, BFA_TSKIM_SM_IOS_DONE);
3339 }
3340
3341 /*
3342  *      Gather affected IO requests and task management commands.
3343  */
3344 static void
3345 bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim)
3346 {
3347         struct bfa_ioim_s *ioim;
3348         struct list_head        *qe, *qen;
3349
3350         bfa_wc_init(&tskim->wc, bfa_tskim_cleanp_comp, tskim);
3351
3352         list_for_each_safe(qe, qen, &tskim->io_q) {
3353                 ioim = (struct bfa_ioim_s *) qe;
3354                 bfa_wc_up(&tskim->wc);
3355                 bfa_ioim_cleanup_tm(ioim, tskim);
3356         }
3357
3358         bfa_wc_wait(&tskim->wc);
3359 }
3360
3361 /*
3362  *      Send task management request to firmware.
3363  */
3364 static bfa_boolean_t
3365 bfa_tskim_send(struct bfa_tskim_s *tskim)
3366 {
3367         struct bfa_itnim_s *itnim = tskim->itnim;
3368         struct bfi_tskim_req_s *m;
3369
3370         /*
3371          * check for room in queue to send request now
3372          */
3373         m = bfa_reqq_next(tskim->bfa, itnim->reqq);
3374         if (!m)
3375                 return BFA_FALSE;
3376
3377         /*
3378          * build i/o request message next
3379          */
3380         bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_TM_REQ,
3381                         bfa_lpuid(tskim->bfa));
3382
3383         m->tsk_tag = cpu_to_be16(tskim->tsk_tag);
3384         m->itn_fhdl = tskim->itnim->rport->fw_handle;
3385         m->t_secs = tskim->tsecs;
3386         m->lun = tskim->lun;
3387         m->tm_flags = tskim->tm_cmnd;
3388
3389         /*
3390          * queue I/O message to firmware
3391          */
3392         bfa_reqq_produce(tskim->bfa, itnim->reqq);
3393         return BFA_TRUE;
3394 }
3395
3396 /*
3397  *      Send abort request to cleanup an active TM to firmware.
3398  */
3399 static bfa_boolean_t
3400 bfa_tskim_send_abort(struct bfa_tskim_s *tskim)
3401 {
3402         struct bfa_itnim_s      *itnim = tskim->itnim;
3403         struct bfi_tskim_abortreq_s     *m;
3404
3405         /*
3406          * check for room in queue to send request now
3407          */
3408         m = bfa_reqq_next(tskim->bfa, itnim->reqq);
3409         if (!m)
3410                 return BFA_FALSE;
3411
3412         /*
3413          * build i/o request message next
3414          */
3415         bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_ABORT_REQ,
3416                         bfa_lpuid(tskim->bfa));
3417
3418         m->tsk_tag  = cpu_to_be16(tskim->tsk_tag);
3419
3420         /*
3421          * queue I/O message to firmware
3422          */
3423         bfa_reqq_produce(tskim->bfa, itnim->reqq);
3424         return BFA_TRUE;
3425 }
3426
3427 /*
3428  *      Call to resume task management cmnd waiting for room in request queue.
3429  */
3430 static void
3431 bfa_tskim_qresume(void *cbarg)
3432 {
3433         struct bfa_tskim_s *tskim = cbarg;
3434
3435         bfa_stats(tskim->itnim, tm_qresumes);
3436         bfa_sm_send_event(tskim, BFA_TSKIM_SM_QRESUME);
3437 }
3438
3439 /*
3440  * Cleanup IOs associated with a task mangement command on IOC failures.
3441  */
3442 static void
3443 bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim)
3444 {
3445         struct bfa_ioim_s *ioim;
3446         struct list_head        *qe, *qen;
3447
3448         list_for_each_safe(qe, qen, &tskim->io_q) {
3449                 ioim = (struct bfa_ioim_s *) qe;
3450                 bfa_ioim_iocdisable(ioim);
3451         }
3452 }
3453
3454
3455
3456 /*
3457  *  hal_tskim_friend
3458  */
3459
3460 /*
3461  * Notification on completions from related ioim.
3462  */
3463 void
3464 bfa_tskim_iodone(struct bfa_tskim_s *tskim)
3465 {
3466         bfa_wc_down(&tskim->wc);
3467 }
3468
3469 /*
3470  * Handle IOC h/w failure notification from itnim.
3471  */
3472 void
3473 bfa_tskim_iocdisable(struct bfa_tskim_s *tskim)
3474 {
3475         tskim->notify = BFA_FALSE;
3476         bfa_stats(tskim->itnim, tm_iocdowns);
3477         bfa_sm_send_event(tskim, BFA_TSKIM_SM_HWFAIL);
3478 }
3479
3480 /*
3481  * Cleanup TM command and associated IOs as part of ITNIM offline.
3482  */
3483 void
3484 bfa_tskim_cleanup(struct bfa_tskim_s *tskim)
3485 {
3486         tskim->notify = BFA_TRUE;
3487         bfa_stats(tskim->itnim, tm_cleanups);
3488         bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP);
3489 }
3490
3491 /*
3492  *      Memory allocation and initialization.
3493  */
3494 void
3495 bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
3496 {
3497         struct bfa_tskim_s *tskim;
3498         u16     i;
3499
3500         INIT_LIST_HEAD(&fcpim->tskim_free_q);
3501
3502         tskim = (struct bfa_tskim_s *) bfa_meminfo_kva(minfo);
3503         fcpim->tskim_arr = tskim;
3504
3505         for (i = 0; i < fcpim->num_tskim_reqs; i++, tskim++) {
3506                 /*
3507                  * initialize TSKIM
3508                  */
3509                 memset(tskim, 0, sizeof(struct bfa_tskim_s));
3510                 tskim->tsk_tag = i;
3511                 tskim->bfa      = fcpim->bfa;
3512                 tskim->fcpim    = fcpim;
3513                 tskim->notify  = BFA_FALSE;
3514                 bfa_reqq_winit(&tskim->reqq_wait, bfa_tskim_qresume,
3515                                         tskim);
3516                 bfa_sm_set_state(tskim, bfa_tskim_sm_uninit);
3517
3518                 list_add_tail(&tskim->qe, &fcpim->tskim_free_q);
3519         }
3520
3521         bfa_meminfo_kva(minfo) = (u8 *) tskim;
3522 }
3523
3524 void
3525 bfa_tskim_detach(struct bfa_fcpim_mod_s *fcpim)
3526 {
3527         /*
3528         * @todo
3529         */
3530 }
3531
3532 void
3533 bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
3534 {
3535         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
3536         struct bfi_tskim_rsp_s *rsp = (struct bfi_tskim_rsp_s *) m;
3537         struct bfa_tskim_s *tskim;
3538         u16     tsk_tag = be16_to_cpu(rsp->tsk_tag);
3539
3540         tskim = BFA_TSKIM_FROM_TAG(fcpim, tsk_tag);
3541         bfa_assert(tskim->tsk_tag == tsk_tag);
3542
3543         tskim->tsk_status = rsp->tsk_status;
3544
3545         /*
3546          * Firmware sends BFI_TSKIM_STS_ABORTED status for abort
3547          * requests. All other statuses are for normal completions.
3548          */
3549         if (rsp->tsk_status == BFI_TSKIM_STS_ABORTED) {
3550                 bfa_stats(tskim->itnim, tm_cleanup_comps);
3551                 bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP_DONE);
3552         } else {
3553                 bfa_stats(tskim->itnim, tm_fw_rsps);
3554                 bfa_sm_send_event(tskim, BFA_TSKIM_SM_DONE);
3555         }
3556 }
3557
3558
3559
3560 /*
3561  *  hal_tskim_api
3562  */
3563
3564
3565 struct bfa_tskim_s *
3566 bfa_tskim_alloc(struct bfa_s *bfa, struct bfad_tskim_s *dtsk)
3567 {
3568         struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
3569         struct bfa_tskim_s *tskim;
3570
3571         bfa_q_deq(&fcpim->tskim_free_q, &tskim);
3572
3573         if (tskim)
3574                 tskim->dtsk = dtsk;
3575
3576         return tskim;
3577 }
3578
3579 void
3580 bfa_tskim_free(struct bfa_tskim_s *tskim)
3581 {
3582         bfa_assert(bfa_q_is_on_q_func(&tskim->itnim->tsk_q, &tskim->qe));
3583         list_del(&tskim->qe);
3584         list_add_tail(&tskim->qe, &tskim->fcpim->tskim_free_q);
3585 }
3586
3587 /*
3588  *      Start a task management command.
3589  *
3590  * @param[in]   tskim   BFA task management command instance
3591  * @param[in]   itnim   i-t nexus for the task management command
3592  * @param[in]   lun     lun, if applicable
3593  * @param[in]   tm_cmnd Task management command code.
3594  * @param[in]   t_secs  Timeout in seconds
3595  *
3596  * @return None.
3597  */
3598 void
3599 bfa_tskim_start(struct bfa_tskim_s *tskim, struct bfa_itnim_s *itnim, lun_t lun,
3600                         enum fcp_tm_cmnd tm_cmnd, u8 tsecs)
3601 {
3602         tskim->itnim    = itnim;
3603         tskim->lun      = lun;
3604         tskim->tm_cmnd = tm_cmnd;
3605         tskim->tsecs    = tsecs;
3606         tskim->notify  = BFA_FALSE;
3607         bfa_stats(itnim, tm_cmnds);
3608
3609         list_add_tail(&tskim->qe, &itnim->tsk_q);
3610         bfa_sm_send_event(tskim, BFA_TSKIM_SM_START);
3611 }