switch (evt) { case EFC_EVT_ENTER:
efc_node_hold_frames(node);
fallthrough;
case EFC_EVT_NODE_ACTIVE_IO_LIST_EMPTY: case EFC_EVT_ALL_CHILD_NODES_FREE: /* These are expected events. */ break;
case EFC_EVT_NODE_DEL_INI_COMPLETE: case EFC_EVT_NODE_DEL_TGT_COMPLETE: /* *nodehaseitherbeendetachedorisintheprocess *ofbeingdetached, *callcommonnode'sinitiatecleanupfunction
*/
efc_node_initiate_cleanup(node); break;
case EFC_EVT_EXIT:
efc_node_accept_frames(node); break;
case EFC_EVT_SRRS_ELS_REQ_FAIL: /* Can happen as ELS IO IO's complete */
WARN_ON(!node->els_req_cnt);
node->els_req_cnt--; break;
/* ignore shutdown events as we're already in shutdown path */ case EFC_EVT_SHUTDOWN: /* have default shutdown event take precedence */
node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
fallthrough;
case EFC_EVT_SHUTDOWN_EXPLICIT_LOGO: case EFC_EVT_SHUTDOWN_IMPLICIT_LOGO:
node_printf(node, "%s received\n", efc_sm_event_name(evt)); break; case EFC_EVT_DOMAIN_ATTACH_OK: /* don't care about domain_attach_ok */ break; default:
__efc_d_common(__func__, ctx, evt, arg);
}
}
switch (evt) { case EFC_EVT_ENTER:
efc_node_hold_frames(node);
fallthrough;
case EFC_EVT_NODE_ACTIVE_IO_LIST_EMPTY: case EFC_EVT_ALL_CHILD_NODES_FREE: /* These are expected events. */ break;
case EFC_EVT_NODE_DEL_INI_COMPLETE: case EFC_EVT_NODE_DEL_TGT_COMPLETE:
efc_node_transition(node, __efc_d_wait_del_node, NULL); break;
case EFC_EVT_EXIT:
efc_node_accept_frames(node); break;
case EFC_EVT_SRRS_ELS_REQ_FAIL: /* Can happen as ELS IO IO's complete */
WARN_ON(!node->els_req_cnt);
node->els_req_cnt--; break;
/* ignore shutdown events as we're already in shutdown path */ case EFC_EVT_SHUTDOWN: /* have default shutdown event take precedence */
node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
fallthrough;
case EFC_EVT_SHUTDOWN_EXPLICIT_LOGO: case EFC_EVT_SHUTDOWN_IMPLICIT_LOGO:
node_printf(node, "%s received\n", efc_sm_event_name(evt)); break; case EFC_EVT_DOMAIN_ATTACH_OK: /* don't care about domain_attach_ok */ break; default:
__efc_d_common(__func__, ctx, evt, arg);
}
}
if (rc == EFC_SCSI_CALL_COMPLETE)
efc_node_post_event(node,
EFC_EVT_NODE_DEL_INI_COMPLETE, NULL); /* assume no wait needed */
rc = EFC_SCSI_CALL_COMPLETE; if (node->nport->enable_ini)
rc = efc->tt.scsi_del_node(efc, node,
EFC_SCSI_TARGET_DELETED);
if (rc == EFC_SCSI_CALL_COMPLETE)
efc_node_post_event(node,
EFC_EVT_NODE_DEL_TGT_COMPLETE, NULL);
}
/* we've initiated the upcalls as needed, now kick off the node *detachtoprecipitatetheabortingofoutstandingexchanges *associatedwithsaidnode * *Beware:ifwe'vemadeupcall(s),we'vealreadytransitioned *toanewstatebythetimeweexecutethis. *considerdoingthisbeforetheupcalls?
*/ if (node->attached) { /* issue hw node free; don't care if succeeds right *awayorsometimelater,willchecknode->attached *laterinshutdownprocess
*/
rc = efc_cmd_node_detach(efc, &node->rnode); if (rc < 0)
node_printf(node, "Failed freeing HW node, rc=%d\n",
rc);
}
/* if neither initiator nor target, proceed to cleanup */ if (!node->init && !node->targ) { /* *nodehaseitherbeendetachedorisin *theprocessofbeingdetached, *callcommonnode'sinitiatecleanupfunction
*/
efc_node_initiate_cleanup(node);
} break;
} case EFC_EVT_ALL_CHILD_NODES_FREE: /* Ignore, this can happen if an ELS is *abortedwhileinadelay/retrystate
*/ break; default:
__efc_d_common(__func__, ctx, evt, arg);
}
}
switch (evt) { case EFC_EVT_ENTER:
efc_node_hold_frames(node); break;
case EFC_EVT_EXIT:
efc_node_accept_frames(node); break;
case EFC_EVT_SRRS_ELS_REQ_OK: case EFC_EVT_SRRS_ELS_REQ_RJT: case EFC_EVT_SRRS_ELS_REQ_FAIL: /* LOGO response received, sent shutdown */ if (efc_node_check_els_req(ctx, evt, arg, ELS_LOGO,
__efc_d_common, __func__)) return;
WARN_ON(!node->els_req_cnt);
node->els_req_cnt--;
node_printf(node, "LOGO sent (evt=%s), shutdown node\n",
efc_sm_event_name(evt)); /* sm: / post explicit logout */
efc_node_post_event(node, EFC_EVT_SHUTDOWN_EXPLICIT_LOGO,
NULL); break;
/* *Thisstateisenteredwhenanodeisinstantiated, *eitherhavingbeendiscoveredfromanameservicesquery, *orhavingreceivedaPLOGI/FLOGI.
*/ switch (evt) { case EFC_EVT_ENTER: if (!node->send_plogi) break; /* only send if we have initiator capability, *anddomainisattached
*/ if (node->nport->enable_ini &&
node->nport->domain->attached) {
efc_send_plogi(node);
/* domain not attached; several possibilities: */ if (!node->nport->domain->attached) {
efc_d_check_plogi_topology(node, ntoh24(hdr->fh_d_id)); break;
}
case EFC_EVT_LOGO_RCVD: { struct fc_frame_header *hdr = cbdata->header->dma.virt;
if (!node->nport->domain->attached) { /* most likely a frame left over from before a link *down;dropand *shutnodedownw/"explicitlogout"sopending *framesareprocessed
*/
node_printf(node, "%s domain not attached, dropping\n",
efc_sm_event_name(evt));
efc_node_post_event(node,
EFC_EVT_SHUTDOWN_EXPLICIT_LOGO, NULL); break;
}
case EFC_EVT_PRLI_RCVD: case EFC_EVT_PRLO_RCVD: case EFC_EVT_PDISC_RCVD: case EFC_EVT_ADISC_RCVD: case EFC_EVT_RSCN_RCVD: { struct fc_frame_header *hdr = cbdata->header->dma.virt;
if (!node->nport->domain->attached) { /* most likely a frame left over from before a link *down;dropandshutnodedownw/"explicitlogout" *sopendingframesareprocessed
*/
node_printf(node, "%s domain not attached, dropping\n",
efc_sm_event_name(evt));
case EFC_EVT_FCP_CMD_RCVD: { /* note: problem, we're now expecting an ELS REQ completion *fromboththeLOGOandPLOGI
*/ if (!node->nport->domain->attached) { /* most likely a frame left over from before a *linkdown;dropand *shutnodedownw/"explicitlogout"sopending *framesareprocessed
*/
node_printf(node, "%s domain not attached, dropping\n",
efc_sm_event_name(evt));
efc_node_post_event(node,
EFC_EVT_SHUTDOWN_EXPLICIT_LOGO,
NULL); break;
}
/* Send LOGO */
node_printf(node, "FCP_CMND received, send LOGO\n"); if (efc_send_logo(node)) { /* *failedtosendLOGO,goaheadandcleanupnode *anyways
*/
node_printf(node, "Failed to send LOGO\n");
efc_node_post_event(node,
EFC_EVT_SHUTDOWN_EXPLICIT_LOGO,
NULL);
} else { /* sent LOGO, wait for response */
efc_node_transition(node,
__efc_d_wait_logo_rsp, NULL);
} break;
} case EFC_EVT_DOMAIN_ATTACH_OK: /* don't care about domain_attach_ok */ break;
switch (evt) { case EFC_EVT_PLOGI_RCVD: { /* T, or I+T */ /* received PLOGI with svc parms, go ahead and attach node *whenPLOGIthatwassentultimatelycompletes,it'llbea *no-op * *IfthereisanoutstandingPLOGIsent,canwesetaflag *toindicatethatwedon'twanttoretryitifittimesout?
*/
efc_node_save_sparms(node, cbdata->payload->dma.virt);
efc_send_ls_acc_after_attach(node,
cbdata->header->dma.virt,
EFC_NODE_SEND_LS_ACC_PLOGI); /* sm: domain->attached / efc_node_attach */
rc = efc_node_attach(node);
efc_node_transition(node, __efc_d_wait_node_attach, NULL); if (rc < 0)
efc_node_post_event(node,
EFC_EVT_NODE_ATTACH_FAIL, NULL);
break;
}
case EFC_EVT_PRLI_RCVD: /* I, or I+T */ /* sent PLOGI and before completion was seen, received the *PRLIfromtheremotenode(WCQEsandRCQEscomeinon *differentqueuesandorderofprocessingcannotbeassumed) *SaveOXIDsoPRLIcanbesentaftertheattachandcontinue *towaitforPLOGIresponse
*/
efc_process_prli_payload(node, cbdata->payload->dma.virt);
efc_send_ls_acc_after_attach(node,
cbdata->header->dma.virt,
EFC_NODE_SEND_LS_ACC_PRLI);
efc_node_transition(node, __efc_d_wait_plogi_rsp_recvd_prli,
NULL); break;
case EFC_EVT_LOGO_RCVD: /* why don't we do a shutdown here?? */ case EFC_EVT_PRLO_RCVD: case EFC_EVT_PDISC_RCVD: case EFC_EVT_FDISC_RCVD: case EFC_EVT_ADISC_RCVD: case EFC_EVT_RSCN_RCVD: case EFC_EVT_SCR_RCVD: { struct fc_frame_header *hdr = cbdata->header->dma.virt;
case EFC_EVT_SRRS_ELS_REQ_OK: /* PLOGI response received */ /* Completion from PLOGI sent */ if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
__efc_d_common, __func__)) return;
case EFC_EVT_SRRS_ELS_REQ_RJT: /* Our PLOGI was rejected, this is ok in some cases */ if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
__efc_d_common, __func__)) return;
case EFC_EVT_FCP_CMD_RCVD: { /* not logged in yet and outstanding PLOGI so don't send LOGO, *justdrop
*/
node_printf(node, "FCP_CMND received, drop\n"); break;
}
case EFC_EVT_EXIT:
efc_node_accept_frames(node); break;
case EFC_EVT_SRRS_ELS_REQ_OK: /* PLOGI response received */ /* Completion from PLOGI sent */ if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
__efc_d_common, __func__)) return;
case EFC_EVT_SRRS_ELS_REQ_FAIL: /* PLOGI response received */ case EFC_EVT_SRRS_ELS_REQ_RJT: /* PLOGI failed, shutdown the node */ if (efc_node_check_els_req(ctx, evt, arg, ELS_PLOGI,
__efc_d_common, __func__)) return;
/* At the time the PLOGI was received, the topology was unknown, *sowedidn'tknowwhichnodewouldperformthedomainattach: *1.ThenodefromwhichthePLOGIwassent(p2p)or *2.ThenodetowhichtheFLOGIwassent(fabric).
*/ if (*topology == EFC_NPORT_TOPO_P2P) { /* if this is p2p, need to attach to the domain using *thed_idfromthePLOGIreceived
*/
efc_domain_attach(node->nport->domain,
node->ls_acc_did);
} /* else, if this is fabric, the domain attach *shouldbeperformedbythefabricnode(nodesendingFLOGI); *justwaitforattachtocomplete
*/
switch (evt) { case EFC_EVT_ENTER:
efc_node_hold_frames(node); break;
case EFC_EVT_EXIT:
efc_node_accept_frames(node); break;
case EFC_EVT_NODE_ATTACH_OK:
node->attached = true; switch (node->send_ls_acc) { case EFC_NODE_SEND_LS_ACC_PLOGI: { /* sm: send_plogi_acc is set / send PLOGI acc */ /* Normal case for T, or I+T */
efc_send_plogi_acc(node, node->ls_acc_oxid);
efc_node_transition(node, __efc_d_wait_plogi_acc_cmpl,
NULL);
node->send_ls_acc = EFC_NODE_SEND_LS_ACC_NONE;
node->ls_acc_io = NULL; break;
} case EFC_NODE_SEND_LS_ACC_PRLI: {
efc_d_send_prli_rsp(node, node->ls_acc_oxid);
node->send_ls_acc = EFC_NODE_SEND_LS_ACC_NONE;
node->ls_acc_io = NULL; break;
} case EFC_NODE_SEND_LS_ACC_NONE: default: /* Normal case for I */ /* sm: send_plogi_acc is not set / send PLOGI acc */
efc_node_transition(node,
__efc_d_port_logged_in, NULL); break;
} break;
switch (evt) { case EFC_EVT_ENTER:
efc_node_hold_frames(node); break;
case EFC_EVT_EXIT:
efc_node_accept_frames(node); break;
/* wait for any of these attach events and then shutdown */ case EFC_EVT_NODE_ATTACH_OK:
node->attached = true;
node_printf(node, "Attach evt=%s, proceed to shutdown\n",
efc_sm_event_name(evt));
efc_node_transition(node, __efc_d_initiate_shutdown, NULL); break;
case EFC_EVT_NODE_ATTACH_FAIL: /* node attach failed, shutdown the node */
node->attached = false;
node_printf(node, "Attach evt=%s, proceed to shutdown\n",
efc_sm_event_name(evt));
efc_node_transition(node, __efc_d_initiate_shutdown, NULL); break;
/* ignore shutdown events as we're already in shutdown path */ case EFC_EVT_SHUTDOWN: /* have default shutdown event take precedence */
node->shutdown_reason = EFC_NODE_SHUTDOWN_DEFAULT;
fallthrough;
case EFC_EVT_SHUTDOWN_EXPLICIT_LOGO: case EFC_EVT_SHUTDOWN_IMPLICIT_LOGO:
node_printf(node, "%s received\n", efc_sm_event_name(evt)); break;
switch (evt) { case EFC_EVT_ENTER: /* Normal case for I or I+T */ if (node->nport->enable_ini &&
!(node->rnode.fc_id != FC_FID_DOM_MGR)) { /* sm: if enable_ini / send PRLI */
efc_send_prli(node); /* can now expect ELS_REQ_OK/FAIL/RJT */
} break;
case EFC_EVT_FCP_CMD_RCVD: { break;
}
case EFC_EVT_PRLI_RCVD: { /* Normal case for T or I+T */ struct fc_frame_header *hdr = cbdata->header->dma.virt; struct { struct fc_els_prli prli; struct fc_els_spp sp;
} *pp;
pp = cbdata->payload->dma.virt; if (pp->sp.spp_type != FC_TYPE_FCP) { /*Only FCP is supported*/
efc_send_ls_rjt(node, be16_to_cpu(hdr->fh_ox_id),
ELS_RJT_UNAB, ELS_EXPL_UNSUPR, 0); break;
}
case EFC_EVT_SRRS_ELS_REQ_OK: { /* PRLI response */ /* Normal case for I or I+T */ if (efc_node_check_els_req(ctx, evt, arg, ELS_PRLI,
__efc_d_common, __func__)) return;
case EFC_EVT_SRRS_ELS_CMPL_OK: { /* Normal T, I+T, target-server rejected the process login */ /* This would be received only in the case where we sent *LS_RJTforthePRLI,so *donothing.(note:asTonlywecouldshutdownthenode)
*/
WARN_ON(!node->els_cmpl_cnt);
node->els_cmpl_cnt--; break;
}
case EFC_EVT_PLOGI_RCVD: { /*sm: / save sparams, set send_plogi_acc, *postimplicitlogout *Saveplogiparameters
*/
efc_node_save_sparms(node, cbdata->payload->dma.virt);
efc_send_ls_acc_after_attach(node,
cbdata->header->dma.virt,
EFC_NODE_SEND_LS_ACC_PLOGI);
/* Restart node attach with new service parameters, *andsendACC
*/
efc_node_post_event(node, EFC_EVT_SHUTDOWN_IMPLICIT_LOGO,
NULL); break;
}
case EFC_EVT_LOGO_RCVD: { /* I, T, I+T */ struct fc_frame_header *hdr = cbdata->header->dma.virt;
node_printf(node, "%s received attached=%d\n",
efc_sm_event_name(evt),
node->attached); /* sm: / send LOGO acc */
efc_send_logo_acc(node, be16_to_cpu(hdr->fh_ox_id));
efc_node_transition(node, __efc_d_wait_logo_acc_cmpl, NULL); break;
}
switch (evt) { case EFC_EVT_ENTER:
node->fcp_enabled = true; if (node->targ) {
efc_log_info(efc, "[%s] found (target) WWPN %s WWNN %s\n",
node->display_name,
node->wwpn, node->wwnn); if (node->nport->enable_ini)
efc->tt.scsi_new_node(efc, node);
} break;
case EFC_EVT_EXIT:
node->fcp_enabled = false; break;
case EFC_EVT_PLOGI_RCVD: { /* sm: / save sparams, set send_plogi_acc, post implicit *logout *Saveplogiparameters
*/
efc_node_save_sparms(node, cbdata->payload->dma.virt);
efc_send_ls_acc_after_attach(node,
cbdata->header->dma.virt,
EFC_NODE_SEND_LS_ACC_PLOGI);
switch (efc_node_get_enable(node)) { case EFC_NODE_ENABLE_T_TO_T: case EFC_NODE_ENABLE_I_TO_T: case EFC_NODE_ENABLE_IT_TO_T:
rc = efc->tt.scsi_del_node(efc, node,
EFC_SCSI_TARGET_MISSING); break;
case EFC_NODE_ENABLE_T_TO_I: case EFC_NODE_ENABLE_I_TO_I: case EFC_NODE_ENABLE_IT_TO_I:
rc = efc->tt.scsi_del_node(efc, node,
EFC_SCSI_INITIATOR_MISSING); break;
case EFC_NODE_ENABLE_T_TO_IT:
rc = efc->tt.scsi_del_node(efc, node,
EFC_SCSI_INITIATOR_MISSING); break;
case EFC_NODE_ENABLE_I_TO_IT:
rc = efc->tt.scsi_del_node(efc, node,
EFC_SCSI_TARGET_MISSING); break;
case EFC_EVT_PLOGI_RCVD: { /* sm: / save sparams, set send_plogi_acc, post implicit *logout *Saveplogiparameters
*/
efc_node_save_sparms(node, cbdata->payload->dma.virt);
efc_send_ls_acc_after_attach(node,
cbdata->header->dma.virt,
EFC_NODE_SEND_LS_ACC_PLOGI);
case EFC_EVT_FCP_CMD_RCVD: { /* most likely a stale frame (received prior to link down), *ifattempttosendLOGO,willprobablytimeoutandeat *up20s;thus,dropFCP_CMND
*/
node_printf(node, "FCP_CMND received, drop\n"); break;
} case EFC_EVT_LOGO_RCVD: { /* I, T, I+T */ struct fc_frame_header *hdr = cbdata->header->dma.virt;
case EFC_EVT_SRRS_ELS_REQ_RJT: /* received an LS_RJT, in this case, send shutdown *(explicitlogo)eventwhichwillunregisterthenode, *andstartoverwithPLOGI
*/ if (efc_node_check_els_req(ctx, evt, arg, ELS_ADISC,
__efc_d_common, __func__)) return;
case EFC_EVT_LOGO_RCVD: { /* In this case, we have the equivalent of an LS_RJT for *theADISC,soweneedtoaborttheADISC,andre-login *withPLOGI
*/ /* sm: / request abort, send LOGO acc */ struct fc_frame_header *hdr = cbdata->header->dma.virt;
node_printf(node, "%s received attached=%d\n",
efc_sm_event_name(evt), node->attached);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.