diff options
Diffstat (limited to 'drivers/scsi/iscsi_tcp.c')
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 303 |
1 files changed, 147 insertions, 156 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 10bcf42cb65c..1b495afe6d17 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
34 | #include <linux/kfifo.h> | 34 | #include <linux/kfifo.h> |
35 | #include <linux/scatterlist.h> | 35 | #include <linux/scatterlist.h> |
36 | #include <linux/mutex.h> | ||
36 | #include <net/tcp.h> | 37 | #include <net/tcp.h> |
37 | #include <scsi/scsi_cmnd.h> | 38 | #include <scsi/scsi_cmnd.h> |
38 | #include <scsi/scsi_device.h> | 39 | #include <scsi/scsi_device.h> |
@@ -86,35 +87,32 @@ iscsi_buf_init_virt(struct iscsi_buf *ibuf, char *vbuf, int size) | |||
86 | { | 87 | { |
87 | sg_init_one(&ibuf->sg, (u8 *)vbuf, size); | 88 | sg_init_one(&ibuf->sg, (u8 *)vbuf, size); |
88 | ibuf->sent = 0; | 89 | ibuf->sent = 0; |
90 | ibuf->use_sendmsg = 0; | ||
89 | } | 91 | } |
90 | 92 | ||
91 | static inline void | 93 | static inline void |
92 | iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size) | 94 | iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size) |
93 | { | 95 | { |
94 | ibuf->sg.page = (void*)vbuf; | 96 | ibuf->sg.page = virt_to_page(vbuf); |
95 | ibuf->sg.offset = (unsigned int)-1; | 97 | ibuf->sg.offset = offset_in_page(vbuf); |
96 | ibuf->sg.length = size; | 98 | ibuf->sg.length = size; |
97 | ibuf->sent = 0; | 99 | ibuf->sent = 0; |
98 | } | 100 | ibuf->use_sendmsg = 1; |
99 | |||
100 | static inline void* | ||
101 | iscsi_buf_iov_base(struct iscsi_buf *ibuf) | ||
102 | { | ||
103 | return (char*)ibuf->sg.page + ibuf->sent; | ||
104 | } | 101 | } |
105 | 102 | ||
106 | static inline void | 103 | static inline void |
107 | iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg) | 104 | iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg) |
108 | { | 105 | { |
106 | ibuf->sg.page = sg->page; | ||
107 | ibuf->sg.offset = sg->offset; | ||
108 | ibuf->sg.length = sg->length; | ||
109 | /* | 109 | /* |
110 | * Fastpath: sg element fits into single page | 110 | * Fastpath: sg element fits into single page |
111 | */ | 111 | */ |
112 | if (sg->length + sg->offset <= PAGE_SIZE && page_count(sg->page) >= 2) { | 112 | if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg->page)) |
113 | ibuf->sg.page = sg->page; | 113 | ibuf->use_sendmsg = 0; |
114 | ibuf->sg.offset = sg->offset; | 114 | else |
115 | ibuf->sg.length = sg->length; | 115 | ibuf->use_sendmsg = 1; |
116 | } else | ||
117 | iscsi_buf_init_iov(ibuf, page_address(sg->page), sg->length); | ||
118 | ibuf->sent = 0; | 116 | ibuf->sent = 0; |
119 | } | 117 | } |
120 | 118 | ||
@@ -356,7 +354,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
356 | struct scsi_cmnd *sc = ctask->sc; | 354 | struct scsi_cmnd *sc = ctask->sc; |
357 | 355 | ||
358 | conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1; | 356 | conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1; |
359 | if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) { | 357 | if (rhdr->flags & ISCSI_FLAG_DATA_UNDERFLOW) { |
360 | int res_count = be32_to_cpu(rhdr->residual_count); | 358 | int res_count = be32_to_cpu(rhdr->residual_count); |
361 | 359 | ||
362 | if (res_count > 0 && | 360 | if (res_count > 0 && |
@@ -366,9 +364,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
366 | } else | 364 | } else |
367 | sc->result = (DID_BAD_TARGET << 16) | | 365 | sc->result = (DID_BAD_TARGET << 16) | |
368 | rhdr->cmd_status; | 366 | rhdr->cmd_status; |
369 | } else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW) | 367 | } else if (rhdr->flags & ISCSI_FLAG_DATA_OVERFLOW) { |
370 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; | ||
371 | else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) { | ||
372 | sc->resid = be32_to_cpu(rhdr->residual_count); | 368 | sc->resid = be32_to_cpu(rhdr->residual_count); |
373 | sc->result = (DID_OK << 16) | rhdr->cmd_status; | 369 | sc->result = (DID_OK << 16) | rhdr->cmd_status; |
374 | } else | 370 | } else |
@@ -529,7 +525,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
529 | __kfifo_put(ctask->r2tqueue, (void*)&r2t, sizeof(void*)); | 525 | __kfifo_put(ctask->r2tqueue, (void*)&r2t, sizeof(void*)); |
530 | __kfifo_put(conn->writequeue, (void*)&ctask, sizeof(void*)); | 526 | __kfifo_put(conn->writequeue, (void*)&ctask, sizeof(void*)); |
531 | 527 | ||
532 | schedule_work(&conn->xmitwork); | 528 | scsi_queue_work(session->host, &conn->xmitwork); |
533 | conn->r2t_pdus_cnt++; | 529 | conn->r2t_pdus_cnt++; |
534 | spin_unlock(&session->lock); | 530 | spin_unlock(&session->lock); |
535 | 531 | ||
@@ -686,7 +682,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn) | |||
686 | switch(conn->in.opcode) { | 682 | switch(conn->in.opcode) { |
687 | case ISCSI_OP_LOGIN_RSP: | 683 | case ISCSI_OP_LOGIN_RSP: |
688 | case ISCSI_OP_TEXT_RSP: | 684 | case ISCSI_OP_TEXT_RSP: |
689 | case ISCSI_OP_LOGOUT_RSP: | 685 | case ISCSI_OP_LOGOUT_RSP: |
690 | rc = iscsi_check_assign_cmdsn(session, | 686 | rc = iscsi_check_assign_cmdsn(session, |
691 | (struct iscsi_nopin*)hdr); | 687 | (struct iscsi_nopin*)hdr); |
692 | if (rc) | 688 | if (rc) |
@@ -727,12 +723,12 @@ iscsi_hdr_recv(struct iscsi_conn *conn) | |||
727 | } | 723 | } |
728 | spin_unlock(&session->lock); | 724 | spin_unlock(&session->lock); |
729 | break; | 725 | break; |
730 | case ISCSI_OP_NOOP_IN: | 726 | case ISCSI_OP_NOOP_IN: |
731 | if (hdr->ttt != ISCSI_RESERVED_TAG) { | 727 | if (hdr->ttt != ISCSI_RESERVED_TAG) { |
732 | rc = ISCSI_ERR_PROTO; | 728 | rc = ISCSI_ERR_PROTO; |
733 | break; | 729 | break; |
734 | } | 730 | } |
735 | rc = iscsi_check_assign_cmdsn(session, | 731 | rc = iscsi_check_assign_cmdsn(session, |
736 | (struct iscsi_nopin*)hdr); | 732 | (struct iscsi_nopin*)hdr); |
737 | if (rc) | 733 | if (rc) |
738 | break; | 734 | break; |
@@ -767,7 +763,7 @@ iscsi_hdr_recv(struct iscsi_conn *conn) | |||
767 | if (!rc && hdr->ttt != ISCSI_RESERVED_TAG) | 763 | if (!rc && hdr->ttt != ISCSI_RESERVED_TAG) |
768 | rc = iscsi_recv_pdu(iscsi_handle(conn), | 764 | rc = iscsi_recv_pdu(iscsi_handle(conn), |
769 | hdr, NULL, 0); | 765 | hdr, NULL, 0); |
770 | } else | 766 | } else |
771 | rc = ISCSI_ERR_PROTO; | 767 | rc = ISCSI_ERR_PROTO; |
772 | break; | 768 | break; |
773 | case ISCSI_OP_REJECT: | 769 | case ISCSI_OP_REJECT: |
@@ -929,7 +925,7 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) | |||
929 | sc->request_bufflen, ctask->data_offset); | 925 | sc->request_bufflen, ctask->data_offset); |
930 | if (rc == -EAGAIN) | 926 | if (rc == -EAGAIN) |
931 | return rc; | 927 | return rc; |
932 | if (conn->datadgst_en) | 928 | if (conn->datadgst_en) |
933 | iscsi_recv_digest_update(conn, sc->request_buffer, i); | 929 | iscsi_recv_digest_update(conn, sc->request_buffer, i); |
934 | rc = 0; | 930 | rc = 0; |
935 | goto done; | 931 | goto done; |
@@ -1024,7 +1020,7 @@ iscsi_data_recv(struct iscsi_conn *conn) | |||
1024 | conn->in.hdr = &conn->hdr; | 1020 | conn->in.hdr = &conn->hdr; |
1025 | conn->senselen = (conn->data[0] << 8) | conn->data[1]; | 1021 | conn->senselen = (conn->data[0] << 8) | conn->data[1]; |
1026 | rc = iscsi_cmd_rsp(conn, conn->in.ctask); | 1022 | rc = iscsi_cmd_rsp(conn, conn->in.ctask); |
1027 | if (!rc && conn->datadgst_en) | 1023 | if (!rc && conn->datadgst_en) |
1028 | iscsi_recv_digest_update(conn, conn->data, | 1024 | iscsi_recv_digest_update(conn, conn->data, |
1029 | conn->in.datalen); | 1025 | conn->in.datalen); |
1030 | } | 1026 | } |
@@ -1051,7 +1047,7 @@ iscsi_data_recv(struct iscsi_conn *conn) | |||
1051 | rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr, | 1047 | rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr, |
1052 | conn->data, conn->in.datalen); | 1048 | conn->data, conn->in.datalen); |
1053 | 1049 | ||
1054 | if (!rc && conn->datadgst_en && | 1050 | if (!rc && conn->datadgst_en && |
1055 | conn->in.opcode != ISCSI_OP_LOGIN_RSP) | 1051 | conn->in.opcode != ISCSI_OP_LOGIN_RSP) |
1056 | iscsi_recv_digest_update(conn, conn->data, | 1052 | iscsi_recv_digest_update(conn, conn->data, |
1057 | conn->in.datalen); | 1053 | conn->in.datalen); |
@@ -1271,7 +1267,7 @@ iscsi_write_space(struct sock *sk) | |||
1271 | conn->old_write_space(sk); | 1267 | conn->old_write_space(sk); |
1272 | debug_tcp("iscsi_write_space: cid %d\n", conn->id); | 1268 | debug_tcp("iscsi_write_space: cid %d\n", conn->id); |
1273 | clear_bit(SUSPEND_BIT, &conn->suspend_tx); | 1269 | clear_bit(SUSPEND_BIT, &conn->suspend_tx); |
1274 | schedule_work(&conn->xmitwork); | 1270 | scsi_queue_work(conn->session->host, &conn->xmitwork); |
1275 | } | 1271 | } |
1276 | 1272 | ||
1277 | static void | 1273 | static void |
@@ -1312,35 +1308,25 @@ iscsi_conn_restore_callbacks(struct iscsi_conn *conn) | |||
1312 | * @buf: buffer to write from | 1308 | * @buf: buffer to write from |
1313 | * @size: actual size to write | 1309 | * @size: actual size to write |
1314 | * @flags: socket's flags | 1310 | * @flags: socket's flags |
1315 | * | ||
1316 | * Notes: | ||
1317 | * depending on buffer will use tcp_sendpage() or tcp_sendmsg(). | ||
1318 | * buf->sg.offset == -1 tells us that buffer is non S/G and forces | ||
1319 | * to use tcp_sendmsg(). | ||
1320 | */ | 1311 | */ |
1321 | static inline int | 1312 | static inline int |
1322 | iscsi_send(struct socket *sk, struct iscsi_buf *buf, int size, int flags) | 1313 | iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags) |
1323 | { | 1314 | { |
1324 | int res; | 1315 | struct socket *sk = conn->sock; |
1325 | 1316 | int offset = buf->sg.offset + buf->sent; | |
1326 | if ((int)buf->sg.offset >= 0) { | ||
1327 | int offset = buf->sg.offset + buf->sent; | ||
1328 | |||
1329 | /* tcp_sendpage */ | ||
1330 | res = sk->ops->sendpage(sk, buf->sg.page, offset, size, flags); | ||
1331 | } else { | ||
1332 | struct msghdr msg; | ||
1333 | |||
1334 | buf->iov.iov_base = iscsi_buf_iov_base(buf); | ||
1335 | buf->iov.iov_len = size; | ||
1336 | |||
1337 | memset(&msg, 0, sizeof(struct msghdr)); | ||
1338 | |||
1339 | /* tcp_sendmsg */ | ||
1340 | res = kernel_sendmsg(sk, &msg, &buf->iov, 1, size); | ||
1341 | } | ||
1342 | 1317 | ||
1343 | return res; | 1318 | /* |
1319 | * if we got use_sg=0 or are sending something we kmallocd | ||
1320 | * then we did not have to do kmap (kmap returns page_address) | ||
1321 | * | ||
1322 | * if we got use_sg > 0, but had to drop down, we do not | ||
1323 | * set clustering so this should only happen for that | ||
1324 | * slab case. | ||
1325 | */ | ||
1326 | if (buf->use_sendmsg) | ||
1327 | return sock_no_sendpage(sk, buf->sg.page, offset, size, flags); | ||
1328 | else | ||
1329 | return conn->sendpage(sk, buf->sg.page, offset, size, flags); | ||
1344 | } | 1330 | } |
1345 | 1331 | ||
1346 | /** | 1332 | /** |
@@ -1355,7 +1341,6 @@ iscsi_send(struct socket *sk, struct iscsi_buf *buf, int size, int flags) | |||
1355 | static inline int | 1341 | static inline int |
1356 | iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen) | 1342 | iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen) |
1357 | { | 1343 | { |
1358 | struct socket *sk = conn->sock; | ||
1359 | int flags = 0; /* MSG_DONTWAIT; */ | 1344 | int flags = 0; /* MSG_DONTWAIT; */ |
1360 | int res, size; | 1345 | int res, size; |
1361 | 1346 | ||
@@ -1364,7 +1349,7 @@ iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen) | |||
1364 | if (buf->sent + size != buf->sg.length || datalen) | 1349 | if (buf->sent + size != buf->sg.length || datalen) |
1365 | flags |= MSG_MORE; | 1350 | flags |= MSG_MORE; |
1366 | 1351 | ||
1367 | res = iscsi_send(sk, buf, size, flags); | 1352 | res = iscsi_send(conn, buf, size, flags); |
1368 | debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res); | 1353 | debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res); |
1369 | if (res >= 0) { | 1354 | if (res >= 0) { |
1370 | conn->txdata_octets += res; | 1355 | conn->txdata_octets += res; |
@@ -1395,7 +1380,6 @@ static inline int | |||
1395 | iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf, | 1380 | iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf, |
1396 | int *count, int *sent) | 1381 | int *count, int *sent) |
1397 | { | 1382 | { |
1398 | struct socket *sk = conn->sock; | ||
1399 | int flags = 0; /* MSG_DONTWAIT; */ | 1383 | int flags = 0; /* MSG_DONTWAIT; */ |
1400 | int res, size; | 1384 | int res, size; |
1401 | 1385 | ||
@@ -1406,7 +1390,7 @@ iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf, | |||
1406 | if (buf->sent + size != buf->sg.length || *count != size) | 1390 | if (buf->sent + size != buf->sg.length || *count != size) |
1407 | flags |= MSG_MORE; | 1391 | flags |= MSG_MORE; |
1408 | 1392 | ||
1409 | res = iscsi_send(sk, buf, size, flags); | 1393 | res = iscsi_send(conn, buf, size, flags); |
1410 | debug_tcp("sendpage: %d bytes, sent %d left %d sent %d res %d\n", | 1394 | debug_tcp("sendpage: %d bytes, sent %d left %d sent %d res %d\n", |
1411 | size, buf->sent, *count, *sent, res); | 1395 | size, buf->sent, *count, *sent, res); |
1412 | if (res >= 0) { | 1396 | if (res >= 0) { |
@@ -1434,19 +1418,6 @@ iscsi_data_digest_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
1434 | ctask->digest_count = 4; | 1418 | ctask->digest_count = 4; |
1435 | } | 1419 | } |
1436 | 1420 | ||
1437 | static inline void | ||
1438 | iscsi_buf_data_digest_update(struct iscsi_conn *conn, struct iscsi_buf *buf) | ||
1439 | { | ||
1440 | struct scatterlist sg; | ||
1441 | |||
1442 | if (buf->sg.offset != -1) | ||
1443 | crypto_digest_update(conn->data_tx_tfm, &buf->sg, 1); | ||
1444 | else { | ||
1445 | sg_init_one(&sg, (char *)buf->sg.page, buf->sg.length); | ||
1446 | crypto_digest_update(conn->data_tx_tfm, &sg, 1); | ||
1447 | } | ||
1448 | } | ||
1449 | |||
1450 | static inline int | 1421 | static inline int |
1451 | iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, | 1422 | iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, |
1452 | struct iscsi_buf *buf, uint32_t *digest, int final) | 1423 | struct iscsi_buf *buf, uint32_t *digest, int final) |
@@ -1680,7 +1651,7 @@ iscsi_cmd_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, | |||
1680 | zero_data(ctask->hdr.dlength); | 1651 | zero_data(ctask->hdr.dlength); |
1681 | } | 1652 | } |
1682 | 1653 | ||
1683 | iscsi_buf_init_virt(&ctask->headbuf, (char*)&ctask->hdr, | 1654 | iscsi_buf_init_virt(&ctask->headbuf, (char*)&ctask->hdr, |
1684 | sizeof(struct iscsi_hdr)); | 1655 | sizeof(struct iscsi_hdr)); |
1685 | conn->scsicmd_pdus_cnt++; | 1656 | conn->scsicmd_pdus_cnt++; |
1686 | } | 1657 | } |
@@ -1746,7 +1717,7 @@ static inline int | |||
1746 | handle_xmstate_r_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | 1717 | handle_xmstate_r_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) |
1747 | { | 1718 | { |
1748 | ctask->xmstate &= ~XMSTATE_R_HDR; | 1719 | ctask->xmstate &= ~XMSTATE_R_HDR; |
1749 | if (conn->hdrdgst_en) | 1720 | if (conn->hdrdgst_en) |
1750 | iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext); | 1721 | iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext); |
1751 | if (!iscsi_sendhdr(conn, &ctask->headbuf, 0)) { | 1722 | if (!iscsi_sendhdr(conn, &ctask->headbuf, 0)) { |
1752 | BUG_ON(ctask->xmstate != XMSTATE_IDLE); | 1723 | BUG_ON(ctask->xmstate != XMSTATE_IDLE); |
@@ -1760,7 +1731,7 @@ static inline int | |||
1760 | handle_xmstate_w_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | 1731 | handle_xmstate_w_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) |
1761 | { | 1732 | { |
1762 | ctask->xmstate &= ~XMSTATE_W_HDR; | 1733 | ctask->xmstate &= ~XMSTATE_W_HDR; |
1763 | if (conn->hdrdgst_en) | 1734 | if (conn->hdrdgst_en) |
1764 | iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext); | 1735 | iscsi_hdr_digest(conn, &ctask->headbuf, (u8*)ctask->hdrext); |
1765 | if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->imm_count)) { | 1736 | if (iscsi_sendhdr(conn, &ctask->headbuf, ctask->imm_count)) { |
1766 | ctask->xmstate |= XMSTATE_W_HDR; | 1737 | ctask->xmstate |= XMSTATE_W_HDR; |
@@ -1809,7 +1780,8 @@ handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
1809 | return -EAGAIN; | 1780 | return -EAGAIN; |
1810 | } | 1781 | } |
1811 | if (conn->datadgst_en) | 1782 | if (conn->datadgst_en) |
1812 | iscsi_buf_data_digest_update(conn, &ctask->sendbuf); | 1783 | crypto_digest_update(conn->data_tx_tfm, |
1784 | &ctask->sendbuf.sg, 1); | ||
1813 | 1785 | ||
1814 | if (!ctask->imm_count) | 1786 | if (!ctask->imm_count) |
1815 | break; | 1787 | break; |
@@ -1894,7 +1866,8 @@ handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
1894 | * so pass it | 1866 | * so pass it |
1895 | */ | 1867 | */ |
1896 | if (conn->datadgst_en && ctask->sent - start > 0) | 1868 | if (conn->datadgst_en && ctask->sent - start > 0) |
1897 | iscsi_buf_data_digest_update(conn, &ctask->sendbuf); | 1869 | crypto_digest_update(conn->data_tx_tfm, |
1870 | &ctask->sendbuf.sg, 1); | ||
1898 | 1871 | ||
1899 | if (!ctask->data_count) | 1872 | if (!ctask->data_count) |
1900 | break; | 1873 | break; |
@@ -1972,7 +1945,7 @@ solicit_again: | |||
1972 | 1945 | ||
1973 | BUG_ON(r2t->data_count < 0); | 1946 | BUG_ON(r2t->data_count < 0); |
1974 | if (conn->datadgst_en) | 1947 | if (conn->datadgst_en) |
1975 | iscsi_buf_data_digest_update(conn, &r2t->sendbuf); | 1948 | crypto_digest_update(conn->data_tx_tfm, &r2t->sendbuf.sg, 1); |
1976 | 1949 | ||
1977 | if (r2t->data_count) { | 1950 | if (r2t->data_count) { |
1978 | BUG_ON(ctask->sc->use_sg == 0); | 1951 | BUG_ON(ctask->sc->use_sg == 0); |
@@ -2054,7 +2027,7 @@ handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
2054 | } | 2027 | } |
2055 | 2028 | ||
2056 | if (conn->datadgst_en) { | 2029 | if (conn->datadgst_en) { |
2057 | iscsi_buf_data_digest_update(conn, &ctask->sendbuf); | 2030 | crypto_digest_update(conn->data_tx_tfm, &ctask->sendbuf.sg, 1); |
2058 | /* imm data? */ | 2031 | /* imm data? */ |
2059 | if (!dtask) { | 2032 | if (!dtask) { |
2060 | if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf, | 2033 | if (iscsi_digest_final_send(conn, ctask, &ctask->immbuf, |
@@ -2148,7 +2121,7 @@ unsolicit_head_again: | |||
2148 | solicit_head_again: | 2121 | solicit_head_again: |
2149 | r2t = ctask->r2t; | 2122 | r2t = ctask->r2t; |
2150 | if (conn->hdrdgst_en) | 2123 | if (conn->hdrdgst_en) |
2151 | iscsi_hdr_digest(conn, &r2t->headbuf, | 2124 | iscsi_hdr_digest(conn, &r2t->headbuf, |
2152 | (u8*)r2t->dtask->hdrext); | 2125 | (u8*)r2t->dtask->hdrext); |
2153 | if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) { | 2126 | if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) { |
2154 | ctask->xmstate &= ~XMSTATE_SOL_DATA; | 2127 | ctask->xmstate &= ~XMSTATE_SOL_DATA; |
@@ -2300,10 +2273,10 @@ iscsi_xmitworker(void *data) | |||
2300 | /* | 2273 | /* |
2301 | * serialize Xmit worker on a per-connection basis. | 2274 | * serialize Xmit worker on a per-connection basis. |
2302 | */ | 2275 | */ |
2303 | down(&conn->xmitsema); | 2276 | mutex_lock(&conn->xmitmutex); |
2304 | if (iscsi_data_xmit(conn)) | 2277 | if (iscsi_data_xmit(conn)) |
2305 | schedule_work(&conn->xmitwork); | 2278 | scsi_queue_work(conn->session->host, &conn->xmitwork); |
2306 | up(&conn->xmitsema); | 2279 | mutex_unlock(&conn->xmitmutex); |
2307 | } | 2280 | } |
2308 | 2281 | ||
2309 | #define FAILURE_BAD_HOST 1 | 2282 | #define FAILURE_BAD_HOST 1 |
@@ -2367,15 +2340,7 @@ iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
2367 | session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); | 2340 | session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); |
2368 | spin_unlock(&session->lock); | 2341 | spin_unlock(&session->lock); |
2369 | 2342 | ||
2370 | if (!in_interrupt() && !down_trylock(&conn->xmitsema)) { | 2343 | scsi_queue_work(host, &conn->xmitwork); |
2371 | spin_unlock_irq(host->host_lock); | ||
2372 | if (iscsi_data_xmit(conn)) | ||
2373 | schedule_work(&conn->xmitwork); | ||
2374 | up(&conn->xmitsema); | ||
2375 | spin_lock_irq(host->host_lock); | ||
2376 | } else | ||
2377 | schedule_work(&conn->xmitwork); | ||
2378 | |||
2379 | return 0; | 2344 | return 0; |
2380 | 2345 | ||
2381 | reject: | 2346 | reject: |
@@ -2462,17 +2427,20 @@ iscsi_pool_free(struct iscsi_queue *q, void **items) | |||
2462 | kfree(items); | 2427 | kfree(items); |
2463 | } | 2428 | } |
2464 | 2429 | ||
2465 | static iscsi_connh_t | 2430 | static struct iscsi_cls_conn * |
2466 | iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx) | 2431 | iscsi_conn_create(struct Scsi_Host *shost, uint32_t conn_idx) |
2467 | { | 2432 | { |
2468 | struct iscsi_session *session = iscsi_ptr(sessionh); | 2433 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); |
2469 | struct iscsi_conn *conn = NULL; | 2434 | struct iscsi_conn *conn; |
2435 | struct iscsi_cls_conn *cls_conn; | ||
2470 | 2436 | ||
2471 | conn = kmalloc(sizeof(struct iscsi_conn), GFP_KERNEL); | 2437 | cls_conn = iscsi_create_conn(hostdata_session(shost->hostdata), |
2472 | if (conn == NULL) | 2438 | conn_idx); |
2473 | goto conn_alloc_fail; | 2439 | if (!cls_conn) |
2474 | memset(conn, 0, sizeof(struct iscsi_conn)); | 2440 | return NULL; |
2441 | conn = cls_conn->dd_data; | ||
2475 | 2442 | ||
2443 | memset(conn, 0, sizeof(struct iscsi_conn)); | ||
2476 | conn->c_stage = ISCSI_CONN_INITIAL_STAGE; | 2444 | conn->c_stage = ISCSI_CONN_INITIAL_STAGE; |
2477 | conn->in_progress = IN_PROGRESS_WAIT_HEADER; | 2445 | conn->in_progress = IN_PROGRESS_WAIT_HEADER; |
2478 | conn->id = conn_idx; | 2446 | conn->id = conn_idx; |
@@ -2531,10 +2499,10 @@ iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx) | |||
2531 | goto max_recv_dlenght_alloc_fail; | 2499 | goto max_recv_dlenght_alloc_fail; |
2532 | 2500 | ||
2533 | init_timer(&conn->tmabort_timer); | 2501 | init_timer(&conn->tmabort_timer); |
2534 | init_MUTEX(&conn->xmitsema); | 2502 | mutex_init(&conn->xmitmutex); |
2535 | init_waitqueue_head(&conn->ehwait); | 2503 | init_waitqueue_head(&conn->ehwait); |
2536 | 2504 | ||
2537 | return iscsi_handle(conn); | 2505 | return cls_conn; |
2538 | 2506 | ||
2539 | max_recv_dlenght_alloc_fail: | 2507 | max_recv_dlenght_alloc_fail: |
2540 | spin_lock_bh(&session->lock); | 2508 | spin_lock_bh(&session->lock); |
@@ -2550,18 +2518,18 @@ immqueue_alloc_fail: | |||
2550 | writequeue_alloc_fail: | 2518 | writequeue_alloc_fail: |
2551 | kfifo_free(conn->xmitqueue); | 2519 | kfifo_free(conn->xmitqueue); |
2552 | xmitqueue_alloc_fail: | 2520 | xmitqueue_alloc_fail: |
2553 | kfree(conn); | 2521 | iscsi_destroy_conn(cls_conn); |
2554 | conn_alloc_fail: | 2522 | return NULL; |
2555 | return iscsi_handle(NULL); | ||
2556 | } | 2523 | } |
2557 | 2524 | ||
2558 | static void | 2525 | static void |
2559 | iscsi_conn_destroy(iscsi_connh_t connh) | 2526 | iscsi_conn_destroy(struct iscsi_cls_conn *cls_conn) |
2560 | { | 2527 | { |
2561 | struct iscsi_conn *conn = iscsi_ptr(connh); | 2528 | struct iscsi_conn *conn = cls_conn->dd_data; |
2562 | struct iscsi_session *session = conn->session; | 2529 | struct iscsi_session *session = conn->session; |
2530 | unsigned long flags; | ||
2563 | 2531 | ||
2564 | down(&conn->xmitsema); | 2532 | mutex_lock(&conn->xmitmutex); |
2565 | set_bit(SUSPEND_BIT, &conn->suspend_tx); | 2533 | set_bit(SUSPEND_BIT, &conn->suspend_tx); |
2566 | if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE && conn->sock) { | 2534 | if (conn->c_stage == ISCSI_CONN_INITIAL_STAGE && conn->sock) { |
2567 | struct sock *sk = conn->sock->sk; | 2535 | struct sock *sk = conn->sock->sk; |
@@ -2592,19 +2560,19 @@ iscsi_conn_destroy(iscsi_connh_t connh) | |||
2592 | } | 2560 | } |
2593 | spin_unlock_bh(&session->lock); | 2561 | spin_unlock_bh(&session->lock); |
2594 | 2562 | ||
2595 | up(&conn->xmitsema); | 2563 | mutex_unlock(&conn->xmitmutex); |
2596 | 2564 | ||
2597 | /* | 2565 | /* |
2598 | * Block until all in-progress commands for this connection | 2566 | * Block until all in-progress commands for this connection |
2599 | * time out or fail. | 2567 | * time out or fail. |
2600 | */ | 2568 | */ |
2601 | for (;;) { | 2569 | for (;;) { |
2602 | spin_lock_bh(&conn->lock); | 2570 | spin_lock_irqsave(session->host->host_lock, flags); |
2603 | if (!session->host->host_busy) { /* OK for ERL == 0 */ | 2571 | if (!session->host->host_busy) { /* OK for ERL == 0 */ |
2604 | spin_unlock_bh(&conn->lock); | 2572 | spin_unlock_irqrestore(session->host->host_lock, flags); |
2605 | break; | 2573 | break; |
2606 | } | 2574 | } |
2607 | spin_unlock_bh(&conn->lock); | 2575 | spin_unlock_irqrestore(session->host->host_lock, flags); |
2608 | msleep_interruptible(500); | 2576 | msleep_interruptible(500); |
2609 | printk("conn_destroy(): host_busy %d host_failed %d\n", | 2577 | printk("conn_destroy(): host_busy %d host_failed %d\n", |
2610 | session->host->host_busy, session->host->host_failed); | 2578 | session->host->host_busy, session->host->host_failed); |
@@ -2652,7 +2620,8 @@ iscsi_conn_destroy(iscsi_connh_t connh) | |||
2652 | kfifo_free(conn->writequeue); | 2620 | kfifo_free(conn->writequeue); |
2653 | kfifo_free(conn->immqueue); | 2621 | kfifo_free(conn->immqueue); |
2654 | kfifo_free(conn->mgmtqueue); | 2622 | kfifo_free(conn->mgmtqueue); |
2655 | kfree(conn); | 2623 | |
2624 | iscsi_destroy_conn(cls_conn); | ||
2656 | } | 2625 | } |
2657 | 2626 | ||
2658 | static int | 2627 | static int |
@@ -2713,6 +2682,8 @@ iscsi_conn_bind(iscsi_sessionh_t sessionh, iscsi_connh_t connh, | |||
2713 | */ | 2682 | */ |
2714 | iscsi_conn_set_callbacks(conn); | 2683 | iscsi_conn_set_callbacks(conn); |
2715 | 2684 | ||
2685 | conn->sendpage = conn->sock->ops->sendpage; | ||
2686 | |||
2716 | /* | 2687 | /* |
2717 | * set receive state machine into initial state | 2688 | * set receive state machine into initial state |
2718 | */ | 2689 | */ |
@@ -2796,7 +2767,7 @@ iscsi_conn_stop(iscsi_connh_t connh, int flag) | |||
2796 | set_bit(SUSPEND_BIT, &conn->suspend_rx); | 2767 | set_bit(SUSPEND_BIT, &conn->suspend_rx); |
2797 | write_unlock_bh(&sk->sk_callback_lock); | 2768 | write_unlock_bh(&sk->sk_callback_lock); |
2798 | 2769 | ||
2799 | down(&conn->xmitsema); | 2770 | mutex_lock(&conn->xmitmutex); |
2800 | 2771 | ||
2801 | spin_lock_irqsave(session->host->host_lock, flags); | 2772 | spin_lock_irqsave(session->host->host_lock, flags); |
2802 | spin_lock(&session->lock); | 2773 | spin_lock(&session->lock); |
@@ -2878,7 +2849,7 @@ iscsi_conn_stop(iscsi_connh_t connh, int flag) | |||
2878 | conn->datadgst_en = 0; | 2849 | conn->datadgst_en = 0; |
2879 | } | 2850 | } |
2880 | } | 2851 | } |
2881 | up(&conn->xmitsema); | 2852 | mutex_unlock(&conn->xmitmutex); |
2882 | } | 2853 | } |
2883 | 2854 | ||
2884 | static int | 2855 | static int |
@@ -2963,8 +2934,7 @@ iscsi_conn_send_generic(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
2963 | else | 2934 | else |
2964 | __kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*)); | 2935 | __kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*)); |
2965 | 2936 | ||
2966 | schedule_work(&conn->xmitwork); | 2937 | scsi_queue_work(session->host, &conn->xmitwork); |
2967 | |||
2968 | return 0; | 2938 | return 0; |
2969 | } | 2939 | } |
2970 | 2940 | ||
@@ -3029,12 +2999,12 @@ iscsi_eh_abort(struct scsi_cmnd *sc) | |||
3029 | * 1) connection-level failure; | 2999 | * 1) connection-level failure; |
3030 | * 2) recovery due protocol error; | 3000 | * 2) recovery due protocol error; |
3031 | */ | 3001 | */ |
3032 | down(&conn->xmitsema); | 3002 | mutex_lock(&conn->xmitmutex); |
3033 | spin_lock_bh(&session->lock); | 3003 | spin_lock_bh(&session->lock); |
3034 | if (session->state != ISCSI_STATE_LOGGED_IN) { | 3004 | if (session->state != ISCSI_STATE_LOGGED_IN) { |
3035 | if (session->state == ISCSI_STATE_TERMINATE) { | 3005 | if (session->state == ISCSI_STATE_TERMINATE) { |
3036 | spin_unlock_bh(&session->lock); | 3006 | spin_unlock_bh(&session->lock); |
3037 | up(&conn->xmitsema); | 3007 | mutex_unlock(&conn->xmitmutex); |
3038 | goto failed; | 3008 | goto failed; |
3039 | } | 3009 | } |
3040 | spin_unlock_bh(&session->lock); | 3010 | spin_unlock_bh(&session->lock); |
@@ -3052,7 +3022,7 @@ iscsi_eh_abort(struct scsi_cmnd *sc) | |||
3052 | * 2) session was re-open during time out of ctask. | 3022 | * 2) session was re-open during time out of ctask. |
3053 | */ | 3023 | */ |
3054 | spin_unlock_bh(&session->lock); | 3024 | spin_unlock_bh(&session->lock); |
3055 | up(&conn->xmitsema); | 3025 | mutex_unlock(&conn->xmitmutex); |
3056 | goto success; | 3026 | goto success; |
3057 | } | 3027 | } |
3058 | conn->tmabort_state = TMABORT_INITIAL; | 3028 | conn->tmabort_state = TMABORT_INITIAL; |
@@ -3107,7 +3077,7 @@ iscsi_eh_abort(struct scsi_cmnd *sc) | |||
3107 | conn->tmabort_state == TMABORT_SUCCESS) { | 3077 | conn->tmabort_state == TMABORT_SUCCESS) { |
3108 | conn->tmabort_state = TMABORT_INITIAL; | 3078 | conn->tmabort_state = TMABORT_INITIAL; |
3109 | spin_unlock_bh(&session->lock); | 3079 | spin_unlock_bh(&session->lock); |
3110 | up(&conn->xmitsema); | 3080 | mutex_unlock(&conn->xmitmutex); |
3111 | goto success; | 3081 | goto success; |
3112 | } | 3082 | } |
3113 | conn->tmabort_state = TMABORT_INITIAL; | 3083 | conn->tmabort_state = TMABORT_INITIAL; |
@@ -3116,7 +3086,7 @@ iscsi_eh_abort(struct scsi_cmnd *sc) | |||
3116 | spin_unlock_bh(&session->lock); | 3086 | spin_unlock_bh(&session->lock); |
3117 | } | 3087 | } |
3118 | } | 3088 | } |
3119 | up(&conn->xmitsema); | 3089 | mutex_unlock(&conn->xmitmutex); |
3120 | 3090 | ||
3121 | 3091 | ||
3122 | /* | 3092 | /* |
@@ -3182,7 +3152,7 @@ failed: | |||
3182 | exit: | 3152 | exit: |
3183 | del_timer_sync(&conn->tmabort_timer); | 3153 | del_timer_sync(&conn->tmabort_timer); |
3184 | 3154 | ||
3185 | down(&conn->xmitsema); | 3155 | mutex_lock(&conn->xmitmutex); |
3186 | if (conn->sock) { | 3156 | if (conn->sock) { |
3187 | struct sock *sk = conn->sock->sk; | 3157 | struct sock *sk = conn->sock->sk; |
3188 | 3158 | ||
@@ -3190,7 +3160,7 @@ exit: | |||
3190 | iscsi_ctask_cleanup(conn, ctask); | 3160 | iscsi_ctask_cleanup(conn, ctask); |
3191 | write_unlock_bh(&sk->sk_callback_lock); | 3161 | write_unlock_bh(&sk->sk_callback_lock); |
3192 | } | 3162 | } |
3193 | up(&conn->xmitsema); | 3163 | mutex_unlock(&conn->xmitmutex); |
3194 | return rc; | 3164 | return rc; |
3195 | } | 3165 | } |
3196 | 3166 | ||
@@ -3281,17 +3251,23 @@ static struct scsi_host_template iscsi_sht = { | |||
3281 | .this_id = -1, | 3251 | .this_id = -1, |
3282 | }; | 3252 | }; |
3283 | 3253 | ||
3284 | static iscsi_sessionh_t | 3254 | static struct iscsi_transport iscsi_tcp_transport; |
3285 | iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host) | 3255 | |
3256 | static struct Scsi_Host * | ||
3257 | iscsi_session_create(struct scsi_transport_template *scsit, | ||
3258 | uint32_t initial_cmdsn) | ||
3286 | { | 3259 | { |
3287 | int cmd_i; | 3260 | struct Scsi_Host *shost; |
3288 | struct iscsi_session *session; | 3261 | struct iscsi_session *session; |
3262 | int cmd_i; | ||
3289 | 3263 | ||
3290 | session = iscsi_hostdata(host->hostdata); | 3264 | shost = iscsi_transport_create_session(scsit, &iscsi_tcp_transport); |
3291 | memset(session, 0, sizeof(struct iscsi_session)); | 3265 | if (!shost) |
3266 | return NULL; | ||
3292 | 3267 | ||
3293 | session->host = host; | 3268 | session = iscsi_hostdata(shost->hostdata); |
3294 | session->id = host->host_no; | 3269 | memset(session, 0, sizeof(struct iscsi_session)); |
3270 | session->host = shost; | ||
3295 | session->state = ISCSI_STATE_LOGGED_IN; | 3271 | session->state = ISCSI_STATE_LOGGED_IN; |
3296 | session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; | 3272 | session->mgmtpool_max = ISCSI_MGMT_CMDS_MAX; |
3297 | session->cmds_max = ISCSI_XMIT_CMDS_MAX; | 3273 | session->cmds_max = ISCSI_XMIT_CMDS_MAX; |
@@ -3335,7 +3311,7 @@ iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host) | |||
3335 | if (iscsi_r2tpool_alloc(session)) | 3311 | if (iscsi_r2tpool_alloc(session)) |
3336 | goto r2tpool_alloc_fail; | 3312 | goto r2tpool_alloc_fail; |
3337 | 3313 | ||
3338 | return iscsi_handle(session); | 3314 | return shost; |
3339 | 3315 | ||
3340 | r2tpool_alloc_fail: | 3316 | r2tpool_alloc_fail: |
3341 | for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) | 3317 | for (cmd_i = 0; cmd_i < session->mgmtpool_max; cmd_i++) |
@@ -3345,15 +3321,15 @@ immdata_alloc_fail: | |||
3345 | mgmtpool_alloc_fail: | 3321 | mgmtpool_alloc_fail: |
3346 | iscsi_pool_free(&session->cmdpool, (void**)session->cmds); | 3322 | iscsi_pool_free(&session->cmdpool, (void**)session->cmds); |
3347 | cmdpool_alloc_fail: | 3323 | cmdpool_alloc_fail: |
3348 | return iscsi_handle(NULL); | 3324 | return NULL; |
3349 | } | 3325 | } |
3350 | 3326 | ||
3351 | static void | 3327 | static void |
3352 | iscsi_session_destroy(iscsi_sessionh_t sessionh) | 3328 | iscsi_session_destroy(struct Scsi_Host *shost) |
3353 | { | 3329 | { |
3330 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); | ||
3354 | int cmd_i; | 3331 | int cmd_i; |
3355 | struct iscsi_data_task *dtask, *n; | 3332 | struct iscsi_data_task *dtask, *n; |
3356 | struct iscsi_session *session = iscsi_ptr(sessionh); | ||
3357 | 3333 | ||
3358 | for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { | 3334 | for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { |
3359 | struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; | 3335 | struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; |
@@ -3369,6 +3345,8 @@ iscsi_session_destroy(iscsi_sessionh_t sessionh) | |||
3369 | iscsi_r2tpool_free(session); | 3345 | iscsi_r2tpool_free(session); |
3370 | iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); | 3346 | iscsi_pool_free(&session->mgmtpool, (void**)session->mgmt_cmds); |
3371 | iscsi_pool_free(&session->cmdpool, (void**)session->cmds); | 3347 | iscsi_pool_free(&session->cmdpool, (void**)session->cmds); |
3348 | |||
3349 | iscsi_transport_destroy_session(shost); | ||
3372 | } | 3350 | } |
3373 | 3351 | ||
3374 | static int | 3352 | static int |
@@ -3467,6 +3445,8 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param, | |||
3467 | if (conn->data_rx_tfm) | 3445 | if (conn->data_rx_tfm) |
3468 | crypto_free_tfm(conn->data_rx_tfm); | 3446 | crypto_free_tfm(conn->data_rx_tfm); |
3469 | } | 3447 | } |
3448 | conn->sendpage = conn->datadgst_en ? | ||
3449 | sock_no_sendpage : conn->sock->ops->sendpage; | ||
3470 | break; | 3450 | break; |
3471 | case ISCSI_PARAM_INITIAL_R2T_EN: | 3451 | case ISCSI_PARAM_INITIAL_R2T_EN: |
3472 | session->initial_r2t_en = value; | 3452 | session->initial_r2t_en = value; |
@@ -3515,25 +3495,12 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param, | |||
3515 | } | 3495 | } |
3516 | 3496 | ||
3517 | static int | 3497 | static int |
3518 | iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param, | 3498 | iscsi_session_get_param(struct Scsi_Host *shost, |
3519 | uint32_t *value) | 3499 | enum iscsi_param param, uint32_t *value) |
3520 | { | 3500 | { |
3521 | struct iscsi_conn *conn = iscsi_ptr(connh); | 3501 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); |
3522 | struct iscsi_session *session = conn->session; | ||
3523 | 3502 | ||
3524 | switch(param) { | 3503 | switch(param) { |
3525 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
3526 | *value = conn->max_recv_dlength; | ||
3527 | break; | ||
3528 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
3529 | *value = conn->max_xmit_dlength; | ||
3530 | break; | ||
3531 | case ISCSI_PARAM_HDRDGST_EN: | ||
3532 | *value = conn->hdrdgst_en; | ||
3533 | break; | ||
3534 | case ISCSI_PARAM_DATADGST_EN: | ||
3535 | *value = conn->datadgst_en; | ||
3536 | break; | ||
3537 | case ISCSI_PARAM_INITIAL_R2T_EN: | 3504 | case ISCSI_PARAM_INITIAL_R2T_EN: |
3538 | *value = session->initial_r2t_en; | 3505 | *value = session->initial_r2t_en; |
3539 | break; | 3506 | break; |
@@ -3571,6 +3538,31 @@ iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param, | |||
3571 | return 0; | 3538 | return 0; |
3572 | } | 3539 | } |
3573 | 3540 | ||
3541 | static int | ||
3542 | iscsi_conn_get_param(void *data, enum iscsi_param param, uint32_t *value) | ||
3543 | { | ||
3544 | struct iscsi_conn *conn = data; | ||
3545 | |||
3546 | switch(param) { | ||
3547 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
3548 | *value = conn->max_recv_dlength; | ||
3549 | break; | ||
3550 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
3551 | *value = conn->max_xmit_dlength; | ||
3552 | break; | ||
3553 | case ISCSI_PARAM_HDRDGST_EN: | ||
3554 | *value = conn->hdrdgst_en; | ||
3555 | break; | ||
3556 | case ISCSI_PARAM_DATADGST_EN: | ||
3557 | *value = conn->datadgst_en; | ||
3558 | break; | ||
3559 | default: | ||
3560 | return ISCSI_ERR_PARAM_NOT_FOUND; | ||
3561 | } | ||
3562 | |||
3563 | return 0; | ||
3564 | } | ||
3565 | |||
3574 | static void | 3566 | static void |
3575 | iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats) | 3567 | iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats) |
3576 | { | 3568 | { |
@@ -3601,9 +3593,9 @@ iscsi_conn_send_pdu(iscsi_connh_t connh, struct iscsi_hdr *hdr, char *data, | |||
3601 | struct iscsi_conn *conn = iscsi_ptr(connh); | 3593 | struct iscsi_conn *conn = iscsi_ptr(connh); |
3602 | int rc; | 3594 | int rc; |
3603 | 3595 | ||
3604 | down(&conn->xmitsema); | 3596 | mutex_lock(&conn->xmitmutex); |
3605 | rc = iscsi_conn_send_generic(conn, hdr, data, data_size); | 3597 | rc = iscsi_conn_send_generic(conn, hdr, data, data_size); |
3606 | up(&conn->xmitsema); | 3598 | mutex_unlock(&conn->xmitmutex); |
3607 | 3599 | ||
3608 | return rc; | 3600 | return rc; |
3609 | } | 3601 | } |
@@ -3615,6 +3607,7 @@ static struct iscsi_transport iscsi_tcp_transport = { | |||
3615 | | CAP_DATADGST, | 3607 | | CAP_DATADGST, |
3616 | .host_template = &iscsi_sht, | 3608 | .host_template = &iscsi_sht, |
3617 | .hostdata_size = sizeof(struct iscsi_session), | 3609 | .hostdata_size = sizeof(struct iscsi_session), |
3610 | .conndata_size = sizeof(struct iscsi_conn), | ||
3618 | .max_conn = 1, | 3611 | .max_conn = 1, |
3619 | .max_cmd_len = ISCSI_TCP_MAX_CMD_LEN, | 3612 | .max_cmd_len = ISCSI_TCP_MAX_CMD_LEN, |
3620 | .create_session = iscsi_session_create, | 3613 | .create_session = iscsi_session_create, |
@@ -3623,7 +3616,8 @@ static struct iscsi_transport iscsi_tcp_transport = { | |||
3623 | .bind_conn = iscsi_conn_bind, | 3616 | .bind_conn = iscsi_conn_bind, |
3624 | .destroy_conn = iscsi_conn_destroy, | 3617 | .destroy_conn = iscsi_conn_destroy, |
3625 | .set_param = iscsi_conn_set_param, | 3618 | .set_param = iscsi_conn_set_param, |
3626 | .get_param = iscsi_conn_get_param, | 3619 | .get_conn_param = iscsi_conn_get_param, |
3620 | .get_session_param = iscsi_session_get_param, | ||
3627 | .start_conn = iscsi_conn_start, | 3621 | .start_conn = iscsi_conn_start, |
3628 | .stop_conn = iscsi_conn_stop, | 3622 | .stop_conn = iscsi_conn_stop, |
3629 | .send_pdu = iscsi_conn_send_pdu, | 3623 | .send_pdu = iscsi_conn_send_pdu, |
@@ -3633,8 +3627,6 @@ static struct iscsi_transport iscsi_tcp_transport = { | |||
3633 | static int __init | 3627 | static int __init |
3634 | iscsi_tcp_init(void) | 3628 | iscsi_tcp_init(void) |
3635 | { | 3629 | { |
3636 | int error; | ||
3637 | |||
3638 | if (iscsi_max_lun < 1) { | 3630 | if (iscsi_max_lun < 1) { |
3639 | printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun); | 3631 | printk(KERN_ERR "Invalid max_lun value of %u\n", iscsi_max_lun); |
3640 | return -EINVAL; | 3632 | return -EINVAL; |
@@ -3647,11 +3639,10 @@ iscsi_tcp_init(void) | |||
3647 | if (!taskcache) | 3639 | if (!taskcache) |
3648 | return -ENOMEM; | 3640 | return -ENOMEM; |
3649 | 3641 | ||
3650 | error = iscsi_register_transport(&iscsi_tcp_transport); | 3642 | if (!iscsi_register_transport(&iscsi_tcp_transport)) |
3651 | if (error) | ||
3652 | kmem_cache_destroy(taskcache); | 3643 | kmem_cache_destroy(taskcache); |
3653 | 3644 | ||
3654 | return error; | 3645 | return 0; |
3655 | } | 3646 | } |
3656 | 3647 | ||
3657 | static void __exit | 3648 | static void __exit |