aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/iscsi_tcp.c
diff options
context:
space:
mode:
authorJames Bottomley <jejb@sparkweed.localdomain>2006-09-23 16:33:43 -0400
committerJames Bottomley <jejb@sparkweed.localdomain>2006-09-23 16:33:43 -0400
commitc9802cd9574a80444e689c7525627b40d7dc3a06 (patch)
tree5954e2ac7e97023b51d36127963a1e9262fbcfe0 /drivers/scsi/iscsi_tcp.c
parent3eeab61aa3ddd3c0bedb7449ada1599de22fdb5a (diff)
parent2d2f8d59b14bec6c745e219a350ac51d9e00673f (diff)
Merge mulgrave-w:git/scsi-misc-2.6
Conflicts: drivers/scsi/iscsi_tcp.c drivers/scsi/iscsi_tcp.h Pretty horrible merge between crypto hash consolidation and crypto_digest_...->crypto_hash_... conversion Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/iscsi_tcp.c')
-rw-r--r--drivers/scsi/iscsi_tcp.c811
1 files changed, 312 insertions, 499 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 66a1ae1d6982..0a9dbc59663f 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -26,7 +26,6 @@
26 * Zhenyu Wang 26 * Zhenyu Wang
27 */ 27 */
28 28
29#include <linux/err.h>
30#include <linux/types.h> 29#include <linux/types.h>
31#include <linux/list.h> 30#include <linux/list.h>
32#include <linux/inet.h> 31#include <linux/inet.h>
@@ -108,12 +107,9 @@ iscsi_hdr_digest(struct iscsi_conn *conn, struct iscsi_buf *buf,
108 u8* crc) 107 u8* crc)
109{ 108{
110 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 109 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
111 struct hash_desc desc;
112 110
113 desc.tfm = tcp_conn->tx_tfm; 111 crypto_hash_digest(&tcp_conn->tx_hash, &buf->sg, buf->sg.length, crc);
114 desc.flags = 0; 112 buf->sg.length = tcp_conn->hdr_size;
115 crypto_hash_digest(&desc, &buf->sg, buf->sg.length, crc);
116 buf->sg.length += sizeof(uint32_t);
117} 113}
118 114
119static inline int 115static inline int
@@ -285,7 +281,6 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
285{ 281{
286 struct iscsi_data *hdr; 282 struct iscsi_data *hdr;
287 struct scsi_cmnd *sc = ctask->sc; 283 struct scsi_cmnd *sc = ctask->sc;
288 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
289 284
290 hdr = &r2t->dtask.hdr; 285 hdr = &r2t->dtask.hdr;
291 memset(hdr, 0, sizeof(struct iscsi_data)); 286 memset(hdr, 0, sizeof(struct iscsi_data));
@@ -340,10 +335,12 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
340 sg_count += sg->length; 335 sg_count += sg->length;
341 } 336 }
342 BUG_ON(r2t->sg == NULL); 337 BUG_ON(r2t->sg == NULL);
343 } else 338 } else {
344 iscsi_buf_init_iov(&tcp_ctask->sendbuf, 339 iscsi_buf_init_iov(&r2t->sendbuf,
345 (char*)sc->request_buffer + r2t->data_offset, 340 (char*)sc->request_buffer + r2t->data_offset,
346 r2t->data_count); 341 r2t->data_count);
342 r2t->sg = NULL;
343 }
347} 344}
348 345
349/** 346/**
@@ -362,8 +359,11 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
362 int r2tsn = be32_to_cpu(rhdr->r2tsn); 359 int r2tsn = be32_to_cpu(rhdr->r2tsn);
363 int rc; 360 int rc;
364 361
365 if (tcp_conn->in.datalen) 362 if (tcp_conn->in.datalen) {
363 printk(KERN_ERR "iscsi_tcp: invalid R2t with datalen %d\n",
364 tcp_conn->in.datalen);
366 return ISCSI_ERR_DATALEN; 365 return ISCSI_ERR_DATALEN;
366 }
367 367
368 if (tcp_ctask->exp_r2tsn && tcp_ctask->exp_r2tsn != r2tsn) 368 if (tcp_ctask->exp_r2tsn && tcp_ctask->exp_r2tsn != r2tsn)
369 return ISCSI_ERR_R2TSN; 369 return ISCSI_ERR_R2TSN;
@@ -389,15 +389,23 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
389 389
390 r2t->exp_statsn = rhdr->statsn; 390 r2t->exp_statsn = rhdr->statsn;
391 r2t->data_length = be32_to_cpu(rhdr->data_length); 391 r2t->data_length = be32_to_cpu(rhdr->data_length);
392 if (r2t->data_length == 0 || 392 if (r2t->data_length == 0) {
393 r2t->data_length > session->max_burst) { 393 printk(KERN_ERR "iscsi_tcp: invalid R2T with zero data len\n");
394 spin_unlock(&session->lock); 394 spin_unlock(&session->lock);
395 return ISCSI_ERR_DATALEN; 395 return ISCSI_ERR_DATALEN;
396 } 396 }
397 397
398 if (r2t->data_length > session->max_burst)
399 debug_scsi("invalid R2T with data len %u and max burst %u."
400 "Attempting to execute request.\n",
401 r2t->data_length, session->max_burst);
402
398 r2t->data_offset = be32_to_cpu(rhdr->data_offset); 403 r2t->data_offset = be32_to_cpu(rhdr->data_offset);
399 if (r2t->data_offset + r2t->data_length > ctask->total_length) { 404 if (r2t->data_offset + r2t->data_length > ctask->total_length) {
400 spin_unlock(&session->lock); 405 spin_unlock(&session->lock);
406 printk(KERN_ERR "iscsi_tcp: invalid R2T with data len %u at "
407 "offset %u and total length %d\n", r2t->data_length,
408 r2t->data_offset, ctask->total_length);
401 return ISCSI_ERR_DATALEN; 409 return ISCSI_ERR_DATALEN;
402 } 410 }
403 411
@@ -456,14 +464,12 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn)
456 } 464 }
457 465
458 if (conn->hdrdgst_en) { 466 if (conn->hdrdgst_en) {
459 struct hash_desc desc;
460 struct scatterlist sg; 467 struct scatterlist sg;
461 468
462 sg_init_one(&sg, (u8 *)hdr, 469 sg_init_one(&sg, (u8 *)hdr,
463 sizeof(struct iscsi_hdr) + ahslen); 470 sizeof(struct iscsi_hdr) + ahslen);
464 desc.tfm = tcp_conn->rx_tfm; 471 crypto_hash_digest(&tcp_conn->rx_hash, &sg, sg.length,
465 desc.flags = 0; 472 (u8 *)&cdgst);
466 crypto_hash_digest(&desc, &sg, sg.length, (u8 *)&cdgst);
467 rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) + 473 rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) +
468 ahslen); 474 ahslen);
469 if (cdgst != rdgst) { 475 if (cdgst != rdgst) {
@@ -499,7 +505,6 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn)
499 goto copy_hdr; 505 goto copy_hdr;
500 506
501 spin_lock(&session->lock); 507 spin_lock(&session->lock);
502 iscsi_tcp_cleanup_ctask(conn, tcp_conn->in.ctask);
503 rc = __iscsi_complete_pdu(conn, hdr, NULL, 0); 508 rc = __iscsi_complete_pdu(conn, hdr, NULL, 0);
504 spin_unlock(&session->lock); 509 spin_unlock(&session->lock);
505 break; 510 break;
@@ -644,10 +649,9 @@ iscsi_ctask_copy(struct iscsi_tcp_conn *tcp_conn, struct iscsi_cmd_task *ctask,
644 * byte counters. 649 * byte counters.
645 **/ 650 **/
646static inline int 651static inline int
647iscsi_tcp_copy(struct iscsi_conn *conn) 652iscsi_tcp_copy(struct iscsi_conn *conn, int buf_size)
648{ 653{
649 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 654 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
650 int buf_size = tcp_conn->in.datalen;
651 int buf_left = buf_size - tcp_conn->data_copied; 655 int buf_left = buf_size - tcp_conn->data_copied;
652 int size = min(tcp_conn->in.copy, buf_left); 656 int size = min(tcp_conn->in.copy, buf_left);
653 int rc; 657 int rc;
@@ -672,15 +676,15 @@ iscsi_tcp_copy(struct iscsi_conn *conn)
672} 676}
673 677
674static inline void 678static inline void
675partial_sg_digest_update(struct iscsi_tcp_conn *tcp_conn, 679partial_sg_digest_update(struct hash_desc *desc, struct scatterlist *sg,
676 struct scatterlist *sg, int offset, int length) 680 int offset, int length)
677{ 681{
678 struct scatterlist temp; 682 struct scatterlist temp;
679 683
680 memcpy(&temp, sg, sizeof(struct scatterlist)); 684 memcpy(&temp, sg, sizeof(struct scatterlist));
681 temp.offset = offset; 685 temp.offset = offset;
682 temp.length = length; 686 temp.length = length;
683 crypto_hash_update(&tcp_conn->data_rx_hash, &temp, length); 687 crypto_hash_update(desc, &temp, length);
684} 688}
685 689
686static void 690static void
@@ -689,7 +693,7 @@ iscsi_recv_digest_update(struct iscsi_tcp_conn *tcp_conn, char* buf, int len)
689 struct scatterlist tmp; 693 struct scatterlist tmp;
690 694
691 sg_init_one(&tmp, buf, len); 695 sg_init_one(&tmp, buf, len);
692 crypto_hash_update(&tcp_conn->data_rx_hash, &tmp, len); 696 crypto_hash_update(&tcp_conn->rx_hash, &tmp, len);
693} 697}
694 698
695static int iscsi_scsi_data_in(struct iscsi_conn *conn) 699static int iscsi_scsi_data_in(struct iscsi_conn *conn)
@@ -744,10 +748,11 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
744 if (conn->datadgst_en) { 748 if (conn->datadgst_en) {
745 if (!offset) 749 if (!offset)
746 crypto_hash_update( 750 crypto_hash_update(
747 &tcp_conn->data_rx_hash, 751 &tcp_conn->rx_hash,
748 &sg[i], sg[i].length); 752 &sg[i], 1);
749 else 753 else
750 partial_sg_digest_update(tcp_conn, 754 partial_sg_digest_update(
755 &tcp_conn->rx_hash,
751 &sg[i], 756 &sg[i],
752 sg[i].offset + offset, 757 sg[i].offset + offset,
753 sg[i].length - offset); 758 sg[i].length - offset);
@@ -761,8 +766,10 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
761 /* 766 /*
762 * data-in is complete, but buffer not... 767 * data-in is complete, but buffer not...
763 */ 768 */
764 partial_sg_digest_update(tcp_conn, &sg[i], 769 partial_sg_digest_update(&tcp_conn->rx_hash,
765 sg[i].offset, sg[i].length-rc); 770 &sg[i],
771 sg[i].offset,
772 sg[i].length-rc);
766 rc = 0; 773 rc = 0;
767 break; 774 break;
768 } 775 }
@@ -779,7 +786,6 @@ done:
779 (long)sc, sc->result, ctask->itt, 786 (long)sc, sc->result, ctask->itt,
780 tcp_conn->in.hdr->flags); 787 tcp_conn->in.hdr->flags);
781 spin_lock(&conn->session->lock); 788 spin_lock(&conn->session->lock);
782 iscsi_tcp_cleanup_ctask(conn, ctask);
783 __iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0); 789 __iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0);
784 spin_unlock(&conn->session->lock); 790 spin_unlock(&conn->session->lock);
785 } 791 }
@@ -799,9 +805,6 @@ iscsi_data_recv(struct iscsi_conn *conn)
799 rc = iscsi_scsi_data_in(conn); 805 rc = iscsi_scsi_data_in(conn);
800 break; 806 break;
801 case ISCSI_OP_SCSI_CMD_RSP: 807 case ISCSI_OP_SCSI_CMD_RSP:
802 spin_lock(&conn->session->lock);
803 iscsi_tcp_cleanup_ctask(conn, tcp_conn->in.ctask);
804 spin_unlock(&conn->session->lock);
805 case ISCSI_OP_TEXT_RSP: 808 case ISCSI_OP_TEXT_RSP:
806 case ISCSI_OP_LOGIN_RSP: 809 case ISCSI_OP_LOGIN_RSP:
807 case ISCSI_OP_ASYNC_EVENT: 810 case ISCSI_OP_ASYNC_EVENT:
@@ -810,7 +813,7 @@ iscsi_data_recv(struct iscsi_conn *conn)
810 * Collect data segment to the connection's data 813 * Collect data segment to the connection's data
811 * placeholder 814 * placeholder
812 */ 815 */
813 if (iscsi_tcp_copy(conn)) { 816 if (iscsi_tcp_copy(conn, tcp_conn->in.datalen)) {
814 rc = -EAGAIN; 817 rc = -EAGAIN;
815 goto exit; 818 goto exit;
816 } 819 }
@@ -883,9 +886,8 @@ more:
883 */ 886 */
884 rc = iscsi_tcp_hdr_recv(conn); 887 rc = iscsi_tcp_hdr_recv(conn);
885 if (!rc && tcp_conn->in.datalen) { 888 if (!rc && tcp_conn->in.datalen) {
886 if (conn->datadgst_en) { 889 if (conn->datadgst_en)
887 crypto_hash_init(&tcp_conn->data_rx_hash); 890 crypto_hash_init(&tcp_conn->rx_hash);
888 }
889 tcp_conn->in_progress = IN_PROGRESS_DATA_RECV; 891 tcp_conn->in_progress = IN_PROGRESS_DATA_RECV;
890 } else if (rc) { 892 } else if (rc) {
891 iscsi_conn_failure(conn, rc); 893 iscsi_conn_failure(conn, rc);
@@ -898,10 +900,15 @@ more:
898 900
899 debug_tcp("extra data_recv offset %d copy %d\n", 901 debug_tcp("extra data_recv offset %d copy %d\n",
900 tcp_conn->in.offset, tcp_conn->in.copy); 902 tcp_conn->in.offset, tcp_conn->in.copy);
901 skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset, 903 rc = iscsi_tcp_copy(conn, sizeof(uint32_t));
902 &recv_digest, 4); 904 if (rc) {
903 tcp_conn->in.offset += 4; 905 if (rc == -EAGAIN)
904 tcp_conn->in.copy -= 4; 906 goto again;
907 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
908 return 0;
909 }
910
911 memcpy(&recv_digest, conn->data, sizeof(uint32_t));
905 if (recv_digest != tcp_conn->in.datadgst) { 912 if (recv_digest != tcp_conn->in.datadgst) {
906 debug_tcp("iscsi_tcp: data digest error!" 913 debug_tcp("iscsi_tcp: data digest error!"
907 "0x%x != 0x%x\n", recv_digest, 914 "0x%x != 0x%x\n", recv_digest,
@@ -937,13 +944,14 @@ more:
937 tcp_conn->in.padding); 944 tcp_conn->in.padding);
938 memset(pad, 0, tcp_conn->in.padding); 945 memset(pad, 0, tcp_conn->in.padding);
939 sg_init_one(&sg, pad, tcp_conn->in.padding); 946 sg_init_one(&sg, pad, tcp_conn->in.padding);
940 crypto_hash_update(&tcp_conn->data_rx_hash, 947 crypto_hash_update(&tcp_conn->rx_hash,
941 &sg, sg.length); 948 &sg, sg.length);
942 } 949 }
943 crypto_hash_final(&tcp_conn->data_rx_hash, 950 crypto_hash_final(&tcp_conn->rx_hash,
944 (u8 *)&tcp_conn->in.datadgst); 951 (u8 *) &tcp_conn->in.datadgst);
945 debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst); 952 debug_tcp("rx digest 0x%x\n", tcp_conn->in.datadgst);
946 tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV; 953 tcp_conn->in_progress = IN_PROGRESS_DDIGEST_RECV;
954 tcp_conn->data_copied = 0;
947 } else 955 } else
948 tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER; 956 tcp_conn->in_progress = IN_PROGRESS_WAIT_HEADER;
949 } 957 }
@@ -1183,36 +1191,12 @@ iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf,
1183 1191
1184static inline void 1192static inline void
1185iscsi_data_digest_init(struct iscsi_tcp_conn *tcp_conn, 1193iscsi_data_digest_init(struct iscsi_tcp_conn *tcp_conn,
1186 struct iscsi_cmd_task *ctask) 1194 struct iscsi_tcp_cmd_task *tcp_ctask)
1187{ 1195{
1188 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1196 crypto_hash_init(&tcp_conn->tx_hash);
1189
1190 crypto_hash_init(&tcp_conn->data_tx_hash);
1191 tcp_ctask->digest_count = 4; 1197 tcp_ctask->digest_count = 4;
1192} 1198}
1193 1199
1194static int
1195iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1196 struct iscsi_buf *buf, uint32_t *digest, int final)
1197{
1198 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1199 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1200 int rc = 0;
1201 int sent = 0;
1202
1203 if (final)
1204 crypto_hash_final(&tcp_conn->data_tx_hash, (u8 *)digest);
1205
1206 iscsi_buf_init_iov(buf, (char*)digest, 4);
1207 rc = iscsi_sendpage(conn, buf, &tcp_ctask->digest_count, &sent);
1208 if (rc) {
1209 tcp_ctask->datadigest = *digest;
1210 tcp_ctask->xmstate |= XMSTATE_DATA_DIGEST;
1211 } else
1212 tcp_ctask->digest_count = 4;
1213 return rc;
1214}
1215
1216/** 1200/**
1217 * iscsi_solicit_data_cont - initialize next Data-Out 1201 * iscsi_solicit_data_cont - initialize next Data-Out
1218 * @conn: iscsi connection 1202 * @conn: iscsi connection
@@ -1230,7 +1214,6 @@ static void
1230iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, 1214iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1231 struct iscsi_r2t_info *r2t, int left) 1215 struct iscsi_r2t_info *r2t, int left)
1232{ 1216{
1233 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1234 struct iscsi_data *hdr; 1217 struct iscsi_data *hdr;
1235 struct scsi_cmnd *sc = ctask->sc; 1218 struct scsi_cmnd *sc = ctask->sc;
1236 int new_offset; 1219 int new_offset;
@@ -1259,27 +1242,30 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1259 iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr, 1242 iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr,
1260 sizeof(struct iscsi_hdr)); 1243 sizeof(struct iscsi_hdr));
1261 1244
1262 if (sc->use_sg && !iscsi_buf_left(&r2t->sendbuf)) { 1245 if (iscsi_buf_left(&r2t->sendbuf))
1263 BUG_ON(tcp_ctask->bad_sg == r2t->sg); 1246 return;
1247
1248 if (sc->use_sg) {
1264 iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg); 1249 iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg);
1265 r2t->sg += 1; 1250 r2t->sg += 1;
1266 } else 1251 } else {
1267 iscsi_buf_init_iov(&tcp_ctask->sendbuf, 1252 iscsi_buf_init_iov(&r2t->sendbuf,
1268 (char*)sc->request_buffer + new_offset, 1253 (char*)sc->request_buffer + new_offset,
1269 r2t->data_count); 1254 r2t->data_count);
1255 r2t->sg = NULL;
1256 }
1270} 1257}
1271 1258
1272static void 1259static void iscsi_set_padding(struct iscsi_tcp_cmd_task *tcp_ctask,
1273iscsi_unsolicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1260 unsigned long len)
1274{ 1261{
1275 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1262 tcp_ctask->pad_count = len & (ISCSI_PAD_LEN - 1);
1276 struct iscsi_data_task *dtask; 1263 if (!tcp_ctask->pad_count)
1264 return;
1277 1265
1278 dtask = tcp_ctask->dtask = &tcp_ctask->unsol_dtask; 1266 tcp_ctask->pad_count = ISCSI_PAD_LEN - tcp_ctask->pad_count;
1279 iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr, 1267 debug_scsi("write padding %d bytes\n", tcp_ctask->pad_count);
1280 tcp_ctask->r2t_data_count); 1268 tcp_ctask->xmstate |= XMSTATE_W_PAD;
1281 iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr,
1282 sizeof(struct iscsi_hdr));
1283} 1269}
1284 1270
1285/** 1271/**
@@ -1307,38 +1293,20 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
1307 if (sc->use_sg) { 1293 if (sc->use_sg) {
1308 struct scatterlist *sg = sc->request_buffer; 1294 struct scatterlist *sg = sc->request_buffer;
1309 1295
1310 iscsi_buf_init_sg(&tcp_ctask->sendbuf, 1296 iscsi_buf_init_sg(&tcp_ctask->sendbuf, sg);
1311 &sg[tcp_ctask->sg_count++]); 1297 tcp_ctask->sg = sg + 1;
1312 tcp_ctask->sg = sg;
1313 tcp_ctask->bad_sg = sg + sc->use_sg; 1298 tcp_ctask->bad_sg = sg + sc->use_sg;
1314 } else 1299 } else {
1315 iscsi_buf_init_iov(&tcp_ctask->sendbuf, 1300 iscsi_buf_init_iov(&tcp_ctask->sendbuf,
1316 sc->request_buffer, 1301 sc->request_buffer,
1317 sc->request_bufflen); 1302 sc->request_bufflen);
1318 1303 tcp_ctask->sg = NULL;
1319 if (ctask->imm_count) 1304 tcp_ctask->bad_sg = NULL;
1320 tcp_ctask->xmstate |= XMSTATE_IMM_DATA;
1321
1322 tcp_ctask->pad_count = ctask->total_length & (ISCSI_PAD_LEN-1);
1323 if (tcp_ctask->pad_count) {
1324 tcp_ctask->pad_count = ISCSI_PAD_LEN -
1325 tcp_ctask->pad_count;
1326 debug_scsi("write padding %d bytes\n",
1327 tcp_ctask->pad_count);
1328 tcp_ctask->xmstate |= XMSTATE_W_PAD;
1329 } 1305 }
1330 1306 debug_scsi("cmd [itt 0x%x total %d imm_data %d "
1331 if (ctask->unsol_count) 1307 "unsol count %d, unsol offset %d]\n",
1332 tcp_ctask->xmstate |= XMSTATE_UNS_HDR |
1333 XMSTATE_UNS_INIT;
1334 tcp_ctask->r2t_data_count = ctask->total_length -
1335 ctask->imm_count -
1336 ctask->unsol_count;
1337
1338 debug_scsi("cmd [itt 0x%x total %d imm %d imm_data %d "
1339 "r2t_data %d]\n",
1340 ctask->itt, ctask->total_length, ctask->imm_count, 1308 ctask->itt, ctask->total_length, ctask->imm_count,
1341 ctask->unsol_count, tcp_ctask->r2t_data_count); 1309 ctask->unsol_count, ctask->unsol_offset);
1342 } else 1310 } else
1343 tcp_ctask->xmstate = XMSTATE_R_HDR; 1311 tcp_ctask->xmstate = XMSTATE_R_HDR;
1344 1312
@@ -1420,8 +1388,8 @@ iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
1420} 1388}
1421 1389
1422static inline int 1390static inline int
1423handle_xmstate_r_hdr(struct iscsi_conn *conn, 1391iscsi_send_read_hdr(struct iscsi_conn *conn,
1424 struct iscsi_tcp_cmd_task *tcp_ctask) 1392 struct iscsi_tcp_cmd_task *tcp_ctask)
1425{ 1393{
1426 int rc; 1394 int rc;
1427 1395
@@ -1439,7 +1407,7 @@ handle_xmstate_r_hdr(struct iscsi_conn *conn,
1439} 1407}
1440 1408
1441static inline int 1409static inline int
1442handle_xmstate_w_hdr(struct iscsi_conn *conn, 1410iscsi_send_write_hdr(struct iscsi_conn *conn,
1443 struct iscsi_cmd_task *ctask) 1411 struct iscsi_cmd_task *ctask)
1444{ 1412{
1445 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1413 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
@@ -1450,86 +1418,126 @@ handle_xmstate_w_hdr(struct iscsi_conn *conn,
1450 iscsi_hdr_digest(conn, &tcp_ctask->headbuf, 1418 iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
1451 (u8*)tcp_ctask->hdrext); 1419 (u8*)tcp_ctask->hdrext);
1452 rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count); 1420 rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count);
1453 if (rc) 1421 if (rc) {
1454 tcp_ctask->xmstate |= XMSTATE_W_HDR; 1422 tcp_ctask->xmstate |= XMSTATE_W_HDR;
1455 return rc; 1423 return rc;
1424 }
1425
1426 if (ctask->imm_count) {
1427 tcp_ctask->xmstate |= XMSTATE_IMM_DATA;
1428 iscsi_set_padding(tcp_ctask, ctask->imm_count);
1429
1430 if (ctask->conn->datadgst_en) {
1431 iscsi_data_digest_init(ctask->conn->dd_data, tcp_ctask);
1432 tcp_ctask->immdigest = 0;
1433 }
1434 }
1435
1436 if (ctask->unsol_count)
1437 tcp_ctask->xmstate |= XMSTATE_UNS_HDR | XMSTATE_UNS_INIT;
1438 return 0;
1456} 1439}
1457 1440
1458static inline int 1441static int
1459handle_xmstate_data_digest(struct iscsi_conn *conn, 1442iscsi_send_padding(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1460 struct iscsi_cmd_task *ctask)
1461{ 1443{
1462 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1444 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1463 int rc; 1445 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1446 int sent = 0, rc;
1464 1447
1465 tcp_ctask->xmstate &= ~XMSTATE_DATA_DIGEST; 1448 if (tcp_ctask->xmstate & XMSTATE_W_PAD) {
1466 debug_tcp("resent data digest 0x%x\n", tcp_ctask->datadigest); 1449 iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad,
1467 rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf, 1450 tcp_ctask->pad_count);
1468 &tcp_ctask->datadigest, 0); 1451 if (conn->datadgst_en)
1452 crypto_hash_update(&tcp_conn->tx_hash,
1453 &tcp_ctask->sendbuf.sg,
1454 tcp_ctask->sendbuf.sg.length);
1455 } else if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_PAD))
1456 return 0;
1457
1458 tcp_ctask->xmstate &= ~XMSTATE_W_PAD;
1459 tcp_ctask->xmstate &= ~XMSTATE_W_RESEND_PAD;
1460 debug_scsi("sending %d pad bytes for itt 0x%x\n",
1461 tcp_ctask->pad_count, ctask->itt);
1462 rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, &tcp_ctask->pad_count,
1463 &sent);
1469 if (rc) { 1464 if (rc) {
1470 tcp_ctask->xmstate |= XMSTATE_DATA_DIGEST; 1465 debug_scsi("padding send failed %d\n", rc);
1471 debug_tcp("resent data digest 0x%x fail!\n", 1466 tcp_ctask->xmstate |= XMSTATE_W_RESEND_PAD;
1472 tcp_ctask->datadigest);
1473 } 1467 }
1474
1475 return rc; 1468 return rc;
1476} 1469}
1477 1470
1478static inline int 1471static int
1479handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1472iscsi_send_digest(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1473 struct iscsi_buf *buf, uint32_t *digest)
1480{ 1474{
1481 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1475 struct iscsi_tcp_cmd_task *tcp_ctask;
1482 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 1476 struct iscsi_tcp_conn *tcp_conn;
1483 int rc; 1477 int rc, sent = 0;
1484 1478
1485 BUG_ON(!ctask->imm_count); 1479 if (!conn->datadgst_en)
1486 tcp_ctask->xmstate &= ~XMSTATE_IMM_DATA; 1480 return 0;
1487 1481
1488 if (conn->datadgst_en) { 1482 tcp_ctask = ctask->dd_data;
1489 iscsi_data_digest_init(tcp_conn, ctask); 1483 tcp_conn = conn->dd_data;
1490 tcp_ctask->immdigest = 0;
1491 }
1492 1484
1493 for (;;) { 1485 if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_DATA_DIGEST)) {
1494 rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, 1486 crypto_hash_final(&tcp_conn->tx_hash, (u8*)digest);
1495 &ctask->imm_count, &tcp_ctask->sent); 1487 iscsi_buf_init_iov(buf, (char*)digest, 4);
1496 if (rc) { 1488 }
1497 tcp_ctask->xmstate |= XMSTATE_IMM_DATA; 1489 tcp_ctask->xmstate &= ~XMSTATE_W_RESEND_DATA_DIGEST;
1498 if (conn->datadgst_en) {
1499 crypto_hash_final(&tcp_conn->data_tx_hash,
1500 (u8 *)&tcp_ctask->immdigest);
1501 debug_tcp("tx imm sendpage fail 0x%x\n",
1502 tcp_ctask->datadigest);
1503 }
1504 return rc;
1505 }
1506 if (conn->datadgst_en)
1507 crypto_hash_update(&tcp_conn->data_tx_hash,
1508 &tcp_ctask->sendbuf.sg,
1509 tcp_ctask->sendbuf.sg.length);
1510 1490
1511 if (!ctask->imm_count) 1491 rc = iscsi_sendpage(conn, buf, &tcp_ctask->digest_count, &sent);
1512 break; 1492 if (!rc)
1513 iscsi_buf_init_sg(&tcp_ctask->sendbuf, 1493 debug_scsi("sent digest 0x%x for itt 0x%x\n", *digest,
1514 &tcp_ctask->sg[tcp_ctask->sg_count++]); 1494 ctask->itt);
1495 else {
1496 debug_scsi("sending digest 0x%x failed for itt 0x%x!\n",
1497 *digest, ctask->itt);
1498 tcp_ctask->xmstate |= XMSTATE_W_RESEND_DATA_DIGEST;
1515 } 1499 }
1500 return rc;
1501}
1516 1502
1517 if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) { 1503static int
1518 rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf, 1504iscsi_send_data(struct iscsi_cmd_task *ctask, struct iscsi_buf *sendbuf,
1519 &tcp_ctask->immdigest, 1); 1505 struct scatterlist **sg, int *sent, int *count,
1520 if (rc) { 1506 struct iscsi_buf *digestbuf, uint32_t *digest)
1521 debug_tcp("sending imm digest 0x%x fail!\n", 1507{
1522 tcp_ctask->immdigest); 1508 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1523 return rc; 1509 struct iscsi_conn *conn = ctask->conn;
1510 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1511 int rc, buf_sent, offset;
1512
1513 while (*count) {
1514 buf_sent = 0;
1515 offset = sendbuf->sent;
1516
1517 rc = iscsi_sendpage(conn, sendbuf, count, &buf_sent);
1518 *sent = *sent + buf_sent;
1519 if (buf_sent && conn->datadgst_en)
1520 partial_sg_digest_update(&tcp_conn->tx_hash,
1521 &sendbuf->sg, sendbuf->sg.offset + offset,
1522 buf_sent);
1523 if (!iscsi_buf_left(sendbuf) && *sg != tcp_ctask->bad_sg) {
1524 iscsi_buf_init_sg(sendbuf, *sg);
1525 *sg = *sg + 1;
1524 } 1526 }
1525 debug_tcp("sending imm digest 0x%x\n", tcp_ctask->immdigest); 1527
1528 if (rc)
1529 return rc;
1526 } 1530 }
1527 1531
1528 return 0; 1532 rc = iscsi_send_padding(conn, ctask);
1533 if (rc)
1534 return rc;
1535
1536 return iscsi_send_digest(conn, ctask, digestbuf, digest);
1529} 1537}
1530 1538
1531static inline int 1539static int
1532handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1540iscsi_send_unsol_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1533{ 1541{
1534 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1542 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1535 struct iscsi_data_task *dtask; 1543 struct iscsi_data_task *dtask;
@@ -1537,12 +1545,17 @@ handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1537 1545
1538 tcp_ctask->xmstate |= XMSTATE_UNS_DATA; 1546 tcp_ctask->xmstate |= XMSTATE_UNS_DATA;
1539 if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) { 1547 if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) {
1540 iscsi_unsolicit_data_init(conn, ctask); 1548 dtask = &tcp_ctask->unsol_dtask;
1541 dtask = tcp_ctask->dtask; 1549
1550 iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr);
1551 iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr,
1552 sizeof(struct iscsi_hdr));
1542 if (conn->hdrdgst_en) 1553 if (conn->hdrdgst_en)
1543 iscsi_hdr_digest(conn, &tcp_ctask->headbuf, 1554 iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
1544 (u8*)dtask->hdrext); 1555 (u8*)dtask->hdrext);
1556
1545 tcp_ctask->xmstate &= ~XMSTATE_UNS_INIT; 1557 tcp_ctask->xmstate &= ~XMSTATE_UNS_INIT;
1558 iscsi_set_padding(tcp_ctask, ctask->data_count);
1546 } 1559 }
1547 1560
1548 rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->data_count); 1561 rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->data_count);
@@ -1552,256 +1565,138 @@ handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1552 return rc; 1565 return rc;
1553 } 1566 }
1554 1567
1568 if (conn->datadgst_en) {
1569 dtask = &tcp_ctask->unsol_dtask;
1570 iscsi_data_digest_init(ctask->conn->dd_data, tcp_ctask);
1571 dtask->digest = 0;
1572 }
1573
1555 debug_scsi("uns dout [itt 0x%x dlen %d sent %d]\n", 1574 debug_scsi("uns dout [itt 0x%x dlen %d sent %d]\n",
1556 ctask->itt, ctask->unsol_count, tcp_ctask->sent); 1575 ctask->itt, ctask->unsol_count, tcp_ctask->sent);
1557 return 0; 1576 return 0;
1558} 1577}
1559 1578
1560static inline int 1579static int
1561handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1580iscsi_send_unsol_pdu(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1562{ 1581{
1563 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1582 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1564 struct iscsi_data_task *dtask = tcp_ctask->dtask;
1565 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1566 int rc; 1583 int rc;
1567 1584
1568 BUG_ON(!ctask->data_count); 1585 if (tcp_ctask->xmstate & XMSTATE_UNS_HDR) {
1569 tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA; 1586 BUG_ON(!ctask->unsol_count);
1570 1587 tcp_ctask->xmstate &= ~XMSTATE_UNS_HDR;
1571 if (conn->datadgst_en) { 1588send_hdr:
1572 iscsi_data_digest_init(tcp_conn, ctask); 1589 rc = iscsi_send_unsol_hdr(conn, ctask);
1573 dtask->digest = 0; 1590 if (rc)
1591 return rc;
1574 } 1592 }
1575 1593
1576 for (;;) { 1594 if (tcp_ctask->xmstate & XMSTATE_UNS_DATA) {
1595 struct iscsi_data_task *dtask = &tcp_ctask->unsol_dtask;
1577 int start = tcp_ctask->sent; 1596 int start = tcp_ctask->sent;
1578 1597
1579 rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, 1598 rc = iscsi_send_data(ctask, &tcp_ctask->sendbuf, &tcp_ctask->sg,
1580 &ctask->data_count, &tcp_ctask->sent); 1599 &tcp_ctask->sent, &ctask->data_count,
1581 if (rc) { 1600 &dtask->digestbuf, &dtask->digest);
1582 ctask->unsol_count -= tcp_ctask->sent - start;
1583 tcp_ctask->xmstate |= XMSTATE_UNS_DATA;
1584 /* will continue with this ctask later.. */
1585 if (conn->datadgst_en) {
1586 crypto_hash_final(&tcp_conn->data_tx_hash,
1587 (u8 *)&dtask->digest);
1588 debug_tcp("tx uns data fail 0x%x\n",
1589 dtask->digest);
1590 }
1591 return rc;
1592 }
1593
1594 BUG_ON(tcp_ctask->sent > ctask->total_length);
1595 ctask->unsol_count -= tcp_ctask->sent - start; 1601 ctask->unsol_count -= tcp_ctask->sent - start;
1596 1602 if (rc)
1603 return rc;
1604 tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA;
1597 /* 1605 /*
1598 * XXX:we may run here with un-initial sendbuf. 1606 * Done with the Data-Out. Next, check if we need
1599 * so pass it 1607 * to send another unsolicited Data-Out.
1600 */ 1608 */
1601 if (conn->datadgst_en && tcp_ctask->sent - start > 0) 1609 if (ctask->unsol_count) {
1602 crypto_hash_update(&tcp_conn->data_tx_hash, 1610 debug_scsi("sending more uns\n");
1603 &tcp_ctask->sendbuf.sg, 1611 tcp_ctask->xmstate |= XMSTATE_UNS_INIT;
1604 tcp_ctask->sendbuf.sg.length); 1612 goto send_hdr;
1605
1606 if (!ctask->data_count)
1607 break;
1608 iscsi_buf_init_sg(&tcp_ctask->sendbuf,
1609 &tcp_ctask->sg[tcp_ctask->sg_count++]);
1610 }
1611 BUG_ON(ctask->unsol_count < 0);
1612
1613 /*
1614 * Done with the Data-Out. Next, check if we need
1615 * to send another unsolicited Data-Out.
1616 */
1617 if (ctask->unsol_count) {
1618 if (conn->datadgst_en) {
1619 rc = iscsi_digest_final_send(conn, ctask,
1620 &dtask->digestbuf,
1621 &dtask->digest, 1);
1622 if (rc) {
1623 debug_tcp("send uns digest 0x%x fail\n",
1624 dtask->digest);
1625 return rc;
1626 }
1627 debug_tcp("sending uns digest 0x%x, more uns\n",
1628 dtask->digest);
1629 } 1613 }
1630 tcp_ctask->xmstate |= XMSTATE_UNS_INIT;
1631 return 1;
1632 } 1614 }
1633
1634 if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) {
1635 rc = iscsi_digest_final_send(conn, ctask,
1636 &dtask->digestbuf,
1637 &dtask->digest, 1);
1638 if (rc) {
1639 debug_tcp("send last uns digest 0x%x fail\n",
1640 dtask->digest);
1641 return rc;
1642 }
1643 debug_tcp("sending uns digest 0x%x\n",dtask->digest);
1644 }
1645
1646 return 0; 1615 return 0;
1647} 1616}
1648 1617
1649static inline int 1618static int iscsi_send_sol_pdu(struct iscsi_conn *conn,
1650handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1619 struct iscsi_cmd_task *ctask)
1651{ 1620{
1652 struct iscsi_session *session = conn->session;
1653 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1654 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1621 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1655 struct iscsi_r2t_info *r2t = tcp_ctask->r2t; 1622 struct iscsi_session *session = conn->session;
1656 struct iscsi_data_task *dtask = &r2t->dtask; 1623 struct iscsi_r2t_info *r2t;
1624 struct iscsi_data_task *dtask;
1657 int left, rc; 1625 int left, rc;
1658 1626
1659 tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA; 1627 if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) {
1660 tcp_ctask->dtask = dtask; 1628 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1661
1662 if (conn->datadgst_en) {
1663 iscsi_data_digest_init(tcp_conn, ctask);
1664 dtask->digest = 0;
1665 }
1666solicit_again:
1667 /*
1668 * send Data-Out within this R2T sequence.
1669 */
1670 if (!r2t->data_count)
1671 goto data_out_done;
1672
1673 rc = iscsi_sendpage(conn, &r2t->sendbuf, &r2t->data_count, &r2t->sent);
1674 if (rc) {
1675 tcp_ctask->xmstate |= XMSTATE_SOL_DATA; 1629 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1676 /* will continue with this ctask later.. */ 1630 if (!tcp_ctask->r2t)
1677 if (conn->datadgst_en) { 1631 __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
1678 crypto_hash_final(&tcp_conn->data_tx_hash, 1632 sizeof(void*));
1679 (u8 *)&dtask->digest); 1633send_hdr:
1680 debug_tcp("r2t data send fail 0x%x\n", dtask->digest); 1634 r2t = tcp_ctask->r2t;
1681 } 1635 dtask = &r2t->dtask;
1682 return rc;
1683 }
1684 1636
1685 BUG_ON(r2t->data_count < 0); 1637 if (conn->hdrdgst_en)
1686 if (conn->datadgst_en) 1638 iscsi_hdr_digest(conn, &r2t->headbuf,
1687 crypto_hash_update(&tcp_conn->data_tx_hash, &r2t->sendbuf.sg, 1639 (u8*)dtask->hdrext);
1688 r2t->sendbuf.sg.length); 1640 rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count);
1689 1641 if (rc) {
1690 if (r2t->data_count) { 1642 tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA;
1691 BUG_ON(ctask->sc->use_sg == 0); 1643 tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
1692 if (!iscsi_buf_left(&r2t->sendbuf)) { 1644 return rc;
1693 BUG_ON(tcp_ctask->bad_sg == r2t->sg);
1694 iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg);
1695 r2t->sg += 1;
1696 } 1645 }
1697 goto solicit_again;
1698 }
1699 1646
1700data_out_done:
1701 /*
1702 * Done with this Data-Out. Next, check if we have
1703 * to send another Data-Out for this R2T.
1704 */
1705 BUG_ON(r2t->data_length - r2t->sent < 0);
1706 left = r2t->data_length - r2t->sent;
1707 if (left) {
1708 if (conn->datadgst_en) { 1647 if (conn->datadgst_en) {
1709 rc = iscsi_digest_final_send(conn, ctask, 1648 iscsi_data_digest_init(conn->dd_data, tcp_ctask);
1710 &dtask->digestbuf, 1649 dtask->digest = 0;
1711 &dtask->digest, 1);
1712 if (rc) {
1713 debug_tcp("send r2t data digest 0x%x"
1714 "fail\n", dtask->digest);
1715 return rc;
1716 }
1717 debug_tcp("r2t data send digest 0x%x\n",
1718 dtask->digest);
1719 }
1720 iscsi_solicit_data_cont(conn, ctask, r2t, left);
1721 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1722 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1723 return 1;
1724 }
1725
1726 /*
1727 * Done with this R2T. Check if there are more
1728 * outstanding R2Ts ready to be processed.
1729 */
1730 BUG_ON(tcp_ctask->r2t_data_count - r2t->data_length < 0);
1731 if (conn->datadgst_en) {
1732 rc = iscsi_digest_final_send(conn, ctask, &dtask->digestbuf,
1733 &dtask->digest, 1);
1734 if (rc) {
1735 debug_tcp("send last r2t data digest 0x%x"
1736 "fail\n", dtask->digest);
1737 return rc;
1738 } 1650 }
1739 debug_tcp("r2t done dout digest 0x%x\n", dtask->digest);
1740 }
1741 1651
1742 tcp_ctask->r2t_data_count -= r2t->data_length; 1652 iscsi_set_padding(tcp_ctask, r2t->data_count);
1743 tcp_ctask->r2t = NULL; 1653 debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n",
1744 spin_lock_bh(&session->lock); 1654 r2t->solicit_datasn - 1, ctask->itt, r2t->data_count,
1745 __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); 1655 r2t->sent);
1746 spin_unlock_bh(&session->lock);
1747 if (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) {
1748 tcp_ctask->r2t = r2t;
1749 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1750 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1751 return 1;
1752 } 1656 }
1753 1657
1754 return 0; 1658 if (tcp_ctask->xmstate & XMSTATE_SOL_DATA) {
1755} 1659 r2t = tcp_ctask->r2t;
1660 dtask = &r2t->dtask;
1756 1661
1757static inline int 1662 rc = iscsi_send_data(ctask, &r2t->sendbuf, &r2t->sg,
1758handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1663 &r2t->sent, &r2t->data_count,
1759{ 1664 &dtask->digestbuf, &dtask->digest);
1760 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1665 if (rc)
1761 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 1666 return rc;
1762 struct iscsi_data_task *dtask = tcp_ctask->dtask; 1667 tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA;
1763 int sent = 0, rc;
1764 1668
1765 tcp_ctask->xmstate &= ~XMSTATE_W_PAD; 1669 /*
1766 iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad, 1670 * Done with this Data-Out. Next, check if we have
1767 tcp_ctask->pad_count); 1671 * to send another Data-Out for this R2T.
1768 rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, &tcp_ctask->pad_count, 1672 */
1769 &sent); 1673 BUG_ON(r2t->data_length - r2t->sent < 0);
1770 if (rc) { 1674 left = r2t->data_length - r2t->sent;
1771 tcp_ctask->xmstate |= XMSTATE_W_PAD; 1675 if (left) {
1772 return rc; 1676 iscsi_solicit_data_cont(conn, ctask, r2t, left);
1773 } 1677 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1678 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1679 goto send_hdr;
1680 }
1774 1681
1775 if (conn->datadgst_en) { 1682 /*
1776 crypto_hash_update(&tcp_conn->data_tx_hash, 1683 * Done with this R2T. Check if there are more
1777 &tcp_ctask->sendbuf.sg, 1684 * outstanding R2Ts ready to be processed.
1778 tcp_ctask->sendbuf.sg.length); 1685 */
1779 /* imm data? */ 1686 spin_lock_bh(&session->lock);
1780 if (!dtask) { 1687 tcp_ctask->r2t = NULL;
1781 rc = iscsi_digest_final_send(conn, ctask, 1688 __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
1782 &tcp_ctask->immbuf, 1689 sizeof(void*));
1783 &tcp_ctask->immdigest, 1); 1690 if (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t,
1784 if (rc) { 1691 sizeof(void*))) {
1785 debug_tcp("send padding digest 0x%x" 1692 tcp_ctask->r2t = r2t;
1786 "fail!\n", tcp_ctask->immdigest); 1693 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1787 return rc; 1694 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1788 } 1695 spin_unlock_bh(&session->lock);
1789 debug_tcp("done with padding, digest 0x%x\n", 1696 goto send_hdr;
1790 tcp_ctask->datadigest);
1791 } else {
1792 rc = iscsi_digest_final_send(conn, ctask,
1793 &dtask->digestbuf,
1794 &dtask->digest, 1);
1795 if (rc) {
1796 debug_tcp("send padding digest 0x%x"
1797 "fail\n", dtask->digest);
1798 return rc;
1799 }
1800 debug_tcp("done with padding, digest 0x%x\n",
1801 dtask->digest);
1802 } 1697 }
1698 spin_unlock_bh(&session->lock);
1803 } 1699 }
1804
1805 return 0; 1700 return 0;
1806} 1701}
1807 1702
@@ -1821,85 +1716,30 @@ iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1821 return rc; 1716 return rc;
1822 1717
1823 if (tcp_ctask->xmstate & XMSTATE_R_HDR) 1718 if (tcp_ctask->xmstate & XMSTATE_R_HDR)
1824 return handle_xmstate_r_hdr(conn, tcp_ctask); 1719 return iscsi_send_read_hdr(conn, tcp_ctask);
1825 1720
1826 if (tcp_ctask->xmstate & XMSTATE_W_HDR) { 1721 if (tcp_ctask->xmstate & XMSTATE_W_HDR) {
1827 rc = handle_xmstate_w_hdr(conn, ctask); 1722 rc = iscsi_send_write_hdr(conn, ctask);
1828 if (rc)
1829 return rc;
1830 }
1831
1832 /* XXX: for data digest xmit recover */
1833 if (tcp_ctask->xmstate & XMSTATE_DATA_DIGEST) {
1834 rc = handle_xmstate_data_digest(conn, ctask);
1835 if (rc) 1723 if (rc)
1836 return rc; 1724 return rc;
1837 } 1725 }
1838 1726
1839 if (tcp_ctask->xmstate & XMSTATE_IMM_DATA) { 1727 if (tcp_ctask->xmstate & XMSTATE_IMM_DATA) {
1840 rc = handle_xmstate_imm_data(conn, ctask); 1728 rc = iscsi_send_data(ctask, &tcp_ctask->sendbuf, &tcp_ctask->sg,
1729 &tcp_ctask->sent, &ctask->imm_count,
1730 &tcp_ctask->immbuf, &tcp_ctask->immdigest);
1841 if (rc) 1731 if (rc)
1842 return rc; 1732 return rc;
1733 tcp_ctask->xmstate &= ~XMSTATE_IMM_DATA;
1843 } 1734 }
1844 1735
1845 if (tcp_ctask->xmstate & XMSTATE_UNS_HDR) { 1736 rc = iscsi_send_unsol_pdu(conn, ctask);
1846 BUG_ON(!ctask->unsol_count); 1737 if (rc)
1847 tcp_ctask->xmstate &= ~XMSTATE_UNS_HDR; 1738 return rc;
1848unsolicit_head_again:
1849 rc = handle_xmstate_uns_hdr(conn, ctask);
1850 if (rc)
1851 return rc;
1852 }
1853
1854 if (tcp_ctask->xmstate & XMSTATE_UNS_DATA) {
1855 rc = handle_xmstate_uns_data(conn, ctask);
1856 if (rc == 1)
1857 goto unsolicit_head_again;
1858 else if (rc)
1859 return rc;
1860 goto done;
1861 }
1862
1863 if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) {
1864 struct iscsi_r2t_info *r2t;
1865
1866 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1867 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1868 if (!tcp_ctask->r2t)
1869 __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
1870 sizeof(void*));
1871solicit_head_again:
1872 r2t = tcp_ctask->r2t;
1873 if (conn->hdrdgst_en)
1874 iscsi_hdr_digest(conn, &r2t->headbuf,
1875 (u8*)r2t->dtask.hdrext);
1876 rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count);
1877 if (rc) {
1878 tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA;
1879 tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
1880 return rc;
1881 }
1882
1883 debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n",
1884 r2t->solicit_datasn - 1, ctask->itt, r2t->data_count,
1885 r2t->sent);
1886 }
1887
1888 if (tcp_ctask->xmstate & XMSTATE_SOL_DATA) {
1889 rc = handle_xmstate_sol_data(conn, ctask);
1890 if (rc == 1)
1891 goto solicit_head_again;
1892 if (rc)
1893 return rc;
1894 }
1895 1739
1896done: 1740 rc = iscsi_send_sol_pdu(conn, ctask);
1897 /* 1741 if (rc)
1898 * Last thing to check is whether we need to send write 1742 return rc;
1899 * padding. Note that we check for xmstate equality, not just the bit.
1900 */
1901 if (tcp_ctask->xmstate == XMSTATE_W_PAD)
1902 rc = handle_xmstate_w_pad(conn, ctask);
1903 1743
1904 return rc; 1744 return rc;
1905} 1745}
@@ -1931,8 +1771,24 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
1931 /* initial operational parameters */ 1771 /* initial operational parameters */
1932 tcp_conn->hdr_size = sizeof(struct iscsi_hdr); 1772 tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
1933 1773
1774 tcp_conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0,
1775 CRYPTO_ALG_ASYNC);
1776 tcp_conn->tx_hash.flags = 0;
1777 if (!tcp_conn->tx_hash.tfm)
1778 goto free_tcp_conn;
1779
1780 tcp_conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0,
1781 CRYPTO_ALG_ASYNC);
1782 tcp_conn->rx_hash.flags = 0;
1783 if (!tcp_conn->rx_hash.tfm)
1784 goto free_tx_tfm;
1785
1934 return cls_conn; 1786 return cls_conn;
1935 1787
1788free_tx_tfm:
1789 crypto_free_hash(tcp_conn->tx_hash.tfm);
1790free_tcp_conn:
1791 kfree(tcp_conn);
1936tcp_conn_alloc_fail: 1792tcp_conn_alloc_fail:
1937 iscsi_conn_teardown(cls_conn); 1793 iscsi_conn_teardown(cls_conn);
1938 return NULL; 1794 return NULL;
@@ -1970,14 +1826,10 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn)
1970 1826
1971 /* now free tcp_conn */ 1827 /* now free tcp_conn */
1972 if (digest) { 1828 if (digest) {
1973 if (tcp_conn->tx_tfm) 1829 if (tcp_conn->tx_hash.tfm)
1974 crypto_free_hash(tcp_conn->tx_tfm); 1830 crypto_free_hash(tcp_conn->tx_hash.tfm);
1975 if (tcp_conn->rx_tfm) 1831 if (tcp_conn->rx_hash.tfm)
1976 crypto_free_hash(tcp_conn->rx_tfm); 1832 crypto_free_hash(tcp_conn->rx_hash.tfm);
1977 if (tcp_conn->data_tx_hash.tfm)
1978 crypto_free_hash(tcp_conn->data_tx_hash.tfm);
1979 if (tcp_conn->data_rx_hash.tfm)
1980 crypto_free_hash(tcp_conn->data_rx_hash.tfm);
1981 } 1833 }
1982 1834
1983 kfree(tcp_conn); 1835 kfree(tcp_conn);
@@ -1987,9 +1839,11 @@ static void
1987iscsi_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) 1839iscsi_tcp_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
1988{ 1840{
1989 struct iscsi_conn *conn = cls_conn->dd_data; 1841 struct iscsi_conn *conn = cls_conn->dd_data;
1842 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1990 1843
1991 iscsi_conn_stop(cls_conn, flag); 1844 iscsi_conn_stop(cls_conn, flag);
1992 iscsi_tcp_release_conn(conn); 1845 iscsi_tcp_release_conn(conn);
1846 tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
1993} 1847}
1994 1848
1995static int 1849static int
@@ -2135,52 +1989,11 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param,
2135 case ISCSI_PARAM_HDRDGST_EN: 1989 case ISCSI_PARAM_HDRDGST_EN:
2136 iscsi_set_param(cls_conn, param, buf, buflen); 1990 iscsi_set_param(cls_conn, param, buf, buflen);
2137 tcp_conn->hdr_size = sizeof(struct iscsi_hdr); 1991 tcp_conn->hdr_size = sizeof(struct iscsi_hdr);
2138 if (conn->hdrdgst_en) { 1992 if (conn->hdrdgst_en)
2139 tcp_conn->hdr_size += sizeof(__u32); 1993 tcp_conn->hdr_size += sizeof(__u32);
2140 if (!tcp_conn->tx_tfm)
2141 tcp_conn->tx_tfm =
2142 crypto_alloc_hash("crc32c", 0,
2143 CRYPTO_ALG_ASYNC);
2144 if (IS_ERR(tcp_conn->tx_tfm))
2145 return PTR_ERR(tcp_conn->tx_tfm);
2146 if (!tcp_conn->rx_tfm)
2147 tcp_conn->rx_tfm =
2148 crypto_alloc_hash("crc32c", 0,
2149 CRYPTO_ALG_ASYNC);
2150 if (IS_ERR(tcp_conn->rx_tfm)) {
2151 crypto_free_hash(tcp_conn->tx_tfm);
2152 return PTR_ERR(tcp_conn->rx_tfm);
2153 }
2154 } else {
2155 if (tcp_conn->tx_tfm)
2156 crypto_free_hash(tcp_conn->tx_tfm);
2157 if (tcp_conn->rx_tfm)
2158 crypto_free_hash(tcp_conn->rx_tfm);
2159 }
2160 break; 1994 break;
2161 case ISCSI_PARAM_DATADGST_EN: 1995 case ISCSI_PARAM_DATADGST_EN:
2162 iscsi_set_param(cls_conn, param, buf, buflen); 1996 iscsi_set_param(cls_conn, param, buf, buflen);
2163 if (conn->datadgst_en) {
2164 if (!tcp_conn->data_tx_hash.tfm)
2165 tcp_conn->data_tx_hash.tfm =
2166 crypto_alloc_hash("crc32c", 0,
2167 CRYPTO_ALG_ASYNC);
2168 if (IS_ERR(tcp_conn->data_tx_hash.tfm))
2169 return PTR_ERR(tcp_conn->data_tx_hash.tfm);
2170 if (!tcp_conn->data_rx_hash.tfm)
2171 tcp_conn->data_rx_hash.tfm =
2172 crypto_alloc_hash("crc32c", 0,
2173 CRYPTO_ALG_ASYNC);
2174 if (IS_ERR(tcp_conn->data_rx_hash.tfm)) {
2175 crypto_free_hash(tcp_conn->data_tx_hash.tfm);
2176 return PTR_ERR(tcp_conn->data_rx_hash.tfm);
2177 }
2178 } else {
2179 if (tcp_conn->data_tx_hash.tfm)
2180 crypto_free_hash(tcp_conn->data_tx_hash.tfm);
2181 if (tcp_conn->data_rx_hash.tfm)
2182 crypto_free_hash(tcp_conn->data_rx_hash.tfm);
2183 }
2184 tcp_conn->sendpage = conn->datadgst_en ? 1997 tcp_conn->sendpage = conn->datadgst_en ?
2185 sock_no_sendpage : tcp_conn->sock->ops->sendpage; 1998 sock_no_sendpage : tcp_conn->sock->ops->sendpage;
2186 break; 1999 break;