aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/iscsi_tcp.c636
-rw-r--r--drivers/scsi/iscsi_tcp.h33
-rw-r--r--drivers/scsi/libiscsi.c37
3 files changed, 286 insertions, 420 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index d6927f1a6b65..290c1d76cd40 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -281,7 +281,6 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
281{ 281{
282 struct iscsi_data *hdr; 282 struct iscsi_data *hdr;
283 struct scsi_cmnd *sc = ctask->sc; 283 struct scsi_cmnd *sc = ctask->sc;
284 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
285 284
286 hdr = &r2t->dtask.hdr; 285 hdr = &r2t->dtask.hdr;
287 memset(hdr, 0, sizeof(struct iscsi_data)); 286 memset(hdr, 0, sizeof(struct iscsi_data));
@@ -336,10 +335,12 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
336 sg_count += sg->length; 335 sg_count += sg->length;
337 } 336 }
338 BUG_ON(r2t->sg == NULL); 337 BUG_ON(r2t->sg == NULL);
339 } else 338 } else {
340 iscsi_buf_init_iov(&tcp_ctask->sendbuf, 339 iscsi_buf_init_iov(&r2t->sendbuf,
341 (char*)sc->request_buffer + r2t->data_offset, 340 (char*)sc->request_buffer + r2t->data_offset,
342 r2t->data_count); 341 r2t->data_count);
342 r2t->sg = NULL;
343 }
343} 344}
344 345
345/** 346/**
@@ -503,7 +504,6 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn)
503 goto copy_hdr; 504 goto copy_hdr;
504 505
505 spin_lock(&session->lock); 506 spin_lock(&session->lock);
506 iscsi_tcp_cleanup_ctask(conn, tcp_conn->in.ctask);
507 rc = __iscsi_complete_pdu(conn, hdr, NULL, 0); 507 rc = __iscsi_complete_pdu(conn, hdr, NULL, 0);
508 spin_unlock(&session->lock); 508 spin_unlock(&session->lock);
509 break; 509 break;
@@ -676,15 +676,15 @@ iscsi_tcp_copy(struct iscsi_conn *conn)
676} 676}
677 677
678static inline void 678static inline void
679partial_sg_digest_update(struct iscsi_tcp_conn *tcp_conn, 679partial_sg_digest_update(struct crypto_tfm *tfm, struct scatterlist *sg,
680 struct scatterlist *sg, int offset, int length) 680 int offset, int length)
681{ 681{
682 struct scatterlist temp; 682 struct scatterlist temp;
683 683
684 memcpy(&temp, sg, sizeof(struct scatterlist)); 684 memcpy(&temp, sg, sizeof(struct scatterlist));
685 temp.offset = offset; 685 temp.offset = offset;
686 temp.length = length; 686 temp.length = length;
687 crypto_digest_update(tcp_conn->data_rx_tfm, &temp, 1); 687 crypto_digest_update(tfm, &temp, 1);
688} 688}
689 689
690static void 690static void
@@ -751,7 +751,8 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
751 tcp_conn->data_rx_tfm, 751 tcp_conn->data_rx_tfm,
752 &sg[i], 1); 752 &sg[i], 1);
753 else 753 else
754 partial_sg_digest_update(tcp_conn, 754 partial_sg_digest_update(
755 tcp_conn->data_rx_tfm,
755 &sg[i], 756 &sg[i],
756 sg[i].offset + offset, 757 sg[i].offset + offset,
757 sg[i].length - offset); 758 sg[i].length - offset);
@@ -765,7 +766,8 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
765 /* 766 /*
766 * data-in is complete, but buffer not... 767 * data-in is complete, but buffer not...
767 */ 768 */
768 partial_sg_digest_update(tcp_conn, &sg[i], 769 partial_sg_digest_update(tcp_conn->data_rx_tfm,
770 &sg[i],
769 sg[i].offset, sg[i].length-rc); 771 sg[i].offset, sg[i].length-rc);
770 rc = 0; 772 rc = 0;
771 break; 773 break;
@@ -783,7 +785,6 @@ done:
783 (long)sc, sc->result, ctask->itt, 785 (long)sc, sc->result, ctask->itt,
784 tcp_conn->in.hdr->flags); 786 tcp_conn->in.hdr->flags);
785 spin_lock(&conn->session->lock); 787 spin_lock(&conn->session->lock);
786 iscsi_tcp_cleanup_ctask(conn, ctask);
787 __iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0); 788 __iscsi_complete_pdu(conn, tcp_conn->in.hdr, NULL, 0);
788 spin_unlock(&conn->session->lock); 789 spin_unlock(&conn->session->lock);
789 } 790 }
@@ -803,9 +804,6 @@ iscsi_data_recv(struct iscsi_conn *conn)
803 rc = iscsi_scsi_data_in(conn); 804 rc = iscsi_scsi_data_in(conn);
804 break; 805 break;
805 case ISCSI_OP_SCSI_CMD_RSP: 806 case ISCSI_OP_SCSI_CMD_RSP:
806 spin_lock(&conn->session->lock);
807 iscsi_tcp_cleanup_ctask(conn, tcp_conn->in.ctask);
808 spin_unlock(&conn->session->lock);
809 case ISCSI_OP_TEXT_RSP: 807 case ISCSI_OP_TEXT_RSP:
810 case ISCSI_OP_LOGIN_RSP: 808 case ISCSI_OP_LOGIN_RSP:
811 case ISCSI_OP_ASYNC_EVENT: 809 case ISCSI_OP_ASYNC_EVENT:
@@ -1188,37 +1186,12 @@ iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf,
1188 1186
1189static inline void 1187static inline void
1190iscsi_data_digest_init(struct iscsi_tcp_conn *tcp_conn, 1188iscsi_data_digest_init(struct iscsi_tcp_conn *tcp_conn,
1191 struct iscsi_cmd_task *ctask) 1189 struct iscsi_tcp_cmd_task *tcp_ctask)
1192{ 1190{
1193 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1194
1195 BUG_ON(!tcp_conn->data_tx_tfm);
1196 crypto_digest_init(tcp_conn->data_tx_tfm); 1191 crypto_digest_init(tcp_conn->data_tx_tfm);
1197 tcp_ctask->digest_count = 4; 1192 tcp_ctask->digest_count = 4;
1198} 1193}
1199 1194
1200static int
1201iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1202 struct iscsi_buf *buf, uint32_t *digest, int final)
1203{
1204 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1205 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1206 int rc = 0;
1207 int sent = 0;
1208
1209 if (final)
1210 crypto_digest_final(tcp_conn->data_tx_tfm, (u8*)digest);
1211
1212 iscsi_buf_init_iov(buf, (char*)digest, 4);
1213 rc = iscsi_sendpage(conn, buf, &tcp_ctask->digest_count, &sent);
1214 if (rc) {
1215 tcp_ctask->datadigest = *digest;
1216 tcp_ctask->xmstate |= XMSTATE_DATA_DIGEST;
1217 } else
1218 tcp_ctask->digest_count = 4;
1219 return rc;
1220}
1221
1222/** 1195/**
1223 * iscsi_solicit_data_cont - initialize next Data-Out 1196 * iscsi_solicit_data_cont - initialize next Data-Out
1224 * @conn: iscsi connection 1197 * @conn: iscsi connection
@@ -1236,7 +1209,6 @@ static void
1236iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, 1209iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1237 struct iscsi_r2t_info *r2t, int left) 1210 struct iscsi_r2t_info *r2t, int left)
1238{ 1211{
1239 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1240 struct iscsi_data *hdr; 1212 struct iscsi_data *hdr;
1241 struct scsi_cmnd *sc = ctask->sc; 1213 struct scsi_cmnd *sc = ctask->sc;
1242 int new_offset; 1214 int new_offset;
@@ -1265,14 +1237,30 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1265 iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr, 1237 iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr,
1266 sizeof(struct iscsi_hdr)); 1238 sizeof(struct iscsi_hdr));
1267 1239
1268 if (sc->use_sg && !iscsi_buf_left(&r2t->sendbuf)) { 1240 if (iscsi_buf_left(&r2t->sendbuf))
1269 BUG_ON(tcp_ctask->bad_sg == r2t->sg); 1241 return;
1242
1243 if (sc->use_sg) {
1270 iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg); 1244 iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg);
1271 r2t->sg += 1; 1245 r2t->sg += 1;
1272 } else 1246 } else {
1273 iscsi_buf_init_iov(&tcp_ctask->sendbuf, 1247 iscsi_buf_init_iov(&r2t->sendbuf,
1274 (char*)sc->request_buffer + new_offset, 1248 (char*)sc->request_buffer + new_offset,
1275 r2t->data_count); 1249 r2t->data_count);
1250 r2t->sg = NULL;
1251 }
1252}
1253
1254static void iscsi_set_padding(struct iscsi_tcp_cmd_task *tcp_ctask,
1255 unsigned long len)
1256{
1257 tcp_ctask->pad_count = len & (ISCSI_PAD_LEN - 1);
1258 if (!tcp_ctask->pad_count)
1259 return;
1260
1261 tcp_ctask->pad_count = ISCSI_PAD_LEN - tcp_ctask->pad_count;
1262 debug_scsi("write padding %d bytes\n", tcp_ctask->pad_count);
1263 tcp_ctask->xmstate |= XMSTATE_W_PAD;
1276} 1264}
1277 1265
1278/** 1266/**
@@ -1300,31 +1288,16 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
1300 if (sc->use_sg) { 1288 if (sc->use_sg) {
1301 struct scatterlist *sg = sc->request_buffer; 1289 struct scatterlist *sg = sc->request_buffer;
1302 1290
1303 iscsi_buf_init_sg(&tcp_ctask->sendbuf, 1291 iscsi_buf_init_sg(&tcp_ctask->sendbuf, sg);
1304 &sg[tcp_ctask->sg_count++]); 1292 tcp_ctask->sg = sg + 1;
1305 tcp_ctask->sg = sg;
1306 tcp_ctask->bad_sg = sg + sc->use_sg; 1293 tcp_ctask->bad_sg = sg + sc->use_sg;
1307 } else 1294 } else {
1308 iscsi_buf_init_iov(&tcp_ctask->sendbuf, 1295 iscsi_buf_init_iov(&tcp_ctask->sendbuf,
1309 sc->request_buffer, 1296 sc->request_buffer,
1310 sc->request_bufflen); 1297 sc->request_bufflen);
1311 1298 tcp_ctask->sg = NULL;
1312 if (ctask->imm_count) 1299 tcp_ctask->bad_sg = NULL;
1313 tcp_ctask->xmstate |= XMSTATE_IMM_DATA;
1314
1315 tcp_ctask->pad_count = ctask->total_length & (ISCSI_PAD_LEN-1);
1316 if (tcp_ctask->pad_count) {
1317 tcp_ctask->pad_count = ISCSI_PAD_LEN -
1318 tcp_ctask->pad_count;
1319 debug_scsi("write padding %d bytes\n",
1320 tcp_ctask->pad_count);
1321 tcp_ctask->xmstate |= XMSTATE_W_PAD;
1322 } 1300 }
1323
1324 if (ctask->unsol_count)
1325 tcp_ctask->xmstate |= XMSTATE_UNS_HDR |
1326 XMSTATE_UNS_INIT;
1327
1328 debug_scsi("cmd [itt 0x%x total %d imm_data %d " 1301 debug_scsi("cmd [itt 0x%x total %d imm_data %d "
1329 "unsol count %d, unsol offset %d]\n", 1302 "unsol count %d, unsol offset %d]\n",
1330 ctask->itt, ctask->total_length, ctask->imm_count, 1303 ctask->itt, ctask->total_length, ctask->imm_count,
@@ -1410,8 +1383,8 @@ iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
1410} 1383}
1411 1384
1412static inline int 1385static inline int
1413handle_xmstate_r_hdr(struct iscsi_conn *conn, 1386iscsi_send_read_hdr(struct iscsi_conn *conn,
1414 struct iscsi_tcp_cmd_task *tcp_ctask) 1387 struct iscsi_tcp_cmd_task *tcp_ctask)
1415{ 1388{
1416 int rc; 1389 int rc;
1417 1390
@@ -1429,7 +1402,7 @@ handle_xmstate_r_hdr(struct iscsi_conn *conn,
1429} 1402}
1430 1403
1431static inline int 1404static inline int
1432handle_xmstate_w_hdr(struct iscsi_conn *conn, 1405iscsi_send_write_hdr(struct iscsi_conn *conn,
1433 struct iscsi_cmd_task *ctask) 1406 struct iscsi_cmd_task *ctask)
1434{ 1407{
1435 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1408 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
@@ -1440,85 +1413,125 @@ handle_xmstate_w_hdr(struct iscsi_conn *conn,
1440 iscsi_hdr_digest(conn, &tcp_ctask->headbuf, 1413 iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
1441 (u8*)tcp_ctask->hdrext); 1414 (u8*)tcp_ctask->hdrext);
1442 rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count); 1415 rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count);
1443 if (rc) 1416 if (rc) {
1444 tcp_ctask->xmstate |= XMSTATE_W_HDR; 1417 tcp_ctask->xmstate |= XMSTATE_W_HDR;
1445 return rc; 1418 return rc;
1419 }
1420
1421 if (ctask->imm_count) {
1422 tcp_ctask->xmstate |= XMSTATE_IMM_DATA;
1423 iscsi_set_padding(tcp_ctask, ctask->imm_count);
1424
1425 if (ctask->conn->datadgst_en) {
1426 iscsi_data_digest_init(ctask->conn->dd_data, tcp_ctask);
1427 tcp_ctask->immdigest = 0;
1428 }
1429 }
1430
1431 if (ctask->unsol_count)
1432 tcp_ctask->xmstate |= XMSTATE_UNS_HDR | XMSTATE_UNS_INIT;
1433 return 0;
1446} 1434}
1447 1435
1448static inline int 1436static int
1449handle_xmstate_data_digest(struct iscsi_conn *conn, 1437iscsi_send_padding(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1450 struct iscsi_cmd_task *ctask)
1451{ 1438{
1452 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1439 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1453 int rc; 1440 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1441 int sent = 0, rc;
1454 1442
1455 tcp_ctask->xmstate &= ~XMSTATE_DATA_DIGEST; 1443 if (tcp_ctask->xmstate & XMSTATE_W_PAD) {
1456 debug_tcp("resent data digest 0x%x\n", tcp_ctask->datadigest); 1444 iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad,
1457 rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf, 1445 tcp_ctask->pad_count);
1458 &tcp_ctask->datadigest, 0); 1446 if (conn->datadgst_en)
1447 crypto_digest_update(tcp_conn->data_tx_tfm,
1448 &tcp_ctask->sendbuf.sg, 1);
1449 } else if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_PAD))
1450 return 0;
1451
1452 tcp_ctask->xmstate &= ~XMSTATE_W_PAD;
1453 tcp_ctask->xmstate &= ~XMSTATE_W_RESEND_PAD;
1454 debug_scsi("sending %d pad bytes for itt 0x%x\n",
1455 tcp_ctask->pad_count, ctask->itt);
1456 rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, &tcp_ctask->pad_count,
1457 &sent);
1459 if (rc) { 1458 if (rc) {
1460 tcp_ctask->xmstate |= XMSTATE_DATA_DIGEST; 1459 debug_scsi("padding send failed %d\n", rc);
1461 debug_tcp("resent data digest 0x%x fail!\n", 1460 tcp_ctask->xmstate |= XMSTATE_W_RESEND_PAD;
1462 tcp_ctask->datadigest);
1463 } 1461 }
1464
1465 return rc; 1462 return rc;
1466} 1463}
1467 1464
1468static inline int 1465static int
1469handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1466iscsi_send_digest(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1467 struct iscsi_buf *buf, uint32_t *digest)
1470{ 1468{
1471 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1469 struct iscsi_tcp_cmd_task *tcp_ctask;
1472 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 1470 struct iscsi_tcp_conn *tcp_conn;
1473 int rc; 1471 int rc, sent = 0;
1474 1472
1475 BUG_ON(!ctask->imm_count); 1473 if (!conn->datadgst_en)
1476 tcp_ctask->xmstate &= ~XMSTATE_IMM_DATA; 1474 return 0;
1477 1475
1478 if (conn->datadgst_en) { 1476 tcp_ctask = ctask->dd_data;
1479 iscsi_data_digest_init(tcp_conn, ctask); 1477 tcp_conn = conn->dd_data;
1480 tcp_ctask->immdigest = 0;
1481 }
1482 1478
1483 for (;;) { 1479 if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_DATA_DIGEST)) {
1484 rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, 1480 crypto_digest_final(tcp_conn->data_tx_tfm, (u8*)digest);
1485 &ctask->imm_count, &tcp_ctask->sent); 1481 iscsi_buf_init_iov(buf, (char*)digest, 4);
1486 if (rc) { 1482 }
1487 tcp_ctask->xmstate |= XMSTATE_IMM_DATA; 1483 tcp_ctask->xmstate &= ~XMSTATE_W_RESEND_DATA_DIGEST;
1488 if (conn->datadgst_en) {
1489 crypto_digest_final(tcp_conn->data_tx_tfm,
1490 (u8*)&tcp_ctask->immdigest);
1491 debug_tcp("tx imm sendpage fail 0x%x\n",
1492 tcp_ctask->datadigest);
1493 }
1494 return rc;
1495 }
1496 if (conn->datadgst_en)
1497 crypto_digest_update(tcp_conn->data_tx_tfm,
1498 &tcp_ctask->sendbuf.sg, 1);
1499 1484
1500 if (!ctask->imm_count) 1485 rc = iscsi_sendpage(conn, buf, &tcp_ctask->digest_count, &sent);
1501 break; 1486 if (!rc)
1502 iscsi_buf_init_sg(&tcp_ctask->sendbuf, 1487 debug_scsi("sent digest 0x%x for itt 0x%x\n", *digest,
1503 &tcp_ctask->sg[tcp_ctask->sg_count++]); 1488 ctask->itt);
1489 else {
1490 debug_scsi("sending digest 0x%x failed for itt 0x%x!\n",
1491 *digest, ctask->itt);
1492 tcp_ctask->xmstate |= XMSTATE_W_RESEND_DATA_DIGEST;
1504 } 1493 }
1494 return rc;
1495}
1505 1496
1506 if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) { 1497static int
1507 rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf, 1498iscsi_send_data(struct iscsi_cmd_task *ctask, struct iscsi_buf *sendbuf,
1508 &tcp_ctask->immdigest, 1); 1499 struct scatterlist **sg, int *sent, int *count,
1509 if (rc) { 1500 struct iscsi_buf *digestbuf, uint32_t *digest)
1510 debug_tcp("sending imm digest 0x%x fail!\n", 1501{
1511 tcp_ctask->immdigest); 1502 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1512 return rc; 1503 struct iscsi_conn *conn = ctask->conn;
1504 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1505 int rc, buf_sent, offset;
1506
1507 while (*count) {
1508 buf_sent = 0;
1509 offset = sendbuf->sent;
1510
1511 rc = iscsi_sendpage(conn, sendbuf, count, &buf_sent);
1512 *sent = *sent + buf_sent;
1513 if (buf_sent && conn->datadgst_en)
1514 partial_sg_digest_update(tcp_conn->data_tx_tfm,
1515 &sendbuf->sg, sendbuf->sg.offset + offset,
1516 buf_sent);
1517 if (!iscsi_buf_left(sendbuf) && *sg != tcp_ctask->bad_sg) {
1518 iscsi_buf_init_sg(sendbuf, *sg);
1519 *sg = *sg + 1;
1513 } 1520 }
1514 debug_tcp("sending imm digest 0x%x\n", tcp_ctask->immdigest); 1521
1522 if (rc)
1523 return rc;
1515 } 1524 }
1516 1525
1517 return 0; 1526 rc = iscsi_send_padding(conn, ctask);
1527 if (rc)
1528 return rc;
1529
1530 return iscsi_send_digest(conn, ctask, digestbuf, digest);
1518} 1531}
1519 1532
1520static inline int 1533static int
1521handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1534iscsi_send_unsol_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1522{ 1535{
1523 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1536 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1524 struct iscsi_data_task *dtask; 1537 struct iscsi_data_task *dtask;
@@ -1526,14 +1539,21 @@ handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1526 1539
1527 tcp_ctask->xmstate |= XMSTATE_UNS_DATA; 1540 tcp_ctask->xmstate |= XMSTATE_UNS_DATA;
1528 if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) { 1541 if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) {
1529 dtask = tcp_ctask->dtask = &tcp_ctask->unsol_dtask; 1542 dtask = &tcp_ctask->unsol_dtask;
1543
1530 iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr); 1544 iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr);
1531 iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr, 1545 iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr,
1532 sizeof(struct iscsi_hdr)); 1546 sizeof(struct iscsi_hdr));
1533 if (conn->hdrdgst_en) 1547 if (conn->hdrdgst_en)
1534 iscsi_hdr_digest(conn, &tcp_ctask->headbuf, 1548 iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
1535 (u8*)dtask->hdrext); 1549 (u8*)dtask->hdrext);
1550 if (conn->datadgst_en) {
1551 iscsi_data_digest_init(ctask->conn->dd_data, tcp_ctask);
1552 dtask->digest = 0;
1553 }
1554
1536 tcp_ctask->xmstate &= ~XMSTATE_UNS_INIT; 1555 tcp_ctask->xmstate &= ~XMSTATE_UNS_INIT;
1556 iscsi_set_padding(tcp_ctask, ctask->data_count);
1537 } 1557 }
1538 1558
1539 rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->data_count); 1559 rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->data_count);
@@ -1548,247 +1568,128 @@ handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1548 return 0; 1568 return 0;
1549} 1569}
1550 1570
1551static inline int 1571static int
1552handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1572iscsi_send_unsol_pdu(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1553{ 1573{
1554 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1574 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1555 struct iscsi_data_task *dtask = tcp_ctask->dtask;
1556 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1557 int rc; 1575 int rc;
1558 1576
1559 BUG_ON(!ctask->data_count); 1577 if (tcp_ctask->xmstate & XMSTATE_UNS_HDR) {
1560 tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA; 1578 BUG_ON(!ctask->unsol_count);
1561 1579 tcp_ctask->xmstate &= ~XMSTATE_UNS_HDR;
1562 if (conn->datadgst_en) { 1580send_hdr:
1563 iscsi_data_digest_init(tcp_conn, ctask); 1581 rc = iscsi_send_unsol_hdr(conn, ctask);
1564 dtask->digest = 0; 1582 if (rc)
1583 return rc;
1565 } 1584 }
1566 1585
1567 for (;;) { 1586 if (tcp_ctask->xmstate & XMSTATE_UNS_DATA) {
1587 struct iscsi_data_task *dtask = &tcp_ctask->unsol_dtask;
1568 int start = tcp_ctask->sent; 1588 int start = tcp_ctask->sent;
1569 1589
1570 rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, 1590 rc = iscsi_send_data(ctask, &tcp_ctask->sendbuf, &tcp_ctask->sg,
1571 &ctask->data_count, &tcp_ctask->sent); 1591 &tcp_ctask->sent, &ctask->data_count,
1572 if (rc) { 1592 &dtask->digestbuf, &dtask->digest);
1573 ctask->unsol_count -= tcp_ctask->sent - start;
1574 tcp_ctask->xmstate |= XMSTATE_UNS_DATA;
1575 /* will continue with this ctask later.. */
1576 if (conn->datadgst_en) {
1577 crypto_digest_final(tcp_conn->data_tx_tfm,
1578 (u8 *)&dtask->digest);
1579 debug_tcp("tx uns data fail 0x%x\n",
1580 dtask->digest);
1581 }
1582 return rc;
1583 }
1584
1585 BUG_ON(tcp_ctask->sent > ctask->total_length);
1586 ctask->unsol_count -= tcp_ctask->sent - start; 1593 ctask->unsol_count -= tcp_ctask->sent - start;
1587 1594 if (rc)
1595 return rc;
1596 tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA;
1588 /* 1597 /*
1589 * XXX:we may run here with un-initial sendbuf. 1598 * Done with the Data-Out. Next, check if we need
1590 * so pass it 1599 * to send another unsolicited Data-Out.
1591 */ 1600 */
1592 if (conn->datadgst_en && tcp_ctask->sent - start > 0) 1601 if (ctask->unsol_count) {
1593 crypto_digest_update(tcp_conn->data_tx_tfm, 1602 debug_scsi("sending more uns\n");
1594 &tcp_ctask->sendbuf.sg, 1); 1603 tcp_ctask->xmstate |= XMSTATE_UNS_INIT;
1595 1604 goto send_hdr;
1596 if (!ctask->data_count)
1597 break;
1598 iscsi_buf_init_sg(&tcp_ctask->sendbuf,
1599 &tcp_ctask->sg[tcp_ctask->sg_count++]);
1600 }
1601 BUG_ON(ctask->unsol_count < 0);
1602
1603 /*
1604 * Done with the Data-Out. Next, check if we need
1605 * to send another unsolicited Data-Out.
1606 */
1607 if (ctask->unsol_count) {
1608 if (conn->datadgst_en) {
1609 rc = iscsi_digest_final_send(conn, ctask,
1610 &dtask->digestbuf,
1611 &dtask->digest, 1);
1612 if (rc) {
1613 debug_tcp("send uns digest 0x%x fail\n",
1614 dtask->digest);
1615 return rc;
1616 }
1617 debug_tcp("sending uns digest 0x%x, more uns\n",
1618 dtask->digest);
1619 }
1620 tcp_ctask->xmstate |= XMSTATE_UNS_INIT;
1621 return 1;
1622 }
1623
1624 if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) {
1625 rc = iscsi_digest_final_send(conn, ctask,
1626 &dtask->digestbuf,
1627 &dtask->digest, 1);
1628 if (rc) {
1629 debug_tcp("send last uns digest 0x%x fail\n",
1630 dtask->digest);
1631 return rc;
1632 } 1605 }
1633 debug_tcp("sending uns digest 0x%x\n",dtask->digest);
1634 } 1606 }
1635
1636 return 0; 1607 return 0;
1637} 1608}
1638 1609
1639static inline int 1610static int iscsi_send_sol_pdu(struct iscsi_conn *conn,
1640handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1611 struct iscsi_cmd_task *ctask)
1641{ 1612{
1642 struct iscsi_session *session = conn->session;
1643 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1644 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1613 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1645 struct iscsi_r2t_info *r2t = tcp_ctask->r2t; 1614 struct iscsi_session *session = conn->session;
1646 struct iscsi_data_task *dtask = &r2t->dtask; 1615 struct iscsi_r2t_info *r2t;
1616 struct iscsi_data_task *dtask;
1647 int left, rc; 1617 int left, rc;
1648 1618
1649 tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA; 1619 if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) {
1650 tcp_ctask->dtask = dtask; 1620 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1651
1652 if (conn->datadgst_en) {
1653 iscsi_data_digest_init(tcp_conn, ctask);
1654 dtask->digest = 0;
1655 }
1656solicit_again:
1657 /*
1658 * send Data-Out within this R2T sequence.
1659 */
1660 if (!r2t->data_count)
1661 goto data_out_done;
1662
1663 rc = iscsi_sendpage(conn, &r2t->sendbuf, &r2t->data_count, &r2t->sent);
1664 if (rc) {
1665 tcp_ctask->xmstate |= XMSTATE_SOL_DATA; 1621 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1666 /* will continue with this ctask later.. */ 1622 if (!tcp_ctask->r2t)
1667 if (conn->datadgst_en) { 1623 __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
1668 crypto_digest_final(tcp_conn->data_tx_tfm, 1624 sizeof(void*));
1669 (u8 *)&dtask->digest); 1625send_hdr:
1670 debug_tcp("r2t data send fail 0x%x\n", dtask->digest); 1626 r2t = tcp_ctask->r2t;
1671 } 1627 dtask = &r2t->dtask;
1672 return rc;
1673 }
1674 1628
1675 BUG_ON(r2t->data_count < 0); 1629 if (conn->hdrdgst_en)
1676 if (conn->datadgst_en) 1630 iscsi_hdr_digest(conn, &r2t->headbuf,
1677 crypto_digest_update(tcp_conn->data_tx_tfm, &r2t->sendbuf.sg, 1631 (u8*)dtask->hdrext);
1678 1);
1679
1680 if (r2t->data_count) {
1681 BUG_ON(ctask->sc->use_sg == 0);
1682 if (!iscsi_buf_left(&r2t->sendbuf)) {
1683 BUG_ON(tcp_ctask->bad_sg == r2t->sg);
1684 iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg);
1685 r2t->sg += 1;
1686 }
1687 goto solicit_again;
1688 }
1689 1632
1690data_out_done:
1691 /*
1692 * Done with this Data-Out. Next, check if we have
1693 * to send another Data-Out for this R2T.
1694 */
1695 BUG_ON(r2t->data_length - r2t->sent < 0);
1696 left = r2t->data_length - r2t->sent;
1697 if (left) {
1698 if (conn->datadgst_en) { 1633 if (conn->datadgst_en) {
1699 rc = iscsi_digest_final_send(conn, ctask, 1634 iscsi_data_digest_init(conn->dd_data, tcp_ctask);
1700 &dtask->digestbuf, 1635 dtask->digest = 0;
1701 &dtask->digest, 1);
1702 if (rc) {
1703 debug_tcp("send r2t data digest 0x%x"
1704 "fail\n", dtask->digest);
1705 return rc;
1706 }
1707 debug_tcp("r2t data send digest 0x%x\n",
1708 dtask->digest);
1709 } 1636 }
1710 iscsi_solicit_data_cont(conn, ctask, r2t, left);
1711 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1712 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1713 return 1;
1714 }
1715 1637
1716 /* 1638 rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count);
1717 * Done with this R2T. Check if there are more
1718 * outstanding R2Ts ready to be processed.
1719 */
1720 if (conn->datadgst_en) {
1721 rc = iscsi_digest_final_send(conn, ctask, &dtask->digestbuf,
1722 &dtask->digest, 1);
1723 if (rc) { 1639 if (rc) {
1724 debug_tcp("send last r2t data digest 0x%x" 1640 tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA;
1725 "fail\n", dtask->digest); 1641 tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
1726 return rc; 1642 return rc;
1727 } 1643 }
1728 debug_tcp("r2t done dout digest 0x%x\n", dtask->digest);
1729 }
1730 1644
1731 tcp_ctask->r2t = NULL; 1645 iscsi_set_padding(tcp_ctask, r2t->data_count);
1732 spin_lock_bh(&session->lock); 1646 debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n",
1733 __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); 1647 r2t->solicit_datasn - 1, ctask->itt, r2t->data_count,
1734 spin_unlock_bh(&session->lock); 1648 r2t->sent);
1735 if (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*))) {
1736 tcp_ctask->r2t = r2t;
1737 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1738 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1739 return 1;
1740 } 1649 }
1741 1650
1742 return 0; 1651 if (tcp_ctask->xmstate & XMSTATE_SOL_DATA) {
1743} 1652 r2t = tcp_ctask->r2t;
1653 dtask = &r2t->dtask;
1744 1654
1745static inline int 1655 rc = iscsi_send_data(ctask, &r2t->sendbuf, &r2t->sg,
1746handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1656 &r2t->sent, &r2t->data_count,
1747{ 1657 &dtask->digestbuf, &dtask->digest);
1748 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1658 if (rc)
1749 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 1659 return rc;
1750 struct iscsi_data_task *dtask = tcp_ctask->dtask; 1660 tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA;
1751 int sent = 0, rc;
1752 1661
1753 tcp_ctask->xmstate &= ~XMSTATE_W_PAD; 1662 /*
1754 iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad, 1663 * Done with this Data-Out. Next, check if we have
1755 tcp_ctask->pad_count); 1664 * to send another Data-Out for this R2T.
1756 rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, &tcp_ctask->pad_count, 1665 */
1757 &sent); 1666 BUG_ON(r2t->data_length - r2t->sent < 0);
1758 if (rc) { 1667 left = r2t->data_length - r2t->sent;
1759 tcp_ctask->xmstate |= XMSTATE_W_PAD; 1668 if (left) {
1760 return rc; 1669 iscsi_solicit_data_cont(conn, ctask, r2t, left);
1761 } 1670 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1671 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1672 goto send_hdr;
1673 }
1762 1674
1763 if (conn->datadgst_en) { 1675 /*
1764 crypto_digest_update(tcp_conn->data_tx_tfm, 1676 * Done with this R2T. Check if there are more
1765 &tcp_ctask->sendbuf.sg, 1); 1677 * outstanding R2Ts ready to be processed.
1766 /* imm data? */ 1678 */
1767 if (!dtask) { 1679 spin_lock_bh(&session->lock);
1768 rc = iscsi_digest_final_send(conn, ctask, 1680 tcp_ctask->r2t = NULL;
1769 &tcp_ctask->immbuf, 1681 __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
1770 &tcp_ctask->immdigest, 1); 1682 sizeof(void*));
1771 if (rc) { 1683 if (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t,
1772 debug_tcp("send padding digest 0x%x" 1684 sizeof(void*))) {
1773 "fail!\n", tcp_ctask->immdigest); 1685 tcp_ctask->r2t = r2t;
1774 return rc; 1686 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1775 } 1687 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1776 debug_tcp("done with padding, digest 0x%x\n", 1688 spin_unlock_bh(&session->lock);
1777 tcp_ctask->datadigest); 1689 goto send_hdr;
1778 } else {
1779 rc = iscsi_digest_final_send(conn, ctask,
1780 &dtask->digestbuf,
1781 &dtask->digest, 1);
1782 if (rc) {
1783 debug_tcp("send padding digest 0x%x"
1784 "fail\n", dtask->digest);
1785 return rc;
1786 }
1787 debug_tcp("done with padding, digest 0x%x\n",
1788 dtask->digest);
1789 } 1690 }
1691 spin_unlock_bh(&session->lock);
1790 } 1692 }
1791
1792 return 0; 1693 return 0;
1793} 1694}
1794 1695
@@ -1808,85 +1709,30 @@ iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1808 return rc; 1709 return rc;
1809 1710
1810 if (tcp_ctask->xmstate & XMSTATE_R_HDR) 1711 if (tcp_ctask->xmstate & XMSTATE_R_HDR)
1811 return handle_xmstate_r_hdr(conn, tcp_ctask); 1712 return iscsi_send_read_hdr(conn, tcp_ctask);
1812 1713
1813 if (tcp_ctask->xmstate & XMSTATE_W_HDR) { 1714 if (tcp_ctask->xmstate & XMSTATE_W_HDR) {
1814 rc = handle_xmstate_w_hdr(conn, ctask); 1715 rc = iscsi_send_write_hdr(conn, ctask);
1815 if (rc)
1816 return rc;
1817 }
1818
1819 /* XXX: for data digest xmit recover */
1820 if (tcp_ctask->xmstate & XMSTATE_DATA_DIGEST) {
1821 rc = handle_xmstate_data_digest(conn, ctask);
1822 if (rc) 1716 if (rc)
1823 return rc; 1717 return rc;
1824 } 1718 }
1825 1719
1826 if (tcp_ctask->xmstate & XMSTATE_IMM_DATA) { 1720 if (tcp_ctask->xmstate & XMSTATE_IMM_DATA) {
1827 rc = handle_xmstate_imm_data(conn, ctask); 1721 rc = iscsi_send_data(ctask, &tcp_ctask->sendbuf, &tcp_ctask->sg,
1722 &tcp_ctask->sent, &ctask->imm_count,
1723 &tcp_ctask->immbuf, &tcp_ctask->immdigest);
1828 if (rc) 1724 if (rc)
1829 return rc; 1725 return rc;
1726 tcp_ctask->xmstate &= ~XMSTATE_IMM_DATA;
1830 } 1727 }
1831 1728
1832 if (tcp_ctask->xmstate & XMSTATE_UNS_HDR) { 1729 rc = iscsi_send_unsol_pdu(conn, ctask);
1833 BUG_ON(!ctask->unsol_count); 1730 if (rc)
1834 tcp_ctask->xmstate &= ~XMSTATE_UNS_HDR; 1731 return rc;
1835unsolicit_head_again:
1836 rc = handle_xmstate_uns_hdr(conn, ctask);
1837 if (rc)
1838 return rc;
1839 }
1840
1841 if (tcp_ctask->xmstate & XMSTATE_UNS_DATA) {
1842 rc = handle_xmstate_uns_data(conn, ctask);
1843 if (rc == 1)
1844 goto unsolicit_head_again;
1845 else if (rc)
1846 return rc;
1847 goto done;
1848 }
1849
1850 if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) {
1851 struct iscsi_r2t_info *r2t;
1852
1853 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1854 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1855 if (!tcp_ctask->r2t)
1856 __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
1857 sizeof(void*));
1858solicit_head_again:
1859 r2t = tcp_ctask->r2t;
1860 if (conn->hdrdgst_en)
1861 iscsi_hdr_digest(conn, &r2t->headbuf,
1862 (u8*)r2t->dtask.hdrext);
1863 rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count);
1864 if (rc) {
1865 tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA;
1866 tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
1867 return rc;
1868 }
1869
1870 debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n",
1871 r2t->solicit_datasn - 1, ctask->itt, r2t->data_count,
1872 r2t->sent);
1873 }
1874
1875 if (tcp_ctask->xmstate & XMSTATE_SOL_DATA) {
1876 rc = handle_xmstate_sol_data(conn, ctask);
1877 if (rc == 1)
1878 goto solicit_head_again;
1879 if (rc)
1880 return rc;
1881 }
1882 1732
1883done: 1733 rc = iscsi_send_sol_pdu(conn, ctask);
1884 /* 1734 if (rc)
1885 * Last thing to check is whether we need to send write 1735 return rc;
1886 * padding. Note that we check for xmstate equality, not just the bit.
1887 */
1888 if (tcp_ctask->xmstate == XMSTATE_W_PAD)
1889 rc = handle_xmstate_w_pad(conn, ctask);
1890 1736
1891 return rc; 1737 return rc;
1892} 1738}
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
index aace8f70dfd7..7e40e94d9fdc 100644
--- a/drivers/scsi/iscsi_tcp.h
+++ b/drivers/scsi/iscsi_tcp.h
@@ -31,23 +31,21 @@
31#define IN_PROGRESS_DDIGEST_RECV 0x3 31#define IN_PROGRESS_DDIGEST_RECV 0x3
32 32
33/* xmit state machine */ 33/* xmit state machine */
34#define XMSTATE_IDLE 0x0 34#define XMSTATE_IDLE 0x0
35#define XMSTATE_R_HDR 0x1 35#define XMSTATE_R_HDR 0x1
36#define XMSTATE_W_HDR 0x2 36#define XMSTATE_W_HDR 0x2
37#define XMSTATE_IMM_HDR 0x4 37#define XMSTATE_IMM_HDR 0x4
38#define XMSTATE_IMM_DATA 0x8 38#define XMSTATE_IMM_DATA 0x8
39#define XMSTATE_UNS_INIT 0x10 39#define XMSTATE_UNS_INIT 0x10
40#define XMSTATE_UNS_HDR 0x20 40#define XMSTATE_UNS_HDR 0x20
41#define XMSTATE_UNS_DATA 0x40 41#define XMSTATE_UNS_DATA 0x40
42#define XMSTATE_SOL_HDR 0x80 42#define XMSTATE_SOL_HDR 0x80
43#define XMSTATE_SOL_DATA 0x100 43#define XMSTATE_SOL_DATA 0x100
44#define XMSTATE_W_PAD 0x200 44#define XMSTATE_W_PAD 0x200
45#define XMSTATE_DATA_DIGEST 0x400 45#define XMSTATE_W_RESEND_PAD 0x400
46 46#define XMSTATE_W_RESEND_DATA_DIGEST 0x800
47#define ISCSI_CONN_RCVBUF_MIN 262144 47
48#define ISCSI_CONN_SNDBUF_MIN 262144
49#define ISCSI_PAD_LEN 4 48#define ISCSI_PAD_LEN 4
50#define ISCSI_R2T_MAX 16
51#define ISCSI_SG_TABLESIZE SG_ALL 49#define ISCSI_SG_TABLESIZE SG_ALL
52#define ISCSI_TCP_MAX_CMD_LEN 16 50#define ISCSI_TCP_MAX_CMD_LEN 16
53 51
@@ -162,13 +160,10 @@ struct iscsi_tcp_cmd_task {
162 struct iscsi_queue r2tpool; 160 struct iscsi_queue r2tpool;
163 struct kfifo *r2tqueue; 161 struct kfifo *r2tqueue;
164 struct iscsi_r2t_info **r2ts; 162 struct iscsi_r2t_info **r2ts;
165 uint32_t datadigest; /* for recover digest */
166 int digest_count; 163 int digest_count;
167 uint32_t immdigest; /* for imm data */ 164 uint32_t immdigest; /* for imm data */
168 struct iscsi_buf immbuf; /* for imm data digest */ 165 struct iscsi_buf immbuf; /* for imm data digest */
169 struct iscsi_data_task *dtask; /* data task in progress*/
170 struct iscsi_data_task unsol_dtask; /* unsol data task */ 166 struct iscsi_data_task unsol_dtask; /* unsol data task */
171 int digest_offset; /* for partial buff digest */
172}; 167};
173 168
174#endif /* ISCSI_H */ 169#endif /* ISCSI_H */
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 9584cbc082fe..fb65311c81dd 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -325,6 +325,30 @@ static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
325 wake_up(&conn->ehwait); 325 wake_up(&conn->ehwait);
326} 326}
327 327
328static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
329 char *data, int datalen)
330{
331 struct iscsi_reject *reject = (struct iscsi_reject *)hdr;
332 struct iscsi_hdr rejected_pdu;
333 uint32_t itt;
334
335 conn->exp_statsn = be32_to_cpu(reject->statsn) + 1;
336
337 if (reject->reason == ISCSI_REASON_DATA_DIGEST_ERROR) {
338 if (ntoh24(reject->dlength) > datalen)
339 return ISCSI_ERR_PROTO;
340
341 if (ntoh24(reject->dlength) >= sizeof(struct iscsi_hdr)) {
342 memcpy(&rejected_pdu, data, sizeof(struct iscsi_hdr));
343 itt = rejected_pdu.itt & ISCSI_ITT_MASK;
344 printk(KERN_ERR "itt 0x%x had pdu (op 0x%x) rejected "
345 "due to DataDigest error.\n", itt,
346 rejected_pdu.opcode);
347 }
348 }
349 return 0;
350}
351
328/** 352/**
329 * __iscsi_complete_pdu - complete pdu 353 * __iscsi_complete_pdu - complete pdu
330 * @conn: iscsi conn 354 * @conn: iscsi conn
@@ -436,6 +460,11 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
436 break; 460 break;
437 } 461 }
438 } else if (itt == ISCSI_RESERVED_TAG) { 462 } else if (itt == ISCSI_RESERVED_TAG) {
463 rc = iscsi_check_assign_cmdsn(session,
464 (struct iscsi_nopin*)hdr);
465 if (rc)
466 goto done;
467
439 switch(opcode) { 468 switch(opcode) {
440 case ISCSI_OP_NOOP_IN: 469 case ISCSI_OP_NOOP_IN:
441 if (datalen) { 470 if (datalen) {
@@ -443,11 +472,6 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
443 break; 472 break;
444 } 473 }
445 474
446 rc = iscsi_check_assign_cmdsn(session,
447 (struct iscsi_nopin*)hdr);
448 if (rc)
449 break;
450
451 if (hdr->ttt == ISCSI_RESERVED_TAG) 475 if (hdr->ttt == ISCSI_RESERVED_TAG)
452 break; 476 break;
453 477
@@ -455,7 +479,8 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
455 rc = ISCSI_ERR_CONN_FAILED; 479 rc = ISCSI_ERR_CONN_FAILED;
456 break; 480 break;
457 case ISCSI_OP_REJECT: 481 case ISCSI_OP_REJECT:
458 /* we need sth like iscsi_reject_rsp()*/ 482 rc = iscsi_handle_reject(conn, hdr, data, datalen);
483 break;
459 case ISCSI_OP_ASYNC_EVENT: 484 case ISCSI_OP_ASYNC_EVENT:
460 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; 485 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
461 /* we need sth like iscsi_async_event_rsp() */ 486 /* we need sth like iscsi_async_event_rsp() */