Bhanu Gollapudi wrote:
> Unsolicited PRLO is now handled by sending LS_ACC and then
> re-login to the target port.
>
> Signed-off-by: Bhanu Prakash Gollapudi <[email protected]>
From FC-LS-1.2 and 1.3, the PRLO LS_ACC response
should have a parameter response page
with a response code, and a payload length field of 20,
so it's not as simple as using seq_els_rsp_send().
I think that's why it did reject before ... it was a cheat.
Otherwise it looks good.
Joe
> ---
> drivers/scsi/libfc/fc_rport.c | 51
> +++++++++++++++++++++++++----------------
> 1 files changed, 31 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
> index fba5218..46135db 100644
> --- a/drivers/scsi/libfc/fc_rport.c
> +++ b/drivers/scsi/libfc/fc_rport.c
> @@ -71,7 +71,7 @@ static void fc_rport_recv_plogi_req(struct fc_lport *,
> struct fc_seq *, struct fc_frame *);
> static void fc_rport_recv_prli_req(struct fc_rport_priv *,
> struct fc_seq *, struct fc_frame *);
> -static void fc_rport_recv_prlo_req(struct fc_rport_priv *,
> +static void fc_rport_recv_prlo_req(struct fc_lport *,
> struct fc_seq *, struct fc_frame *);
> static void fc_rport_recv_logo_req(struct fc_lport *,
> struct fc_seq *, struct fc_frame *);
> @@ -1227,9 +1227,6 @@ static void fc_rport_recv_els_req(struct fc_lport
> *lport,
> case ELS_PRLI:
> fc_rport_recv_prli_req(rdata, sp, fp);
> break;
> - case ELS_PRLO:
> - fc_rport_recv_prlo_req(rdata, sp, fp);
> - break;
> case ELS_ADISC:
> fc_rport_recv_adisc_req(rdata, sp, fp);
> break;
> @@ -1283,8 +1280,10 @@ void fc_rport_recv_req(struct fc_seq *sp, struct
> fc_frame *fp,
> case ELS_LOGO:
> fc_rport_recv_logo_req(lport, sp, fp);
> break;
> - case ELS_PRLI:
> case ELS_PRLO:
> + fc_rport_recv_prlo_req(lport, sp, fp);
> + break;
> + case ELS_PRLI:
> case ELS_ADISC:
> case ELS_RRQ:
> case ELS_REC:
> @@ -1564,31 +1563,43 @@ drop:
>
> /**
> * fc_rport_recv_prlo_req() - Handler for process logout (PRLO) requests
> - * @rdata: The remote port that sent the PRLO request
> - * @sp: The sequence that the PRLO was on
> + * @lport: The local port that received the PRLO request
> + * @sp: The sequence that the PRLO request was on
> * @fp: The PRLO request frame
> - *
> - * Locking Note: The rport lock is exected to be held before calling
> - * this function.
> */
> -static void fc_rport_recv_prlo_req(struct fc_rport_priv *rdata,
> +static void fc_rport_recv_prlo_req(struct fc_lport *lport,
> struct fc_seq *sp,
> struct fc_frame *fp)
> {
> - struct fc_lport *lport = rdata->local_port;
> -
> struct fc_frame_header *fh;
> - struct fc_seq_els_data rjt_data;
> + struct fc_rport_priv *rdata;
> + u32 sid;
> +
> + lport->tt.seq_els_rsp_send(sp, ELS_LS_ACC, NULL);
>
> fh = fc_frame_header_get(fp);
> + sid = ntoh24(fh->fh_s_id);
>
> - FC_RPORT_DBG(rdata, "Received PRLO request while in state %s\n",
> - fc_rport_state(rdata));
> + mutex_lock(&lport->disc.disc_mutex);
> + rdata = lport->tt.rport_lookup(lport, sid);
> + if (rdata) {
> + mutex_lock(&rdata->rp_mutex);
> + FC_RPORT_DBG(rdata, "Received PRLO request while in state %s\n",
> + fc_rport_state(rdata));
>
> - rjt_data.fp = NULL;
> - rjt_data.reason = ELS_RJT_UNAB;
> - rjt_data.explan = ELS_EXPL_NONE;
> - lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
> + 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,
> + "Received PRLO from non-logged-in port\n");
> + mutex_unlock(&lport->disc.disc_mutex);
> fc_frame_free(fp);
> }
>
_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel