Joe, I've already found the info. Thanks
Steve >-----Original Message----- >From: [email protected] [mailto:[email protected]] On >Behalf Of Ma, Steve >Sent: Monday, April 27, 2009 3:14 PM >To: Joe Eykholt >Cc: [email protected] >Subject: Re: [Open-FCoE] [RFC PATCH] [open-fcoe] Add FC pass-through >support > >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 _______________________________________________ devel mailing list [email protected] http://www.open-fcoe.org/mailman/listinfo/devel
