summary refs log tree commit diff
path: root/drivers/scsi/bfa/bfa_fcs_fcpim.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/bfa/bfa_fcs_fcpim.c')
-rw-r--r--drivers/scsi/bfa/bfa_fcs_fcpim.c124
1 files changed, 68 insertions, 56 deletions
diff --git a/drivers/scsi/bfa/bfa_fcs_fcpim.c b/drivers/scsi/bfa/bfa_fcs_fcpim.c
index 59c062f71f6e..6dc7926a3edd 100644
--- a/drivers/scsi/bfa/bfa_fcs_fcpim.c
+++ b/drivers/scsi/bfa/bfa_fcs_fcpim.c
@@ -40,25 +40,6 @@ static void	bfa_fcs_itnim_prli_response(void *fcsarg,
 static void	bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
 			enum bfa_itnim_aen_event event);
 
-/*
- *  fcs_itnim_sm FCS itnim state machine events
- */
-
-enum bfa_fcs_itnim_event {
-	BFA_FCS_ITNIM_SM_ONLINE = 1,	/*  rport online event */
-	BFA_FCS_ITNIM_SM_OFFLINE = 2,	/*  rport offline */
-	BFA_FCS_ITNIM_SM_FRMSENT = 3,	/*  prli frame is sent */
-	BFA_FCS_ITNIM_SM_RSP_OK = 4,	/*  good response */
-	BFA_FCS_ITNIM_SM_RSP_ERROR = 5,	/*  error response */
-	BFA_FCS_ITNIM_SM_TIMEOUT = 6,	/*  delay timeout */
-	BFA_FCS_ITNIM_SM_HCB_OFFLINE = 7, /*  BFA online callback */
-	BFA_FCS_ITNIM_SM_HCB_ONLINE = 8, /*  BFA offline callback */
-	BFA_FCS_ITNIM_SM_INITIATOR = 9,	/*  rport is initiator */
-	BFA_FCS_ITNIM_SM_DELETE = 10,	/*  delete event from rport */
-	BFA_FCS_ITNIM_SM_PRLO = 11,	/*  delete event from rport */
-	BFA_FCS_ITNIM_SM_RSP_NOT_SUPP = 12, /* cmd not supported rsp */
-};
-
 static void	bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
 					 enum bfa_fcs_itnim_event event);
 static void	bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
@@ -69,6 +50,8 @@ static void	bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
 					    enum bfa_fcs_itnim_event event);
 static void	bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
 					    enum bfa_fcs_itnim_event event);
+static void	bfa_fcs_itnim_sm_hal_rport_online(struct bfa_fcs_itnim_s *itnim,
+					enum bfa_fcs_itnim_event event);
 static void	bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
 					enum bfa_fcs_itnim_event event);
 static void	bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
@@ -99,7 +82,7 @@ bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
 	bfa_trc(itnim->fcs, event);
 
 	switch (event) {
-	case BFA_FCS_ITNIM_SM_ONLINE:
+	case BFA_FCS_ITNIM_SM_FCS_ONLINE:
 		bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send);
 		itnim->prli_retries = 0;
 		bfa_fcs_itnim_send_prli(itnim, NULL);
@@ -138,6 +121,7 @@ bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
 	case BFA_FCS_ITNIM_SM_INITIATOR:
 		bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
 		bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
+		bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
 		break;
 
 	case BFA_FCS_ITNIM_SM_OFFLINE:
@@ -166,12 +150,13 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
 
 	switch (event) {
 	case BFA_FCS_ITNIM_SM_RSP_OK:
-		if (itnim->rport->scsi_function == BFA_RPORT_INITIATOR) {
+		if (itnim->rport->scsi_function == BFA_RPORT_INITIATOR)
 			bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
-		} else {
-			bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_online);
-			bfa_itnim_online(itnim->bfa_itnim, itnim->seq_rec);
-		}
+		else
+			bfa_sm_set_state(itnim,
+				bfa_fcs_itnim_sm_hal_rport_online);
+
+		bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
 		break;
 
 	case BFA_FCS_ITNIM_SM_RSP_ERROR:
@@ -194,6 +179,7 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
 	case BFA_FCS_ITNIM_SM_INITIATOR:
 		bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
 		bfa_fcxp_discard(itnim->fcxp);
+		bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
 		break;
 
 	case BFA_FCS_ITNIM_SM_DELETE:
@@ -208,6 +194,44 @@ bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
 }
 
 static void
+bfa_fcs_itnim_sm_hal_rport_online(struct bfa_fcs_itnim_s *itnim,
+				enum bfa_fcs_itnim_event event)
+{
+	bfa_trc(itnim->fcs, itnim->rport->pwwn);
+	bfa_trc(itnim->fcs, event);
+
+	switch (event) {
+	case BFA_FCS_ITNIM_SM_HAL_ONLINE:
+		if (!itnim->bfa_itnim)
+			itnim->bfa_itnim = bfa_itnim_create(itnim->fcs->bfa,
+					itnim->rport->bfa_rport, itnim);
+
+		if (itnim->bfa_itnim) {
+			bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_online);
+			bfa_itnim_online(itnim->bfa_itnim, itnim->seq_rec);
+		} else {
+			bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
+			bfa_sm_send_event(itnim->rport, RPSM_EVENT_DELETE);
+		}
+
+		break;
+
+	case BFA_FCS_ITNIM_SM_OFFLINE:
+		bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
+		bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
+		break;
+
+	case BFA_FCS_ITNIM_SM_DELETE:
+		bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
+		bfa_fcs_itnim_free(itnim);
+		break;
+
+	default:
+		bfa_sm_fault(itnim->fcs, event);
+	}
+}
+
+static void
 bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
 			    enum bfa_fcs_itnim_event event)
 {
@@ -238,6 +262,7 @@ bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
 	case BFA_FCS_ITNIM_SM_INITIATOR:
 		bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
 		bfa_timer_stop(&itnim->timer);
+		bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
 		break;
 
 	case BFA_FCS_ITNIM_SM_DELETE:
@@ -275,9 +300,8 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
 		break;
 
 	case BFA_FCS_ITNIM_SM_OFFLINE:
-		bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
+		bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_offline);
 		bfa_itnim_offline(itnim->bfa_itnim);
-		bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
 		break;
 
 	case BFA_FCS_ITNIM_SM_DELETE:
@@ -372,8 +396,14 @@ bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
 		bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE);
 		break;
 
+	/*
+	 * fcs_online is expected here for well known initiator ports
+	 */
+	case BFA_FCS_ITNIM_SM_FCS_ONLINE:
+		bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE);
+		break;
+
 	case BFA_FCS_ITNIM_SM_RSP_ERROR:
-	case BFA_FCS_ITNIM_SM_ONLINE:
 	case BFA_FCS_ITNIM_SM_INITIATOR:
 		break;
 
@@ -484,7 +514,7 @@ bfa_fcs_itnim_prli_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
 			if (prli_resp->parampage.servparams.initiator) {
 				bfa_trc(itnim->fcs, prli_resp->parampage.type);
 				itnim->rport->scsi_function =
-					 BFA_RPORT_INITIATOR;
+						BFA_RPORT_INITIATOR;
 				itnim->stats.prli_rsp_acc++;
 				itnim->stats.initiator++;
 				bfa_sm_send_event(itnim,
@@ -532,7 +562,11 @@ bfa_fcs_itnim_timeout(void *arg)
 static void
 bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim)
 {
-	bfa_itnim_delete(itnim->bfa_itnim);
+	if (itnim->bfa_itnim) {
+		bfa_itnim_delete(itnim->bfa_itnim);
+		itnim->bfa_itnim = NULL;
+	}
+
 	bfa_fcb_itnim_free(itnim->fcs->bfad, itnim->itnim_drv);
 }
 
@@ -553,7 +587,6 @@ bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport)
 	struct bfa_fcs_lport_s *port = rport->port;
 	struct bfa_fcs_itnim_s *itnim;
 	struct bfad_itnim_s   *itnim_drv;
-	struct bfa_itnim_s *bfa_itnim;
 
 	/*
 	 * call bfad to allocate the itnim
@@ -571,20 +604,7 @@ bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport)
 	itnim->fcs = rport->fcs;
 	itnim->itnim_drv = itnim_drv;
 
-	/*
-	 * call BFA to create the itnim
-	 */
-	bfa_itnim =
-		bfa_itnim_create(port->fcs->bfa, rport->bfa_rport, itnim);
-
-	if (bfa_itnim == NULL) {
-		bfa_trc(port->fcs, rport->pwwn);
-		bfa_fcb_itnim_free(port->fcs->bfad, itnim_drv);
-		WARN_ON(1);
-		return NULL;
-	}
-
-	itnim->bfa_itnim     = bfa_itnim;
+	itnim->bfa_itnim     = NULL;
 	itnim->seq_rec	     = BFA_FALSE;
 	itnim->rec_support   = BFA_FALSE;
 	itnim->conf_comp     = BFA_FALSE;
@@ -614,20 +634,12 @@ bfa_fcs_itnim_delete(struct bfa_fcs_itnim_s *itnim)
  * Notification from rport that PLOGI is complete to initiate FC-4 session.
  */
 void
-bfa_fcs_itnim_rport_online(struct bfa_fcs_itnim_s *itnim)
+bfa_fcs_itnim_brp_online(struct bfa_fcs_itnim_s *itnim)
 {
 	itnim->stats.onlines++;
 
-	if (!BFA_FCS_PID_IS_WKA(itnim->rport->pid)) {
-		bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_ONLINE);
-	} else {
-		/*
-		 *  For well known addresses, we set the itnim to initiator
-		 *  state
-		 */
-		itnim->stats.initiator++;
-		bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_INITIATOR);
-	}
+	if (!BFA_FCS_PID_IS_WKA(itnim->rport->pid))
+		bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HAL_ONLINE);
 }
 
 /*