Joe Which version of FC-GS and which section I should look for fctraceroute?
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
