aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/iscsi_tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/iscsi_tcp.c')
-rw-r--r--drivers/scsi/iscsi_tcp.c258
1 files changed, 145 insertions, 113 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 1e722f5aabd4..0afdca2224c2 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -109,7 +109,7 @@ iscsi_hdr_digest(struct iscsi_conn *conn, struct iscsi_buf *buf,
109 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 109 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
110 110
111 crypto_hash_digest(&tcp_conn->tx_hash, &buf->sg, buf->sg.length, crc); 111 crypto_hash_digest(&tcp_conn->tx_hash, &buf->sg, buf->sg.length, crc);
112 buf->sg.length = tcp_conn->hdr_size; 112 buf->sg.length += sizeof(u32);
113} 113}
114 114
115static inline int 115static inline int
@@ -423,7 +423,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
423 423
424 tcp_ctask->exp_datasn = r2tsn + 1; 424 tcp_ctask->exp_datasn = r2tsn + 1;
425 __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); 425 __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
426 tcp_ctask->xmstate |= XMSTATE_SOL_HDR; 426 tcp_ctask->xmstate |= XMSTATE_SOL_HDR_INIT;
427 list_move_tail(&ctask->running, &conn->xmitqueue); 427 list_move_tail(&ctask->running, &conn->xmitqueue);
428 428
429 scsi_queue_work(session->host, &conn->xmitwork); 429 scsi_queue_work(session->host, &conn->xmitwork);
@@ -1284,41 +1284,10 @@ static void iscsi_set_padding(struct iscsi_tcp_cmd_task *tcp_ctask,
1284static void 1284static void
1285iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask) 1285iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
1286{ 1286{
1287 struct scsi_cmnd *sc = ctask->sc;
1288 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1287 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1289 1288
1290 BUG_ON(__kfifo_len(tcp_ctask->r2tqueue)); 1289 BUG_ON(__kfifo_len(tcp_ctask->r2tqueue));
1291 1290 tcp_ctask->xmstate = XMSTATE_CMD_HDR_INIT;
1292 tcp_ctask->sent = 0;
1293 tcp_ctask->sg_count = 0;
1294 tcp_ctask->exp_datasn = 0;
1295
1296 if (sc->sc_data_direction == DMA_TO_DEVICE) {
1297 tcp_ctask->xmstate = XMSTATE_W_HDR;
1298 BUG_ON(sc->request_bufflen == 0);
1299
1300 if (sc->use_sg) {
1301 struct scatterlist *sg = sc->request_buffer;
1302
1303 iscsi_buf_init_sg(&tcp_ctask->sendbuf, sg);
1304 tcp_ctask->sg = sg + 1;
1305 tcp_ctask->bad_sg = sg + sc->use_sg;
1306 } else {
1307 iscsi_buf_init_iov(&tcp_ctask->sendbuf,
1308 sc->request_buffer,
1309 sc->request_bufflen);
1310 tcp_ctask->sg = NULL;
1311 tcp_ctask->bad_sg = NULL;
1312 }
1313 debug_scsi("cmd [itt 0x%x total %d imm_data %d "
1314 "unsol count %d, unsol offset %d]\n",
1315 ctask->itt, sc->request_bufflen, ctask->imm_count,
1316 ctask->unsol_count, ctask->unsol_offset);
1317 } else
1318 tcp_ctask->xmstate = XMSTATE_R_HDR;
1319
1320 iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)ctask->hdr,
1321 sizeof(struct iscsi_hdr));
1322} 1291}
1323 1292
1324/** 1293/**
@@ -1331,9 +1300,11 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
1331 * call it again later, or recover. '0' return code means successful 1300 * call it again later, or recover. '0' return code means successful
1332 * xmit. 1301 * xmit.
1333 * 1302 *
1334 * Management xmit state machine consists of two states: 1303 * Management xmit state machine consists of these states:
1335 * IN_PROGRESS_IMM_HEAD - PDU Header xmit in progress 1304 * XMSTATE_IMM_HDR_INIT - calculate digest of PDU Header
1336 * IN_PROGRESS_IMM_DATA - PDU Data xmit in progress 1305 * XMSTATE_IMM_HDR - PDU Header xmit in progress
1306 * XMSTATE_IMM_DATA - PDU Data xmit in progress
1307 * XMSTATE_IDLE - management PDU is done
1337 **/ 1308 **/
1338static int 1309static int
1339iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) 1310iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
@@ -1344,23 +1315,34 @@ iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
1344 debug_scsi("mtask deq [cid %d state %x itt 0x%x]\n", 1315 debug_scsi("mtask deq [cid %d state %x itt 0x%x]\n",
1345 conn->id, tcp_mtask->xmstate, mtask->itt); 1316 conn->id, tcp_mtask->xmstate, mtask->itt);
1346 1317
1347 if (tcp_mtask->xmstate & XMSTATE_IMM_HDR) { 1318 if (tcp_mtask->xmstate & XMSTATE_IMM_HDR_INIT) {
1348 tcp_mtask->xmstate &= ~XMSTATE_IMM_HDR; 1319 iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr,
1349 if (mtask->data_count) 1320 sizeof(struct iscsi_hdr));
1321
1322 if (mtask->data_count) {
1350 tcp_mtask->xmstate |= XMSTATE_IMM_DATA; 1323 tcp_mtask->xmstate |= XMSTATE_IMM_DATA;
1324 iscsi_buf_init_iov(&tcp_mtask->sendbuf,
1325 (char*)mtask->data,
1326 mtask->data_count);
1327 }
1328
1351 if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE && 1329 if (conn->c_stage != ISCSI_CONN_INITIAL_STAGE &&
1352 conn->stop_stage != STOP_CONN_RECOVER && 1330 conn->stop_stage != STOP_CONN_RECOVER &&
1353 conn->hdrdgst_en) 1331 conn->hdrdgst_en)
1354 iscsi_hdr_digest(conn, &tcp_mtask->headbuf, 1332 iscsi_hdr_digest(conn, &tcp_mtask->headbuf,
1355 (u8*)tcp_mtask->hdrext); 1333 (u8*)tcp_mtask->hdrext);
1334
1335 tcp_mtask->sent = 0;
1336 tcp_mtask->xmstate &= ~XMSTATE_IMM_HDR_INIT;
1337 tcp_mtask->xmstate |= XMSTATE_IMM_HDR;
1338 }
1339
1340 if (tcp_mtask->xmstate & XMSTATE_IMM_HDR) {
1356 rc = iscsi_sendhdr(conn, &tcp_mtask->headbuf, 1341 rc = iscsi_sendhdr(conn, &tcp_mtask->headbuf,
1357 mtask->data_count); 1342 mtask->data_count);
1358 if (rc) { 1343 if (rc)
1359 tcp_mtask->xmstate |= XMSTATE_IMM_HDR;
1360 if (mtask->data_count)
1361 tcp_mtask->xmstate &= ~XMSTATE_IMM_DATA;
1362 return rc; 1344 return rc;
1363 } 1345 tcp_mtask->xmstate &= ~XMSTATE_IMM_HDR;
1364 } 1346 }
1365 1347
1366 if (tcp_mtask->xmstate & XMSTATE_IMM_DATA) { 1348 if (tcp_mtask->xmstate & XMSTATE_IMM_DATA) {
@@ -1394,55 +1376,75 @@ iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
1394 return 0; 1376 return 0;
1395} 1377}
1396 1378
1397static inline int 1379static int
1398iscsi_send_read_hdr(struct iscsi_conn *conn, 1380iscsi_send_cmd_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1399 struct iscsi_tcp_cmd_task *tcp_ctask)
1400{ 1381{
1401 int rc; 1382 struct scsi_cmnd *sc = ctask->sc;
1383 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1384 int rc = 0;
1402 1385
1403 tcp_ctask->xmstate &= ~XMSTATE_R_HDR; 1386 if (tcp_ctask->xmstate & XMSTATE_CMD_HDR_INIT) {
1404 if (conn->hdrdgst_en) 1387 tcp_ctask->sent = 0;
1405 iscsi_hdr_digest(conn, &tcp_ctask->headbuf, 1388 tcp_ctask->sg_count = 0;
1406 (u8*)tcp_ctask->hdrext); 1389 tcp_ctask->exp_datasn = 0;
1407 rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, 0); 1390
1408 if (!rc) { 1391 if (sc->sc_data_direction == DMA_TO_DEVICE) {
1409 BUG_ON(tcp_ctask->xmstate != XMSTATE_IDLE); 1392 if (sc->use_sg) {
1410 return 0; /* wait for Data-In */ 1393 struct scatterlist *sg = sc->request_buffer;
1411 } 1394
1412 tcp_ctask->xmstate |= XMSTATE_R_HDR; 1395 iscsi_buf_init_sg(&tcp_ctask->sendbuf, sg);
1413 return rc; 1396 tcp_ctask->sg = sg + 1;
1414} 1397 tcp_ctask->bad_sg = sg + sc->use_sg;
1398 } else {
1399 iscsi_buf_init_iov(&tcp_ctask->sendbuf,
1400 sc->request_buffer,
1401 sc->request_bufflen);
1402 tcp_ctask->sg = NULL;
1403 tcp_ctask->bad_sg = NULL;
1404 }
1415 1405
1416static inline int 1406 debug_scsi("cmd [itt 0x%x total %d imm_data %d "
1417iscsi_send_write_hdr(struct iscsi_conn *conn, 1407 "unsol count %d, unsol offset %d]\n",
1418 struct iscsi_cmd_task *ctask) 1408 ctask->itt, sc->request_bufflen,
1419{ 1409 ctask->imm_count, ctask->unsol_count,
1420 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1410 ctask->unsol_offset);
1421 int rc; 1411 }
1422 1412
1423 tcp_ctask->xmstate &= ~XMSTATE_W_HDR; 1413 iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)ctask->hdr,
1424 if (conn->hdrdgst_en) 1414 sizeof(struct iscsi_hdr));
1425 iscsi_hdr_digest(conn, &tcp_ctask->headbuf, 1415
1426 (u8*)tcp_ctask->hdrext); 1416 if (conn->hdrdgst_en)
1427 rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count); 1417 iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
1428 if (rc) { 1418 (u8*)tcp_ctask->hdrext);
1429 tcp_ctask->xmstate |= XMSTATE_W_HDR; 1419 tcp_ctask->xmstate &= ~XMSTATE_CMD_HDR_INIT;
1430 return rc; 1420 tcp_ctask->xmstate |= XMSTATE_CMD_HDR_XMIT;
1431 } 1421 }
1432 1422
1433 if (ctask->imm_count) { 1423 if (tcp_ctask->xmstate & XMSTATE_CMD_HDR_XMIT) {
1434 tcp_ctask->xmstate |= XMSTATE_IMM_DATA; 1424 rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count);
1435 iscsi_set_padding(tcp_ctask, ctask->imm_count); 1425 if (rc)
1426 return rc;
1427 tcp_ctask->xmstate &= ~XMSTATE_CMD_HDR_XMIT;
1428
1429 if (sc->sc_data_direction != DMA_TO_DEVICE)
1430 return 0;
1431
1432 if (ctask->imm_count) {
1433 tcp_ctask->xmstate |= XMSTATE_IMM_DATA;
1434 iscsi_set_padding(tcp_ctask, ctask->imm_count);
1436 1435
1437 if (ctask->conn->datadgst_en) { 1436 if (ctask->conn->datadgst_en) {
1438 iscsi_data_digest_init(ctask->conn->dd_data, tcp_ctask); 1437 iscsi_data_digest_init(ctask->conn->dd_data,
1439 tcp_ctask->immdigest = 0; 1438 tcp_ctask);
1439 tcp_ctask->immdigest = 0;
1440 }
1440 } 1441 }
1441 }
1442 1442
1443 if (ctask->unsol_count) 1443 if (ctask->unsol_count)
1444 tcp_ctask->xmstate |= XMSTATE_UNS_HDR | XMSTATE_UNS_INIT; 1444 tcp_ctask->xmstate |=
1445 return 0; 1445 XMSTATE_UNS_HDR | XMSTATE_UNS_INIT;
1446 }
1447 return rc;
1446} 1448}
1447 1449
1448static int 1450static int
@@ -1631,9 +1633,7 @@ static int iscsi_send_sol_pdu(struct iscsi_conn *conn,
1631 struct iscsi_data_task *dtask; 1633 struct iscsi_data_task *dtask;
1632 int left, rc; 1634 int left, rc;
1633 1635
1634 if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) { 1636 if (tcp_ctask->xmstate & XMSTATE_SOL_HDR_INIT) {
1635 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1636 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1637 if (!tcp_ctask->r2t) { 1637 if (!tcp_ctask->r2t) {
1638 spin_lock_bh(&session->lock); 1638 spin_lock_bh(&session->lock);
1639 __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t, 1639 __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
@@ -1647,12 +1647,19 @@ send_hdr:
1647 if (conn->hdrdgst_en) 1647 if (conn->hdrdgst_en)
1648 iscsi_hdr_digest(conn, &r2t->headbuf, 1648 iscsi_hdr_digest(conn, &r2t->headbuf,
1649 (u8*)dtask->hdrext); 1649 (u8*)dtask->hdrext);
1650 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR_INIT;
1651 tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
1652 }
1653
1654 if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) {
1655 r2t = tcp_ctask->r2t;
1656 dtask = &r2t->dtask;
1657
1650 rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count); 1658 rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count);
1651 if (rc) { 1659 if (rc)
1652 tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA;
1653 tcp_ctask->xmstate |= XMSTATE_SOL_HDR;
1654 return rc; 1660 return rc;
1655 } 1661 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1662 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1656 1663
1657 if (conn->datadgst_en) { 1664 if (conn->datadgst_en) {
1658 iscsi_data_digest_init(conn->dd_data, tcp_ctask); 1665 iscsi_data_digest_init(conn->dd_data, tcp_ctask);
@@ -1684,8 +1691,6 @@ send_hdr:
1684 left = r2t->data_length - r2t->sent; 1691 left = r2t->data_length - r2t->sent;
1685 if (left) { 1692 if (left) {
1686 iscsi_solicit_data_cont(conn, ctask, r2t, left); 1693 iscsi_solicit_data_cont(conn, ctask, r2t, left);
1687 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1688 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1689 goto send_hdr; 1694 goto send_hdr;
1690 } 1695 }
1691 1696
@@ -1700,8 +1705,6 @@ send_hdr:
1700 if (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t, 1705 if (__kfifo_get(tcp_ctask->r2tqueue, (void*)&r2t,
1701 sizeof(void*))) { 1706 sizeof(void*))) {
1702 tcp_ctask->r2t = r2t; 1707 tcp_ctask->r2t = r2t;
1703 tcp_ctask->xmstate |= XMSTATE_SOL_DATA;
1704 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR;
1705 spin_unlock_bh(&session->lock); 1708 spin_unlock_bh(&session->lock);
1706 goto send_hdr; 1709 goto send_hdr;
1707 } 1710 }
@@ -1710,6 +1713,46 @@ send_hdr:
1710 return 0; 1713 return 0;
1711} 1714}
1712 1715
1716/**
1717 * iscsi_tcp_ctask_xmit - xmit normal PDU task
1718 * @conn: iscsi connection
1719 * @ctask: iscsi command task
1720 *
1721 * Notes:
1722 * The function can return -EAGAIN in which case caller must
1723 * call it again later, or recover. '0' return code means successful
1724 * xmit.
1725 * The function is devided to logical helpers (above) for the different
1726 * xmit stages.
1727 *
1728 *iscsi_send_cmd_hdr()
1729 * XMSTATE_CMD_HDR_INIT - prepare Header and Data buffers Calculate
1730 * Header Digest
1731 * XMSTATE_CMD_HDR_XMIT - Transmit header in progress
1732 *
1733 *iscsi_send_padding
1734 * XMSTATE_W_PAD - Prepare and send pading
1735 * XMSTATE_W_RESEND_PAD - retry send pading
1736 *
1737 *iscsi_send_digest
1738 * XMSTATE_W_RESEND_DATA_DIGEST - Finalize and send Data Digest
1739 * XMSTATE_W_RESEND_DATA_DIGEST - retry sending digest
1740 *
1741 *iscsi_send_unsol_hdr
1742 * XMSTATE_UNS_INIT - prepare un-solicit data header and digest
1743 * XMSTATE_UNS_HDR - send un-solicit header
1744 *
1745 *iscsi_send_unsol_pdu
1746 * XMSTATE_UNS_DATA - send un-solicit data in progress
1747 *
1748 *iscsi_send_sol_pdu
1749 * XMSTATE_SOL_HDR_INIT - solicit data header and digest initialize
1750 * XMSTATE_SOL_HDR - send solicit header
1751 * XMSTATE_SOL_DATA - send solicit data
1752 *
1753 *iscsi_tcp_ctask_xmit
1754 * XMSTATE_IMM_DATA - xmit managment data (??)
1755 **/
1713static int 1756static int
1714iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1757iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1715{ 1758{
@@ -1725,14 +1768,11 @@ iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1725 if (ctask->mtask) 1768 if (ctask->mtask)
1726 return rc; 1769 return rc;
1727 1770
1728 if (tcp_ctask->xmstate & XMSTATE_R_HDR) 1771 rc = iscsi_send_cmd_hdr(conn, ctask);
1729 return iscsi_send_read_hdr(conn, tcp_ctask); 1772 if (rc)
1730 1773 return rc;
1731 if (tcp_ctask->xmstate & XMSTATE_W_HDR) { 1774 if (ctask->sc->sc_data_direction != DMA_TO_DEVICE)
1732 rc = iscsi_send_write_hdr(conn, ctask); 1775 return 0;
1733 if (rc)
1734 return rc;
1735 }
1736 1776
1737 if (tcp_ctask->xmstate & XMSTATE_IMM_DATA) { 1777 if (tcp_ctask->xmstate & XMSTATE_IMM_DATA) {
1738 rc = iscsi_send_data(ctask, &tcp_ctask->sendbuf, &tcp_ctask->sg, 1778 rc = iscsi_send_data(ctask, &tcp_ctask->sendbuf, &tcp_ctask->sg,
@@ -1913,15 +1953,7 @@ iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask,
1913 char *data, uint32_t data_size) 1953 char *data, uint32_t data_size)
1914{ 1954{
1915 struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data; 1955 struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data;
1916 1956 tcp_mtask->xmstate = XMSTATE_IMM_HDR_INIT;
1917 iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr,
1918 sizeof(struct iscsi_hdr));
1919 tcp_mtask->xmstate = XMSTATE_IMM_HDR;
1920 tcp_mtask->sent = 0;
1921
1922 if (mtask->data_count)
1923 iscsi_buf_init_iov(&tcp_mtask->sendbuf, (char*)mtask->data,
1924 mtask->data_count);
1925} 1957}
1926 1958
1927static int 1959static int