diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2008-12-02 00:32:16 -0600 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-12-29 11:24:23 -0600 |
commit | 6df19a791bdd5d820cccd8c7a12679888ae62099 (patch) | |
tree | 5afebc101c362d0a41275337dced617fb06f8a89 /drivers/scsi | |
parent | ae15f80172d95f978b60d40408353943d5bc099b (diff) |
[SCSI] libiscsi_tcp: support padding offload
cxgb3i does not offload the processing of the header,
but it will always process the padding. This patch
adds a padding offload flag to detect when the LLD
supports this.
The patch also modifies the header processing so that
we do not try to read/bypass the header dugest in the
skb. cxgb3i will not include it with the header like
with other offload cards.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 9 | ||||
-rw-r--r-- | drivers/scsi/libiscsi_tcp.c | 37 |
2 files changed, 25 insertions, 21 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index de5c9b3e51f..23808dfe22b 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -194,7 +194,7 @@ iscsi_sw_tcp_conn_restore_callbacks(struct iscsi_sw_tcp_conn *tcp_sw_conn) /** * iscsi_sw_tcp_xmit_segment - transmit segment - * @tcp_sw_conn: the iSCSI TCP connection + * @tcp_conn: the iSCSI TCP connection * @segment: the buffer to transmnit * * This function transmits as much of the buffer as @@ -205,14 +205,15 @@ iscsi_sw_tcp_conn_restore_callbacks(struct iscsi_sw_tcp_conn *tcp_sw_conn) * hash as it goes. When the entire segment has been transmitted, * it will retrieve the hash value and send it as well. */ -static int iscsi_sw_tcp_xmit_segment(struct iscsi_sw_tcp_conn *tcp_sw_conn, +static int iscsi_sw_tcp_xmit_segment(struct iscsi_tcp_conn *tcp_conn, struct iscsi_segment *segment) { + struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; struct socket *sk = tcp_sw_conn->sock; unsigned int copied = 0; int r = 0; - while (!iscsi_tcp_segment_done(segment, 0, r)) { + while (!iscsi_tcp_segment_done(tcp_conn, segment, 0, r)) { struct scatterlist *sg; unsigned int offset, copy; int flags = 0; @@ -263,7 +264,7 @@ static int iscsi_sw_tcp_xmit(struct iscsi_conn *conn) int rc = 0; while (1) { - rc = iscsi_sw_tcp_xmit_segment(tcp_sw_conn, segment); + rc = iscsi_sw_tcp_xmit_segment(tcp_conn, segment); if (rc < 0) { rc = ISCSI_ERR_XMIT_FAILED; goto error; diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index 9df6b3436e4..a745f91d292 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -159,6 +159,7 @@ iscsi_tcp_segment_splice_digest(struct iscsi_segment *segment, void *digest) /** * iscsi_tcp_segment_done - check whether the segment is complete + * @tcp_conn: iscsi tcp connection * @segment: iscsi segment to check * @recv: set to one of this is called from the recv path * @copied: number of bytes copied @@ -172,7 +173,8 @@ iscsi_tcp_segment_splice_digest(struct iscsi_segment *segment, void *digest) * * This function must be re-entrant. */ -int iscsi_tcp_segment_done(struct iscsi_segment *segment, int recv, +int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn, + struct iscsi_segment *segment, int recv, unsigned copied) { static unsigned char padbuf[ISCSI_PAD_LEN]; @@ -225,13 +227,15 @@ int iscsi_tcp_segment_done(struct iscsi_segment *segment, int recv, } /* Do we need to handle padding? */ - pad = iscsi_padding(segment->total_copied); - if (pad != 0) { - debug_tcp("consume %d pad bytes\n", pad); - segment->total_size += pad; - segment->size = pad; - segment->data = padbuf; - return 0; + if (!(tcp_conn->iscsi_conn->session->tt->caps & CAP_PADDING_OFFLOAD)) { + pad = iscsi_padding(segment->total_copied); + if (pad != 0) { + debug_tcp("consume %d pad bytes\n", pad); + segment->total_size += pad; + segment->size = pad; + segment->data = padbuf; + return 0; + } } /* @@ -273,7 +277,7 @@ iscsi_tcp_segment_recv(struct iscsi_tcp_conn *tcp_conn, { unsigned int copy = 0, copied = 0; - while (!iscsi_tcp_segment_done(segment, 1, copy)) { + while (!iscsi_tcp_segment_done(tcp_conn, segment, 1, copy)) { if (copied == len) { debug_tcp("iscsi_tcp_segment_recv copied %d bytes\n", len); @@ -794,7 +798,8 @@ iscsi_tcp_hdr_recv_done(struct iscsi_tcp_conn *tcp_conn, /* We're done processing the header. See if we're doing * header digests; if so, set up the recv_digest buffer * and go back for more. */ - if (conn->hdrdgst_en) { + if (conn->hdrdgst_en && + !(conn->session->tt->caps & CAP_DIGEST_OFFLOAD)) { if (segment->digest_len == 0) { /* * Even if we offload the digest processing we @@ -806,14 +811,12 @@ iscsi_tcp_hdr_recv_done(struct iscsi_tcp_conn *tcp_conn, return 0; } - if (!(conn->session->tt->caps & CAP_DIGEST_OFFLOAD)) { - iscsi_tcp_dgst_header(tcp_conn->rx_hash, hdr, - segment->total_copied - ISCSI_DIGEST_SIZE, - segment->digest); + iscsi_tcp_dgst_header(tcp_conn->rx_hash, hdr, + segment->total_copied - ISCSI_DIGEST_SIZE, + segment->digest); - if (!iscsi_tcp_dgst_verify(tcp_conn, segment)) - return ISCSI_ERR_HDR_DGST; - } + if (!iscsi_tcp_dgst_verify(tcp_conn, segment)) + return ISCSI_ERR_HDR_DGST; } tcp_conn->in.hdr = hdr; |