Bhanu Gollapudi wrote:
> Unsolicited PRLO is now handled by sending LS_ACC,
> and then relogin to the remote port if an N-port login
> session exists for that remote port.
> 
> Note that this patch should be applied on top of Joe Eykholt's
> "Fix remote port restart problem" patch.
> 
> Signed-off-by: Bhanu Prakash Gollapudi <[email protected]>
> ---
>  drivers/scsi/libfc/fc_rport.c |   70 
> ++++++++++++++++++++++++++++++++++++-----
>  include/scsi/fc/fc_els.h      |    9 +++++
>  2 files changed, 71 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
> index 5bf8950..38eeb60 100644
> --- a/drivers/scsi/libfc/fc_rport.c
> +++ b/drivers/scsi/libfc/fc_rport.c
> @@ -1557,30 +1557,84 @@ 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
> - * @fp:         The PRLO request frame
> + * @rx_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,
>                                  struct fc_seq *sp,
> -                                struct fc_frame *fp)
> +                                struct fc_frame *rx_fp)
>  {
>       struct fc_lport *lport = rdata->local_port;
> -
>       struct fc_frame_header *fh;
> +     struct fc_exch *ep;
> +     struct fc_frame *fp;
> +     struct {
> +             struct fc_els_prlo prlo;
> +             struct fc_els_spp spp;
> +     } *pp;
> +     struct fc_els_spp *rspp;        /* request service param page */
> +     struct fc_els_spp *spp;         /* response spp */
> +     unsigned int len;
> +     unsigned int plen;
> +     u32 f_ctl;
>       struct fc_seq_els_data rjt_data;
>  
> -     fh = fc_frame_header_get(fp);
> +     rjt_data.fp = NULL;
> +     fh = fc_frame_header_get(rx_fp);
>  
>       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;
> +     len = fr_len(rx_fp) - sizeof(*fh);
> +     pp = fc_frame_payload_get(rx_fp, sizeof(*pp));
> +     if (!pp)
> +             goto reject_len;
> +     plen = ntohs(pp->prlo.prlo_len);
> +     if (plen != 20)
> +             goto reject_len;
> +     if (plen < len)
> +             len = plen;
> +
> +     rspp = &pp->spp;
> +
> +     fp = fc_frame_alloc(lport, len);
> +     if (!fp) {
> +             rjt_data.reason = ELS_RJT_UNAB;
> +             rjt_data.explan = ELS_EXPL_INSUF_RES;
> +             goto reject;
> +     }
> +
> +     sp = lport->tt.seq_start_next(sp);
> +     WARN_ON(!sp);
> +     pp = fc_frame_payload_get(fp, len);
> +     WARN_ON(!pp);
> +     memset(pp, 0, len);
> +     pp->prlo.prlo_cmd = ELS_LS_ACC;
> +     pp->prlo.prlo_obs = 0x10;
> +     pp->prlo.prlo_len = htons(len);
> +     spp = &pp->spp;
> +     spp->spp_type = rspp->spp_type;

Ideally we would give an error if the type isn't FCP
or 0 (indicating all types).  But, it's OK as is.

> +     spp->spp_type_ext = rspp->spp_type_ext;

I think this should set the response code to 1 (request executed) here.

        spp->spp_flags = FC_SPP_RESP_ACK;

The rest looks good.  Thanks.

> +
> +     fc_rport_enter_delete(rdata, RPORT_EV_LOGO);
> +
> +     f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ;
> +     f_ctl |= FC_FC_END_SEQ | FC_FC_SEQ_INIT;
> +     ep = fc_seq_exch(sp);
> +     fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
> +                    FC_TYPE_ELS, f_ctl, 0);
> +     lport->tt.seq_send(lport, sp, fp);
> +     goto drop;
> +
> +reject_len:
> +     rjt_data.reason = ELS_RJT_PROT;
> +     rjt_data.explan = ELS_EXPL_INV_LEN;
> +reject:
>       lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
> -     fc_frame_free(fp);
> +drop:
> +     fc_frame_free(rx_fp);
>  }
>  
>  /**
> diff --git a/include/scsi/fc/fc_els.h b/include/scsi/fc/fc_els.h
> index f943281..70a7e92 100644
> --- a/include/scsi/fc/fc_els.h
> +++ b/include/scsi/fc/fc_els.h
> @@ -405,6 +405,15 @@ struct fc_els_prli {
>  };
>  
>  /*
> + * ELS_PRLO - Process logout request and response.
> + */
> +struct fc_els_prlo {
> +     __u8            prlo_cmd;       /* command */
> +     __u8            prlo_obs;       /* obsolete, but shall be set to 10h */
> +     __be16          prlo_len;       /* payload length */
> +};
> +
> +/*
>   * ELS_ADISC payload
>   */
>  struct fc_els_adisc {

_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to