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.c303
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
91static inline void 93static inline void
92iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size) 94iscsi_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
100static inline void*
101iscsi_buf_iov_base(struct iscsi_buf *ibuf)
102{
103 return (char*)ibuf->sg.page + ibuf->sent;
104} 101}
105 102
106static inline void 103static inline void
107iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg) 104iscsi_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
1277static void 1273static 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 */
1321static inline int 1312static inline int
1322iscsi_send(struct socket *sk, struct iscsi_buf *buf, int size, int flags) 1313iscsi_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)
1355static inline int 1341static inline int
1356iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen) 1342iscsi_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
1395iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf, 1380iscsi_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
1437static inline void
1438iscsi_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
1450static inline int 1421static inline int
1451iscsi_digest_final_send(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, 1422iscsi_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
1746handle_xmstate_r_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1717handle_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
1760handle_xmstate_w_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1731handle_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:
2148solicit_head_again: 2121solicit_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
2381reject: 2346reject:
@@ -2462,17 +2427,20 @@ iscsi_pool_free(struct iscsi_queue *q, void **items)
2462 kfree(items); 2427 kfree(items);
2463} 2428}
2464 2429
2465static iscsi_connh_t 2430static struct iscsi_cls_conn *
2466iscsi_conn_create(iscsi_sessionh_t sessionh, uint32_t conn_idx) 2431iscsi_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
2539max_recv_dlenght_alloc_fail: 2507max_recv_dlenght_alloc_fail:
2540 spin_lock_bh(&session->lock); 2508 spin_lock_bh(&session->lock);
@@ -2550,18 +2518,18 @@ immqueue_alloc_fail:
2550writequeue_alloc_fail: 2518writequeue_alloc_fail:
2551 kfifo_free(conn->xmitqueue); 2519 kfifo_free(conn->xmitqueue);
2552xmitqueue_alloc_fail: 2520xmitqueue_alloc_fail:
2553 kfree(conn); 2521 iscsi_destroy_conn(cls_conn);
2554conn_alloc_fail: 2522 return NULL;
2555 return iscsi_handle(NULL);
2556} 2523}
2557 2524
2558static void 2525static void
2559iscsi_conn_destroy(iscsi_connh_t connh) 2526iscsi_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
2658static int 2627static 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
2884static int 2855static 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:
3182exit: 3152exit:
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
3284static iscsi_sessionh_t 3254static struct iscsi_transport iscsi_tcp_transport;
3285iscsi_session_create(uint32_t initial_cmdsn, struct Scsi_Host *host) 3255
3256static struct Scsi_Host *
3257iscsi_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
3340r2tpool_alloc_fail: 3316r2tpool_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:
3345mgmtpool_alloc_fail: 3321mgmtpool_alloc_fail:
3346 iscsi_pool_free(&session->cmdpool, (void**)session->cmds); 3322 iscsi_pool_free(&session->cmdpool, (void**)session->cmds);
3347cmdpool_alloc_fail: 3323cmdpool_alloc_fail:
3348 return iscsi_handle(NULL); 3324 return NULL;
3349} 3325}
3350 3326
3351static void 3327static void
3352iscsi_session_destroy(iscsi_sessionh_t sessionh) 3328iscsi_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
3374static int 3352static 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
3517static int 3497static int
3518iscsi_conn_get_param(iscsi_connh_t connh, enum iscsi_param param, 3498iscsi_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
3541static int
3542iscsi_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
3574static void 3566static void
3575iscsi_conn_get_stats(iscsi_connh_t connh, struct iscsi_stats *stats) 3567iscsi_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 = {
3633static int __init 3627static int __init
3634iscsi_tcp_init(void) 3628iscsi_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
3657static void __exit 3648static void __exit