[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:
Yi Zou
2009-02-27 14:07:21 -08:00
committed by James Bottomley
parent 39ca9a065a
commit b277d2aa9a
5 changed files with 95 additions and 37 deletions

View File

@@ -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
*****************************/