diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2007-05-30 13:57:17 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2007-06-01 12:59:26 -0400 |
commit | 218432c68085d6c2b04df57daaf105d2ffa2aa61 (patch) | |
tree | cdc4646cc1d20f16bea893fb366f24c3ea50f0af /drivers/scsi/iscsi_tcp.c | |
parent | b2c6416736b847b91950bd43cc5153e11a1f83ee (diff) |
[SCSI] iscsi tcp: fix iscsi xmit state machine
If iscsi_tcp partially sends a header, it would recalculate the
header size and readd the size of the digest (if header digests
are used).This would cause us to send sizeof(digest) extra bytes
when we sent the rest of the header.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/iscsi_tcp.c')
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 258 |
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 | ||
115 | static inline int | 115 | static 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, | |||
1284 | static void | 1284 | static void |
1285 | iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask) | 1285 | iscsi_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 | **/ |
1338 | static int | 1309 | static int |
1339 | iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) | 1310 | iscsi_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 | ||
1397 | static inline int | 1379 | static int |
1398 | iscsi_send_read_hdr(struct iscsi_conn *conn, | 1380 | iscsi_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 | ||
1416 | static inline int | 1406 | debug_scsi("cmd [itt 0x%x total %d imm_data %d " |
1417 | iscsi_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 | ||
1448 | static int | 1450 | static 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 | **/ | ||
1713 | static int | 1756 | static int |
1714 | iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | 1757 | iscsi_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 | ||
1927 | static int | 1959 | static int |