summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2016-09-30 11:01:19 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2016-11-08 17:29:47 -0500
commitf89b8d67db792a8a303e14e3d02785035e6f1a05 (patch)
tree063c8f36871a7b22612aa82453be073dd5e3bc1c /drivers/scsi/libfc
parent06ee2571a438653bd14c33c70379a5f008a91901 (diff)
downloadlinux-stable-f89b8d67db792a8a303e14e3d02785035e6f1a05.tar.gz
linux-stable-f89b8d67db792a8a303e14e3d02785035e6f1a05.tar.bz2
linux-stable-f89b8d67db792a8a303e14e3d02785035e6f1a05.zip
scsi: libfc: don't advance state machine for incoming FLOGI
When we receive an FLOGI but have already sent our own we should not advance the state machine but rather wait for our FLOGI to return before continuing with PLOGI. Signed-off-by: Hannes Reinecke <hare@suse.com> Acked-by: Johannes Thumshirn <jth@kernel.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r--drivers/scsi/libfc/fc_rport.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 72a7183fdd06..4b9bb6dd4004 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -765,8 +765,10 @@ static void fc_rport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
goto bad;
flogi = fc_frame_payload_get(fp, sizeof(*flogi));
- if (!flogi)
+ if (!flogi) {
+ FC_RPORT_DBG(rdata, "Bad FLOGI response\n");
goto bad;
+ }
r_a_tov = ntohl(flogi->fl_csp.sp_r_a_tov);
if (r_a_tov > rdata->r_a_tov)
rdata->r_a_tov = r_a_tov;
@@ -783,7 +785,6 @@ put:
kref_put(&rdata->kref, lport->tt.rport_destroy);
return;
bad:
- FC_RPORT_DBG(rdata, "Bad FLOGI response\n");
fc_rport_error_retry(rdata, fp);
goto out;
}
@@ -925,10 +926,17 @@ static void fc_rport_recv_flogi_req(struct fc_lport *lport,
fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_ELS_REP, 0);
lport->tt.frame_send(lport, fp);
- if (rdata->ids.port_name < lport->wwpn)
- fc_rport_enter_plogi(rdata);
- else
- fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT);
+ /*
+ * Do not proceed with the state machine if our
+ * FLOGI has crossed with an FLOGI from the
+ * remote port; wait for the FLOGI response instead.
+ */
+ if (rdata->rp_state != RPORT_ST_FLOGI) {
+ if (rdata->ids.port_name < lport->wwpn)
+ fc_rport_enter_plogi(rdata);
+ else
+ fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT);
+ }
out:
mutex_unlock(&rdata->rp_mutex);
kref_put(&rdata->kref, lport->tt.rport_destroy);