My answers inline below. -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.
Always reference my oldies on the way.
>> 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 <<.
Thanks for this comment. I really hate my code at this place.
I will change that base on your advice.
>> + 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 =.
Sure, I will do.
>> + 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