aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorYi Zou <yi.zou@intel.com>2009-02-27 17:07:21 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-03-13 16:15:15 -0400
commitb277d2aa9a4d969002c4157bf77b76b9ad9ca04a (patch)
tree1054ff4ab2d03eaaa527919380ed6334233f632b /include
parent39ca9a065a5a0a6f2f0cd648090a979ba3f4f018 (diff)
[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>
Diffstat (limited to 'include')
-rw-r--r--include/scsi/fc_frame.h19
-rw-r--r--include/scsi/libfc.h30
-rw-r--r--include/scsi/libfcoe.h18
3 files changed, 32 insertions, 35 deletions
diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h
index 04d34a71355f..59511057cee0 100644
--- a/include/scsi/fc_frame.h
+++ b/include/scsi/fc_frame.h
@@ -54,8 +54,7 @@
54#define fr_eof(fp) (fr_cb(fp)->fr_eof) 54#define fr_eof(fp) (fr_cb(fp)->fr_eof)
55#define fr_flags(fp) (fr_cb(fp)->fr_flags) 55#define fr_flags(fp) (fr_cb(fp)->fr_flags)
56#define fr_max_payload(fp) (fr_cb(fp)->fr_max_payload) 56#define fr_max_payload(fp) (fr_cb(fp)->fr_max_payload)
57#define fr_cmd(fp) (fr_cb(fp)->fr_cmd) 57#define fr_fsp(fp) (fr_cb(fp)->fr_fsp)
58#define fr_dir(fp) (fr_cmd(fp)->sc_data_direction)
59#define fr_crc(fp) (fr_cb(fp)->fr_crc) 58#define fr_crc(fp) (fr_cb(fp)->fr_crc)
60 59
61struct fc_frame { 60struct fc_frame {
@@ -66,7 +65,7 @@ struct fcoe_rcv_info {
66 struct packet_type *ptype; 65 struct packet_type *ptype;
67 struct fc_lport *fr_dev; /* transport layer private pointer */ 66 struct fc_lport *fr_dev; /* transport layer private pointer */
68 struct fc_seq *fr_seq; /* for use with exchange manager */ 67 struct fc_seq *fr_seq; /* for use with exchange manager */
69 struct scsi_cmnd *fr_cmd; /* for use of scsi command */ 68 struct fc_fcp_pkt *fr_fsp; /* for the corresponding fcp I/O */
70 u32 fr_crc; 69 u32 fr_crc;
71 u16 fr_max_payload; /* max FC payload */ 70 u16 fr_max_payload; /* max FC payload */
72 enum fc_sof fr_sof; /* start of frame delimiter */ 71 enum fc_sof fr_sof; /* start of frame delimiter */
@@ -218,20 +217,6 @@ static inline bool fc_frame_is_cmd(const struct fc_frame *fp)
218 return fc_frame_rctl(fp) == FC_RCTL_DD_UNSOL_CMD; 217 return fc_frame_rctl(fp) == FC_RCTL_DD_UNSOL_CMD;
219} 218}
220 219
221static inline bool fc_frame_is_read(const struct fc_frame *fp)
222{
223 if (fc_frame_is_cmd(fp) && fr_cmd(fp))
224 return fr_dir(fp) == DMA_FROM_DEVICE;
225 return false;
226}
227
228static inline bool fc_frame_is_write(const struct fc_frame *fp)
229{
230 if (fc_frame_is_cmd(fp) && fr_cmd(fp))
231 return fr_dir(fp) == DMA_TO_DEVICE;
232 return false;
233}
234
235/* 220/*
236 * Check for leaks. 221 * Check for leaks.
237 * Print the frame header of any currently allocated frame, assuming there 222 * Print the frame header of any currently allocated frame, assuming there
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 61c746cf55f3..a70eafaad084 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -245,6 +245,7 @@ struct fc_fcp_pkt {
245 */ 245 */
246 struct fcp_cmnd cdb_cmd; 246 struct fcp_cmnd cdb_cmd;
247 size_t xfer_len; 247 size_t xfer_len;
248 u16 xfer_ddp; /* this xfer is ddped */
248 u32 xfer_contig_end; /* offset of end of contiguous xfer */ 249 u32 xfer_contig_end; /* offset of end of contiguous xfer */
249 u16 max_payload; /* max payload size in bytes */ 250 u16 max_payload; /* max payload size in bytes */
250 251
@@ -267,6 +268,15 @@ struct fc_fcp_pkt {
267 u8 recov_retry; /* count of recovery retries */ 268 u8 recov_retry; /* count of recovery retries */
268 struct fc_seq *recov_seq; /* sequence for REC or SRR */ 269 struct fc_seq *recov_seq; /* sequence for REC or SRR */
269}; 270};
271/*
272 * FC_FCP HELPER FUNCTIONS
273 *****************************/
274static inline bool fc_fcp_is_read(const struct fc_fcp_pkt *fsp)
275{
276 if (fsp && fsp->cmd)
277 return fsp->cmd->sc_data_direction == DMA_FROM_DEVICE;
278 return false;
279}
270 280
271/* 281/*
272 * Structure and function definitions for managing Fibre Channel Exchanges 282 * Structure and function definitions for managing Fibre Channel Exchanges
@@ -400,6 +410,21 @@ struct libfc_function_template {
400 void *arg, unsigned int timer_msec); 410 void *arg, unsigned int timer_msec);
401 411
402 /* 412 /*
413 * Sets up the DDP context for a given exchange id on the given
414 * scatterlist if LLD supports DDP for large receive.
415 *
416 * STATUS: OPTIONAL
417 */
418 int (*ddp_setup)(struct fc_lport *lp, u16 xid,
419 struct scatterlist *sgl, unsigned int sgc);
420 /*
421 * Completes the DDP transfer and returns the length of data DDPed
422 * for the given exchange id.
423 *
424 * STATUS: OPTIONAL
425 */
426 int (*ddp_done)(struct fc_lport *lp, u16 xid);
427 /*
403 * Send a frame using an existing sequence and exchange. 428 * Send a frame using an existing sequence and exchange.
404 * 429 *
405 * STATUS: OPTIONAL 430 * STATUS: OPTIONAL
@@ -822,6 +847,11 @@ int fc_change_queue_type(struct scsi_device *sdev, int tag_type);
822void fc_fcp_destroy(struct fc_lport *); 847void fc_fcp_destroy(struct fc_lport *);
823 848
824/* 849/*
850 * Set up direct-data placement for this I/O request
851 */
852void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid);
853
854/*
825 * ELS/CT interface 855 * ELS/CT interface
826 *****************************/ 856 *****************************/
827/* 857/*
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
index 941818f29f59..c41f7d0c6efc 100644
--- a/include/scsi/libfcoe.h
+++ b/include/scsi/libfcoe.h
@@ -124,24 +124,6 @@ static inline u16 skb_fc_rxid(const struct sk_buff *skb)
124 return be16_to_cpu(skb_fc_header(skb)->fh_rx_id); 124 return be16_to_cpu(skb_fc_header(skb)->fh_rx_id);
125} 125}
126 126
127/* FIXME - DMA_BIDIRECTIONAL ? */
128#define skb_cb(skb) ((struct fcoe_rcv_info *)&((skb)->cb[0]))
129#define skb_cmd(skb) (skb_cb(skb)->fr_cmd)
130#define skb_dir(skb) (skb_cmd(skb)->sc_data_direction)
131static inline bool skb_fc_is_read(const struct sk_buff *skb)
132{
133 if (skb_fc_is_cmd(skb) && skb_cmd(skb))
134 return skb_dir(skb) == DMA_FROM_DEVICE;
135 return false;
136}
137
138static inline bool skb_fc_is_write(const struct sk_buff *skb)
139{
140 if (skb_fc_is_cmd(skb) && skb_cmd(skb))
141 return skb_dir(skb) == DMA_TO_DEVICE;
142 return false;
143}
144
145/* libfcoe funcs */ 127/* libfcoe funcs */
146int fcoe_reset(struct Scsi_Host *shost); 128int fcoe_reset(struct Scsi_Host *shost);
147u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], 129u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN],