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 |
