[Open-FCoE] [PATCH 2/2] fcoe: add recv status in fcoe_recv_info

Yi Zou yi.zou at intel.com
Sat Jan 31 02:09:56 UTC 2009


The LLD should encode the completed length of data by direct data placement
using the added fr_ddplen(fp). The fc_fcp_resp() and fc_fcp_recv_data() are
then able to update xfer_len to include data already ddped. Also, do not clear
the fr_flags(fp) that can be set by LLD in fcoe_percpu_receive_thread().

Signed-off-by: Yi Zou <yi.zou at intel.com>
---

 drivers/scsi/fcoe/libfcoe.c |    2 +-
 drivers/scsi/libfc/fc_fcp.c |    9 +++++++++
 include/scsi/fc_frame.h     |    7 ++++++-
 include/scsi/libfcoe.h      |    2 ++
 4 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 935c6f5..07ad589 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -604,7 +604,7 @@ int fcoe_percpu_receive_thread(void *arg)
 		}
 
 		fp = (struct fc_frame *)skb;
-		fc_frame_init(fp);
+		fr_seq(fp) = NULL;
 		fr_dev(fp) = lp;
 		fr_sof(fp) = hp->fcoe_sof;
 
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index ecc7261..ca4fae3 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -290,6 +290,10 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
 	len = fr_len(fp) - sizeof(*fh);
 	buf = fc_frame_payload_get(fp, 0);
 
+
+	if (lp->lro_enabled && fr_ddplen(fp))
+		fsp->xfer_len = fr_ddplen(fp);
+
 	if (offset + len > fsp->data_len) {
 		/*
 		 * this should never happen
@@ -745,6 +749,9 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
 	fsp->scsi_comp_flags = flags;
 	expected_len = fsp->data_len;
 
+	if (fsp->lp->lro_enabled && fr_ddplen(fp))
+		fsp->xfer_len = fr_ddplen(fp);
+
 	if (unlikely((flags & ~FCP_CONF_REQ) || fc_rp->fr_status)) {
 		rp_ex = (void *)(fc_rp + 1);
 		if (flags & (FCP_RSP_LEN_VAL | FCP_SNS_LEN_VAL)) {
@@ -1008,6 +1015,8 @@ static int fc_fcp_cmd_send(struct fc_lport *lp, struct fc_fcp_pkt *fsp,
 
 	memcpy(fc_frame_payload_get(fp, len), &fsp->cdb_cmd, len);
 	fr_cmd(fp) = fsp->cmd;
+	if (lp->lro_enabled && fsp->req_flags  == FC_SRB_READ)
+		fr_flags(fp) |= FCPHF_DDP_ENABLED;
 	rport = fsp->rport;
 	fsp->max_payload = rport->maxframe_size;
 	rp = rport->dd_data;
diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h
index 04d34a7..e5a97e8 100644
--- a/include/scsi/fc_frame.h
+++ b/include/scsi/fc_frame.h
@@ -57,6 +57,7 @@
 #define fr_cmd(fp)	(fr_cb(fp)->fr_cmd)
 #define fr_dir(fp)	(fr_cmd(fp)->sc_data_direction)
 #define fr_crc(fp)	(fr_cb(fp)->fr_crc)
+#define fr_ddplen(fp)	(fr_cb(fp)->fr_ddplen)
 
 struct fc_frame {
 	struct sk_buff skb;
@@ -66,7 +67,10 @@ struct fcoe_rcv_info {
 	struct packet_type  *ptype;
 	struct fc_lport	*fr_dev;	/* transport layer private pointer */
 	struct fc_seq	*fr_seq;	/* for use with exchange manager */
-	struct scsi_cmnd *fr_cmd;	/* for use of scsi command */
+	union {
+		struct scsi_cmnd *fr_cmd;	/* for use of scsi command */
+		u32	fr_ddplen;		/* data already DDPed */
+	};
 	u32		fr_crc;
 	u16		fr_max_payload;	/* max FC payload */
 	enum fc_sof	fr_sof;		/* start of frame delimiter */
@@ -88,6 +92,7 @@ static inline struct fcoe_rcv_info *fcoe_dev_from_skb(const struct sk_buff *skb)
  * fr_flags.
  */
 #define	FCPHF_CRC_UNCHECKED	0x01	/* CRC not computed, still appended */
+#define	FCPHF_DDP_ENABLED	0X02	/* Request for DDP from LLD */
 
 /*
  * Initialize a frame.
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
index 89fdbb9..6967a8a 100644
--- a/include/scsi/libfcoe.h
+++ b/include/scsi/libfcoe.h
@@ -133,6 +133,8 @@ static inline u16 skb_fc_rxid(const struct sk_buff *skb)
 #define skb_cb(skb)	((struct fcoe_rcv_info *)&((skb)->cb[0]))
 #define skb_cmd(skb)	(skb_cb(skb)->fr_cmd)
 #define skb_dir(skb)	(skb_cmd(skb)->sc_data_direction)
+#define skb_flags(skb)	(skb_cb(skb)->fr_flags)
+#define skb_ddplen(skb)	(skb_cb(skb)->fr_ddplen)
 static inline bool skb_fc_is_read(const struct sk_buff *skb)
 {
 	if (skb_fc_is_cmd(skb) && skb_cmd(skb))




More information about the devel mailing list