*/
static int fc_rport_logoff(struct fc_rport_priv *rdata)
{
+ struct fc_lport *lport = rdata->local_port;
+ u32 port_id = rdata->ids.port_id;
+
mutex_lock(&rdata->rp_mutex);
FC_RPORT_DBG(rdata, "Remove port\n");
FC_RPORT_DBG(rdata, "Port in Delete state, not removing\n");
goto out;
}
+ /*
+ * FC-LS states:
+ * To explicitly Logout, the initiating Nx_Port shall terminate
+ * other open Sequences that it initiated with the destination
+ * Nx_Port prior to performing Logout.
+ */
+ lport->tt.exch_mgr_reset(lport, 0, port_id);
+ lport->tt.exch_mgr_reset(lport, port_id, 0);
+
fc_rport_enter_logo(rdata);
/*
*/
static void fc_rport_error(struct fc_rport_priv *rdata, struct fc_frame *fp)
{
+ struct fc_lport *lport = rdata->local_port;
+
FC_RPORT_DBG(rdata, "Error %ld in state %s, retries %d\n",
IS_ERR(fp) ? -PTR_ERR(fp) : 0,
fc_rport_state(rdata), rdata->retries);
switch (rdata->rp_state) {
case RPORT_ST_FLOGI:
- case RPORT_ST_PLOGI:
rdata->flags &= ~FC_RP_STARTED;
fc_rport_enter_delete(rdata, RPORT_EV_FAILED);
break;
+ case RPORT_ST_PLOGI:
+ if (lport->point_to_multipoint) {
+ rdata->flags &= ~FC_RP_STARTED;
+ fc_rport_enter_delete(rdata, RPORT_EV_FAILED);
+ } else
+ fc_rport_enter_logo(rdata);
+ break;
case RPORT_ST_RTV:
fc_rport_enter_ready(rdata);
break;
spp->spp_type_ext = rspp->spp_type_ext;
spp->spp_flags = FC_SPP_RESP_ACK;
- fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
+ fc_rport_enter_prli(rdata);
fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
lport->tt.frame_send(lport, fp);
FC_RPORT_DBG(rdata, "Received LOGO request while in state %s\n",
fc_rport_state(rdata));
- fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
+ fc_rport_enter_delete(rdata, RPORT_EV_STOP);
mutex_unlock(&rdata->rp_mutex);
kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
} else