[SCSI] libfc: add support of large receive offload by ddp in fc_fcp
When LLD supports direct data placement (ddp) for large receive of an scsi i/o coming into fc_fcp, we call into libfc_function_template's ddp_setup() to prepare for a ddp of large receive for this read I/O. When I/O is complete, we call the corresponding ddp_done() to get the length of data ddped as well as to let LLD do clean up. fc_fcp_ddp_setup()/fc_fcp_ddp_done() are added to setup and complete a ddped read I/O described by the given fc_fcp_pkt. They would call into corresponding ddp_setup/ddp_done implemented by the fcoe layer. Eventually, fcoe layer calls into LLD's ddp_setup/ddp_done provided through net_device Signed-off-by: Yi Zou <yi.zou@intel.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
@@ -245,6 +245,7 @@ struct fc_fcp_pkt {
|
||||
*/
|
||||
struct fcp_cmnd cdb_cmd;
|
||||
size_t xfer_len;
|
||||
u16 xfer_ddp; /* this xfer is ddped */
|
||||
u32 xfer_contig_end; /* offset of end of contiguous xfer */
|
||||
u16 max_payload; /* max payload size in bytes */
|
||||
|
||||
@@ -267,6 +268,15 @@ struct fc_fcp_pkt {
|
||||
u8 recov_retry; /* count of recovery retries */
|
||||
struct fc_seq *recov_seq; /* sequence for REC or SRR */
|
||||
};
|
||||
/*
|
||||
* FC_FCP HELPER FUNCTIONS
|
||||
*****************************/
|
||||
static inline bool fc_fcp_is_read(const struct fc_fcp_pkt *fsp)
|
||||
{
|
||||
if (fsp && fsp->cmd)
|
||||
return fsp->cmd->sc_data_direction == DMA_FROM_DEVICE;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Structure and function definitions for managing Fibre Channel Exchanges
|
||||
@@ -399,6 +409,21 @@ struct libfc_function_template {
|
||||
void *arg),
|
||||
void *arg, unsigned int timer_msec);
|
||||
|
||||
/*
|
||||
* Sets up the DDP context for a given exchange id on the given
|
||||
* scatterlist if LLD supports DDP for large receive.
|
||||
*
|
||||
* STATUS: OPTIONAL
|
||||
*/
|
||||
int (*ddp_setup)(struct fc_lport *lp, u16 xid,
|
||||
struct scatterlist *sgl, unsigned int sgc);
|
||||
/*
|
||||
* Completes the DDP transfer and returns the length of data DDPed
|
||||
* for the given exchange id.
|
||||
*
|
||||
* STATUS: OPTIONAL
|
||||
*/
|
||||
int (*ddp_done)(struct fc_lport *lp, u16 xid);
|
||||
/*
|
||||
* Send a frame using an existing sequence and exchange.
|
||||
*
|
||||
@@ -821,6 +846,11 @@ int fc_change_queue_type(struct scsi_device *sdev, int tag_type);
|
||||
*/
|
||||
void fc_fcp_destroy(struct fc_lport *);
|
||||
|
||||
/*
|
||||
* Set up direct-data placement for this I/O request
|
||||
*/
|
||||
void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid);
|
||||
|
||||
/*
|
||||
* ELS/CT interface
|
||||
*****************************/
|
||||
|
Reference in New Issue
Block a user