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

I should've said "a N_Port Login is required for PRLO".

> 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

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

Reply via email to