Joe, What is the "fctraceroute" you mentioned in your comment? Is it in the old stuff we have?
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
