diff options
author | James Bottomley <JBottomley@Parallels.com> | 2013-07-13 04:22:56 (GMT) |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-07-13 04:22:56 (GMT) |
commit | 622f9a8e7b8043a5ea2c7d047d65ecad01fe0f97 (patch) | |
tree | ac8513cb52c074b43daba22407eb61de520afef9 /drivers/scsi/libfc | |
parent | 655ee63cf3714ac0a7ebee4a7dd00fdc54b006fc (diff) | |
parent | 7a5ed75a782a1f2de7fc773981ecd88bfa7595b1 (diff) | |
download | linux-622f9a8e7b8043a5ea2c7d047d65ecad01fe0f97.tar.xz |
Merge tag 'fcoe' into for-linus
A short series of fixes to libfc, libfcoe and fcoe.
Most patches fix formatting problems, one changes
the behavior of which discovered ports can/will be
logged into and another fixes a memory leak.
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r-- | drivers/scsi/libfc/fc_exch.c | 4 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_rport.c | 27 |
2 files changed, 29 insertions, 2 deletions
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 8b928c6..5879929 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c @@ -337,7 +337,7 @@ static void fc_exch_release(struct fc_exch *ep) * fc_exch_timer_cancel() - cancel exch timer * @ep: The exchange whose timer to be canceled */ -static inline void fc_exch_timer_cancel(struct fc_exch *ep) +static inline void fc_exch_timer_cancel(struct fc_exch *ep) { if (cancel_delayed_work(&ep->timeout_work)) { FC_EXCH_DBG(ep, "Exchange timer canceled\n"); @@ -1567,7 +1567,7 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) fc_exch_rctl_name(fh->fh_r_ctl)); if (cancel_delayed_work_sync(&ep->timeout_work)) { - FC_EXCH_DBG(ep, "Exchange timer canceled\n"); + FC_EXCH_DBG(ep, "Exchange timer canceled due to ABTS response\n"); fc_exch_release(ep); /* release from pending timer hold */ } diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 6bbb944..c710d90 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -926,6 +926,20 @@ err: kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy); } +static bool +fc_rport_compatible_roles(struct fc_lport *lport, struct fc_rport_priv *rdata) +{ + if (rdata->ids.roles == FC_PORT_ROLE_UNKNOWN) + return true; + if ((rdata->ids.roles & FC_PORT_ROLE_FCP_TARGET) && + (lport->service_params & FCP_SPPF_INIT_FCN)) + return true; + if ((rdata->ids.roles & FC_PORT_ROLE_FCP_INITIATOR) && + (lport->service_params & FCP_SPPF_TARG_FCN)) + return true; + return false; +} + /** * fc_rport_enter_plogi() - Send Port Login (PLOGI) request * @rdata: The remote port to send a PLOGI to @@ -938,6 +952,12 @@ static void fc_rport_enter_plogi(struct fc_rport_priv *rdata) struct fc_lport *lport = rdata->local_port; struct fc_frame *fp; + if (!fc_rport_compatible_roles(lport, rdata)) { + FC_RPORT_DBG(rdata, "PLOGI suppressed for incompatible role\n"); + fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT); + return; + } + FC_RPORT_DBG(rdata, "Port entered PLOGI state from %s state\n", fc_rport_state(rdata)); @@ -1646,6 +1666,13 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport, rjt_data.explan = ELS_EXPL_NONE; goto reject; } + if (!fc_rport_compatible_roles(lport, rdata)) { + FC_RPORT_DBG(rdata, "Received PLOGI for incompatible role\n"); + mutex_unlock(&rdata->rp_mutex); + rjt_data.reason = ELS_RJT_LOGIC; + rjt_data.explan = ELS_EXPL_NONE; + goto reject; + } /* * Get session payload size from incoming PLOGI. |