Ma, Steve wrote:
> Joe
> 
> Which version of FC-GS and which section I should look for fctraceroute?

FC-GS-5 rev 8.1 Section 62.5.45.

It describes the primitive, not any user level command.
Again, I don't think this is well supported.

        Joe


> Thanks
> Steve Ma
> 
>> -----Original Message-----
>> From: Joe Eykholt [mailto:[email protected]]
>> Sent: Monday, April 27, 2009 2:07 PM
>> To: Ma, Steve
>> Cc: [email protected]
>> Subject: Re: [Open-FCoE] [RFC PATCH] [open-fcoe] Add FC pass-through
>> support
>>
>> Ma, Steve wrote:
>>> Joe,
>>>
>>> What is the "fctraceroute" you mentioned in your comment?
>>> Is it in the old stuff we have?
>> No, it's future stuff.  It's part of FC-GS.  I'm not sure
>> whether it's supported by switches at this point.
>>
>>      Joe
>>
>>> Thanks
>>> -Steve
>>>
>>>> -----Original Message-----
>>>> From: Joe Eykholt [mailto:[email protected]]
>>>> Sent: Monday, April 20, 2009 11:39 AM
>>>> To: Ma, Steve
>>>> Cc: [email protected]
>>>> Subject: Re: [Open-FCoE] [RFC PATCH] [open-fcoe] Add FC pass-through
>>>> support
>>>>
>>>> Steve Ma wrote:
>>>>> This is an implementation of the FC pass-through support in FCoE
>>>>> via bsg interface according to the RFC published by James Smart
>>>>> on 11/18/2008 with the title "[RFC] FC pass thru - Rev IV"
>>>>> ---
>>>>>
>>>> This is great!   Hopefully we can use this for fcping and fctraceroute
>>>> eventually.
>>>>>  drivers/scsi/fcoe/fcoe_sw.c   |    2
>>>>>  drivers/scsi/libfc/fc_rport.c |  232
>>>> +++++++++++++++++++++++++++++++++++++++++
>>>>>  include/scsi/libfc.h          |    2
>>>>>  3 files changed, 236 insertions(+), 0 deletions(-)
>>>>>
>>>>> diff --git a/drivers/scsi/fcoe/fcoe_sw.c b/drivers/scsi/fcoe/fcoe_sw.c
>>>>> index 765a388..04f38af 100644
>>>>> --- a/drivers/scsi/fcoe/fcoe_sw.c
>>>>> +++ b/drivers/scsi/fcoe/fcoe_sw.c
>>>>> @@ -83,6 +83,8 @@ struct fc_function_template
>> fcoe_sw_transport_function
>>>> = {
>>>>>   .issue_fc_host_lip = fcoe_reset,
>>>>>
>>>>>   .terminate_rport_io = fc_rport_terminate_io,
>>>>> +
>>>>> + .bsg_request = fcoe_bsg_request,
>>>>>  };
>>>>>
>>>>>  static struct scsi_host_template fcoe_sw_shost_template = {
>>>>> diff --git a/drivers/scsi/libfc/fc_rport.c
>>>> b/drivers/scsi/libfc/fc_rport.c
>>>>> index dae6513..41d1519 100644
>>>>> --- a/drivers/scsi/libfc/fc_rport.c
>>>>> +++ b/drivers/scsi/libfc/fc_rport.c
>>>>> @@ -1314,3 +1314,235 @@ void fc_rport_terminate_io(struct fc_rport
>>>> *rport)
>>>>>   lport->tt.exch_mgr_reset(lport, rport->port_id, 0);
>>>>>  }
>>>>>  EXPORT_SYMBOL(fc_rport_terminate_io);
>>>>> +
>>>>> +struct fcoe_bsg_info {
>>>>> + struct fc_bsg_job *job;
>>>>> + struct fc_lport *lport;
>>>>> +};
>>>>> +
>>>>> +static void fc_bsg_els_resp(struct fc_seq *sp, struct fc_frame *fp,
>>>>> +                         void *rp_arg)
>>>>> +{
>>>>> + struct fcoe_bsg_info *info = (struct fcoe_bsg_info *)rp_arg;
>>>>> + struct fc_bsg_job *job = info->job;
>>>>> + struct fc_lport *lport = info->lport;
>>>>> + unsigned int len;
>>>>> + void *pp;
>>>>> +
>>>>> + mutex_lock(&lport->lp_mutex);
>>>>> +
>>>>> + if (IS_ERR(fp))
>>>>> +         goto err;
>>>>> +
>>>>> + len = fr_len(fp) - sizeof(struct fc_frame_header);
>>>>> + pp = fc_frame_payload_get(fp, len);
>>>>> +
>>>>> + sg_copy_from_buffer(job->reply_payload.sg_list,
>>>>> +                     job->reply_payload.sg_cnt,
>>>>> +                     pp, len);
>>>>> + job->reply->reply_payload_rcv_len = job->reply_payload.payload_len;
>>>>> +
>>>>> + if (fc_frame_payload_op(fp) == ELS_LS_ACC)
>>>>> +         job->reply->reply_data.ctels_reply.status
>>>>> +                 = FC_CTELS_STATUS_OK;
>>>>> + else
>>>>> +         job->reply->reply_data.ctels_reply.status
>>>>> +                 = FC_CTELS_STATUS_REJECT;
>>>>> +err:
>>>>> + fc_frame_free(fp);
>>>>> + mutex_unlock(&lport->lp_mutex);
>>>>> + kfree(info);
>>>>> + job->state_flags = FC_RQST_STATE_DONE;
>>>>> + job->job_done(job);
>>>>> +}
>>>>> +
>>>>> +static int fcoe_bsg_els_request(struct fc_bsg_job *job)
>>>>> +{
>>>>> + struct fcoe_bsg_info *info;
>>>>> + struct fc_rport *rport = job->rport;
>>>>> + struct Scsi_Host *shost;
>>>>> + struct fc_lport *lport;
>>>>> + struct fc_frame *fp;
>>>>> + struct fc_frame_header *fh;
>>>>> + char *pp;
>>>>> + int len;
>>>>> + u32 did;
>>>>> +
>>>>> + shost = rport ? rport_to_shost(rport) : job->shost;
>>>>> + lport = shost_priv(shost);
>>>>> +
>>>>> + if (!((lport->state == LPORT_ST_READY) &&
>>>>> +     lport->link_up && !lport->qfull))
>>>>> +         return -EINVAL;
>>>>> +
>>>>> +
>>>>> + fp = fc_frame_alloc(lport, sizeof(struct fc_frame_header) +
>>>>> +                         job->request_payload.payload_len);
>>>>> + if (!fp)
>>>>> +         return -EINVAL;
>>>>> +
>>>>> + len = job->request_payload.payload_len;
>>>>> + pp = fc_frame_payload_get(fp, len);
>>>>> + memset(pp, 0, len);
>>>>> +
>>>>> + sg_copy_to_buffer(job->request_payload.sg_list,
>>>>> +                   job->request_payload.sg_cnt,
>>>>> +                   pp, len);
>>>>> +
>>>>> + switch (pp[0]) {
>>>>> + case ELS_RNID:
>>>>> + case ELS_RLS:
>>>>> + case ELS_RCS:
>>>>> +         did = job->request->rqst_data.h_els.port_id[0]<<16 |
>>>>> +               job->request->rqst_data.h_els.port_id[1]<<8  |
>>>>> +               job->request->rqst_data.h_els.port_id[2];
>>>>>
>>>> Use ntoh24().  This applies in a few other places.  Also, there should
>>>> be spaces around the <<.
>>>>> +         break;
>>>>> + default:
>>>>> +         if (!rport) {
>>>>> +                 fc_frame_free(fp);
>>>>> +                 return -EINVAL;
>>>>> +         }
>>>>> +         did = rport->port_id;
>>>>> +         break;
>>>>> + }
>>>>> +
>>>>> + fh = fc_frame_header_get(fp);
>>>>> + fh->fh_r_ctl = FC_RCTL_ELS_REQ;
>>>>> + hton24(fh->fh_d_id, did);
>>>>> + hton24(fh->fh_s_id, fc_host_port_id(shost));
>>>>> + fh->fh_type = FC_TYPE_ELS;
>>>>> + hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ |
>>>>> +         FC_FC_END_SEQ | FC_FC_SEQ_INIT);
>>>>> + fh->fh_cs_ctl = 0;
>>>>> + fh->fh_df_ctl = 0;
>>>>> + fh->fh_parm_offset = 0;
>>>>> +
>>>>> + info = kzalloc(sizeof(struct fcoe_bsg_info), GFP_KERNEL);
>>>>> + if (!info) {
>>>>> +         fc_frame_free(fp);
>>>>> +         return -EINVAL;
>>>>> + }
>>>>> +
>>>>> + info->job = job;
>>>>> + info->lport = lport;
>>>>> +
>>>>> + lport->tt.exch_seq_send(lport, fp, fc_bsg_els_resp,
>>>>> +                         NULL, (void *)info, lport->e_d_tov);
>>>>> + return 0;
>>>>> +}
>>>>> +
>>>>> +static void fc_bsg_ct_resp(struct fc_seq *sp, struct fc_frame *fp,
>>>>> +                         void *rp_arg)
>>>>> +{
>>>>> + struct fcoe_bsg_info *info = (struct fcoe_bsg_info *)rp_arg;
>>>>> + struct fc_bsg_job *job = info->job;
>>>>> + struct fc_lport *lport = info->lport;
>>>>> + struct fc_ct_hdr *ct;
>>>>> + unsigned int len;
>>>>> + void *pp;
>>>>> +
>>>>> + mutex_lock(&lport->lp_mutex);
>>>>> +
>>>>> + if (IS_ERR(fp))
>>>>> +         goto err;
>>>>> +
>>>>> + len = fr_len(fp) - sizeof(struct fc_frame_header);
>>>>> + pp = fc_frame_payload_get(fp, len);
>>>>> + sg_copy_from_buffer(job->reply_payload.sg_list,
>>>>> +                     job->reply_payload.sg_cnt,
>>>>> +                     pp, len);
>>>>> + job->reply->reply_payload_rcv_len = job->reply_payload.payload_len;
>>>>> +
>>>>> + ct = (struct fc_ct_hdr *)pp;
>>>>> + if (ntohs(ct->ct_cmd) == FC_FS_ACC)
>>>>> +         job->reply->reply_data.ctels_reply.status
>>>>> +                 = FC_CTELS_STATUS_OK;
>>>>>
>>>> Split this lines like this after the =.
>>>>> + else
>>>>> +         job->reply->reply_data.ctels_reply.status
>>>>> +                 = FC_CTELS_STATUS_REJECT;
>>>>> +err:
>>>>> + fc_frame_free(fp);
>>>>> + mutex_unlock(&lport->lp_mutex);
>>>>> + kfree(info);
>>>>> + job->state_flags = FC_RQST_STATE_DONE;
>>>>> + job->job_done(job);
>>>>> +}
>>>>> +
>>>>> +static int fcoe_bsg_ct_request(struct fc_bsg_job *job)
>>>>> +{
>>>>> + struct fcoe_bsg_info *info;
>>>>> + struct fc_rport *rport = job->rport;
>>>>> + struct Scsi_Host *shost;
>>>>> + struct fc_lport *lport;
>>>>> + struct fc_frame *fp;
>>>>> + struct fc_frame_header *fh;
>>>>> + struct fc_ct_req *ct;
>>>>> + struct fc_ct_hdr *ct_hdr;
>>>>> + size_t len;
>>>>> + u32 did;
>>>>> +
>>>>> + shost = rport ? rport_to_shost(rport) : job->shost;
>>>>> + lport = shost_priv(shost);
>>>>> +
>>>>> + if (!((lport->state == LPORT_ST_READY) &&
>>>>> +     lport->link_up && !lport->qfull))
>>>>> +         return -EINVAL;
>>>>> +
>>>>> + fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
>>>>> +                         job->request_payload.payload_len);
>>>>> + if (!fp)
>>>>> +         return -EINVAL;
>>>>> +
>>>>> + len = job->request_payload.payload_len;
>>>>> + ct = fc_frame_payload_get(fp, len);
>>>>> + memset(ct, 0, len);
>>>>> +
>>>>> + sg_copy_to_buffer(job->request_payload.sg_list,
>>>>> +                   job->request_payload.sg_cnt,
>>>>> +                   ct, len);
>>>>> + ct_hdr = &ct->hdr;
>>>>> + ct_hdr->ct_cmd = htons((u16)ct_hdr->ct_cmd);
>>>>> + ct_hdr->ct_mr_size = htons((u16)ct_hdr->ct_mr_size);
>>>>> + did = ct->hdr.ct_in_id[0]<<16 |
>>>>> +       ct->hdr.ct_in_id[1]<<8  |
>>>>> +       ct->hdr.ct_in_id[2];
>>>>> +
>>>>> + fh = fc_frame_header_get(fp);
>>>>> + fh->fh_r_ctl = FC_RCTL_DD_UNSOL_CTL;
>>>>> + hton24(fh->fh_d_id, did);
>>>>> + hton24(fh->fh_s_id, fc_host_port_id(shost));
>>>>> + fh->fh_type = FC_TYPE_CT;
>>>>> + hton24(fh->fh_f_ctl, FC_FC_FIRST_SEQ |
>>>>> +         FC_FC_END_SEQ | FC_FC_SEQ_INIT);
>>>>> + fh->fh_cs_ctl = 0;
>>>>> + fh->fh_df_ctl = 0;
>>>>> + fh->fh_parm_offset = 0;
>>>>> +
>>>>> + info = kzalloc(sizeof(struct fcoe_bsg_info), GFP_KERNEL);
>>>>> + if (!info) {
>>>>> +         fc_frame_free(fp);
>>>>> +         return -EINVAL;
>>>>> + }
>>>>> +
>>>>> + info->job = job;
>>>>> + info->lport = lport;
>>>>> +
>>>>> + lport->tt.exch_seq_send(lport, fp, fc_bsg_ct_resp,
>>>>> +                         NULL, (void *)info, lport->e_d_tov);
>>>>> + return 0;
>>>>> +}
>>>>> +
>>>>> +int fcoe_bsg_request(struct fc_bsg_job *job)
>>>>> +{
>>>>> + switch (job->request->msgcode) {
>>>>> + case FC_BSG_RPT_ELS:
>>>>> + case FC_BSG_HST_ELS_NOLOGIN:
>>>>> +         return fcoe_bsg_els_request(job);
>>>>> + case FC_BSG_RPT_CT:
>>>>> +         return fcoe_bsg_ct_request(job);
>>>>> + default:
>>>>> +         return -EINVAL;
>>>>> + }
>>>>> +}
>>>>> +EXPORT_SYMBOL(fcoe_bsg_request);
>>>>> +
>>>>> diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
>>>>> index a70eafa..221dff0 100644
>>>>> --- a/include/scsi/libfc.h
>>>>> +++ b/include/scsi/libfc.h
>>>>> @@ -25,6 +25,7 @@
>>>>>
>>>>>  #include <scsi/scsi_transport.h>
>>>>>  #include <scsi/scsi_transport_fc.h>
>>>>> +#include <scsi/scsi_bsg_fc.h>
>>>>>
>>>>>  #include <scsi/fc/fc_fcp.h>
>>>>>  #include <scsi/fc/fc_ns.h>
>>>>> @@ -778,6 +779,7 @@ int fc_set_mfs(struct fc_lport *lp, u32 mfs);
>>>>>   *****************************/
>>>>>  int fc_rport_init(struct fc_lport *lp);
>>>>>  void fc_rport_terminate_io(struct fc_rport *rp);
>>>>> +int fcoe_bsg_request(struct fc_bsg_job *job);
>>>>>
>>>>>  /*
>>>>>   * DISCOVERY LAYER
>>>>>
>>>>> _______________________________________________
>>>>> 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