|
@@ -89,7 +89,6 @@ static const char *fc_rport_state_names[] = {
|
|
|
[RPORT_ST_LOGO] = "LOGO",
|
|
|
[RPORT_ST_ADISC] = "ADISC",
|
|
|
[RPORT_ST_DELETE] = "Delete",
|
|
|
- [RPORT_ST_RESTART] = "Restart",
|
|
|
};
|
|
|
|
|
|
/**
|
|
@@ -246,7 +245,6 @@ static void fc_rport_work(struct work_struct *work)
|
|
|
struct fc_rport_operations *rport_ops;
|
|
|
struct fc_rport_identifiers ids;
|
|
|
struct fc_rport *rport;
|
|
|
- int restart = 0;
|
|
|
|
|
|
mutex_lock(&rdata->rp_mutex);
|
|
|
event = rdata->event;
|
|
@@ -298,24 +296,6 @@ static void fc_rport_work(struct work_struct *work)
|
|
|
port_id = rdata->ids.port_id;
|
|
|
mutex_unlock(&rdata->rp_mutex);
|
|
|
|
|
|
- if (port_id != FC_FID_DIR_SERV) {
|
|
|
- /*
|
|
|
- * We must drop rp_mutex before taking disc_mutex.
|
|
|
- * Re-evaluate state to allow for restart.
|
|
|
- * A transition to RESTART state must only happen
|
|
|
- * while disc_mutex is held and rdata is on the list.
|
|
|
- */
|
|
|
- mutex_lock(&lport->disc.disc_mutex);
|
|
|
- mutex_lock(&rdata->rp_mutex);
|
|
|
- if (rdata->rp_state == RPORT_ST_RESTART)
|
|
|
- restart = 1;
|
|
|
- else
|
|
|
- list_del(&rdata->peers);
|
|
|
- rdata->event = RPORT_EV_NONE;
|
|
|
- mutex_unlock(&rdata->rp_mutex);
|
|
|
- mutex_unlock(&lport->disc.disc_mutex);
|
|
|
- }
|
|
|
-
|
|
|
if (rport_ops && rport_ops->event_callback) {
|
|
|
FC_RPORT_DBG(rdata, "callback ev %d\n", event);
|
|
|
rport_ops->event_callback(lport, rdata, event);
|
|
@@ -336,13 +316,34 @@ static void fc_rport_work(struct work_struct *work)
|
|
|
mutex_unlock(&rdata->rp_mutex);
|
|
|
fc_remote_port_delete(rport);
|
|
|
}
|
|
|
- if (restart) {
|
|
|
- mutex_lock(&rdata->rp_mutex);
|
|
|
- FC_RPORT_DBG(rdata, "work restart\n");
|
|
|
- fc_rport_enter_plogi(rdata);
|
|
|
+
|
|
|
+ mutex_lock(&lport->disc.disc_mutex);
|
|
|
+ mutex_lock(&rdata->rp_mutex);
|
|
|
+ if (rdata->rp_state == RPORT_ST_DELETE) {
|
|
|
+ if (port_id == FC_FID_DIR_SERV) {
|
|
|
+ rdata->event = RPORT_EV_NONE;
|
|
|
+ mutex_unlock(&rdata->rp_mutex);
|
|
|
+ } else if (rdata->flags & FC_RP_STARTED) {
|
|
|
+ rdata->event = RPORT_EV_NONE;
|
|
|
+ FC_RPORT_DBG(rdata, "work restart\n");
|
|
|
+ fc_rport_enter_plogi(rdata);
|
|
|
+ mutex_unlock(&rdata->rp_mutex);
|
|
|
+ } else {
|
|
|
+ FC_RPORT_DBG(rdata, "work delete\n");
|
|
|
+ list_del(&rdata->peers);
|
|
|
+ mutex_unlock(&rdata->rp_mutex);
|
|
|
+ kref_put(&rdata->kref, lport->tt.rport_destroy);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ /*
|
|
|
+ * Re-open for events. Reissue READY event if ready.
|
|
|
+ */
|
|
|
+ rdata->event = RPORT_EV_NONE;
|
|
|
+ if (rdata->rp_state == RPORT_ST_READY)
|
|
|
+ fc_rport_enter_ready(rdata);
|
|
|
mutex_unlock(&rdata->rp_mutex);
|
|
|
- } else
|
|
|
- kref_put(&rdata->kref, lport->tt.rport_destroy);
|
|
|
+ }
|
|
|
+ mutex_unlock(&lport->disc.disc_mutex);
|
|
|
break;
|
|
|
|
|
|
default:
|
|
@@ -367,16 +368,14 @@ int fc_rport_login(struct fc_rport_priv *rdata)
|
|
|
{
|
|
|
mutex_lock(&rdata->rp_mutex);
|
|
|
|
|
|
+ rdata->flags |= FC_RP_STARTED;
|
|
|
switch (rdata->rp_state) {
|
|
|
case RPORT_ST_READY:
|
|
|
FC_RPORT_DBG(rdata, "ADISC port\n");
|
|
|
fc_rport_enter_adisc(rdata);
|
|
|
break;
|
|
|
- case RPORT_ST_RESTART:
|
|
|
- break;
|
|
|
case RPORT_ST_DELETE:
|
|
|
FC_RPORT_DBG(rdata, "Restart deleted port\n");
|
|
|
- fc_rport_state_enter(rdata, RPORT_ST_RESTART);
|
|
|
break;
|
|
|
default:
|
|
|
FC_RPORT_DBG(rdata, "Login to port\n");
|
|
@@ -431,15 +430,12 @@ int fc_rport_logoff(struct fc_rport_priv *rdata)
|
|
|
|
|
|
FC_RPORT_DBG(rdata, "Remove port\n");
|
|
|
|
|
|
+ rdata->flags &= ~FC_RP_STARTED;
|
|
|
if (rdata->rp_state == RPORT_ST_DELETE) {
|
|
|
FC_RPORT_DBG(rdata, "Port in Delete state, not removing\n");
|
|
|
goto out;
|
|
|
}
|
|
|
-
|
|
|
- if (rdata->rp_state == RPORT_ST_RESTART)
|
|
|
- FC_RPORT_DBG(rdata, "Port in Restart state, deleting\n");
|
|
|
- else
|
|
|
- fc_rport_enter_logo(rdata);
|
|
|
+ fc_rport_enter_logo(rdata);
|
|
|
|
|
|
/*
|
|
|
* Change the state to Delete so that we discard
|
|
@@ -503,7 +499,6 @@ static void fc_rport_timeout(struct work_struct *work)
|
|
|
case RPORT_ST_READY:
|
|
|
case RPORT_ST_INIT:
|
|
|
case RPORT_ST_DELETE:
|
|
|
- case RPORT_ST_RESTART:
|
|
|
break;
|
|
|
}
|
|
|
|
|
@@ -527,6 +522,7 @@ static void fc_rport_error(struct fc_rport_priv *rdata, struct fc_frame *fp)
|
|
|
switch (rdata->rp_state) {
|
|
|
case RPORT_ST_PLOGI:
|
|
|
case RPORT_ST_LOGO:
|
|
|
+ rdata->flags &= ~FC_RP_STARTED;
|
|
|
fc_rport_enter_delete(rdata, RPORT_EV_FAILED);
|
|
|
break;
|
|
|
case RPORT_ST_RTV:
|
|
@@ -537,7 +533,6 @@ static void fc_rport_error(struct fc_rport_priv *rdata, struct fc_frame *fp)
|
|
|
fc_rport_enter_logo(rdata);
|
|
|
break;
|
|
|
case RPORT_ST_DELETE:
|
|
|
- case RPORT_ST_RESTART:
|
|
|
case RPORT_ST_READY:
|
|
|
case RPORT_ST_INIT:
|
|
|
break;
|
|
@@ -1392,7 +1387,6 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport,
|
|
|
break;
|
|
|
case RPORT_ST_DELETE:
|
|
|
case RPORT_ST_LOGO:
|
|
|
- case RPORT_ST_RESTART:
|
|
|
FC_RPORT_DBG(rdata, "Received PLOGI in state %s - send busy\n",
|
|
|
fc_rport_state(rdata));
|
|
|
mutex_unlock(&rdata->rp_mutex);
|
|
@@ -1684,13 +1678,6 @@ static void fc_rport_recv_logo_req(struct fc_lport *lport,
|
|
|
fc_rport_state(rdata));
|
|
|
|
|
|
fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
|
|
|
-
|
|
|
- /*
|
|
|
- * If the remote port was created due to discovery, set state
|
|
|
- * to log back in. It may have seen a stale RSCN about us.
|
|
|
- */
|
|
|
- if (rdata->disc_id)
|
|
|
- fc_rport_state_enter(rdata, RPORT_ST_RESTART);
|
|
|
mutex_unlock(&rdata->rp_mutex);
|
|
|
} else
|
|
|
FC_RPORT_ID_DBG(lport, sid,
|