| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * 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: | 
					
						
							| 
									
										
										
										
											2010-03-05 19:35:02 -08:00
										 |  |  | 		bfa_sm_fault(itnim->bfa, event); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * 		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: | 
					
						
							| 
									
										
										
										
											2010-03-05 19:35:02 -08:00
										 |  |  | 		bfa_sm_fault(itnim->bfa, event); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * 		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: | 
					
						
							| 
									
										
										
										
											2010-03-05 19:35:02 -08:00
										 |  |  | 		bfa_sm_fault(itnim->bfa, event); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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: | 
					
						
							| 
									
										
										
										
											2010-03-05 19:35:02 -08:00
										 |  |  | 		bfa_sm_fault(itnim->bfa, event); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * 	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: | 
					
						
							| 
									
										
										
										
											2010-03-05 19:35:02 -08:00
										 |  |  | 		bfa_sm_fault(itnim->bfa, event); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * 		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: | 
					
						
							| 
									
										
										
										
											2010-03-05 19:35:02 -08:00
										 |  |  | 		bfa_sm_fault(itnim->bfa, event); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * 		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: | 
					
						
							| 
									
										
										
										
											2010-03-05 19:35:02 -08:00
										 |  |  | 		bfa_sm_fault(itnim->bfa, event); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * 		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: | 
					
						
							| 
									
										
										
										
											2010-03-05 19:35:02 -08:00
										 |  |  | 		bfa_sm_fault(itnim->bfa, event); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * 		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: | 
					
						
							| 
									
										
										
										
											2010-03-05 19:35:02 -08:00
										 |  |  | 		bfa_sm_fault(itnim->bfa, event); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * 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: | 
					
						
							| 
									
										
										
										
											2010-03-05 19:35:02 -08:00
										 |  |  | 		bfa_sm_fault(itnim->bfa, event); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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: | 
					
						
							| 
									
										
										
										
											2010-03-05 19:35:02 -08:00
										 |  |  | 		bfa_sm_fault(itnim->bfa, event); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * 		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: | 
					
						
							| 
									
										
										
										
											2010-03-05 19:35:02 -08:00
										 |  |  | 		bfa_sm_fault(itnim->bfa, event); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * 		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: | 
					
						
							| 
									
										
										
										
											2010-03-05 19:35:02 -08:00
										 |  |  | 		bfa_sm_fault(itnim->bfa, event); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * 		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: | 
					
						
							| 
									
										
										
										
											2010-03-05 19:35:02 -08:00
										 |  |  | 		bfa_sm_fault(itnim->bfa, event); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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: | 
					
						
							| 
									
										
										
										
											2010-03-05 19:35:02 -08:00
										 |  |  | 		bfa_sm_fault(itnim->bfa, event); | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  *  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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-25 12:29:54 -07:00
										 |  |  | 	return itnim; | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-09-25 12:29:54 -07:00
										 |  |  | 	return | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | 		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)) | 
					
						
							| 
									
										
										
										
											2009-09-25 12:29:54 -07:00
										 |  |  | 	; | 
					
						
							| 
									
										
										
										
											2009-09-23 17:46:15 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 |