lport->tt.rport_logoff(rport);
}
+ list_for_each_entry_safe(rdata, next, &disc->rogue_rports, peers) {
+ rport = PRIV_TO_RPORT(rdata);
+ lport->tt.rport_logoff(rport);
+ }
+
mutex_unlock(&disc->disc_mutex);
}
{
struct fc_rport_libfc_priv *rdata = rport->dd_data;
struct fc_disc *disc = &lport->disc;
- int found = 0;
FC_DEBUG_DISC("Received a %d event for port (%6x)\n", event,
rport->port_id);
- if (event == RPORT_EV_CREATED) {
+ switch (event) {
+ case RPORT_EV_CREATED:
if (disc) {
- found = 1;
mutex_lock(&disc->disc_mutex);
list_add_tail(&rdata->peers, &disc->rports);
mutex_unlock(&disc->disc_mutex);
}
+ break;
+ case RPORT_EV_LOGO:
+ case RPORT_EV_FAILED:
+ case RPORT_EV_STOP:
+ mutex_lock(&disc->disc_mutex);
+ mutex_lock(&rdata->rp_mutex);
+ if (rdata->trans_state == FC_PORTSTATE_ROGUE)
+ list_del(&rdata->peers);
+ mutex_unlock(&rdata->rp_mutex);
+ mutex_unlock(&disc->disc_mutex);
+ break;
+ default:
+ break;
}
- if (!found)
- FC_DEBUG_DISC("The rport (%6x) is not maintained "
- "by the discovery layer\n", rport->port_id);
}
/**
rdata = rport->dd_data;
rdata->ops = &fc_disc_rport_ops;
rdata->rp_state = RPORT_ST_INIT;
+ list_add_tail(&rdata->peers, &disc->rogue_rports);
lport->tt.rport_login(rport);
}
}
rdata = rport->dd_data;
rdata->ops = &fc_disc_rport_ops;
rdata->local_port = lport;
+ list_add_tail(&rdata->peers,
+ &disc->rogue_rports);
lport->tt.rport_login(rport);
} else
FC_DBG("Failed to allocate memory for "
static void fc_disc_single(struct fc_disc *disc, struct fc_disc_port *dp)
{
struct fc_lport *lport;
- struct fc_rport *rport;
struct fc_rport *new_rport;
struct fc_rport_libfc_priv *rdata;
if (dp->ids.port_id == fc_host_port_id(lport->host))
goto out;
- rport = lport->tt.rport_lookup(lport, dp->ids.port_id);
- if (rport)
- fc_disc_del_target(disc, rport);
-
new_rport = lport->tt.rport_create(dp);
if (new_rport) {
rdata = new_rport->dd_data;
rdata->ops = &fc_disc_rport_ops;
kfree(dp);
+ list_add_tail(&rdata->peers, &disc->rogue_rports);
lport->tt.rport_login(new_rport);
}
return;
INIT_DELAYED_WORK(&disc->disc_work, fc_disc_timeout);
mutex_init(&disc->disc_mutex);
INIT_LIST_HEAD(&disc->rports);
+ INIT_LIST_HEAD(&disc->rogue_rports);
disc->lport = lport;
disc->delay = FC_DISC_DELAY;
"(%6x).\n", ids.port_id);
event = RPORT_EV_FAILED;
}
+ if (rport->port_id != FC_FID_DIR_SERV)
+ if (rport_ops->event_callback)
+ rport_ops->event_callback(lport, rport,
+ RPORT_EV_FAILED);
put_device(&rport->dev);
rport = new_rport;
rdata = new_rport->dd_data;
int fc_rport_logoff(struct fc_rport *rport)
{
struct fc_rport_libfc_priv *rdata = rport->dd_data;
+ struct fc_lport *lport = rdata->local_port;
mutex_lock(&rdata->rp_mutex);
FC_DEBUG_RPORT("Remove port (%6x)\n", rport->port_id);
+ if (rdata->rp_state == RPORT_ST_NONE) {
+ FC_DEBUG_RPORT("(%6x): Port (%6x) in NONE state,"
+ " not removing", fc_host_port_id(lport->host),
+ rport->port_id);
+ mutex_unlock(&rdata->rp_mutex);
+ goto out;
+ }
+
fc_rport_enter_logo(rport);
/*
mutex_unlock(&rdata->rp_mutex);
+out:
return 0;
}
default:
FC_DEBUG_RPORT("incoming PLOGI from %x in unexpected "
"state %d\n", sid, rdata->rp_state);
+ fc_frame_free(fp);
+ return;
break;
}
reason = ELS_RJT_NONE;
break;
default:
+ fc_frame_free(rx_fp);
+ return;
break;
}
len = fr_len(rx_fp) - sizeof(*fh);
"while in state %s\n", ntoh24(fh->fh_s_id),
fc_rport_state(rport));
+ if (rdata->rp_state == RPORT_ST_NONE) {
+ fc_frame_free(fp);
+ return;
+ }
+
rjt_data.fp = NULL;
rjt_data.reason = ELS_RJT_UNAB;
rjt_data.explan = ELS_EXPL_NONE;
"while in state %s\n", ntoh24(fh->fh_s_id),
fc_rport_state(rport));
+ if (rdata->rp_state == RPORT_ST_NONE) {
+ fc_frame_free(fp);
+ return;
+ }
+
rdata->event = RPORT_EV_LOGO;
queue_work(rport_event_queue, &rdata->event_work);