Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
bfa_fcs_fcpim.c
Go to the documentation of this file.
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 /*
19  * fcpim.c - FCP initiator mode i-t nexus state machine
20  */
21 
22 #include "bfad_drv.h"
23 #include "bfa_fcs.h"
24 #include "bfa_fcbuild.h"
25 #include "bfad_im.h"
26 
27 BFA_TRC_FILE(FCS, FCPIM);
28 
29 /*
30  * forward declarations
31  */
32 static void bfa_fcs_itnim_timeout(void *arg);
33 static void bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim);
34 static void bfa_fcs_itnim_send_prli(void *itnim_cbarg,
35  struct bfa_fcxp_s *fcxp_alloced);
36 static void bfa_fcs_itnim_prli_response(void *fcsarg,
37  struct bfa_fcxp_s *fcxp, void *cbarg,
38  bfa_status_t req_status, u32 rsp_len,
39  u32 resid_len, struct fchs_s *rsp_fchs);
40 static void bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
42 
43 static void bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
45 static void bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
47 static void bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
49 static void bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
51 static void bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
53 static void bfa_fcs_itnim_sm_hal_rport_online(struct bfa_fcs_itnim_s *itnim,
55 static void bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
57 static void bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
59 static void bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
61 
62 static struct bfa_sm_table_s itnim_sm_table[] = {
63  {BFA_SM(bfa_fcs_itnim_sm_offline), BFA_ITNIM_OFFLINE},
64  {BFA_SM(bfa_fcs_itnim_sm_prli_send), BFA_ITNIM_PRLI_SEND},
65  {BFA_SM(bfa_fcs_itnim_sm_prli), BFA_ITNIM_PRLI_SENT},
66  {BFA_SM(bfa_fcs_itnim_sm_prli_retry), BFA_ITNIM_PRLI_RETRY},
67  {BFA_SM(bfa_fcs_itnim_sm_hcb_online), BFA_ITNIM_HCB_ONLINE},
68  {BFA_SM(bfa_fcs_itnim_sm_online), BFA_ITNIM_ONLINE},
69  {BFA_SM(bfa_fcs_itnim_sm_hcb_offline), BFA_ITNIM_HCB_OFFLINE},
70  {BFA_SM(bfa_fcs_itnim_sm_initiator), BFA_ITNIM_INITIATIOR},
71 };
72 
73 /*
74  * fcs_itnim_sm FCS itnim state machine
75  */
76 
77 static void
78 bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
80 {
81  bfa_trc(itnim->fcs, itnim->rport->pwwn);
82  bfa_trc(itnim->fcs, event);
83 
84  switch (event) {
86  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send);
87  itnim->prli_retries = 0;
88  bfa_fcs_itnim_send_prli(itnim, NULL);
89  break;
90 
93  break;
94 
96  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
97  break;
98 
100  bfa_fcs_itnim_free(itnim);
101  break;
102 
103  default:
104  bfa_sm_fault(itnim->fcs, event);
105  }
106 
107 }
108 
109 static void
110 bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
111  enum bfa_fcs_itnim_event event)
112 {
113  bfa_trc(itnim->fcs, itnim->rport->pwwn);
114  bfa_trc(itnim->fcs, event);
115 
116  switch (event) {
118  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli);
119  break;
120 
122  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
123  bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
125  break;
126 
128  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
129  bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
131  break;
132 
134  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
135  bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
136  bfa_fcs_itnim_free(itnim);
137  break;
138 
139  default:
140  bfa_sm_fault(itnim->fcs, event);
141  }
142 }
143 
144 static void
145 bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
146  enum bfa_fcs_itnim_event event)
147 {
148  bfa_trc(itnim->fcs, itnim->rport->pwwn);
149  bfa_trc(itnim->fcs, event);
150 
151  switch (event) {
153  if (itnim->rport->scsi_function == BFA_RPORT_INITIATOR)
154  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
155  else
156  bfa_sm_set_state(itnim,
157  bfa_fcs_itnim_sm_hal_rport_online);
158 
160  break;
161 
163  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_retry);
164  bfa_timer_start(itnim->fcs->bfa, &itnim->timer,
165  bfa_fcs_itnim_timeout, itnim,
167  break;
168 
170  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
171  break;
172 
174  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
175  bfa_fcxp_discard(itnim->fcxp);
177  break;
178 
180  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
181  bfa_fcxp_discard(itnim->fcxp);
183  break;
184 
186  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
187  bfa_fcxp_discard(itnim->fcxp);
188  bfa_fcs_itnim_free(itnim);
189  break;
190 
191  default:
192  bfa_sm_fault(itnim->fcs, event);
193  }
194 }
195 
196 static void
197 bfa_fcs_itnim_sm_hal_rport_online(struct bfa_fcs_itnim_s *itnim,
198  enum bfa_fcs_itnim_event event)
199 {
200  bfa_trc(itnim->fcs, itnim->rport->pwwn);
201  bfa_trc(itnim->fcs, event);
202 
203  switch (event) {
205  if (!itnim->bfa_itnim)
206  itnim->bfa_itnim = bfa_itnim_create(itnim->fcs->bfa,
207  itnim->rport->bfa_rport, itnim);
208 
209  if (itnim->bfa_itnim) {
210  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_online);
211  bfa_itnim_online(itnim->bfa_itnim, itnim->seq_rec);
212  } else {
213  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
215  }
216 
217  break;
218 
220  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
222  break;
223 
225  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
226  bfa_fcs_itnim_free(itnim);
227  break;
228 
229  default:
230  bfa_sm_fault(itnim->fcs, event);
231  }
232 }
233 
234 static void
235 bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
236  enum bfa_fcs_itnim_event event)
237 {
238  bfa_trc(itnim->fcs, itnim->rport->pwwn);
239  bfa_trc(itnim->fcs, event);
240 
241  switch (event) {
244  itnim->prli_retries++;
245  bfa_trc(itnim->fcs, itnim->prli_retries);
246  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send);
247  bfa_fcs_itnim_send_prli(itnim, NULL);
248  } else {
249  /* invoke target offline */
250  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
252  }
253  break;
254 
255 
257  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
258  bfa_timer_stop(&itnim->timer);
260  break;
261 
263  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
264  bfa_timer_stop(&itnim->timer);
266  break;
267 
269  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
270  bfa_timer_stop(&itnim->timer);
271  bfa_fcs_itnim_free(itnim);
272  break;
273 
274  default:
275  bfa_sm_fault(itnim->fcs, event);
276  }
277 }
278 
279 static void
280 bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
281  enum bfa_fcs_itnim_event event)
282 {
283  struct bfad_s *bfad = (struct bfad_s *)itnim->fcs->bfad;
284  char lpwwn_buf[BFA_STRING_32];
285  char rpwwn_buf[BFA_STRING_32];
286 
287  bfa_trc(itnim->fcs, itnim->rport->pwwn);
288  bfa_trc(itnim->fcs, event);
289 
290  switch (event) {
292  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_online);
294  wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port));
295  wwn2str(rpwwn_buf, itnim->rport->pwwn);
297  "Target (WWN = %s) is online for initiator (WWN = %s)\n",
298  rpwwn_buf, lpwwn_buf);
299  bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_ONLINE);
300  break;
301 
303  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_offline);
305  break;
306 
308  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
309  bfa_fcs_itnim_free(itnim);
310  break;
311 
312  default:
313  bfa_sm_fault(itnim->fcs, event);
314  }
315 }
316 
317 static void
318 bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
319  enum bfa_fcs_itnim_event event)
320 {
321  struct bfad_s *bfad = (struct bfad_s *)itnim->fcs->bfad;
322  char lpwwn_buf[BFA_STRING_32];
323  char rpwwn_buf[BFA_STRING_32];
324 
325  bfa_trc(itnim->fcs, itnim->rport->pwwn);
326  bfa_trc(itnim->fcs, event);
327 
328  switch (event) {
330  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_offline);
333  wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port));
334  wwn2str(rpwwn_buf, itnim->rport->pwwn);
335  if (bfa_fcs_lport_is_online(itnim->rport->port) == BFA_TRUE) {
337  "Target (WWN = %s) connectivity lost for "
338  "initiator (WWN = %s)\n", rpwwn_buf, lpwwn_buf);
339  bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_DISCONNECT);
340  } else {
342  "Target (WWN = %s) offlined by initiator (WWN = %s)\n",
343  rpwwn_buf, lpwwn_buf);
344  bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_OFFLINE);
345  }
346  break;
347 
349  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
350  bfa_fcs_itnim_free(itnim);
351  break;
352 
353  default:
354  bfa_sm_fault(itnim->fcs, event);
355  }
356 }
357 
358 static void
359 bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
360  enum bfa_fcs_itnim_event event)
361 {
362  bfa_trc(itnim->fcs, itnim->rport->pwwn);
363  bfa_trc(itnim->fcs, event);
364 
365  switch (event) {
367  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
369  break;
370 
372  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
373  bfa_fcs_itnim_free(itnim);
374  break;
375 
376  default:
377  bfa_sm_fault(itnim->fcs, event);
378  }
379 }
380 
381 /*
382  * This state is set when a discovered rport is also in intiator mode.
383  * This ITN is marked as no_op and is not active and will not be truned into
384  * online state.
385  */
386 static void
387 bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
388  enum bfa_fcs_itnim_event event)
389 {
390  bfa_trc(itnim->fcs, itnim->rport->pwwn);
391  bfa_trc(itnim->fcs, event);
392 
393  switch (event) {
395  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
397  break;
398 
399  /*
400  * fcs_online is expected here for well known initiator ports
401  */
404  break;
405 
408  break;
409 
411  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
412  bfa_fcs_itnim_free(itnim);
413  break;
414 
415  default:
416  bfa_sm_fault(itnim->fcs, event);
417  }
418 }
419 
420 static void
421 bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
422  enum bfa_itnim_aen_event event)
423 {
424  struct bfa_fcs_rport_s *rport = itnim->rport;
425  struct bfad_s *bfad = (struct bfad_s *)itnim->fcs->bfad;
426  struct bfa_aen_entry_s *aen_entry;
427 
428  /* Don't post events for well known addresses */
429  if (BFA_FCS_PID_IS_WKA(rport->pid))
430  return;
431 
432  bfad_get_aen_entry(bfad, aen_entry);
433  if (!aen_entry)
434  return;
435 
436  aen_entry->aen_data.itnim.vf_id = rport->port->fabric->vf_id;
437  aen_entry->aen_data.itnim.ppwwn = bfa_fcs_lport_get_pwwn(
438  bfa_fcs_get_base_port(itnim->fcs));
439  aen_entry->aen_data.itnim.lpwwn = bfa_fcs_lport_get_pwwn(rport->port);
440  aen_entry->aen_data.itnim.rpwwn = rport->pwwn;
441 
442  /* Send the AEN notification */
443  bfad_im_post_vendor_event(aen_entry, bfad, ++rport->fcs->fcs_aen_seq,
444  BFA_AEN_CAT_ITNIM, event);
445 }
446 
447 static void
448 bfa_fcs_itnim_send_prli(void *itnim_cbarg, struct bfa_fcxp_s *fcxp_alloced)
449 {
450  struct bfa_fcs_itnim_s *itnim = itnim_cbarg;
451  struct bfa_fcs_rport_s *rport = itnim->rport;
452  struct bfa_fcs_lport_s *port = rport->port;
453  struct fchs_s fchs;
454  struct bfa_fcxp_s *fcxp;
455  int len;
456 
457  bfa_trc(itnim->fcs, itnim->rport->pwwn);
458 
459  fcxp = fcxp_alloced ? fcxp_alloced :
461  if (!fcxp) {
462  itnim->stats.fcxp_alloc_wait++;
463  bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &itnim->fcxp_wqe,
464  bfa_fcs_itnim_send_prli, itnim, BFA_TRUE);
465  return;
466  }
467  itnim->fcxp = fcxp;
468 
469  len = fc_prli_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
470  itnim->rport->pid, bfa_fcs_lport_get_fcid(port), 0);
471 
472  bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id, port->lp_tag,
473  BFA_FALSE, FC_CLASS_3, len, &fchs,
474  bfa_fcs_itnim_prli_response, (void *)itnim,
476 
477  itnim->stats.prli_sent++;
479 }
480 
481 static void
482 bfa_fcs_itnim_prli_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
483  bfa_status_t req_status, u32 rsp_len,
484  u32 resid_len, struct fchs_s *rsp_fchs)
485 {
486  struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cbarg;
487  struct fc_els_cmd_s *els_cmd;
488  struct fc_prli_s *prli_resp;
489  struct fc_ls_rjt_s *ls_rjt;
490  struct fc_prli_params_s *sparams;
491 
492  bfa_trc(itnim->fcs, req_status);
493 
494  /*
495  * Sanity Checks
496  */
497  if (req_status != BFA_STATUS_OK) {
498  itnim->stats.prli_rsp_err++;
500  return;
501  }
502 
503  els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
504 
505  if (els_cmd->els_code == FC_ELS_ACC) {
506  prli_resp = (struct fc_prli_s *) els_cmd;
507 
508  if (fc_prli_rsp_parse(prli_resp, rsp_len) != FC_PARSE_OK) {
509  bfa_trc(itnim->fcs, rsp_len);
510  /*
511  * Check if this r-port is also in Initiator mode.
512  * If so, we need to set this ITN as a no-op.
513  */
514  if (prli_resp->parampage.servparams.initiator) {
515  bfa_trc(itnim->fcs, prli_resp->parampage.type);
516  itnim->rport->scsi_function =
518  itnim->stats.prli_rsp_acc++;
519  itnim->stats.initiator++;
520  bfa_sm_send_event(itnim,
522  return;
523  }
524 
525  itnim->stats.prli_rsp_parse_err++;
526  return;
527  }
528  itnim->rport->scsi_function = BFA_RPORT_TARGET;
529 
530  sparams = &prli_resp->parampage.servparams;
531  itnim->seq_rec = sparams->retry;
532  itnim->rec_support = sparams->rec_support;
533  itnim->task_retry_id = sparams->task_retry_id;
534  itnim->conf_comp = sparams->confirm;
535 
536  itnim->stats.prli_rsp_acc++;
538  } else {
539  ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
540 
541  bfa_trc(itnim->fcs, ls_rjt->reason_code);
542  bfa_trc(itnim->fcs, ls_rjt->reason_code_expl);
543 
544  itnim->stats.prli_rsp_rjt++;
545  if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) {
547  return;
548  }
550  }
551 }
552 
553 static void
554 bfa_fcs_itnim_timeout(void *arg)
555 {
556  struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) arg;
557 
558  itnim->stats.timeout++;
560 }
561 
562 static void
563 bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim)
564 {
565  if (itnim->bfa_itnim) {
566  bfa_itnim_delete(itnim->bfa_itnim);
567  itnim->bfa_itnim = NULL;
568  }
569 
570  bfa_fcb_itnim_free(itnim->fcs->bfad, itnim->itnim_drv);
571 }
572 
573 
574 
575 /*
576  * itnim_public FCS ITNIM public interfaces
577  */
578 
579 /*
580  * Called by rport when a new rport is created.
581  *
582  * @param[in] rport - remote port.
583  */
584 struct bfa_fcs_itnim_s *
586 {
587  struct bfa_fcs_lport_s *port = rport->port;
588  struct bfa_fcs_itnim_s *itnim;
589  struct bfad_itnim_s *itnim_drv;
590 
591  /*
592  * call bfad to allocate the itnim
593  */
594  bfa_fcb_itnim_alloc(port->fcs->bfad, &itnim, &itnim_drv);
595  if (itnim == NULL) {
596  bfa_trc(port->fcs, rport->pwwn);
597  return NULL;
598  }
599 
600  /*
601  * Initialize itnim
602  */
603  itnim->rport = rport;
604  itnim->fcs = rport->fcs;
605  itnim->itnim_drv = itnim_drv;
606 
607  itnim->bfa_itnim = NULL;
608  itnim->seq_rec = BFA_FALSE;
609  itnim->rec_support = BFA_FALSE;
610  itnim->conf_comp = BFA_FALSE;
611  itnim->task_retry_id = BFA_FALSE;
612 
613  /*
614  * Set State machine
615  */
616  bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
617 
618  return itnim;
619 }
620 
621 /*
622  * Called by rport to delete the instance of FCPIM.
623  *
624  * @param[in] rport - remote port.
625  */
626 void
628 {
629  bfa_trc(itnim->fcs, itnim->rport->pid);
631 }
632 
633 /*
634  * Notification from rport that PLOGI is complete to initiate FC-4 session.
635  */
636 void
638 {
639  itnim->stats.onlines++;
640 
641  if (!BFA_FCS_PID_IS_WKA(itnim->rport->pid))
643 }
644 
645 /*
646  * Called by rport to handle a remote device offline.
647  */
648 void
650 {
651  itnim->stats.offlines++;
653 }
654 
655 /*
656  * Called by rport when remote port is known to be an initiator from
657  * PRLI received.
658  */
659 void
661 {
662  bfa_trc(itnim->fcs, itnim->rport->pid);
663  itnim->stats.initiator++;
665 }
666 
667 /*
668  * Called by rport to check if the itnim is online.
669  */
672 {
673  bfa_trc(itnim->fcs, itnim->rport->pid);
674  switch (bfa_sm_to_state(itnim_sm_table, itnim->sm)) {
675  case BFA_ITNIM_ONLINE:
677  return BFA_STATUS_OK;
678 
679  default:
681  }
682 }
683 
684 /*
685  * BFA completion callback for bfa_itnim_online().
686  */
687 void
689 {
690  struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cbarg;
691 
692  bfa_trc(itnim->fcs, itnim->rport->pwwn);
694 }
695 
696 /*
697  * BFA completion callback for bfa_itnim_offline().
698  */
699 void
700 bfa_cb_itnim_offline(void *cb_arg)
701 {
702  struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cb_arg;
703 
704  bfa_trc(itnim->fcs, itnim->rport->pwwn);
706 }
707 
708 /*
709  * Mark the beginning of PATH TOV handling. IO completion callbacks
710  * are still pending.
711  */
712 void
714 {
715  struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cb_arg;
716 
717  bfa_trc(itnim->fcs, itnim->rport->pwwn);
718 }
719 
720 /*
721  * Mark the end of PATH TOV handling. All pending IOs are already cleaned up.
722  */
723 void
724 bfa_cb_itnim_tov(void *cb_arg)
725 {
726  struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cb_arg;
727  struct bfad_itnim_s *itnim_drv = itnim->itnim_drv;
728 
729  bfa_trc(itnim->fcs, itnim->rport->pwwn);
730  itnim_drv->state = ITNIM_STATE_TIMEOUT;
731 }
732 
733 /*
734  * BFA notification to FCS/driver for second level error recovery.
735  *
736  * Atleast one I/O request has timedout and target is unresponsive to
737  * repeated abort requests. Second level error recovery should be initiated
738  * by starting implicit logout and recovery procedures.
739  */
740 void
741 bfa_cb_itnim_sler(void *cb_arg)
742 {
743  struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cb_arg;
744 
745  itnim->stats.sler++;
746  bfa_trc(itnim->fcs, itnim->rport->pwwn);
748 }
749 
750 struct bfa_fcs_itnim_s *
752 {
753  struct bfa_fcs_rport_s *rport;
754  rport = bfa_fcs_rport_lookup(port, rpwwn);
755 
756  if (!rport)
757  return NULL;
758 
759  WARN_ON(rport->itnim == NULL);
760  return rport->itnim;
761 }
762 
765  struct bfa_itnim_attr_s *attr)
766 {
767  struct bfa_fcs_itnim_s *itnim = NULL;
768 
769  itnim = bfa_fcs_itnim_lookup(port, rpwwn);
770 
771  if (itnim == NULL)
773 
774  attr->state = bfa_sm_to_state(itnim_sm_table, itnim->sm);
775  attr->retry = itnim->seq_rec;
776  attr->rec_support = itnim->rec_support;
777  attr->conf_comp = itnim->conf_comp;
778  attr->task_retry_id = itnim->task_retry_id;
779  return BFA_STATUS_OK;
780 }
781 
784  struct bfa_itnim_stats_s *stats)
785 {
786  struct bfa_fcs_itnim_s *itnim = NULL;
787 
788  WARN_ON(port == NULL);
789 
790  itnim = bfa_fcs_itnim_lookup(port, rpwwn);
791 
792  if (itnim == NULL)
794 
795  memcpy(stats, &itnim->stats, sizeof(struct bfa_itnim_stats_s));
796 
797  return BFA_STATUS_OK;
798 }
799 
802 {
803  struct bfa_fcs_itnim_s *itnim = NULL;
804 
805  WARN_ON(port == NULL);
806 
807  itnim = bfa_fcs_itnim_lookup(port, rpwwn);
808 
809  if (itnim == NULL)
811 
812  memset(&itnim->stats, 0, sizeof(struct bfa_itnim_stats_s));
813  return BFA_STATUS_OK;
814 }
815 
816 void
818  struct fchs_s *fchs, u16 len)
819 {
820  struct fc_els_cmd_s *els_cmd;
821 
822  bfa_trc(itnim->fcs, fchs->type);
823 
824  if (fchs->type != FC_TYPE_ELS)
825  return;
826 
827  els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
828 
829  bfa_trc(itnim->fcs, els_cmd->els_code);
830 
831  switch (els_cmd->els_code) {
832  case FC_ELS_PRLO:
833  bfa_fcs_rport_prlo(itnim->rport, fchs->ox_id);
834  break;
835 
836  default:
837  WARN_ON(1);
838  }
839 }