Joe Eykholt wrote:
> 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.

Actually, on further reading, table 3 in FC-LS-3 says that
a process login is required for PRLO, so the existing case
in fc_rport_recv_els_req() was correct.  The requestor
should handle a reject with reason unable, and
the explanation "Port login required".

        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

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

Reply via email to