mirror of
				https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
				synced 2025-10-31 08:14:06 +00:00 
			
		
		
		
	 e641de37e6
			
		
	
	
		e641de37e6
		
	
	
	
	
		
			
			Replace bfa_assert() with bfa_sm_fault() to get unhandled events for debugging. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
		
			
				
	
	
		
			1089 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1089 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
 | |
|  * All rights reserved
 | |
|  * www.brocade.com
 | |
|  *
 | |
|  * Linux driver for Brocade Fibre Channel Host Bus Adapter.
 | |
|  *
 | |
|  * This program is free software; you can redistribute it and/or modify it
 | |
|  * under the terms of the GNU General Public License (GPL) Version 2 as
 | |
|  * published by the Free Software Foundation
 | |
|  *
 | |
|  * This program is distributed in the hope that it will be useful, but
 | |
|  * WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|  * General Public License for more details.
 | |
|  */
 | |
| 
 | |
| #include <bfa.h>
 | |
| #include <bfa_fcpim.h>
 | |
| #include "bfa_fcpim_priv.h"
 | |
| 
 | |
| BFA_TRC_FILE(HAL, ITNIM);
 | |
| 
 | |
| #define BFA_ITNIM_FROM_TAG(_fcpim, _tag)				\
 | |
| 	((_fcpim)->itnim_arr + ((_tag) & ((_fcpim)->num_itnims - 1)))
 | |
| 
 | |
| #define bfa_fcpim_additn(__itnim)					\
 | |
| 	list_add_tail(&(__itnim)->qe, &(__itnim)->fcpim->itnim_q)
 | |
| #define bfa_fcpim_delitn(__itnim)	do {				\
 | |
| 	bfa_assert(bfa_q_is_on_q(&(__itnim)->fcpim->itnim_q, __itnim));      \
 | |
| 	list_del(&(__itnim)->qe);      \
 | |
| 	bfa_assert(list_empty(&(__itnim)->io_q));      \
 | |
| 	bfa_assert(list_empty(&(__itnim)->io_cleanup_q));      \
 | |
| 	bfa_assert(list_empty(&(__itnim)->pending_q));      \
 | |
| } while (0)
 | |
| 
 | |
| #define bfa_itnim_online_cb(__itnim) do {				\
 | |
| 	if ((__itnim)->bfa->fcs)					\
 | |
| 		bfa_cb_itnim_online((__itnim)->ditn);      \
 | |
| 	else {								\
 | |
| 		bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe,	\
 | |
| 		__bfa_cb_itnim_online, (__itnim));      \
 | |
| 	}								\
 | |
| } while (0)
 | |
| 
 | |
| #define bfa_itnim_offline_cb(__itnim) do {				\
 | |
| 	if ((__itnim)->bfa->fcs)					\
 | |
| 		bfa_cb_itnim_offline((__itnim)->ditn);      \
 | |
| 	else {								\
 | |
| 		bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe,	\
 | |
| 		__bfa_cb_itnim_offline, (__itnim));      \
 | |
| 	}								\
 | |
| } while (0)
 | |
| 
 | |
| #define bfa_itnim_sler_cb(__itnim) do {					\
 | |
| 	if ((__itnim)->bfa->fcs)					\
 | |
| 		bfa_cb_itnim_sler((__itnim)->ditn);      \
 | |
| 	else {								\
 | |
| 		bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe,	\
 | |
| 		__bfa_cb_itnim_sler, (__itnim));      \
 | |
| 	}								\
 | |
| } while (0)
 | |
| 
 | |
| /*
 | |
|  * forward declarations
 | |
|  */
 | |
| static void     bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim);
 | |
| static bfa_boolean_t bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim);
 | |
| static bfa_boolean_t bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim);
 | |
| static void     bfa_itnim_cleanp_comp(void *itnim_cbarg);
 | |
| static void     bfa_itnim_cleanup(struct bfa_itnim_s *itnim);
 | |
| static void     __bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete);
 | |
| static void     __bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete);
 | |
| static void     __bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete);
 | |
| static void     bfa_itnim_iotov_online(struct bfa_itnim_s *itnim);
 | |
| static void     bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim);
 | |
| static void     bfa_itnim_iotov(void *itnim_arg);
 | |
| static void     bfa_itnim_iotov_start(struct bfa_itnim_s *itnim);
 | |
| static void     bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim);
 | |
| static void     bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim);
 | |
| 
 | |
| /**
 | |
|  *  bfa_itnim_sm BFA itnim state machine
 | |
|  */
 | |
| 
 | |
| 
 | |
| enum bfa_itnim_event {
 | |
| 	BFA_ITNIM_SM_CREATE = 1,	/*  itnim is created */
 | |
| 	BFA_ITNIM_SM_ONLINE = 2,	/*  itnim is online */
 | |
| 	BFA_ITNIM_SM_OFFLINE = 3,	/*  itnim is offline */
 | |
| 	BFA_ITNIM_SM_FWRSP = 4,		/*  firmware response */
 | |
| 	BFA_ITNIM_SM_DELETE = 5,	/*  deleting an existing itnim */
 | |
| 	BFA_ITNIM_SM_CLEANUP = 6,	/*  IO cleanup completion */
 | |
| 	BFA_ITNIM_SM_SLER = 7,		/*  second level error recovery */
 | |
| 	BFA_ITNIM_SM_HWFAIL = 8,	/*  IOC h/w failure event */
 | |
| 	BFA_ITNIM_SM_QRESUME = 9,	/*  queue space available */
 | |
| };
 | |
| 
 | |
| static void     bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim,
 | |
| 					enum bfa_itnim_event event);
 | |
| static void     bfa_itnim_sm_created(struct bfa_itnim_s *itnim,
 | |
| 					 enum bfa_itnim_event event);
 | |
| static void     bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim,
 | |
| 					  enum bfa_itnim_event event);
 | |
| static void	bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
 | |
| 				enum bfa_itnim_event event);
 | |
| static void     bfa_itnim_sm_online(struct bfa_itnim_s *itnim,
 | |
| 					enum bfa_itnim_event event);
 | |
| static void     bfa_itnim_sm_sler(struct bfa_itnim_s *itnim,
 | |
| 				      enum bfa_itnim_event event);
 | |
| static void     bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
 | |
| 						 enum bfa_itnim_event event);
 | |
| static void     bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
 | |
| 						enum bfa_itnim_event event);
 | |
| static void     bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim,
 | |
| 					  enum bfa_itnim_event event);
 | |
| static void     bfa_itnim_sm_offline(struct bfa_itnim_s *itnim,
 | |
| 					 enum bfa_itnim_event event);
 | |
| static void     bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
 | |
| 					    enum bfa_itnim_event event);
 | |
| static void     bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim,
 | |
| 					  enum bfa_itnim_event event);
 | |
| static void     bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
 | |
| 					  enum bfa_itnim_event event);
 | |
| static void     bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
 | |
| 					  enum bfa_itnim_event event);
 | |
| static void     bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
 | |
| 					  enum bfa_itnim_event event);
 | |
| 
 | |
| /**
 | |
|  * 		Beginning/unallocated state - no events expected.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 | |
| {
 | |
| 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 | |
| 	bfa_trc(itnim->bfa, event);
 | |
| 
 | |
| 	switch (event) {
 | |
| 	case BFA_ITNIM_SM_CREATE:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_created);
 | |
| 		itnim->is_online = BFA_FALSE;
 | |
| 		bfa_fcpim_additn(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_sm_fault(itnim->bfa, event);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 		Beginning state, only online event expected.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 | |
| {
 | |
| 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 | |
| 	bfa_trc(itnim->bfa, event);
 | |
| 
 | |
| 	switch (event) {
 | |
| 	case BFA_ITNIM_SM_ONLINE:
 | |
| 		if (bfa_itnim_send_fwcreate(itnim))
 | |
| 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
 | |
| 		else
 | |
| 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_DELETE:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
 | |
| 		bfa_fcpim_delitn(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_HWFAIL:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_sm_fault(itnim->bfa, event);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 		Waiting for itnim create response from firmware.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 | |
| {
 | |
| 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 | |
| 	bfa_trc(itnim->bfa, event);
 | |
| 
 | |
| 	switch (event) {
 | |
| 	case BFA_ITNIM_SM_FWRSP:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_online);
 | |
| 		itnim->is_online = BFA_TRUE;
 | |
| 		bfa_itnim_iotov_online(itnim);
 | |
| 		bfa_itnim_online_cb(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_DELETE:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_delete_pending);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_OFFLINE:
 | |
| 		if (bfa_itnim_send_fwdelete(itnim))
 | |
| 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
 | |
| 		else
 | |
| 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_HWFAIL:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_sm_fault(itnim->bfa, event);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static void
 | |
| bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
 | |
| 			enum bfa_itnim_event event)
 | |
| {
 | |
| 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 | |
| 	bfa_trc(itnim->bfa, event);
 | |
| 
 | |
| 	switch (event) {
 | |
| 	case BFA_ITNIM_SM_QRESUME:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
 | |
| 		bfa_itnim_send_fwcreate(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_DELETE:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
 | |
| 		bfa_reqq_wcancel(&itnim->reqq_wait);
 | |
| 		bfa_fcpim_delitn(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_OFFLINE:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_offline);
 | |
| 		bfa_reqq_wcancel(&itnim->reqq_wait);
 | |
| 		bfa_itnim_offline_cb(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_HWFAIL:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 | |
| 		bfa_reqq_wcancel(&itnim->reqq_wait);
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_sm_fault(itnim->bfa, event);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 	Waiting for itnim create response from firmware, a delete is pending.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
 | |
| 				enum bfa_itnim_event event)
 | |
| {
 | |
| 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 | |
| 	bfa_trc(itnim->bfa, event);
 | |
| 
 | |
| 	switch (event) {
 | |
| 	case BFA_ITNIM_SM_FWRSP:
 | |
| 		if (bfa_itnim_send_fwdelete(itnim))
 | |
| 			bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
 | |
| 		else
 | |
| 			bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_HWFAIL:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
 | |
| 		bfa_fcpim_delitn(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_sm_fault(itnim->bfa, event);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 		Online state - normal parking state.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 | |
| {
 | |
| 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 | |
| 	bfa_trc(itnim->bfa, event);
 | |
| 
 | |
| 	switch (event) {
 | |
| 	case BFA_ITNIM_SM_OFFLINE:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline);
 | |
| 		itnim->is_online = BFA_FALSE;
 | |
| 		bfa_itnim_iotov_start(itnim);
 | |
| 		bfa_itnim_cleanup(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_DELETE:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
 | |
| 		itnim->is_online = BFA_FALSE;
 | |
| 		bfa_itnim_cleanup(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_SLER:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_sler);
 | |
| 		itnim->is_online = BFA_FALSE;
 | |
| 		bfa_itnim_iotov_start(itnim);
 | |
| 		bfa_itnim_sler_cb(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_HWFAIL:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 | |
| 		itnim->is_online = BFA_FALSE;
 | |
| 		bfa_itnim_iotov_start(itnim);
 | |
| 		bfa_itnim_iocdisable_cleanup(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_sm_fault(itnim->bfa, event);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 		Second level error recovery need.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 | |
| {
 | |
| 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 | |
| 	bfa_trc(itnim->bfa, event);
 | |
| 
 | |
| 	switch (event) {
 | |
| 	case BFA_ITNIM_SM_OFFLINE:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline);
 | |
| 		bfa_itnim_cleanup(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_DELETE:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
 | |
| 		bfa_itnim_cleanup(itnim);
 | |
| 		bfa_itnim_iotov_delete(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_HWFAIL:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 | |
| 		bfa_itnim_iocdisable_cleanup(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_sm_fault(itnim->bfa, event);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 		Going offline. Waiting for active IO cleanup.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
 | |
| 				 enum bfa_itnim_event event)
 | |
| {
 | |
| 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 | |
| 	bfa_trc(itnim->bfa, event);
 | |
| 
 | |
| 	switch (event) {
 | |
| 	case BFA_ITNIM_SM_CLEANUP:
 | |
| 		if (bfa_itnim_send_fwdelete(itnim))
 | |
| 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
 | |
| 		else
 | |
| 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_DELETE:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
 | |
| 		bfa_itnim_iotov_delete(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_HWFAIL:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 | |
| 		bfa_itnim_iocdisable_cleanup(itnim);
 | |
| 		bfa_itnim_offline_cb(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_SLER:
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_sm_fault(itnim->bfa, event);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 		Deleting itnim. Waiting for active IO cleanup.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
 | |
| 				enum bfa_itnim_event event)
 | |
| {
 | |
| 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 | |
| 	bfa_trc(itnim->bfa, event);
 | |
| 
 | |
| 	switch (event) {
 | |
| 	case BFA_ITNIM_SM_CLEANUP:
 | |
| 		if (bfa_itnim_send_fwdelete(itnim))
 | |
| 			bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
 | |
| 		else
 | |
| 			bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_HWFAIL:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 | |
| 		bfa_itnim_iocdisable_cleanup(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_sm_fault(itnim->bfa, event);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Rport offline. Fimrware itnim is being deleted - awaiting f/w response.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 | |
| {
 | |
| 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 | |
| 	bfa_trc(itnim->bfa, event);
 | |
| 
 | |
| 	switch (event) {
 | |
| 	case BFA_ITNIM_SM_FWRSP:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_offline);
 | |
| 		bfa_itnim_offline_cb(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_DELETE:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_HWFAIL:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 | |
| 		bfa_itnim_offline_cb(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_sm_fault(itnim->bfa, event);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static void
 | |
| bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
 | |
| 			enum bfa_itnim_event event)
 | |
| {
 | |
| 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 | |
| 	bfa_trc(itnim->bfa, event);
 | |
| 
 | |
| 	switch (event) {
 | |
| 	case BFA_ITNIM_SM_QRESUME:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
 | |
| 		bfa_itnim_send_fwdelete(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_DELETE:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_HWFAIL:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 | |
| 		bfa_reqq_wcancel(&itnim->reqq_wait);
 | |
| 		bfa_itnim_offline_cb(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_sm_fault(itnim->bfa, event);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 		Offline state.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 | |
| {
 | |
| 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 | |
| 	bfa_trc(itnim->bfa, event);
 | |
| 
 | |
| 	switch (event) {
 | |
| 	case BFA_ITNIM_SM_DELETE:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
 | |
| 		bfa_itnim_iotov_delete(itnim);
 | |
| 		bfa_fcpim_delitn(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_ONLINE:
 | |
| 		if (bfa_itnim_send_fwcreate(itnim))
 | |
| 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
 | |
| 		else
 | |
| 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_HWFAIL:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_sm_fault(itnim->bfa, event);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 		IOC h/w failed state.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
 | |
| 			    enum bfa_itnim_event event)
 | |
| {
 | |
| 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 | |
| 	bfa_trc(itnim->bfa, event);
 | |
| 
 | |
| 	switch (event) {
 | |
| 	case BFA_ITNIM_SM_DELETE:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
 | |
| 		bfa_itnim_iotov_delete(itnim);
 | |
| 		bfa_fcpim_delitn(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_OFFLINE:
 | |
| 		bfa_itnim_offline_cb(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_ONLINE:
 | |
| 		if (bfa_itnim_send_fwcreate(itnim))
 | |
| 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
 | |
| 		else
 | |
| 			bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_HWFAIL:
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_sm_fault(itnim->bfa, event);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 		Itnim is deleted, waiting for firmware response to delete.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
 | |
| {
 | |
| 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 | |
| 	bfa_trc(itnim->bfa, event);
 | |
| 
 | |
| 	switch (event) {
 | |
| 	case BFA_ITNIM_SM_FWRSP:
 | |
| 	case BFA_ITNIM_SM_HWFAIL:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
 | |
| 		bfa_fcpim_delitn(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_sm_fault(itnim->bfa, event);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static void
 | |
| bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
 | |
| 			enum bfa_itnim_event event)
 | |
| {
 | |
| 	bfa_trc(itnim->bfa, itnim->rport->rport_tag);
 | |
| 	bfa_trc(itnim->bfa, event);
 | |
| 
 | |
| 	switch (event) {
 | |
| 	case BFA_ITNIM_SM_QRESUME:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
 | |
| 		bfa_itnim_send_fwdelete(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	case BFA_ITNIM_SM_HWFAIL:
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
 | |
| 		bfa_reqq_wcancel(&itnim->reqq_wait);
 | |
| 		bfa_fcpim_delitn(itnim);
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_sm_fault(itnim->bfa, event);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /**
 | |
|  *  bfa_itnim_private
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * 		Initiate cleanup of all IOs on an IOC failure.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim)
 | |
| {
 | |
| 	struct bfa_tskim_s *tskim;
 | |
| 	struct bfa_ioim_s *ioim;
 | |
| 	struct list_head        *qe, *qen;
 | |
| 
 | |
| 	list_for_each_safe(qe, qen, &itnim->tsk_q) {
 | |
| 		tskim = (struct bfa_tskim_s *) qe;
 | |
| 		bfa_tskim_iocdisable(tskim);
 | |
| 	}
 | |
| 
 | |
| 	list_for_each_safe(qe, qen, &itnim->io_q) {
 | |
| 		ioim = (struct bfa_ioim_s *) qe;
 | |
| 		bfa_ioim_iocdisable(ioim);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * For IO request in pending queue, we pretend an early timeout.
 | |
| 	 */
 | |
| 	list_for_each_safe(qe, qen, &itnim->pending_q) {
 | |
| 		ioim = (struct bfa_ioim_s *) qe;
 | |
| 		bfa_ioim_tov(ioim);
 | |
| 	}
 | |
| 
 | |
| 	list_for_each_safe(qe, qen, &itnim->io_cleanup_q) {
 | |
| 		ioim = (struct bfa_ioim_s *) qe;
 | |
| 		bfa_ioim_iocdisable(ioim);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 		IO cleanup completion
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_cleanp_comp(void *itnim_cbarg)
 | |
| {
 | |
| 	struct bfa_itnim_s *itnim = itnim_cbarg;
 | |
| 
 | |
| 	bfa_stats(itnim, cleanup_comps);
 | |
| 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_CLEANUP);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 		Initiate cleanup of all IOs.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_cleanup(struct bfa_itnim_s *itnim)
 | |
| {
 | |
| 	struct bfa_ioim_s  *ioim;
 | |
| 	struct bfa_tskim_s *tskim;
 | |
| 	struct list_head         *qe, *qen;
 | |
| 
 | |
| 	bfa_wc_init(&itnim->wc, bfa_itnim_cleanp_comp, itnim);
 | |
| 
 | |
| 	list_for_each_safe(qe, qen, &itnim->io_q) {
 | |
| 		ioim = (struct bfa_ioim_s *) qe;
 | |
| 
 | |
| 		/**
 | |
| 		 * Move IO to a cleanup queue from active queue so that a later
 | |
| 		 * TM will not pickup this IO.
 | |
| 		 */
 | |
| 		list_del(&ioim->qe);
 | |
| 		list_add_tail(&ioim->qe, &itnim->io_cleanup_q);
 | |
| 
 | |
| 		bfa_wc_up(&itnim->wc);
 | |
| 		bfa_ioim_cleanup(ioim);
 | |
| 	}
 | |
| 
 | |
| 	list_for_each_safe(qe, qen, &itnim->tsk_q) {
 | |
| 		tskim = (struct bfa_tskim_s *) qe;
 | |
| 		bfa_wc_up(&itnim->wc);
 | |
| 		bfa_tskim_cleanup(tskim);
 | |
| 	}
 | |
| 
 | |
| 	bfa_wc_wait(&itnim->wc);
 | |
| }
 | |
| 
 | |
| static void
 | |
| __bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete)
 | |
| {
 | |
| 	struct bfa_itnim_s *itnim = cbarg;
 | |
| 
 | |
| 	if (complete)
 | |
| 		bfa_cb_itnim_online(itnim->ditn);
 | |
| }
 | |
| 
 | |
| static void
 | |
| __bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete)
 | |
| {
 | |
| 	struct bfa_itnim_s *itnim = cbarg;
 | |
| 
 | |
| 	if (complete)
 | |
| 		bfa_cb_itnim_offline(itnim->ditn);
 | |
| }
 | |
| 
 | |
| static void
 | |
| __bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete)
 | |
| {
 | |
| 	struct bfa_itnim_s *itnim = cbarg;
 | |
| 
 | |
| 	if (complete)
 | |
| 		bfa_cb_itnim_sler(itnim->ditn);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Call to resume any I/O requests waiting for room in request queue.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_qresume(void *cbarg)
 | |
| {
 | |
| 	struct bfa_itnim_s *itnim = cbarg;
 | |
| 
 | |
| 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_QRESUME);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| /**
 | |
|  *  bfa_itnim_public
 | |
|  */
 | |
| 
 | |
| void
 | |
| bfa_itnim_iodone(struct bfa_itnim_s *itnim)
 | |
| {
 | |
| 	bfa_wc_down(&itnim->wc);
 | |
| }
 | |
| 
 | |
| void
 | |
| bfa_itnim_tskdone(struct bfa_itnim_s *itnim)
 | |
| {
 | |
| 	bfa_wc_down(&itnim->wc);
 | |
| }
 | |
| 
 | |
| void
 | |
| bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
 | |
| 		u32 *dm_len)
 | |
| {
 | |
| 	/**
 | |
| 	 * ITN memory
 | |
| 	 */
 | |
| 	*km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_itnim_s);
 | |
| }
 | |
| 
 | |
| void
 | |
| bfa_itnim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
 | |
| {
 | |
| 	struct bfa_s      *bfa = fcpim->bfa;
 | |
| 	struct bfa_itnim_s *itnim;
 | |
| 	int             i;
 | |
| 
 | |
| 	INIT_LIST_HEAD(&fcpim->itnim_q);
 | |
| 
 | |
| 	itnim = (struct bfa_itnim_s *) bfa_meminfo_kva(minfo);
 | |
| 	fcpim->itnim_arr = itnim;
 | |
| 
 | |
| 	for (i = 0; i < fcpim->num_itnims; i++, itnim++) {
 | |
| 		bfa_os_memset(itnim, 0, sizeof(struct bfa_itnim_s));
 | |
| 		itnim->bfa = bfa;
 | |
| 		itnim->fcpim = fcpim;
 | |
| 		itnim->reqq = BFA_REQQ_QOS_LO;
 | |
| 		itnim->rport = BFA_RPORT_FROM_TAG(bfa, i);
 | |
| 		itnim->iotov_active = BFA_FALSE;
 | |
| 		bfa_reqq_winit(&itnim->reqq_wait, bfa_itnim_qresume, itnim);
 | |
| 
 | |
| 		INIT_LIST_HEAD(&itnim->io_q);
 | |
| 		INIT_LIST_HEAD(&itnim->io_cleanup_q);
 | |
| 		INIT_LIST_HEAD(&itnim->pending_q);
 | |
| 		INIT_LIST_HEAD(&itnim->tsk_q);
 | |
| 		INIT_LIST_HEAD(&itnim->delay_comp_q);
 | |
| 		bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
 | |
| 	}
 | |
| 
 | |
| 	bfa_meminfo_kva(minfo) = (u8 *) itnim;
 | |
| }
 | |
| 
 | |
| void
 | |
| bfa_itnim_iocdisable(struct bfa_itnim_s *itnim)
 | |
| {
 | |
| 	bfa_stats(itnim, ioc_disabled);
 | |
| 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_HWFAIL);
 | |
| }
 | |
| 
 | |
| static bfa_boolean_t
 | |
| bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim)
 | |
| {
 | |
| 	struct bfi_itnim_create_req_s *m;
 | |
| 
 | |
| 	itnim->msg_no++;
 | |
| 
 | |
| 	/**
 | |
| 	 * check for room in queue to send request now
 | |
| 	 */
 | |
| 	m = bfa_reqq_next(itnim->bfa, itnim->reqq);
 | |
| 	if (!m) {
 | |
| 		bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait);
 | |
| 		return BFA_FALSE;
 | |
| 	}
 | |
| 
 | |
| 	bfi_h2i_set(m->mh, BFI_MC_ITNIM, BFI_ITNIM_H2I_CREATE_REQ,
 | |
| 			bfa_lpuid(itnim->bfa));
 | |
| 	m->fw_handle = itnim->rport->fw_handle;
 | |
| 	m->class = FC_CLASS_3;
 | |
| 	m->seq_rec = itnim->seq_rec;
 | |
| 	m->msg_no = itnim->msg_no;
 | |
| 
 | |
| 	/**
 | |
| 	 * queue I/O message to firmware
 | |
| 	 */
 | |
| 	bfa_reqq_produce(itnim->bfa, itnim->reqq);
 | |
| 	return BFA_TRUE;
 | |
| }
 | |
| 
 | |
| static bfa_boolean_t
 | |
| bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim)
 | |
| {
 | |
| 	struct bfi_itnim_delete_req_s *m;
 | |
| 
 | |
| 	/**
 | |
| 	 * check for room in queue to send request now
 | |
| 	 */
 | |
| 	m = bfa_reqq_next(itnim->bfa, itnim->reqq);
 | |
| 	if (!m) {
 | |
| 		bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait);
 | |
| 		return BFA_FALSE;
 | |
| 	}
 | |
| 
 | |
| 	bfi_h2i_set(m->mh, BFI_MC_ITNIM, BFI_ITNIM_H2I_DELETE_REQ,
 | |
| 			bfa_lpuid(itnim->bfa));
 | |
| 	m->fw_handle = itnim->rport->fw_handle;
 | |
| 
 | |
| 	/**
 | |
| 	 * queue I/O message to firmware
 | |
| 	 */
 | |
| 	bfa_reqq_produce(itnim->bfa, itnim->reqq);
 | |
| 	return BFA_TRUE;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Cleanup all pending failed inflight requests.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_delayed_comp(struct bfa_itnim_s *itnim, bfa_boolean_t iotov)
 | |
| {
 | |
| 	struct bfa_ioim_s *ioim;
 | |
| 	struct list_head *qe, *qen;
 | |
| 
 | |
| 	list_for_each_safe(qe, qen, &itnim->delay_comp_q) {
 | |
| 		ioim = (struct bfa_ioim_s *)qe;
 | |
| 		bfa_ioim_delayed_comp(ioim, iotov);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Start all pending IO requests.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_iotov_online(struct bfa_itnim_s *itnim)
 | |
| {
 | |
| 	struct bfa_ioim_s *ioim;
 | |
| 
 | |
| 	bfa_itnim_iotov_stop(itnim);
 | |
| 
 | |
| 	/**
 | |
| 	 * Abort all inflight IO requests in the queue
 | |
| 	 */
 | |
| 	bfa_itnim_delayed_comp(itnim, BFA_FALSE);
 | |
| 
 | |
| 	/**
 | |
| 	 * Start all pending IO requests.
 | |
| 	 */
 | |
| 	while (!list_empty(&itnim->pending_q)) {
 | |
| 		bfa_q_deq(&itnim->pending_q, &ioim);
 | |
| 		list_add_tail(&ioim->qe, &itnim->io_q);
 | |
| 		bfa_ioim_start(ioim);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Fail all pending IO requests
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim)
 | |
| {
 | |
| 	struct bfa_ioim_s *ioim;
 | |
| 
 | |
| 	/**
 | |
| 	 * Fail all inflight IO requests in the queue
 | |
| 	 */
 | |
| 	bfa_itnim_delayed_comp(itnim, BFA_TRUE);
 | |
| 
 | |
| 	/**
 | |
| 	 * Fail any pending IO requests.
 | |
| 	 */
 | |
| 	while (!list_empty(&itnim->pending_q)) {
 | |
| 		bfa_q_deq(&itnim->pending_q, &ioim);
 | |
| 		list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
 | |
| 		bfa_ioim_tov(ioim);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * IO TOV timer callback. Fail any pending IO requests.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_iotov(void *itnim_arg)
 | |
| {
 | |
| 	struct bfa_itnim_s *itnim = itnim_arg;
 | |
| 
 | |
| 	itnim->iotov_active = BFA_FALSE;
 | |
| 
 | |
| 	bfa_cb_itnim_tov_begin(itnim->ditn);
 | |
| 	bfa_itnim_iotov_cleanup(itnim);
 | |
| 	bfa_cb_itnim_tov(itnim->ditn);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Start IO TOV timer for failing back pending IO requests in offline state.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_iotov_start(struct bfa_itnim_s *itnim)
 | |
| {
 | |
| 	if (itnim->fcpim->path_tov > 0) {
 | |
| 
 | |
| 		itnim->iotov_active = BFA_TRUE;
 | |
| 		bfa_assert(bfa_itnim_hold_io(itnim));
 | |
| 		bfa_timer_start(itnim->bfa, &itnim->timer,
 | |
| 			bfa_itnim_iotov, itnim, itnim->fcpim->path_tov);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Stop IO TOV timer.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim)
 | |
| {
 | |
| 	if (itnim->iotov_active) {
 | |
| 		itnim->iotov_active = BFA_FALSE;
 | |
| 		bfa_timer_stop(&itnim->timer);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Stop IO TOV timer.
 | |
|  */
 | |
| static void
 | |
| bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim)
 | |
| {
 | |
|     bfa_boolean_t pathtov_active = BFA_FALSE;
 | |
| 
 | |
|     if (itnim->iotov_active)
 | |
| 		pathtov_active = BFA_TRUE;
 | |
| 
 | |
| 	bfa_itnim_iotov_stop(itnim);
 | |
| 	if (pathtov_active)
 | |
| 		bfa_cb_itnim_tov_begin(itnim->ditn);
 | |
| 	bfa_itnim_iotov_cleanup(itnim);
 | |
| 	if (pathtov_active)
 | |
| 		bfa_cb_itnim_tov(itnim->ditn);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /**
 | |
|  *  bfa_itnim_public
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * 		Itnim interrupt processing.
 | |
|  */
 | |
| void
 | |
| bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
 | |
| {
 | |
| 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
 | |
| 	union bfi_itnim_i2h_msg_u msg;
 | |
| 	struct bfa_itnim_s *itnim;
 | |
| 
 | |
| 	bfa_trc(bfa, m->mhdr.msg_id);
 | |
| 
 | |
| 	msg.msg = m;
 | |
| 
 | |
| 	switch (m->mhdr.msg_id) {
 | |
| 	case BFI_ITNIM_I2H_CREATE_RSP:
 | |
| 		itnim = BFA_ITNIM_FROM_TAG(fcpim,
 | |
| 					       msg.create_rsp->bfa_handle);
 | |
| 		bfa_assert(msg.create_rsp->status == BFA_STATUS_OK);
 | |
| 		bfa_stats(itnim, create_comps);
 | |
| 		bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP);
 | |
| 		break;
 | |
| 
 | |
| 	case BFI_ITNIM_I2H_DELETE_RSP:
 | |
| 		itnim = BFA_ITNIM_FROM_TAG(fcpim,
 | |
| 					       msg.delete_rsp->bfa_handle);
 | |
| 		bfa_assert(msg.delete_rsp->status == BFA_STATUS_OK);
 | |
| 		bfa_stats(itnim, delete_comps);
 | |
| 		bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP);
 | |
| 		break;
 | |
| 
 | |
| 	case BFI_ITNIM_I2H_SLER_EVENT:
 | |
| 		itnim = BFA_ITNIM_FROM_TAG(fcpim,
 | |
| 					       msg.sler_event->bfa_handle);
 | |
| 		bfa_stats(itnim, sler_events);
 | |
| 		bfa_sm_send_event(itnim, BFA_ITNIM_SM_SLER);
 | |
| 		break;
 | |
| 
 | |
| 	default:
 | |
| 		bfa_trc(bfa, m->mhdr.msg_id);
 | |
| 		bfa_assert(0);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /**
 | |
|  *  bfa_itnim_api
 | |
|  */
 | |
| 
 | |
| struct bfa_itnim_s *
 | |
| bfa_itnim_create(struct bfa_s *bfa, struct bfa_rport_s *rport, void *ditn)
 | |
| {
 | |
| 	struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
 | |
| 	struct bfa_itnim_s *itnim;
 | |
| 
 | |
| 	itnim = BFA_ITNIM_FROM_TAG(fcpim, rport->rport_tag);
 | |
| 	bfa_assert(itnim->rport == rport);
 | |
| 
 | |
| 	itnim->ditn = ditn;
 | |
| 
 | |
| 	bfa_stats(itnim, creates);
 | |
| 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_CREATE);
 | |
| 
 | |
| 	return itnim;
 | |
| }
 | |
| 
 | |
| void
 | |
| bfa_itnim_delete(struct bfa_itnim_s *itnim)
 | |
| {
 | |
| 	bfa_stats(itnim, deletes);
 | |
| 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_DELETE);
 | |
| }
 | |
| 
 | |
| void
 | |
| bfa_itnim_online(struct bfa_itnim_s *itnim, bfa_boolean_t seq_rec)
 | |
| {
 | |
| 	itnim->seq_rec = seq_rec;
 | |
| 	bfa_stats(itnim, onlines);
 | |
| 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_ONLINE);
 | |
| }
 | |
| 
 | |
| void
 | |
| bfa_itnim_offline(struct bfa_itnim_s *itnim)
 | |
| {
 | |
| 	bfa_stats(itnim, offlines);
 | |
| 	bfa_sm_send_event(itnim, BFA_ITNIM_SM_OFFLINE);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Return true if itnim is considered offline for holding off IO request.
 | |
|  * IO is not held if itnim is being deleted.
 | |
|  */
 | |
| bfa_boolean_t
 | |
| bfa_itnim_hold_io(struct bfa_itnim_s *itnim)
 | |
| {
 | |
| 	return
 | |
| 		itnim->fcpim->path_tov && itnim->iotov_active &&
 | |
| 		(bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwcreate) ||
 | |
| 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_sler) ||
 | |
| 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_cleanup_offline) ||
 | |
| 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwdelete) ||
 | |
| 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_offline) ||
 | |
| 		 bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable))
 | |
| 	;
 | |
| }
 | |
| 
 | |
| void
 | |
| bfa_itnim_get_stats(struct bfa_itnim_s *itnim,
 | |
| 	struct bfa_itnim_hal_stats_s *stats)
 | |
| {
 | |
| 	*stats = itnim->stats;
 | |
| }
 | |
| 
 | |
| void
 | |
| bfa_itnim_clear_stats(struct bfa_itnim_s *itnim)
 | |
| {
 | |
| 	bfa_os_memset(&itnim->stats, 0, sizeof(itnim->stats));
 | |
| }
 | |
| 
 | |
| 
 |