diff options
Diffstat (limited to 'drivers/scsi/bfa/bfa_itnim.c')
-rw-r--r-- | drivers/scsi/bfa/bfa_itnim.c | 1088 |
1 files changed, 1088 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfa_itnim.c b/drivers/scsi/bfa/bfa_itnim.c new file mode 100644 index 000000000000..4d5c61a4f85c --- /dev/null +++ b/drivers/scsi/bfa/bfa_itnim.c | |||
@@ -0,0 +1,1088 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2009 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.h> | ||
19 | #include <bfa_fcpim.h> | ||
20 | #include "bfa_fcpim_priv.h" | ||
21 | |||
22 | BFA_TRC_FILE(HAL, ITNIM); | ||
23 | |||
24 | #define BFA_ITNIM_FROM_TAG(_fcpim, _tag) \ | ||
25 | ((_fcpim)->itnim_arr + ((_tag) & ((_fcpim)->num_itnims - 1))) | ||
26 | |||
27 | #define bfa_fcpim_additn(__itnim) \ | ||
28 | list_add_tail(&(__itnim)->qe, &(__itnim)->fcpim->itnim_q) | ||
29 | #define bfa_fcpim_delitn(__itnim) do { \ | ||
30 | bfa_assert(bfa_q_is_on_q(&(__itnim)->fcpim->itnim_q, __itnim)); \ | ||
31 | list_del(&(__itnim)->qe); \ | ||
32 | bfa_assert(list_empty(&(__itnim)->io_q)); \ | ||
33 | bfa_assert(list_empty(&(__itnim)->io_cleanup_q)); \ | ||
34 | bfa_assert(list_empty(&(__itnim)->pending_q)); \ | ||
35 | } while (0) | ||
36 | |||
37 | #define bfa_itnim_online_cb(__itnim) do { \ | ||
38 | if ((__itnim)->bfa->fcs) \ | ||
39 | bfa_cb_itnim_online((__itnim)->ditn); \ | ||
40 | else { \ | ||
41 | bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \ | ||
42 | __bfa_cb_itnim_online, (__itnim)); \ | ||
43 | } \ | ||
44 | } while (0) | ||
45 | |||
46 | #define bfa_itnim_offline_cb(__itnim) do { \ | ||
47 | if ((__itnim)->bfa->fcs) \ | ||
48 | bfa_cb_itnim_offline((__itnim)->ditn); \ | ||
49 | else { \ | ||
50 | bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \ | ||
51 | __bfa_cb_itnim_offline, (__itnim)); \ | ||
52 | } \ | ||
53 | } while (0) | ||
54 | |||
55 | #define bfa_itnim_sler_cb(__itnim) do { \ | ||
56 | if ((__itnim)->bfa->fcs) \ | ||
57 | bfa_cb_itnim_sler((__itnim)->ditn); \ | ||
58 | else { \ | ||
59 | bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \ | ||
60 | __bfa_cb_itnim_sler, (__itnim)); \ | ||
61 | } \ | ||
62 | } while (0) | ||
63 | |||
64 | /* | ||
65 | * forward declarations | ||
66 | */ | ||
67 | static void bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim); | ||
68 | static bfa_boolean_t bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim); | ||
69 | static bfa_boolean_t bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim); | ||
70 | static void bfa_itnim_cleanp_comp(void *itnim_cbarg); | ||
71 | static void bfa_itnim_cleanup(struct bfa_itnim_s *itnim); | ||
72 | static void __bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete); | ||
73 | static void __bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete); | ||
74 | static void __bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete); | ||
75 | static void bfa_itnim_iotov_online(struct bfa_itnim_s *itnim); | ||
76 | static void bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim); | ||
77 | static void bfa_itnim_iotov(void *itnim_arg); | ||
78 | static void bfa_itnim_iotov_start(struct bfa_itnim_s *itnim); | ||
79 | static void bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim); | ||
80 | static void bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim); | ||
81 | |||
82 | /** | ||
83 | * bfa_itnim_sm BFA itnim state machine | ||
84 | */ | ||
85 | |||
86 | |||
87 | enum bfa_itnim_event { | ||
88 | BFA_ITNIM_SM_CREATE = 1, /* itnim is created */ | ||
89 | BFA_ITNIM_SM_ONLINE = 2, /* itnim is online */ | ||
90 | BFA_ITNIM_SM_OFFLINE = 3, /* itnim is offline */ | ||
91 | BFA_ITNIM_SM_FWRSP = 4, /* firmware response */ | ||
92 | BFA_ITNIM_SM_DELETE = 5, /* deleting an existing itnim */ | ||
93 | BFA_ITNIM_SM_CLEANUP = 6, /* IO cleanup completion */ | ||
94 | BFA_ITNIM_SM_SLER = 7, /* second level error recovery */ | ||
95 | BFA_ITNIM_SM_HWFAIL = 8, /* IOC h/w failure event */ | ||
96 | BFA_ITNIM_SM_QRESUME = 9, /* queue space available */ | ||
97 | }; | ||
98 | |||
99 | static void bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, | ||
100 | enum bfa_itnim_event event); | ||
101 | static void bfa_itnim_sm_created(struct bfa_itnim_s *itnim, | ||
102 | enum bfa_itnim_event event); | ||
103 | static void bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, | ||
104 | enum bfa_itnim_event event); | ||
105 | static void bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim, | ||
106 | enum bfa_itnim_event event); | ||
107 | static void bfa_itnim_sm_online(struct bfa_itnim_s *itnim, | ||
108 | enum bfa_itnim_event event); | ||
109 | static void bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, | ||
110 | enum bfa_itnim_event event); | ||
111 | static void bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim, | ||
112 | enum bfa_itnim_event event); | ||
113 | static void bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim, | ||
114 | enum bfa_itnim_event event); | ||
115 | static void bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, | ||
116 | enum bfa_itnim_event event); | ||
117 | static void bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, | ||
118 | enum bfa_itnim_event event); | ||
119 | static void bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim, | ||
120 | enum bfa_itnim_event event); | ||
121 | static void bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, | ||
122 | enum bfa_itnim_event event); | ||
123 | static void bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim, | ||
124 | enum bfa_itnim_event event); | ||
125 | static void bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim, | ||
126 | enum bfa_itnim_event event); | ||
127 | static void bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim, | ||
128 | enum bfa_itnim_event event); | ||
129 | |||
130 | /** | ||
131 | * Beginning/unallocated state - no events expected. | ||
132 | */ | ||
133 | static void | ||
134 | bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | ||
135 | { | ||
136 | bfa_trc(itnim->bfa, itnim->rport->rport_tag); | ||
137 | bfa_trc(itnim->bfa, event); | ||
138 | |||
139 | switch (event) { | ||
140 | case BFA_ITNIM_SM_CREATE: | ||
141 | bfa_sm_set_state(itnim, bfa_itnim_sm_created); | ||
142 | itnim->is_online = BFA_FALSE; | ||
143 | bfa_fcpim_additn(itnim); | ||
144 | break; | ||
145 | |||
146 | default: | ||
147 | bfa_assert(0); | ||
148 | } | ||
149 | } | ||
150 | |||
151 | /** | ||
152 | * Beginning state, only online event expected. | ||
153 | */ | ||
154 | static void | ||
155 | bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | ||
156 | { | ||
157 | bfa_trc(itnim->bfa, itnim->rport->rport_tag); | ||
158 | bfa_trc(itnim->bfa, event); | ||
159 | |||
160 | switch (event) { | ||
161 | case BFA_ITNIM_SM_ONLINE: | ||
162 | if (bfa_itnim_send_fwcreate(itnim)) | ||
163 | bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate); | ||
164 | else | ||
165 | bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull); | ||
166 | break; | ||
167 | |||
168 | case BFA_ITNIM_SM_DELETE: | ||
169 | bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); | ||
170 | bfa_fcpim_delitn(itnim); | ||
171 | break; | ||
172 | |||
173 | case BFA_ITNIM_SM_HWFAIL: | ||
174 | bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); | ||
175 | break; | ||
176 | |||
177 | default: | ||
178 | bfa_assert(0); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | /** | ||
183 | * Waiting for itnim create response from firmware. | ||
184 | */ | ||
185 | static void | ||
186 | bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | ||
187 | { | ||
188 | bfa_trc(itnim->bfa, itnim->rport->rport_tag); | ||
189 | bfa_trc(itnim->bfa, event); | ||
190 | |||
191 | switch (event) { | ||
192 | case BFA_ITNIM_SM_FWRSP: | ||
193 | bfa_sm_set_state(itnim, bfa_itnim_sm_online); | ||
194 | itnim->is_online = BFA_TRUE; | ||
195 | bfa_itnim_iotov_online(itnim); | ||
196 | bfa_itnim_online_cb(itnim); | ||
197 | break; | ||
198 | |||
199 | case BFA_ITNIM_SM_DELETE: | ||
200 | bfa_sm_set_state(itnim, bfa_itnim_sm_delete_pending); | ||
201 | break; | ||
202 | |||
203 | case BFA_ITNIM_SM_OFFLINE: | ||
204 | if (bfa_itnim_send_fwdelete(itnim)) | ||
205 | bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete); | ||
206 | else | ||
207 | bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull); | ||
208 | break; | ||
209 | |||
210 | case BFA_ITNIM_SM_HWFAIL: | ||
211 | bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); | ||
212 | break; | ||
213 | |||
214 | default: | ||
215 | bfa_assert(0); | ||
216 | } | ||
217 | } | ||
218 | |||
219 | static void | ||
220 | bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim, | ||
221 | enum bfa_itnim_event event) | ||
222 | { | ||
223 | bfa_trc(itnim->bfa, itnim->rport->rport_tag); | ||
224 | bfa_trc(itnim->bfa, event); | ||
225 | |||
226 | switch (event) { | ||
227 | case BFA_ITNIM_SM_QRESUME: | ||
228 | bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate); | ||
229 | bfa_itnim_send_fwcreate(itnim); | ||
230 | break; | ||
231 | |||
232 | case BFA_ITNIM_SM_DELETE: | ||
233 | bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); | ||
234 | bfa_reqq_wcancel(&itnim->reqq_wait); | ||
235 | bfa_fcpim_delitn(itnim); | ||
236 | break; | ||
237 | |||
238 | case BFA_ITNIM_SM_OFFLINE: | ||
239 | bfa_sm_set_state(itnim, bfa_itnim_sm_offline); | ||
240 | bfa_reqq_wcancel(&itnim->reqq_wait); | ||
241 | bfa_itnim_offline_cb(itnim); | ||
242 | break; | ||
243 | |||
244 | case BFA_ITNIM_SM_HWFAIL: | ||
245 | bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); | ||
246 | bfa_reqq_wcancel(&itnim->reqq_wait); | ||
247 | break; | ||
248 | |||
249 | default: | ||
250 | bfa_assert(0); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | /** | ||
255 | * Waiting for itnim create response from firmware, a delete is pending. | ||
256 | */ | ||
257 | static void | ||
258 | bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim, | ||
259 | enum bfa_itnim_event event) | ||
260 | { | ||
261 | bfa_trc(itnim->bfa, itnim->rport->rport_tag); | ||
262 | bfa_trc(itnim->bfa, event); | ||
263 | |||
264 | switch (event) { | ||
265 | case BFA_ITNIM_SM_FWRSP: | ||
266 | if (bfa_itnim_send_fwdelete(itnim)) | ||
267 | bfa_sm_set_state(itnim, bfa_itnim_sm_deleting); | ||
268 | else | ||
269 | bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull); | ||
270 | break; | ||
271 | |||
272 | case BFA_ITNIM_SM_HWFAIL: | ||
273 | bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); | ||
274 | bfa_fcpim_delitn(itnim); | ||
275 | break; | ||
276 | |||
277 | default: | ||
278 | bfa_assert(0); | ||
279 | } | ||
280 | } | ||
281 | |||
282 | /** | ||
283 | * Online state - normal parking state. | ||
284 | */ | ||
285 | static void | ||
286 | bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | ||
287 | { | ||
288 | bfa_trc(itnim->bfa, itnim->rport->rport_tag); | ||
289 | bfa_trc(itnim->bfa, event); | ||
290 | |||
291 | switch (event) { | ||
292 | case BFA_ITNIM_SM_OFFLINE: | ||
293 | bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline); | ||
294 | itnim->is_online = BFA_FALSE; | ||
295 | bfa_itnim_iotov_start(itnim); | ||
296 | bfa_itnim_cleanup(itnim); | ||
297 | break; | ||
298 | |||
299 | case BFA_ITNIM_SM_DELETE: | ||
300 | bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete); | ||
301 | itnim->is_online = BFA_FALSE; | ||
302 | bfa_itnim_cleanup(itnim); | ||
303 | break; | ||
304 | |||
305 | case BFA_ITNIM_SM_SLER: | ||
306 | bfa_sm_set_state(itnim, bfa_itnim_sm_sler); | ||
307 | itnim->is_online = BFA_FALSE; | ||
308 | bfa_itnim_iotov_start(itnim); | ||
309 | bfa_itnim_sler_cb(itnim); | ||
310 | break; | ||
311 | |||
312 | case BFA_ITNIM_SM_HWFAIL: | ||
313 | bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); | ||
314 | itnim->is_online = BFA_FALSE; | ||
315 | bfa_itnim_iotov_start(itnim); | ||
316 | bfa_itnim_iocdisable_cleanup(itnim); | ||
317 | break; | ||
318 | |||
319 | default: | ||
320 | bfa_assert(0); | ||
321 | } | ||
322 | } | ||
323 | |||
324 | /** | ||
325 | * Second level error recovery need. | ||
326 | */ | ||
327 | static void | ||
328 | bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | ||
329 | { | ||
330 | bfa_trc(itnim->bfa, itnim->rport->rport_tag); | ||
331 | bfa_trc(itnim->bfa, event); | ||
332 | |||
333 | switch (event) { | ||
334 | case BFA_ITNIM_SM_OFFLINE: | ||
335 | bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline); | ||
336 | bfa_itnim_cleanup(itnim); | ||
337 | break; | ||
338 | |||
339 | case BFA_ITNIM_SM_DELETE: | ||
340 | bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete); | ||
341 | bfa_itnim_cleanup(itnim); | ||
342 | bfa_itnim_iotov_delete(itnim); | ||
343 | break; | ||
344 | |||
345 | case BFA_ITNIM_SM_HWFAIL: | ||
346 | bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); | ||
347 | bfa_itnim_iocdisable_cleanup(itnim); | ||
348 | break; | ||
349 | |||
350 | default: | ||
351 | bfa_assert(0); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * Going offline. Waiting for active IO cleanup. | ||
357 | */ | ||
358 | static void | ||
359 | bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim, | ||
360 | enum bfa_itnim_event event) | ||
361 | { | ||
362 | bfa_trc(itnim->bfa, itnim->rport->rport_tag); | ||
363 | bfa_trc(itnim->bfa, event); | ||
364 | |||
365 | switch (event) { | ||
366 | case BFA_ITNIM_SM_CLEANUP: | ||
367 | if (bfa_itnim_send_fwdelete(itnim)) | ||
368 | bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete); | ||
369 | else | ||
370 | bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull); | ||
371 | break; | ||
372 | |||
373 | case BFA_ITNIM_SM_DELETE: | ||
374 | bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete); | ||
375 | bfa_itnim_iotov_delete(itnim); | ||
376 | break; | ||
377 | |||
378 | case BFA_ITNIM_SM_HWFAIL: | ||
379 | bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); | ||
380 | bfa_itnim_iocdisable_cleanup(itnim); | ||
381 | bfa_itnim_offline_cb(itnim); | ||
382 | break; | ||
383 | |||
384 | case BFA_ITNIM_SM_SLER: | ||
385 | break; | ||
386 | |||
387 | default: | ||
388 | bfa_assert(0); | ||
389 | } | ||
390 | } | ||
391 | |||
392 | /** | ||
393 | * Deleting itnim. Waiting for active IO cleanup. | ||
394 | */ | ||
395 | static void | ||
396 | bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim, | ||
397 | enum bfa_itnim_event event) | ||
398 | { | ||
399 | bfa_trc(itnim->bfa, itnim->rport->rport_tag); | ||
400 | bfa_trc(itnim->bfa, event); | ||
401 | |||
402 | switch (event) { | ||
403 | case BFA_ITNIM_SM_CLEANUP: | ||
404 | if (bfa_itnim_send_fwdelete(itnim)) | ||
405 | bfa_sm_set_state(itnim, bfa_itnim_sm_deleting); | ||
406 | else | ||
407 | bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull); | ||
408 | break; | ||
409 | |||
410 | case BFA_ITNIM_SM_HWFAIL: | ||
411 | bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); | ||
412 | bfa_itnim_iocdisable_cleanup(itnim); | ||
413 | break; | ||
414 | |||
415 | default: | ||
416 | bfa_assert(0); | ||
417 | } | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | * Rport offline. Fimrware itnim is being deleted - awaiting f/w response. | ||
422 | */ | ||
423 | static void | ||
424 | bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | ||
425 | { | ||
426 | bfa_trc(itnim->bfa, itnim->rport->rport_tag); | ||
427 | bfa_trc(itnim->bfa, event); | ||
428 | |||
429 | switch (event) { | ||
430 | case BFA_ITNIM_SM_FWRSP: | ||
431 | bfa_sm_set_state(itnim, bfa_itnim_sm_offline); | ||
432 | bfa_itnim_offline_cb(itnim); | ||
433 | break; | ||
434 | |||
435 | case BFA_ITNIM_SM_DELETE: | ||
436 | bfa_sm_set_state(itnim, bfa_itnim_sm_deleting); | ||
437 | break; | ||
438 | |||
439 | case BFA_ITNIM_SM_HWFAIL: | ||
440 | bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); | ||
441 | bfa_itnim_offline_cb(itnim); | ||
442 | break; | ||
443 | |||
444 | default: | ||
445 | bfa_assert(0); | ||
446 | } | ||
447 | } | ||
448 | |||
449 | static void | ||
450 | bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim, | ||
451 | enum bfa_itnim_event event) | ||
452 | { | ||
453 | bfa_trc(itnim->bfa, itnim->rport->rport_tag); | ||
454 | bfa_trc(itnim->bfa, event); | ||
455 | |||
456 | switch (event) { | ||
457 | case BFA_ITNIM_SM_QRESUME: | ||
458 | bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete); | ||
459 | bfa_itnim_send_fwdelete(itnim); | ||
460 | break; | ||
461 | |||
462 | case BFA_ITNIM_SM_DELETE: | ||
463 | bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull); | ||
464 | break; | ||
465 | |||
466 | case BFA_ITNIM_SM_HWFAIL: | ||
467 | bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); | ||
468 | bfa_reqq_wcancel(&itnim->reqq_wait); | ||
469 | bfa_itnim_offline_cb(itnim); | ||
470 | break; | ||
471 | |||
472 | default: | ||
473 | bfa_assert(0); | ||
474 | } | ||
475 | } | ||
476 | |||
477 | /** | ||
478 | * Offline state. | ||
479 | */ | ||
480 | static void | ||
481 | bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | ||
482 | { | ||
483 | bfa_trc(itnim->bfa, itnim->rport->rport_tag); | ||
484 | bfa_trc(itnim->bfa, event); | ||
485 | |||
486 | switch (event) { | ||
487 | case BFA_ITNIM_SM_DELETE: | ||
488 | bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); | ||
489 | bfa_itnim_iotov_delete(itnim); | ||
490 | bfa_fcpim_delitn(itnim); | ||
491 | break; | ||
492 | |||
493 | case BFA_ITNIM_SM_ONLINE: | ||
494 | if (bfa_itnim_send_fwcreate(itnim)) | ||
495 | bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate); | ||
496 | else | ||
497 | bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull); | ||
498 | break; | ||
499 | |||
500 | case BFA_ITNIM_SM_HWFAIL: | ||
501 | bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); | ||
502 | break; | ||
503 | |||
504 | default: | ||
505 | bfa_assert(0); | ||
506 | } | ||
507 | } | ||
508 | |||
509 | /** | ||
510 | * IOC h/w failed state. | ||
511 | */ | ||
512 | static void | ||
513 | bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim, | ||
514 | enum bfa_itnim_event event) | ||
515 | { | ||
516 | bfa_trc(itnim->bfa, itnim->rport->rport_tag); | ||
517 | bfa_trc(itnim->bfa, event); | ||
518 | |||
519 | switch (event) { | ||
520 | case BFA_ITNIM_SM_DELETE: | ||
521 | bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); | ||
522 | bfa_itnim_iotov_delete(itnim); | ||
523 | bfa_fcpim_delitn(itnim); | ||
524 | break; | ||
525 | |||
526 | case BFA_ITNIM_SM_OFFLINE: | ||
527 | bfa_itnim_offline_cb(itnim); | ||
528 | break; | ||
529 | |||
530 | case BFA_ITNIM_SM_ONLINE: | ||
531 | if (bfa_itnim_send_fwcreate(itnim)) | ||
532 | bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate); | ||
533 | else | ||
534 | bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull); | ||
535 | break; | ||
536 | |||
537 | case BFA_ITNIM_SM_HWFAIL: | ||
538 | break; | ||
539 | |||
540 | default: | ||
541 | bfa_assert(0); | ||
542 | } | ||
543 | } | ||
544 | |||
545 | /** | ||
546 | * Itnim is deleted, waiting for firmware response to delete. | ||
547 | */ | ||
548 | static void | ||
549 | bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) | ||
550 | { | ||
551 | bfa_trc(itnim->bfa, itnim->rport->rport_tag); | ||
552 | bfa_trc(itnim->bfa, event); | ||
553 | |||
554 | switch (event) { | ||
555 | case BFA_ITNIM_SM_FWRSP: | ||
556 | case BFA_ITNIM_SM_HWFAIL: | ||
557 | bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); | ||
558 | bfa_fcpim_delitn(itnim); | ||
559 | break; | ||
560 | |||
561 | default: | ||
562 | bfa_assert(0); | ||
563 | } | ||
564 | } | ||
565 | |||
566 | static void | ||
567 | bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim, | ||
568 | enum bfa_itnim_event event) | ||
569 | { | ||
570 | bfa_trc(itnim->bfa, itnim->rport->rport_tag); | ||
571 | bfa_trc(itnim->bfa, event); | ||
572 | |||
573 | switch (event) { | ||
574 | case BFA_ITNIM_SM_QRESUME: | ||
575 | bfa_sm_set_state(itnim, bfa_itnim_sm_deleting); | ||
576 | bfa_itnim_send_fwdelete(itnim); | ||
577 | break; | ||
578 | |||
579 | case BFA_ITNIM_SM_HWFAIL: | ||
580 | bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); | ||
581 | bfa_reqq_wcancel(&itnim->reqq_wait); | ||
582 | bfa_fcpim_delitn(itnim); | ||
583 | break; | ||
584 | |||
585 | default: | ||
586 | bfa_assert(0); | ||
587 | } | ||
588 | } | ||
589 | |||
590 | |||
591 | |||
592 | /** | ||
593 | * bfa_itnim_private | ||
594 | */ | ||
595 | |||
596 | /** | ||
597 | * Initiate cleanup of all IOs on an IOC failure. | ||
598 | */ | ||
599 | static void | ||
600 | bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim) | ||
601 | { | ||
602 | struct bfa_tskim_s *tskim; | ||
603 | struct bfa_ioim_s *ioim; | ||
604 | struct list_head *qe, *qen; | ||
605 | |||
606 | list_for_each_safe(qe, qen, &itnim->tsk_q) { | ||
607 | tskim = (struct bfa_tskim_s *) qe; | ||
608 | bfa_tskim_iocdisable(tskim); | ||
609 | } | ||
610 | |||
611 | list_for_each_safe(qe, qen, &itnim->io_q) { | ||
612 | ioim = (struct bfa_ioim_s *) qe; | ||
613 | bfa_ioim_iocdisable(ioim); | ||
614 | } | ||
615 | |||
616 | /** | ||
617 | * For IO request in pending queue, we pretend an early timeout. | ||
618 | */ | ||
619 | list_for_each_safe(qe, qen, &itnim->pending_q) { | ||
620 | ioim = (struct bfa_ioim_s *) qe; | ||
621 | bfa_ioim_tov(ioim); | ||
622 | } | ||
623 | |||
624 | list_for_each_safe(qe, qen, &itnim->io_cleanup_q) { | ||
625 | ioim = (struct bfa_ioim_s *) qe; | ||
626 | bfa_ioim_iocdisable(ioim); | ||
627 | } | ||
628 | } | ||
629 | |||
630 | /** | ||
631 | * IO cleanup completion | ||
632 | */ | ||
633 | static void | ||
634 | bfa_itnim_cleanp_comp(void *itnim_cbarg) | ||
635 | { | ||
636 | struct bfa_itnim_s *itnim = itnim_cbarg; | ||
637 | |||
638 | bfa_stats(itnim, cleanup_comps); | ||
639 | bfa_sm_send_event(itnim, BFA_ITNIM_SM_CLEANUP); | ||
640 | } | ||
641 | |||
642 | /** | ||
643 | * Initiate cleanup of all IOs. | ||
644 | */ | ||
645 | static void | ||
646 | bfa_itnim_cleanup(struct bfa_itnim_s *itnim) | ||
647 | { | ||
648 | struct bfa_ioim_s *ioim; | ||
649 | struct bfa_tskim_s *tskim; | ||
650 | struct list_head *qe, *qen; | ||
651 | |||
652 | bfa_wc_init(&itnim->wc, bfa_itnim_cleanp_comp, itnim); | ||
653 | |||
654 | list_for_each_safe(qe, qen, &itnim->io_q) { | ||
655 | ioim = (struct bfa_ioim_s *) qe; | ||
656 | |||
657 | /** | ||
658 | * Move IO to a cleanup queue from active queue so that a later | ||
659 | * TM will not pickup this IO. | ||
660 | */ | ||
661 | list_del(&ioim->qe); | ||
662 | list_add_tail(&ioim->qe, &itnim->io_cleanup_q); | ||
663 | |||
664 | bfa_wc_up(&itnim->wc); | ||
665 | bfa_ioim_cleanup(ioim); | ||
666 | } | ||
667 | |||
668 | list_for_each_safe(qe, qen, &itnim->tsk_q) { | ||
669 | tskim = (struct bfa_tskim_s *) qe; | ||
670 | bfa_wc_up(&itnim->wc); | ||
671 | bfa_tskim_cleanup(tskim); | ||
672 | } | ||
673 | |||
674 | bfa_wc_wait(&itnim->wc); | ||
675 | } | ||
676 | |||
677 | static void | ||
678 | __bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete) | ||
679 | { | ||
680 | struct bfa_itnim_s *itnim = cbarg; | ||
681 | |||
682 | if (complete) | ||
683 | bfa_cb_itnim_online(itnim->ditn); | ||
684 | } | ||
685 | |||
686 | static void | ||
687 | __bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete) | ||
688 | { | ||
689 | struct bfa_itnim_s *itnim = cbarg; | ||
690 | |||
691 | if (complete) | ||
692 | bfa_cb_itnim_offline(itnim->ditn); | ||
693 | } | ||
694 | |||
695 | static void | ||
696 | __bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete) | ||
697 | { | ||
698 | struct bfa_itnim_s *itnim = cbarg; | ||
699 | |||
700 | if (complete) | ||
701 | bfa_cb_itnim_sler(itnim->ditn); | ||
702 | } | ||
703 | |||
704 | /** | ||
705 | * Call to resume any I/O requests waiting for room in request queue. | ||
706 | */ | ||
707 | static void | ||
708 | bfa_itnim_qresume(void *cbarg) | ||
709 | { | ||
710 | struct bfa_itnim_s *itnim = cbarg; | ||
711 | |||
712 | bfa_sm_send_event(itnim, BFA_ITNIM_SM_QRESUME); | ||
713 | } | ||
714 | |||
715 | |||
716 | |||
717 | |||
718 | /** | ||
719 | * bfa_itnim_public | ||
720 | */ | ||
721 | |||
722 | void | ||
723 | bfa_itnim_iodone(struct bfa_itnim_s *itnim) | ||
724 | { | ||
725 | bfa_wc_down(&itnim->wc); | ||
726 | } | ||
727 | |||
728 | void | ||
729 | bfa_itnim_tskdone(struct bfa_itnim_s *itnim) | ||
730 | { | ||
731 | bfa_wc_down(&itnim->wc); | ||
732 | } | ||
733 | |||
734 | void | ||
735 | bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len, | ||
736 | u32 *dm_len) | ||
737 | { | ||
738 | /** | ||
739 | * ITN memory | ||
740 | */ | ||
741 | *km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_itnim_s); | ||
742 | } | ||
743 | |||
744 | void | ||
745 | bfa_itnim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo) | ||
746 | { | ||
747 | struct bfa_s *bfa = fcpim->bfa; | ||
748 | struct bfa_itnim_s *itnim; | ||
749 | int i; | ||
750 | |||
751 | INIT_LIST_HEAD(&fcpim->itnim_q); | ||
752 | |||
753 | itnim = (struct bfa_itnim_s *) bfa_meminfo_kva(minfo); | ||
754 | fcpim->itnim_arr = itnim; | ||
755 | |||
756 | for (i = 0; i < fcpim->num_itnims; i++, itnim++) { | ||
757 | bfa_os_memset(itnim, 0, sizeof(struct bfa_itnim_s)); | ||
758 | itnim->bfa = bfa; | ||
759 | itnim->fcpim = fcpim; | ||
760 | itnim->reqq = BFA_REQQ_QOS_LO; | ||
761 | itnim->rport = BFA_RPORT_FROM_TAG(bfa, i); | ||
762 | itnim->iotov_active = BFA_FALSE; | ||
763 | bfa_reqq_winit(&itnim->reqq_wait, bfa_itnim_qresume, itnim); | ||
764 | |||
765 | INIT_LIST_HEAD(&itnim->io_q); | ||
766 | INIT_LIST_HEAD(&itnim->io_cleanup_q); | ||
767 | INIT_LIST_HEAD(&itnim->pending_q); | ||
768 | INIT_LIST_HEAD(&itnim->tsk_q); | ||
769 | INIT_LIST_HEAD(&itnim->delay_comp_q); | ||
770 | bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); | ||
771 | } | ||
772 | |||
773 | bfa_meminfo_kva(minfo) = (u8 *) itnim; | ||
774 | } | ||
775 | |||
776 | void | ||
777 | bfa_itnim_iocdisable(struct bfa_itnim_s *itnim) | ||
778 | { | ||
779 | bfa_stats(itnim, ioc_disabled); | ||
780 | bfa_sm_send_event(itnim, BFA_ITNIM_SM_HWFAIL); | ||
781 | } | ||
782 | |||
783 | static bfa_boolean_t | ||
784 | bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim) | ||
785 | { | ||
786 | struct bfi_itnim_create_req_s *m; | ||
787 | |||
788 | itnim->msg_no++; | ||
789 | |||
790 | /** | ||
791 | * check for room in queue to send request now | ||
792 | */ | ||
793 | m = bfa_reqq_next(itnim->bfa, itnim->reqq); | ||
794 | if (!m) { | ||
795 | bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait); | ||
796 | return BFA_FALSE; | ||
797 | } | ||
798 | |||
799 | bfi_h2i_set(m->mh, BFI_MC_ITNIM, BFI_ITNIM_H2I_CREATE_REQ, | ||
800 | bfa_lpuid(itnim->bfa)); | ||
801 | m->fw_handle = itnim->rport->fw_handle; | ||
802 | m->class = FC_CLASS_3; | ||
803 | m->seq_rec = itnim->seq_rec; | ||
804 | m->msg_no = itnim->msg_no; | ||
805 | |||
806 | /** | ||
807 | * queue I/O message to firmware | ||
808 | */ | ||
809 | bfa_reqq_produce(itnim->bfa, itnim->reqq); | ||
810 | return BFA_TRUE; | ||
811 | } | ||
812 | |||
813 | static bfa_boolean_t | ||
814 | bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim) | ||
815 | { | ||
816 | struct bfi_itnim_delete_req_s *m; | ||
817 | |||
818 | /** | ||
819 | * check for room in queue to send request now | ||
820 | */ | ||
821 | m = bfa_reqq_next(itnim->bfa, itnim->reqq); | ||
822 | if (!m) { | ||
823 | bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait); | ||
824 | return BFA_FALSE; | ||
825 | } | ||
826 | |||
827 | bfi_h2i_set(m->mh, BFI_MC_ITNIM, BFI_ITNIM_H2I_DELETE_REQ, | ||
828 | bfa_lpuid(itnim->bfa)); | ||
829 | m->fw_handle = itnim->rport->fw_handle; | ||
830 | |||
831 | /** | ||
832 | * queue I/O message to firmware | ||
833 | */ | ||
834 | bfa_reqq_produce(itnim->bfa, itnim->reqq); | ||
835 | return BFA_TRUE; | ||
836 | } | ||
837 | |||
838 | /** | ||
839 | * Cleanup all pending failed inflight requests. | ||
840 | */ | ||
841 | static void | ||
842 | bfa_itnim_delayed_comp(struct bfa_itnim_s *itnim, bfa_boolean_t iotov) | ||
843 | { | ||
844 | struct bfa_ioim_s *ioim; | ||
845 | struct list_head *qe, *qen; | ||
846 | |||
847 | list_for_each_safe(qe, qen, &itnim->delay_comp_q) { | ||
848 | ioim = (struct bfa_ioim_s *)qe; | ||
849 | bfa_ioim_delayed_comp(ioim, iotov); | ||
850 | } | ||
851 | } | ||
852 | |||
853 | /** | ||
854 | * Start all pending IO requests. | ||
855 | */ | ||
856 | static void | ||
857 | bfa_itnim_iotov_online(struct bfa_itnim_s *itnim) | ||
858 | { | ||
859 | struct bfa_ioim_s *ioim; | ||
860 | |||
861 | bfa_itnim_iotov_stop(itnim); | ||
862 | |||
863 | /** | ||
864 | * Abort all inflight IO requests in the queue | ||
865 | */ | ||
866 | bfa_itnim_delayed_comp(itnim, BFA_FALSE); | ||
867 | |||
868 | /** | ||
869 | * Start all pending IO requests. | ||
870 | */ | ||
871 | while (!list_empty(&itnim->pending_q)) { | ||
872 | bfa_q_deq(&itnim->pending_q, &ioim); | ||
873 | list_add_tail(&ioim->qe, &itnim->io_q); | ||
874 | bfa_ioim_start(ioim); | ||
875 | } | ||
876 | } | ||
877 | |||
878 | /** | ||
879 | * Fail all pending IO requests | ||
880 | */ | ||
881 | static void | ||
882 | bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim) | ||
883 | { | ||
884 | struct bfa_ioim_s *ioim; | ||
885 | |||
886 | /** | ||
887 | * Fail all inflight IO requests in the queue | ||
888 | */ | ||
889 | bfa_itnim_delayed_comp(itnim, BFA_TRUE); | ||
890 | |||
891 | /** | ||
892 | * Fail any pending IO requests. | ||
893 | */ | ||
894 | while (!list_empty(&itnim->pending_q)) { | ||
895 | bfa_q_deq(&itnim->pending_q, &ioim); | ||
896 | list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q); | ||
897 | bfa_ioim_tov(ioim); | ||
898 | } | ||
899 | } | ||
900 | |||
901 | /** | ||
902 | * IO TOV timer callback. Fail any pending IO requests. | ||
903 | */ | ||
904 | static void | ||
905 | bfa_itnim_iotov(void *itnim_arg) | ||
906 | { | ||
907 | struct bfa_itnim_s *itnim = itnim_arg; | ||
908 | |||
909 | itnim->iotov_active = BFA_FALSE; | ||
910 | |||
911 | bfa_cb_itnim_tov_begin(itnim->ditn); | ||
912 | bfa_itnim_iotov_cleanup(itnim); | ||
913 | bfa_cb_itnim_tov(itnim->ditn); | ||
914 | } | ||
915 | |||
916 | /** | ||
917 | * Start IO TOV timer for failing back pending IO requests in offline state. | ||
918 | */ | ||
919 | static void | ||
920 | bfa_itnim_iotov_start(struct bfa_itnim_s *itnim) | ||
921 | { | ||
922 | if (itnim->fcpim->path_tov > 0) { | ||
923 | |||
924 | itnim->iotov_active = BFA_TRUE; | ||
925 | bfa_assert(bfa_itnim_hold_io(itnim)); | ||
926 | bfa_timer_start(itnim->bfa, &itnim->timer, | ||
927 | bfa_itnim_iotov, itnim, itnim->fcpim->path_tov); | ||
928 | } | ||
929 | } | ||
930 | |||
931 | /** | ||
932 | * Stop IO TOV timer. | ||
933 | */ | ||
934 | static void | ||
935 | bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim) | ||
936 | { | ||
937 | if (itnim->iotov_active) { | ||
938 | itnim->iotov_active = BFA_FALSE; | ||
939 | bfa_timer_stop(&itnim->timer); | ||
940 | } | ||
941 | } | ||
942 | |||
943 | /** | ||
944 | * Stop IO TOV timer. | ||
945 | */ | ||
946 | static void | ||
947 | bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim) | ||
948 | { | ||
949 | bfa_boolean_t pathtov_active = BFA_FALSE; | ||
950 | |||
951 | if (itnim->iotov_active) | ||
952 | pathtov_active = BFA_TRUE; | ||
953 | |||
954 | bfa_itnim_iotov_stop(itnim); | ||
955 | if (pathtov_active) | ||
956 | bfa_cb_itnim_tov_begin(itnim->ditn); | ||
957 | bfa_itnim_iotov_cleanup(itnim); | ||
958 | if (pathtov_active) | ||
959 | bfa_cb_itnim_tov(itnim->ditn); | ||
960 | } | ||
961 | |||
962 | |||
963 | |||
964 | /** | ||
965 | * bfa_itnim_public | ||
966 | */ | ||
967 | |||
968 | /** | ||
969 | * Itnim interrupt processing. | ||
970 | */ | ||
971 | void | ||
972 | bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m) | ||
973 | { | ||
974 | struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); | ||
975 | union bfi_itnim_i2h_msg_u msg; | ||
976 | struct bfa_itnim_s *itnim; | ||
977 | |||
978 | bfa_trc(bfa, m->mhdr.msg_id); | ||
979 | |||
980 | msg.msg = m; | ||
981 | |||
982 | switch (m->mhdr.msg_id) { | ||
983 | case BFI_ITNIM_I2H_CREATE_RSP: | ||
984 | itnim = BFA_ITNIM_FROM_TAG(fcpim, | ||
985 | msg.create_rsp->bfa_handle); | ||
986 | bfa_assert(msg.create_rsp->status == BFA_STATUS_OK); | ||
987 | bfa_stats(itnim, create_comps); | ||
988 | bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP); | ||
989 | break; | ||
990 | |||
991 | case BFI_ITNIM_I2H_DELETE_RSP: | ||
992 | itnim = BFA_ITNIM_FROM_TAG(fcpim, | ||
993 | msg.delete_rsp->bfa_handle); | ||
994 | bfa_assert(msg.delete_rsp->status == BFA_STATUS_OK); | ||
995 | bfa_stats(itnim, delete_comps); | ||
996 | bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP); | ||
997 | break; | ||
998 | |||
999 | case BFI_ITNIM_I2H_SLER_EVENT: | ||
1000 | itnim = BFA_ITNIM_FROM_TAG(fcpim, | ||
1001 | msg.sler_event->bfa_handle); | ||
1002 | bfa_stats(itnim, sler_events); | ||
1003 | bfa_sm_send_event(itnim, BFA_ITNIM_SM_SLER); | ||
1004 | break; | ||
1005 | |||
1006 | default: | ||
1007 | bfa_trc(bfa, m->mhdr.msg_id); | ||
1008 | bfa_assert(0); | ||
1009 | } | ||
1010 | } | ||
1011 | |||
1012 | |||
1013 | |||
1014 | /** | ||
1015 | * bfa_itnim_api | ||
1016 | */ | ||
1017 | |||
1018 | struct bfa_itnim_s * | ||
1019 | bfa_itnim_create(struct bfa_s *bfa, struct bfa_rport_s *rport, void *ditn) | ||
1020 | { | ||
1021 | struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); | ||
1022 | struct bfa_itnim_s *itnim; | ||
1023 | |||
1024 | itnim = BFA_ITNIM_FROM_TAG(fcpim, rport->rport_tag); | ||
1025 | bfa_assert(itnim->rport == rport); | ||
1026 | |||
1027 | itnim->ditn = ditn; | ||
1028 | |||
1029 | bfa_stats(itnim, creates); | ||
1030 | bfa_sm_send_event(itnim, BFA_ITNIM_SM_CREATE); | ||
1031 | |||
1032 | return (itnim); | ||
1033 | } | ||
1034 | |||
1035 | void | ||
1036 | bfa_itnim_delete(struct bfa_itnim_s *itnim) | ||
1037 | { | ||
1038 | bfa_stats(itnim, deletes); | ||
1039 | bfa_sm_send_event(itnim, BFA_ITNIM_SM_DELETE); | ||
1040 | } | ||
1041 | |||
1042 | void | ||
1043 | bfa_itnim_online(struct bfa_itnim_s *itnim, bfa_boolean_t seq_rec) | ||
1044 | { | ||
1045 | itnim->seq_rec = seq_rec; | ||
1046 | bfa_stats(itnim, onlines); | ||
1047 | bfa_sm_send_event(itnim, BFA_ITNIM_SM_ONLINE); | ||
1048 | } | ||
1049 | |||
1050 | void | ||
1051 | bfa_itnim_offline(struct bfa_itnim_s *itnim) | ||
1052 | { | ||
1053 | bfa_stats(itnim, offlines); | ||
1054 | bfa_sm_send_event(itnim, BFA_ITNIM_SM_OFFLINE); | ||
1055 | } | ||
1056 | |||
1057 | /** | ||
1058 | * Return true if itnim is considered offline for holding off IO request. | ||
1059 | * IO is not held if itnim is being deleted. | ||
1060 | */ | ||
1061 | bfa_boolean_t | ||
1062 | bfa_itnim_hold_io(struct bfa_itnim_s *itnim) | ||
1063 | { | ||
1064 | return ( | ||
1065 | itnim->fcpim->path_tov && itnim->iotov_active && | ||
1066 | (bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwcreate) || | ||
1067 | bfa_sm_cmp_state(itnim, bfa_itnim_sm_sler) || | ||
1068 | bfa_sm_cmp_state(itnim, bfa_itnim_sm_cleanup_offline) || | ||
1069 | bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwdelete) || | ||
1070 | bfa_sm_cmp_state(itnim, bfa_itnim_sm_offline) || | ||
1071 | bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable)) | ||
1072 | ); | ||
1073 | } | ||
1074 | |||
1075 | void | ||
1076 | bfa_itnim_get_stats(struct bfa_itnim_s *itnim, | ||
1077 | struct bfa_itnim_hal_stats_s *stats) | ||
1078 | { | ||
1079 | *stats = itnim->stats; | ||
1080 | } | ||
1081 | |||
1082 | void | ||
1083 | bfa_itnim_clear_stats(struct bfa_itnim_s *itnim) | ||
1084 | { | ||
1085 | bfa_os_memset(&itnim->stats, 0, sizeof(itnim->stats)); | ||
1086 | } | ||
1087 | |||
1088 | |||