aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2013-03-20 18:29:15 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2013-04-25 04:05:27 -0400
commit2ec5a8c118139e756d4d39844550ba77ec3543cc (patch)
tree70302ecc6412cfd5f979b1d8515373fcbc5b9c92
parent3e1c81a95f0d776cea68a36cfc78a0ce8f6d3a77 (diff)
iscsi-target: Refactor TX queue logic + export response PDU creation
This patch refactors TX immediate + response queue handling to use the new iscsit_transport API callers, and exports the necessary traditional iscsi PDU response creation functions for iser-target to utilize. This includes: - Add iscsit_build_datain_pdu() for DATAIN PDU init + convert iscsit_build_datain_pdu() - Add iscsit_build_logout_rsp() for LOGOUT_RSP PDU init + convert iscsit_send_logout() - Add iscsit_build_nopin_rsp() for NOPIN_RSP PDU init + convert iscsit_send_nopin() - Add iscsit_build_rsp_pdu() for SCSI_RSP PDU init + convert iscsit_send_response() - Add iscsit_build_task_mgt_rsp for TM_RSP PDU init + convert iscsit_send_task_mgt_rsp() - Refactor immediate queue state switch into iscsit_immediate_queue() - Convert handle_immediate_queue() to use iscsit_transport caller - Refactor response queue state switch into iscsit_response_queue() - Convert handle_response_queue to use iscsit_transport caller - Export iscsit_logout_post_handler(), iscsit_increment_maxcmdsn() and iscsit_tmr_post_handler() for external transport module usage v5 changes: - Fix solicited NopIN handling with RDMAExtensions=No (nab) v3 changes: - Add iscsit_build_reject for REJECT PDU init + convert iscsit_send_reject() v2 changes: - Add iscsit_queue_rsp() for iscsit_transport->iscsit_queue_data_in() and iscsit_transport->iscsit_queue_status() - Update lio_queue_data_in() to use ->iscsit_queue_data_in() - Update lio_queue_status() to use ->iscsit_queue_status() - Use mutex_trylock() in iscsit_increment_maxcmdsn() Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/target/iscsi/iscsi_target.c659
-rw-r--r--drivers/target/iscsi/iscsi_target_configfs.c7
-rw-r--r--drivers/target/iscsi/iscsi_target_device.c7
-rw-r--r--drivers/target/iscsi/iscsi_target_tmr.c1
4 files changed, 370 insertions, 304 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 40bb916f57ff..ffbc6a94be52 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -70,8 +70,7 @@ struct kmem_cache *lio_ooo_cache;
70struct kmem_cache *lio_r2t_cache; 70struct kmem_cache *lio_r2t_cache;
71 71
72static int iscsit_handle_immediate_data(struct iscsi_cmd *, 72static int iscsit_handle_immediate_data(struct iscsi_cmd *,
73 unsigned char *buf, u32); 73 struct iscsi_scsi_req *, u32);
74static int iscsit_logout_post_handler(struct iscsi_cmd *, struct iscsi_conn *);
75 74
76struct iscsi_tiqn *iscsit_get_tiqn_for_login(unsigned char *buf) 75struct iscsi_tiqn *iscsit_get_tiqn_for_login(unsigned char *buf)
77{ 76{
@@ -482,6 +481,15 @@ int iscsit_del_np(struct iscsi_np *np)
482 return 0; 481 return 0;
483} 482}
484 483
484static int iscsit_immediate_queue(struct iscsi_conn *, struct iscsi_cmd *, int);
485static int iscsit_response_queue(struct iscsi_conn *, struct iscsi_cmd *, int);
486
487static int iscsit_queue_rsp(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
488{
489 iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state);
490 return 0;
491}
492
485static struct iscsit_transport iscsi_target_transport = { 493static struct iscsit_transport iscsi_target_transport = {
486 .name = "iSCSI/TCP", 494 .name = "iSCSI/TCP",
487 .transport_type = ISCSI_TCP, 495 .transport_type = ISCSI_TCP,
@@ -493,6 +501,10 @@ static struct iscsit_transport iscsi_target_transport = {
493 .iscsit_get_login_rx = iscsit_get_login_rx, 501 .iscsit_get_login_rx = iscsit_get_login_rx,
494 .iscsit_put_login_tx = iscsit_put_login_tx, 502 .iscsit_put_login_tx = iscsit_put_login_tx,
495 .iscsit_get_dataout = iscsit_build_r2ts_for_cmd, 503 .iscsit_get_dataout = iscsit_build_r2ts_for_cmd,
504 .iscsit_immediate_queue = iscsit_immediate_queue,
505 .iscsit_response_queue = iscsit_response_queue,
506 .iscsit_queue_data_in = iscsit_queue_rsp,
507 .iscsit_queue_status = iscsit_queue_rsp,
496}; 508};
497 509
498static int __init iscsi_target_init_module(void) 510static int __init iscsi_target_init_module(void)
@@ -651,14 +663,6 @@ static int iscsit_add_reject(
651 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state); 663 iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
652 664
653 ret = wait_for_completion_interruptible(&cmd->reject_comp); 665 ret = wait_for_completion_interruptible(&cmd->reject_comp);
654 /*
655 * Perform the kref_put now if se_cmd has been setup by
656 * iscsit_setup_scsi_cmd()
657 */
658 if (cmd->se_cmd.se_tfo != NULL) {
659 pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n");
660 target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
661 }
662 if (ret != 0) 666 if (ret != 0)
663 return -1; 667 return -1;
664 668
@@ -2549,18 +2553,60 @@ static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn)
2549 } 2553 }
2550} 2554}
2551 2555
2552static int iscsit_send_data_in( 2556static void
2553 struct iscsi_cmd *cmd, 2557iscsit_build_datain_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
2554 struct iscsi_conn *conn) 2558 struct iscsi_datain *datain, struct iscsi_data_rsp *hdr,
2559 bool set_statsn)
2555{ 2560{
2556 int iov_ret = 0, set_statsn = 0; 2561 hdr->opcode = ISCSI_OP_SCSI_DATA_IN;
2557 u32 iov_count = 0, tx_size = 0; 2562 hdr->flags = datain->flags;
2563 if (hdr->flags & ISCSI_FLAG_DATA_STATUS) {
2564 if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) {
2565 hdr->flags |= ISCSI_FLAG_DATA_OVERFLOW;
2566 hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
2567 } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) {
2568 hdr->flags |= ISCSI_FLAG_DATA_UNDERFLOW;
2569 hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
2570 }
2571 }
2572 hton24(hdr->dlength, datain->length);
2573 if (hdr->flags & ISCSI_FLAG_DATA_ACK)
2574 int_to_scsilun(cmd->se_cmd.orig_fe_lun,
2575 (struct scsi_lun *)&hdr->lun);
2576 else
2577 put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun);
2578
2579 hdr->itt = cmd->init_task_tag;
2580
2581 if (hdr->flags & ISCSI_FLAG_DATA_ACK)
2582 hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
2583 else
2584 hdr->ttt = cpu_to_be32(0xFFFFFFFF);
2585 if (set_statsn)
2586 hdr->statsn = cpu_to_be32(cmd->stat_sn);
2587 else
2588 hdr->statsn = cpu_to_be32(0xFFFFFFFF);
2589
2590 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
2591 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
2592 hdr->datasn = cpu_to_be32(datain->data_sn);
2593 hdr->offset = cpu_to_be32(datain->offset);
2594
2595 pr_debug("Built DataIN ITT: 0x%08x, StatSN: 0x%08x,"
2596 " DataSN: 0x%08x, Offset: %u, Length: %u, CID: %hu\n",
2597 cmd->init_task_tag, ntohl(hdr->statsn), ntohl(hdr->datasn),
2598 ntohl(hdr->offset), datain->length, conn->cid);
2599}
2600
2601static int iscsit_send_datain(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
2602{
2603 struct iscsi_data_rsp *hdr = (struct iscsi_data_rsp *)&cmd->pdu[0];
2558 struct iscsi_datain datain; 2604 struct iscsi_datain datain;
2559 struct iscsi_datain_req *dr; 2605 struct iscsi_datain_req *dr;
2560 struct iscsi_data_rsp *hdr;
2561 struct kvec *iov; 2606 struct kvec *iov;
2562 int eodr = 0; 2607 u32 iov_count = 0, tx_size = 0;
2563 int ret; 2608 int eodr = 0, ret, iov_ret;
2609 bool set_statsn = false;
2564 2610
2565 memset(&datain, 0, sizeof(struct iscsi_datain)); 2611 memset(&datain, 0, sizeof(struct iscsi_datain));
2566 dr = iscsit_get_datain_values(cmd, &datain); 2612 dr = iscsit_get_datain_values(cmd, &datain);
@@ -2569,7 +2615,6 @@ static int iscsit_send_data_in(
2569 cmd->init_task_tag); 2615 cmd->init_task_tag);
2570 return -1; 2616 return -1;
2571 } 2617 }
2572
2573 /* 2618 /*
2574 * Be paranoid and double check the logic for now. 2619 * Be paranoid and double check the logic for now.
2575 */ 2620 */
@@ -2577,7 +2622,7 @@ static int iscsit_send_data_in(
2577 pr_err("Command ITT: 0x%08x, datain.offset: %u and" 2622 pr_err("Command ITT: 0x%08x, datain.offset: %u and"
2578 " datain.length: %u exceeds cmd->data_length: %u\n", 2623 " datain.length: %u exceeds cmd->data_length: %u\n",
2579 cmd->init_task_tag, datain.offset, datain.length, 2624 cmd->init_task_tag, datain.offset, datain.length,
2580 cmd->se_cmd.data_length); 2625 cmd->se_cmd.data_length);
2581 return -1; 2626 return -1;
2582 } 2627 }
2583 2628
@@ -2601,47 +2646,13 @@ static int iscsit_send_data_in(
2601 (dr->dr_complete == DATAIN_COMPLETE_CONNECTION_RECOVERY)) { 2646 (dr->dr_complete == DATAIN_COMPLETE_CONNECTION_RECOVERY)) {
2602 iscsit_increment_maxcmdsn(cmd, conn->sess); 2647 iscsit_increment_maxcmdsn(cmd, conn->sess);
2603 cmd->stat_sn = conn->stat_sn++; 2648 cmd->stat_sn = conn->stat_sn++;
2604 set_statsn = 1; 2649 set_statsn = true;
2605 } else if (dr->dr_complete == 2650 } else if (dr->dr_complete ==
2606 DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY) 2651 DATAIN_COMPLETE_WITHIN_COMMAND_RECOVERY)
2607 set_statsn = 1; 2652 set_statsn = true;
2608 } 2653 }
2609 2654
2610 hdr = (struct iscsi_data_rsp *) cmd->pdu; 2655 iscsit_build_datain_pdu(cmd, conn, &datain, hdr, set_statsn);
2611 memset(hdr, 0, ISCSI_HDR_LEN);
2612 hdr->opcode = ISCSI_OP_SCSI_DATA_IN;
2613 hdr->flags = datain.flags;
2614 if (hdr->flags & ISCSI_FLAG_DATA_STATUS) {
2615 if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) {
2616 hdr->flags |= ISCSI_FLAG_DATA_OVERFLOW;
2617 hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
2618 } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) {
2619 hdr->flags |= ISCSI_FLAG_DATA_UNDERFLOW;
2620 hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count);
2621 }
2622 }
2623 hton24(hdr->dlength, datain.length);
2624 if (hdr->flags & ISCSI_FLAG_DATA_ACK)
2625 int_to_scsilun(cmd->se_cmd.orig_fe_lun,
2626 (struct scsi_lun *)&hdr->lun);
2627 else
2628 put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun);
2629
2630 hdr->itt = cmd->init_task_tag;
2631
2632 if (hdr->flags & ISCSI_FLAG_DATA_ACK)
2633 hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
2634 else
2635 hdr->ttt = cpu_to_be32(0xFFFFFFFF);
2636 if (set_statsn)
2637 hdr->statsn = cpu_to_be32(cmd->stat_sn);
2638 else
2639 hdr->statsn = cpu_to_be32(0xFFFFFFFF);
2640
2641 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
2642 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
2643 hdr->datasn = cpu_to_be32(datain.data_sn);
2644 hdr->offset = cpu_to_be32(datain.offset);
2645 2656
2646 iov = &cmd->iov_data[0]; 2657 iov = &cmd->iov_data[0];
2647 iov[iov_count].iov_base = cmd->pdu; 2658 iov[iov_count].iov_base = cmd->pdu;
@@ -2652,7 +2663,7 @@ static int iscsit_send_data_in(
2652 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; 2663 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
2653 2664
2654 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, 2665 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
2655 (unsigned char *)hdr, ISCSI_HDR_LEN, 2666 (unsigned char *)cmd->pdu, ISCSI_HDR_LEN,
2656 0, NULL, (u8 *)header_digest); 2667 0, NULL, (u8 *)header_digest);
2657 2668
2658 iov[0].iov_len += ISCSI_CRC_LEN; 2669 iov[0].iov_len += ISCSI_CRC_LEN;
@@ -2662,7 +2673,8 @@ static int iscsit_send_data_in(
2662 " for DataIN PDU 0x%08x\n", *header_digest); 2673 " for DataIN PDU 0x%08x\n", *header_digest);
2663 } 2674 }
2664 2675
2665 iov_ret = iscsit_map_iovec(cmd, &cmd->iov_data[1], datain.offset, datain.length); 2676 iov_ret = iscsit_map_iovec(cmd, &cmd->iov_data[1],
2677 datain.offset, datain.length);
2666 if (iov_ret < 0) 2678 if (iov_ret < 0)
2667 return -1; 2679 return -1;
2668 2680
@@ -2693,11 +2705,6 @@ static int iscsit_send_data_in(
2693 cmd->iov_data_count = iov_count; 2705 cmd->iov_data_count = iov_count;
2694 cmd->tx_size = tx_size; 2706 cmd->tx_size = tx_size;
2695 2707
2696 pr_debug("Built DataIN ITT: 0x%08x, StatSN: 0x%08x,"
2697 " DataSN: 0x%08x, Offset: %u, Length: %u, CID: %hu\n",
2698 cmd->init_task_tag, ntohl(hdr->statsn), ntohl(hdr->datasn),
2699 ntohl(hdr->offset), datain.length, conn->cid);
2700
2701 /* sendpage is preferred but can't insert markers */ 2708 /* sendpage is preferred but can't insert markers */
2702 if (!conn->conn_ops->IFMarker) 2709 if (!conn->conn_ops->IFMarker)
2703 ret = iscsit_fe_sendpage_sg(cmd, conn); 2710 ret = iscsit_fe_sendpage_sg(cmd, conn);
@@ -2720,16 +2727,13 @@ static int iscsit_send_data_in(
2720 return eodr; 2727 return eodr;
2721} 2728}
2722 2729
2723static int iscsit_send_logout_response( 2730int
2724 struct iscsi_cmd *cmd, 2731iscsit_build_logout_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
2725 struct iscsi_conn *conn) 2732 struct iscsi_logout_rsp *hdr)
2726{ 2733{
2727 int niov = 0, tx_size;
2728 struct iscsi_conn *logout_conn = NULL; 2734 struct iscsi_conn *logout_conn = NULL;
2729 struct iscsi_conn_recovery *cr = NULL; 2735 struct iscsi_conn_recovery *cr = NULL;
2730 struct iscsi_session *sess = conn->sess; 2736 struct iscsi_session *sess = conn->sess;
2731 struct kvec *iov;
2732 struct iscsi_logout_rsp *hdr;
2733 /* 2737 /*
2734 * The actual shutting down of Sessions and/or Connections 2738 * The actual shutting down of Sessions and/or Connections
2735 * for CLOSESESSION and CLOSECONNECTION Logout Requests 2739 * for CLOSESESSION and CLOSECONNECTION Logout Requests
@@ -2798,9 +2802,6 @@ static int iscsit_send_logout_response(
2798 return -1; 2802 return -1;
2799 } 2803 }
2800 2804
2801 tx_size = ISCSI_HDR_LEN;
2802 hdr = (struct iscsi_logout_rsp *)cmd->pdu;
2803 memset(hdr, 0, ISCSI_HDR_LEN);
2804 hdr->opcode = ISCSI_OP_LOGOUT_RSP; 2805 hdr->opcode = ISCSI_OP_LOGOUT_RSP;
2805 hdr->flags |= ISCSI_FLAG_CMD_FINAL; 2806 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
2806 hdr->response = cmd->logout_response; 2807 hdr->response = cmd->logout_response;
@@ -2812,6 +2813,27 @@ static int iscsit_send_logout_response(
2812 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); 2813 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
2813 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); 2814 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
2814 2815
2816 pr_debug("Built Logout Response ITT: 0x%08x StatSN:"
2817 " 0x%08x Response: 0x%02x CID: %hu on CID: %hu\n",
2818 cmd->init_task_tag, cmd->stat_sn, hdr->response,
2819 cmd->logout_cid, conn->cid);
2820
2821 return 0;
2822}
2823EXPORT_SYMBOL(iscsit_build_logout_rsp);
2824
2825static int
2826iscsit_send_logout(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
2827{
2828 struct kvec *iov;
2829 int niov = 0, tx_size, rc;
2830
2831 rc = iscsit_build_logout_rsp(cmd, conn,
2832 (struct iscsi_logout_rsp *)&cmd->pdu[0]);
2833 if (rc < 0)
2834 return rc;
2835
2836 tx_size = ISCSI_HDR_LEN;
2815 iov = &cmd->iov_misc[0]; 2837 iov = &cmd->iov_misc[0];
2816 iov[niov].iov_base = cmd->pdu; 2838 iov[niov].iov_base = cmd->pdu;
2817 iov[niov++].iov_len = ISCSI_HDR_LEN; 2839 iov[niov++].iov_len = ISCSI_HDR_LEN;
@@ -2820,7 +2842,7 @@ static int iscsit_send_logout_response(
2820 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; 2842 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
2821 2843
2822 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, 2844 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
2823 (unsigned char *)hdr, ISCSI_HDR_LEN, 2845 (unsigned char *)&cmd->pdu[0], ISCSI_HDR_LEN,
2824 0, NULL, (u8 *)header_digest); 2846 0, NULL, (u8 *)header_digest);
2825 2847
2826 iov[0].iov_len += ISCSI_CRC_LEN; 2848 iov[0].iov_len += ISCSI_CRC_LEN;
@@ -2831,14 +2853,37 @@ static int iscsit_send_logout_response(
2831 cmd->iov_misc_count = niov; 2853 cmd->iov_misc_count = niov;
2832 cmd->tx_size = tx_size; 2854 cmd->tx_size = tx_size;
2833 2855
2834 pr_debug("Sending Logout Response ITT: 0x%08x StatSN:"
2835 " 0x%08x Response: 0x%02x CID: %hu on CID: %hu\n",
2836 cmd->init_task_tag, cmd->stat_sn, hdr->response,
2837 cmd->logout_cid, conn->cid);
2838
2839 return 0; 2856 return 0;
2840} 2857}
2841 2858
2859void
2860iscsit_build_nopin_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
2861 struct iscsi_nopin *hdr, bool nopout_response)
2862{
2863 hdr->opcode = ISCSI_OP_NOOP_IN;
2864 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
2865 hton24(hdr->dlength, cmd->buf_ptr_size);
2866 if (nopout_response)
2867 put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun);
2868 hdr->itt = cmd->init_task_tag;
2869 hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
2870 cmd->stat_sn = (nopout_response) ? conn->stat_sn++ :
2871 conn->stat_sn;
2872 hdr->statsn = cpu_to_be32(cmd->stat_sn);
2873
2874 if (nopout_response)
2875 iscsit_increment_maxcmdsn(cmd, conn->sess);
2876
2877 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
2878 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
2879
2880 pr_debug("Built NOPIN %s Response ITT: 0x%08x, TTT: 0x%08x,"
2881 " StatSN: 0x%08x, Length %u\n", (nopout_response) ?
2882 "Solicitied" : "Unsolicitied", cmd->init_task_tag,
2883 cmd->targ_xfer_tag, cmd->stat_sn, cmd->buf_ptr_size);
2884}
2885EXPORT_SYMBOL(iscsit_build_nopin_rsp);
2886
2842/* 2887/*
2843 * Unsolicited NOPIN, either requesting a response or not. 2888 * Unsolicited NOPIN, either requesting a response or not.
2844 */ 2889 */
@@ -2847,20 +2892,10 @@ static int iscsit_send_unsolicited_nopin(
2847 struct iscsi_conn *conn, 2892 struct iscsi_conn *conn,
2848 int want_response) 2893 int want_response)
2849{ 2894{
2850 int tx_size = ISCSI_HDR_LEN; 2895 struct iscsi_nopin *hdr = (struct iscsi_nopin *)&cmd->pdu[0];
2851 struct iscsi_nopin *hdr; 2896 int tx_size = ISCSI_HDR_LEN, ret;
2852 int ret;
2853 2897
2854 hdr = (struct iscsi_nopin *) cmd->pdu; 2898 iscsit_build_nopin_rsp(cmd, conn, hdr, false);
2855 memset(hdr, 0, ISCSI_HDR_LEN);
2856 hdr->opcode = ISCSI_OP_NOOP_IN;
2857 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
2858 hdr->itt = cmd->init_task_tag;
2859 hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
2860 cmd->stat_sn = conn->stat_sn;
2861 hdr->statsn = cpu_to_be32(cmd->stat_sn);
2862 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
2863 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
2864 2899
2865 if (conn->conn_ops->HeaderDigest) { 2900 if (conn->conn_ops->HeaderDigest) {
2866 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; 2901 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
@@ -2896,31 +2931,17 @@ static int iscsit_send_unsolicited_nopin(
2896 return 0; 2931 return 0;
2897} 2932}
2898 2933
2899static int iscsit_send_nopin_response( 2934static int
2900 struct iscsi_cmd *cmd, 2935iscsit_send_nopin(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
2901 struct iscsi_conn *conn)
2902{ 2936{
2903 int niov = 0, tx_size; 2937 struct iscsi_nopin *hdr = (struct iscsi_nopin *)&cmd->pdu[0];
2904 u32 padding = 0;
2905 struct kvec *iov; 2938 struct kvec *iov;
2906 struct iscsi_nopin *hdr; 2939 u32 padding = 0;
2907 2940 int niov = 0, tx_size;
2908 tx_size = ISCSI_HDR_LEN;
2909 hdr = (struct iscsi_nopin *) cmd->pdu;
2910 memset(hdr, 0, ISCSI_HDR_LEN);
2911 hdr->opcode = ISCSI_OP_NOOP_IN;
2912 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
2913 hton24(hdr->dlength, cmd->buf_ptr_size);
2914 put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun);
2915 hdr->itt = cmd->init_task_tag;
2916 hdr->ttt = cpu_to_be32(cmd->targ_xfer_tag);
2917 cmd->stat_sn = conn->stat_sn++;
2918 hdr->statsn = cpu_to_be32(cmd->stat_sn);
2919 2941
2920 iscsit_increment_maxcmdsn(cmd, conn->sess); 2942 iscsit_build_nopin_rsp(cmd, conn, hdr, true);
2921 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
2922 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
2923 2943
2944 tx_size = ISCSI_HDR_LEN;
2924 iov = &cmd->iov_misc[0]; 2945 iov = &cmd->iov_misc[0];
2925 iov[niov].iov_base = cmd->pdu; 2946 iov[niov].iov_base = cmd->pdu;
2926 iov[niov++].iov_len = ISCSI_HDR_LEN; 2947 iov[niov++].iov_len = ISCSI_HDR_LEN;
@@ -2976,10 +2997,6 @@ static int iscsit_send_nopin_response(
2976 cmd->iov_misc_count = niov; 2997 cmd->iov_misc_count = niov;
2977 cmd->tx_size = tx_size; 2998 cmd->tx_size = tx_size;
2978 2999
2979 pr_debug("Sending NOPIN Response ITT: 0x%08x, TTT:"
2980 " 0x%08x, StatSN: 0x%08x, Length %u\n", cmd->init_task_tag,
2981 cmd->targ_xfer_tag, cmd->stat_sn, cmd->buf_ptr_size);
2982
2983 return 0; 3000 return 0;
2984} 3001}
2985 3002
@@ -3140,24 +3157,16 @@ int iscsit_build_r2ts_for_cmd(
3140 return 0; 3157 return 0;
3141} 3158}
3142 3159
3143static int iscsit_send_status( 3160void iscsit_build_rsp_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
3144 struct iscsi_cmd *cmd, 3161 bool inc_stat_sn, struct iscsi_scsi_rsp *hdr)
3145 struct iscsi_conn *conn)
3146{ 3162{
3147 u8 iov_count = 0, recovery; 3163 if (inc_stat_sn)
3148 u32 padding = 0, tx_size = 0;
3149 struct iscsi_scsi_rsp *hdr;
3150 struct kvec *iov;
3151
3152 recovery = (cmd->i_state != ISTATE_SEND_STATUS);
3153 if (!recovery)
3154 cmd->stat_sn = conn->stat_sn++; 3164 cmd->stat_sn = conn->stat_sn++;
3155 3165
3156 spin_lock_bh(&conn->sess->session_stats_lock); 3166 spin_lock_bh(&conn->sess->session_stats_lock);
3157 conn->sess->rsp_pdus++; 3167 conn->sess->rsp_pdus++;
3158 spin_unlock_bh(&conn->sess->session_stats_lock); 3168 spin_unlock_bh(&conn->sess->session_stats_lock);
3159 3169
3160 hdr = (struct iscsi_scsi_rsp *) cmd->pdu;
3161 memset(hdr, 0, ISCSI_HDR_LEN); 3170 memset(hdr, 0, ISCSI_HDR_LEN);
3162 hdr->opcode = ISCSI_OP_SCSI_CMD_RSP; 3171 hdr->opcode = ISCSI_OP_SCSI_CMD_RSP;
3163 hdr->flags |= ISCSI_FLAG_CMD_FINAL; 3172 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
@@ -3177,6 +3186,23 @@ static int iscsit_send_status(
3177 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); 3186 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
3178 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); 3187 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
3179 3188
3189 pr_debug("Built SCSI Response, ITT: 0x%08x, StatSN: 0x%08x,"
3190 " Response: 0x%02x, SAM Status: 0x%02x, CID: %hu\n",
3191 cmd->init_task_tag, cmd->stat_sn, cmd->se_cmd.scsi_status,
3192 cmd->se_cmd.scsi_status, conn->cid);
3193}
3194EXPORT_SYMBOL(iscsit_build_rsp_pdu);
3195
3196static int iscsit_send_response(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
3197{
3198 struct iscsi_scsi_rsp *hdr = (struct iscsi_scsi_rsp *)&cmd->pdu[0];
3199 struct kvec *iov;
3200 u32 padding = 0, tx_size = 0;
3201 int iov_count = 0;
3202 bool inc_stat_sn = (cmd->i_state == ISTATE_SEND_STATUS);
3203
3204 iscsit_build_rsp_pdu(cmd, conn, inc_stat_sn, hdr);
3205
3180 iov = &cmd->iov_misc[0]; 3206 iov = &cmd->iov_misc[0];
3181 iov[iov_count].iov_base = cmd->pdu; 3207 iov[iov_count].iov_base = cmd->pdu;
3182 iov[iov_count++].iov_len = ISCSI_HDR_LEN; 3208 iov[iov_count++].iov_len = ISCSI_HDR_LEN;
@@ -3231,7 +3257,7 @@ static int iscsit_send_status(
3231 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN]; 3257 u32 *header_digest = (u32 *)&cmd->pdu[ISCSI_HDR_LEN];
3232 3258
3233 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash, 3259 iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
3234 (unsigned char *)hdr, ISCSI_HDR_LEN, 3260 (unsigned char *)cmd->pdu, ISCSI_HDR_LEN,
3235 0, NULL, (u8 *)header_digest); 3261 0, NULL, (u8 *)header_digest);
3236 3262
3237 iov[0].iov_len += ISCSI_CRC_LEN; 3263 iov[0].iov_len += ISCSI_CRC_LEN;
@@ -3243,11 +3269,6 @@ static int iscsit_send_status(
3243 cmd->iov_misc_count = iov_count; 3269 cmd->iov_misc_count = iov_count;
3244 cmd->tx_size = tx_size; 3270 cmd->tx_size = tx_size;
3245 3271
3246 pr_debug("Built %sSCSI Response, ITT: 0x%08x, StatSN: 0x%08x,"
3247 " Response: 0x%02x, SAM Status: 0x%02x, CID: %hu\n",
3248 (!recovery) ? "" : "Recovery ", cmd->init_task_tag,
3249 cmd->stat_sn, 0x00, cmd->se_cmd.scsi_status, conn->cid);
3250
3251 return 0; 3272 return 0;
3252} 3273}
3253 3274
@@ -3270,16 +3291,12 @@ static u8 iscsit_convert_tcm_tmr_rsp(struct se_tmr_req *se_tmr)
3270 } 3291 }
3271} 3292}
3272 3293
3273static int iscsit_send_task_mgt_rsp( 3294void
3274 struct iscsi_cmd *cmd, 3295iscsit_build_task_mgt_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
3275 struct iscsi_conn *conn) 3296 struct iscsi_tm_rsp *hdr)
3276{ 3297{
3277 struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req; 3298 struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
3278 struct iscsi_tm_rsp *hdr;
3279 u32 tx_size = 0;
3280 3299
3281 hdr = (struct iscsi_tm_rsp *) cmd->pdu;
3282 memset(hdr, 0, ISCSI_HDR_LEN);
3283 hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP; 3300 hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP;
3284 hdr->flags = ISCSI_FLAG_CMD_FINAL; 3301 hdr->flags = ISCSI_FLAG_CMD_FINAL;
3285 hdr->response = iscsit_convert_tcm_tmr_rsp(se_tmr); 3302 hdr->response = iscsit_convert_tcm_tmr_rsp(se_tmr);
@@ -3291,6 +3308,20 @@ static int iscsit_send_task_mgt_rsp(
3291 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn); 3308 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
3292 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn); 3309 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
3293 3310
3311 pr_debug("Built Task Management Response ITT: 0x%08x,"
3312 " StatSN: 0x%08x, Response: 0x%02x, CID: %hu\n",
3313 cmd->init_task_tag, cmd->stat_sn, hdr->response, conn->cid);
3314}
3315EXPORT_SYMBOL(iscsit_build_task_mgt_rsp);
3316
3317static int
3318iscsit_send_task_mgt_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
3319{
3320 struct iscsi_tm_rsp *hdr = (struct iscsi_tm_rsp *)&cmd->pdu[0];
3321 u32 tx_size = 0;
3322
3323 iscsit_build_task_mgt_rsp(cmd, conn, hdr);
3324
3294 cmd->iov_misc[0].iov_base = cmd->pdu; 3325 cmd->iov_misc[0].iov_base = cmd->pdu;
3295 cmd->iov_misc[0].iov_len = ISCSI_HDR_LEN; 3326 cmd->iov_misc[0].iov_len = ISCSI_HDR_LEN;
3296 tx_size += ISCSI_HDR_LEN; 3327 tx_size += ISCSI_HDR_LEN;
@@ -3311,10 +3342,6 @@ static int iscsit_send_task_mgt_rsp(
3311 cmd->iov_misc_count = 1; 3342 cmd->iov_misc_count = 1;
3312 cmd->tx_size = tx_size; 3343 cmd->tx_size = tx_size;
3313 3344
3314 pr_debug("Built Task Management Response ITT: 0x%08x,"
3315 " StatSN: 0x%08x, Response: 0x%02x, CID: %hu\n",
3316 cmd->init_task_tag, cmd->stat_sn, hdr->response, conn->cid);
3317
3318 return 0; 3345 return 0;
3319} 3346}
3320 3347
@@ -3510,6 +3537,22 @@ static int iscsit_send_text_rsp(
3510 return 0; 3537 return 0;
3511} 3538}
3512 3539
3540void
3541iscsit_build_reject(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
3542 struct iscsi_reject *hdr)
3543{
3544 hdr->opcode = ISCSI_OP_REJECT;
3545 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
3546 hton24(hdr->dlength, ISCSI_HDR_LEN);
3547 hdr->ffffffff = cpu_to_be32(0xffffffff);
3548 cmd->stat_sn = conn->stat_sn++;
3549 hdr->statsn = cpu_to_be32(cmd->stat_sn);
3550 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
3551 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
3552
3553}
3554EXPORT_SYMBOL(iscsit_build_reject);
3555
3513static int iscsit_send_reject( 3556static int iscsit_send_reject(
3514 struct iscsi_cmd *cmd, 3557 struct iscsi_cmd *cmd,
3515 struct iscsi_conn *conn) 3558 struct iscsi_conn *conn)
@@ -3518,18 +3561,9 @@ static int iscsit_send_reject(
3518 struct iscsi_reject *hdr; 3561 struct iscsi_reject *hdr;
3519 struct kvec *iov; 3562 struct kvec *iov;
3520 3563
3521 hdr = (struct iscsi_reject *) cmd->pdu; 3564 iscsit_build_reject(cmd, conn, (struct iscsi_reject *)&cmd->pdu[0]);
3522 hdr->opcode = ISCSI_OP_REJECT;
3523 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
3524 hton24(hdr->dlength, ISCSI_HDR_LEN);
3525 hdr->ffffffff = cpu_to_be32(0xffffffff);
3526 cmd->stat_sn = conn->stat_sn++;
3527 hdr->statsn = cpu_to_be32(cmd->stat_sn);
3528 hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
3529 hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
3530 3565
3531 iov = &cmd->iov_misc[0]; 3566 iov = &cmd->iov_misc[0];
3532
3533 iov[iov_count].iov_base = cmd->pdu; 3567 iov[iov_count].iov_base = cmd->pdu;
3534 iov[iov_count++].iov_len = ISCSI_HDR_LEN; 3568 iov[iov_count++].iov_len = ISCSI_HDR_LEN;
3535 iov[iov_count].iov_base = cmd->buf_ptr; 3569 iov[iov_count].iov_base = cmd->buf_ptr;
@@ -3626,55 +3660,41 @@ static inline void iscsit_thread_check_cpumask(
3626 set_cpus_allowed_ptr(p, conn->conn_cpumask); 3660 set_cpus_allowed_ptr(p, conn->conn_cpumask);
3627} 3661}
3628 3662
3629static int handle_immediate_queue(struct iscsi_conn *conn) 3663static int
3664iscsit_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state)
3630{ 3665{
3631 struct iscsi_queue_req *qr;
3632 struct iscsi_cmd *cmd;
3633 u8 state;
3634 int ret; 3666 int ret;
3635 3667
3636 while ((qr = iscsit_get_cmd_from_immediate_queue(conn))) { 3668 switch (state) {
3637 atomic_set(&conn->check_immediate_queue, 0); 3669 case ISTATE_SEND_R2T:
3638 cmd = qr->cmd; 3670 ret = iscsit_send_r2t(cmd, conn);
3639 state = qr->state; 3671 if (ret < 0)
3640 kmem_cache_free(lio_qr_cache, qr); 3672 goto err;
3641 3673 break;
3642 switch (state) { 3674 case ISTATE_REMOVE:
3643 case ISTATE_SEND_R2T: 3675 spin_lock_bh(&conn->cmd_lock);
3644 ret = iscsit_send_r2t(cmd, conn); 3676 list_del(&cmd->i_conn_node);
3645 if (ret < 0) 3677 spin_unlock_bh(&conn->cmd_lock);
3646 goto err;
3647 break;
3648 case ISTATE_REMOVE:
3649 if (cmd->data_direction == DMA_TO_DEVICE)
3650 iscsit_stop_dataout_timer(cmd);
3651
3652 spin_lock_bh(&conn->cmd_lock);
3653 list_del(&cmd->i_conn_node);
3654 spin_unlock_bh(&conn->cmd_lock);
3655 3678
3656 iscsit_free_cmd(cmd); 3679 iscsit_free_cmd(cmd);
3657 continue; 3680 break;
3658 case ISTATE_SEND_NOPIN_WANT_RESPONSE: 3681 case ISTATE_SEND_NOPIN_WANT_RESPONSE:
3659 iscsit_mod_nopin_response_timer(conn); 3682 iscsit_mod_nopin_response_timer(conn);
3660 ret = iscsit_send_unsolicited_nopin(cmd, 3683 ret = iscsit_send_unsolicited_nopin(cmd, conn, 1);
3661 conn, 1); 3684 if (ret < 0)
3662 if (ret < 0)
3663 goto err;
3664 break;
3665 case ISTATE_SEND_NOPIN_NO_RESPONSE:
3666 ret = iscsit_send_unsolicited_nopin(cmd,
3667 conn, 0);
3668 if (ret < 0)
3669 goto err;
3670 break;
3671 default:
3672 pr_err("Unknown Opcode: 0x%02x ITT:"
3673 " 0x%08x, i_state: %d on CID: %hu\n",
3674 cmd->iscsi_opcode, cmd->init_task_tag, state,
3675 conn->cid);
3676 goto err; 3685 goto err;
3677 } 3686 break;
3687 case ISTATE_SEND_NOPIN_NO_RESPONSE:
3688 ret = iscsit_send_unsolicited_nopin(cmd, conn, 0);
3689 if (ret < 0)
3690 goto err;
3691 break;
3692 default:
3693 pr_err("Unknown Opcode: 0x%02x ITT:"
3694 " 0x%08x, i_state: %d on CID: %hu\n",
3695 cmd->iscsi_opcode, cmd->init_task_tag, state,
3696 conn->cid);
3697 goto err;
3678 } 3698 }
3679 3699
3680 return 0; 3700 return 0;
@@ -3683,128 +3703,143 @@ err:
3683 return -1; 3703 return -1;
3684} 3704}
3685 3705
3686static int handle_response_queue(struct iscsi_conn *conn) 3706static int
3707iscsit_handle_immediate_queue(struct iscsi_conn *conn)
3687{ 3708{
3709 struct iscsit_transport *t = conn->conn_transport;
3688 struct iscsi_queue_req *qr; 3710 struct iscsi_queue_req *qr;
3689 struct iscsi_cmd *cmd; 3711 struct iscsi_cmd *cmd;
3690 u8 state; 3712 u8 state;
3691 int ret; 3713 int ret;
3692 3714
3693 while ((qr = iscsit_get_cmd_from_response_queue(conn))) { 3715 while ((qr = iscsit_get_cmd_from_immediate_queue(conn))) {
3716 atomic_set(&conn->check_immediate_queue, 0);
3694 cmd = qr->cmd; 3717 cmd = qr->cmd;
3695 state = qr->state; 3718 state = qr->state;
3696 kmem_cache_free(lio_qr_cache, qr); 3719 kmem_cache_free(lio_qr_cache, qr);
3697 3720
3698check_rsp_state: 3721 ret = t->iscsit_immediate_queue(conn, cmd, state);
3699 switch (state) { 3722 if (ret < 0)
3700 case ISTATE_SEND_DATAIN: 3723 return ret;
3701 ret = iscsit_send_data_in(cmd, conn); 3724 }
3702 if (ret < 0)
3703 goto err;
3704 else if (!ret)
3705 /* more drs */
3706 goto check_rsp_state;
3707 else if (ret == 1) {
3708 /* all done */
3709 spin_lock_bh(&cmd->istate_lock);
3710 cmd->i_state = ISTATE_SENT_STATUS;
3711 spin_unlock_bh(&cmd->istate_lock);
3712
3713 if (atomic_read(&conn->check_immediate_queue))
3714 return 1;
3715 3725
3716 continue; 3726 return 0;
3717 } else if (ret == 2) { 3727}
3718 /* Still must send status,
3719 SCF_TRANSPORT_TASK_SENSE was set */
3720 spin_lock_bh(&cmd->istate_lock);
3721 cmd->i_state = ISTATE_SEND_STATUS;
3722 spin_unlock_bh(&cmd->istate_lock);
3723 state = ISTATE_SEND_STATUS;
3724 goto check_rsp_state;
3725 }
3726 3728
3727 break; 3729static int
3728 case ISTATE_SEND_STATUS: 3730iscsit_response_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state)
3729 case ISTATE_SEND_STATUS_RECOVERY: 3731{
3730 ret = iscsit_send_status(cmd, conn); 3732 int ret;
3731 break; 3733
3732 case ISTATE_SEND_LOGOUTRSP: 3734check_rsp_state:
3733 ret = iscsit_send_logout_response(cmd, conn); 3735 switch (state) {
3734 break; 3736 case ISTATE_SEND_DATAIN:
3735 case ISTATE_SEND_ASYNCMSG: 3737 ret = iscsit_send_datain(cmd, conn);
3736 ret = iscsit_send_conn_drop_async_message(
3737 cmd, conn);
3738 break;
3739 case ISTATE_SEND_NOPIN:
3740 ret = iscsit_send_nopin_response(cmd, conn);
3741 break;
3742 case ISTATE_SEND_REJECT:
3743 ret = iscsit_send_reject(cmd, conn);
3744 break;
3745 case ISTATE_SEND_TASKMGTRSP:
3746 ret = iscsit_send_task_mgt_rsp(cmd, conn);
3747 if (ret != 0)
3748 break;
3749 ret = iscsit_tmr_post_handler(cmd, conn);
3750 if (ret != 0)
3751 iscsit_fall_back_to_erl0(conn->sess);
3752 break;
3753 case ISTATE_SEND_TEXTRSP:
3754 ret = iscsit_send_text_rsp(cmd, conn);
3755 break;
3756 default:
3757 pr_err("Unknown Opcode: 0x%02x ITT:"
3758 " 0x%08x, i_state: %d on CID: %hu\n",
3759 cmd->iscsi_opcode, cmd->init_task_tag,
3760 state, conn->cid);
3761 goto err;
3762 }
3763 if (ret < 0) 3738 if (ret < 0)
3764 goto err; 3739 goto err;
3740 else if (!ret)
3741 /* more drs */
3742 goto check_rsp_state;
3743 else if (ret == 1) {
3744 /* all done */
3745 spin_lock_bh(&cmd->istate_lock);
3746 cmd->i_state = ISTATE_SENT_STATUS;
3747 spin_unlock_bh(&cmd->istate_lock);
3765 3748
3766 if (iscsit_send_tx_data(cmd, conn, 1) < 0) { 3749 if (atomic_read(&conn->check_immediate_queue))
3767 iscsit_tx_thread_wait_for_tcp(conn); 3750 return 1;
3768 iscsit_unmap_iovec(cmd);
3769 goto err;
3770 }
3771 iscsit_unmap_iovec(cmd);
3772 3751
3773 switch (state) { 3752 return 0;
3774 case ISTATE_SEND_LOGOUTRSP: 3753 } else if (ret == 2) {
3775 if (!iscsit_logout_post_handler(cmd, conn)) 3754 /* Still must send status,
3776 goto restart; 3755 SCF_TRANSPORT_TASK_SENSE was set */
3777 /* fall through */
3778 case ISTATE_SEND_STATUS:
3779 case ISTATE_SEND_ASYNCMSG:
3780 case ISTATE_SEND_NOPIN:
3781 case ISTATE_SEND_STATUS_RECOVERY:
3782 case ISTATE_SEND_TEXTRSP:
3783 case ISTATE_SEND_TASKMGTRSP:
3784 spin_lock_bh(&cmd->istate_lock); 3756 spin_lock_bh(&cmd->istate_lock);
3785 cmd->i_state = ISTATE_SENT_STATUS; 3757 cmd->i_state = ISTATE_SEND_STATUS;
3786 spin_unlock_bh(&cmd->istate_lock); 3758 spin_unlock_bh(&cmd->istate_lock);
3759 state = ISTATE_SEND_STATUS;
3760 goto check_rsp_state;
3761 }
3762
3763 break;
3764 case ISTATE_SEND_STATUS:
3765 case ISTATE_SEND_STATUS_RECOVERY:
3766 ret = iscsit_send_response(cmd, conn);
3767 break;
3768 case ISTATE_SEND_LOGOUTRSP:
3769 ret = iscsit_send_logout(cmd, conn);
3770 break;
3771 case ISTATE_SEND_ASYNCMSG:
3772 ret = iscsit_send_conn_drop_async_message(
3773 cmd, conn);
3774 break;
3775 case ISTATE_SEND_NOPIN:
3776 ret = iscsit_send_nopin(cmd, conn);
3777 break;
3778 case ISTATE_SEND_REJECT:
3779 ret = iscsit_send_reject(cmd, conn);
3780 break;
3781 case ISTATE_SEND_TASKMGTRSP:
3782 ret = iscsit_send_task_mgt_rsp(cmd, conn);
3783 if (ret != 0)
3787 break; 3784 break;
3788 case ISTATE_SEND_REJECT: 3785 ret = iscsit_tmr_post_handler(cmd, conn);
3789 if (cmd->cmd_flags & ICF_REJECT_FAIL_CONN) { 3786 if (ret != 0)
3790 cmd->cmd_flags &= ~ICF_REJECT_FAIL_CONN; 3787 iscsit_fall_back_to_erl0(conn->sess);
3791 complete(&cmd->reject_comp); 3788 break;
3792 goto err; 3789 case ISTATE_SEND_TEXTRSP:
3793 } 3790 ret = iscsit_send_text_rsp(cmd, conn);
3791 break;
3792 default:
3793 pr_err("Unknown Opcode: 0x%02x ITT:"
3794 " 0x%08x, i_state: %d on CID: %hu\n",
3795 cmd->iscsi_opcode, cmd->init_task_tag,
3796 state, conn->cid);
3797 goto err;
3798 }
3799 if (ret < 0)
3800 goto err;
3801
3802 if (iscsit_send_tx_data(cmd, conn, 1) < 0) {
3803 iscsit_tx_thread_wait_for_tcp(conn);
3804 iscsit_unmap_iovec(cmd);
3805 goto err;
3806 }
3807 iscsit_unmap_iovec(cmd);
3808
3809 switch (state) {
3810 case ISTATE_SEND_LOGOUTRSP:
3811 if (!iscsit_logout_post_handler(cmd, conn))
3812 goto restart;
3813 /* fall through */
3814 case ISTATE_SEND_STATUS:
3815 case ISTATE_SEND_ASYNCMSG:
3816 case ISTATE_SEND_NOPIN:
3817 case ISTATE_SEND_STATUS_RECOVERY:
3818 case ISTATE_SEND_TEXTRSP:
3819 case ISTATE_SEND_TASKMGTRSP:
3820 spin_lock_bh(&cmd->istate_lock);
3821 cmd->i_state = ISTATE_SENT_STATUS;
3822 spin_unlock_bh(&cmd->istate_lock);
3823 break;
3824 case ISTATE_SEND_REJECT:
3825 if (cmd->cmd_flags & ICF_REJECT_FAIL_CONN) {
3826 cmd->cmd_flags &= ~ICF_REJECT_FAIL_CONN;
3794 complete(&cmd->reject_comp); 3827 complete(&cmd->reject_comp);
3795 break;
3796 default:
3797 pr_err("Unknown Opcode: 0x%02x ITT:"
3798 " 0x%08x, i_state: %d on CID: %hu\n",
3799 cmd->iscsi_opcode, cmd->init_task_tag,
3800 cmd->i_state, conn->cid);
3801 goto err; 3828 goto err;
3802 } 3829 }
3803 3830 complete(&cmd->reject_comp);
3804 if (atomic_read(&conn->check_immediate_queue)) 3831 break;
3805 return 1; 3832 default:
3833 pr_err("Unknown Opcode: 0x%02x ITT:"
3834 " 0x%08x, i_state: %d on CID: %hu\n",
3835 cmd->iscsi_opcode, cmd->init_task_tag,
3836 cmd->i_state, conn->cid);
3837 goto err;
3806 } 3838 }
3807 3839
3840 if (atomic_read(&conn->check_immediate_queue))
3841 return 1;
3842
3808 return 0; 3843 return 0;
3809 3844
3810err: 3845err:
@@ -3813,6 +3848,27 @@ restart:
3813 return -EAGAIN; 3848 return -EAGAIN;
3814} 3849}
3815 3850
3851static int iscsit_handle_response_queue(struct iscsi_conn *conn)
3852{
3853 struct iscsit_transport *t = conn->conn_transport;
3854 struct iscsi_queue_req *qr;
3855 struct iscsi_cmd *cmd;
3856 u8 state;
3857 int ret;
3858
3859 while ((qr = iscsit_get_cmd_from_response_queue(conn))) {
3860 cmd = qr->cmd;
3861 state = qr->state;
3862 kmem_cache_free(lio_qr_cache, qr);
3863
3864 ret = t->iscsit_response_queue(conn, cmd, state);
3865 if (ret == 1 || ret < 0)
3866 return ret;
3867 }
3868
3869 return 0;
3870}
3871
3816int iscsi_target_tx_thread(void *arg) 3872int iscsi_target_tx_thread(void *arg)
3817{ 3873{
3818 int ret = 0; 3874 int ret = 0;
@@ -3847,11 +3903,11 @@ restart:
3847 goto transport_err; 3903 goto transport_err;
3848 3904
3849get_immediate: 3905get_immediate:
3850 ret = handle_immediate_queue(conn); 3906 ret = iscsit_handle_immediate_queue(conn);
3851 if (ret < 0) 3907 if (ret < 0)
3852 goto transport_err; 3908 goto transport_err;
3853 3909
3854 ret = handle_response_queue(conn); 3910 ret = iscsit_handle_response_queue(conn);
3855 if (ret == 1) 3911 if (ret == 1)
3856 goto get_immediate; 3912 goto get_immediate;
3857 else if (ret == -EAGAIN) 3913 else if (ret == -EAGAIN)
@@ -4451,7 +4507,7 @@ static void iscsit_logout_post_handler_diffcid(
4451/* 4507/*
4452 * Return of 0 causes the TX thread to restart. 4508 * Return of 0 causes the TX thread to restart.
4453 */ 4509 */
4454static int iscsit_logout_post_handler( 4510int iscsit_logout_post_handler(
4455 struct iscsi_cmd *cmd, 4511 struct iscsi_cmd *cmd,
4456 struct iscsi_conn *conn) 4512 struct iscsi_conn *conn)
4457{ 4513{
@@ -4509,6 +4565,7 @@ static int iscsit_logout_post_handler(
4509 } 4565 }
4510 return ret; 4566 return ret;
4511} 4567}
4568EXPORT_SYMBOL(iscsit_logout_post_handler);
4512 4569
4513void iscsit_fail_session(struct iscsi_session *sess) 4570void iscsit_fail_session(struct iscsi_session *sess)
4514{ 4571{
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
index ce3d3210fe41..2704daf6ba74 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -27,6 +27,7 @@
27#include <target/target_core_fabric_configfs.h> 27#include <target/target_core_fabric_configfs.h>
28#include <target/target_core_configfs.h> 28#include <target/target_core_configfs.h>
29#include <target/configfs_macros.h> 29#include <target/configfs_macros.h>
30#include <target/iscsi/iscsi_transport.h>
30 31
31#include "iscsi_target_core.h" 32#include "iscsi_target_core.h"
32#include "iscsi_target_parameters.h" 33#include "iscsi_target_parameters.h"
@@ -1536,7 +1537,8 @@ static int lio_queue_data_in(struct se_cmd *se_cmd)
1536 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); 1537 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
1537 1538
1538 cmd->i_state = ISTATE_SEND_DATAIN; 1539 cmd->i_state = ISTATE_SEND_DATAIN;
1539 iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state); 1540 cmd->conn->conn_transport->iscsit_queue_data_in(cmd->conn, cmd);
1541
1540 return 0; 1542 return 0;
1541} 1543}
1542 1544
@@ -1568,7 +1570,8 @@ static int lio_queue_status(struct se_cmd *se_cmd)
1568 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd); 1570 struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
1569 1571
1570 cmd->i_state = ISTATE_SEND_STATUS; 1572 cmd->i_state = ISTATE_SEND_STATUS;
1571 iscsit_add_cmd_to_response_queue(cmd, cmd->conn, cmd->i_state); 1573 cmd->conn->conn_transport->iscsit_queue_status(cmd->conn, cmd);
1574
1572 return 0; 1575 return 0;
1573} 1576}
1574 1577
diff --git a/drivers/target/iscsi/iscsi_target_device.c b/drivers/target/iscsi/iscsi_target_device.c
index bcc409853a67..1b74033510a0 100644
--- a/drivers/target/iscsi/iscsi_target_device.c
+++ b/drivers/target/iscsi/iscsi_target_device.c
@@ -60,8 +60,13 @@ void iscsit_increment_maxcmdsn(struct iscsi_cmd *cmd, struct iscsi_session *sess
60 60
61 cmd->maxcmdsn_inc = 1; 61 cmd->maxcmdsn_inc = 1;
62 62
63 mutex_lock(&sess->cmdsn_mutex); 63 if (!mutex_trylock(&sess->cmdsn_mutex)) {
64 sess->max_cmd_sn += 1;
65 pr_debug("Updated MaxCmdSN to 0x%08x\n", sess->max_cmd_sn);
66 return;
67 }
64 sess->max_cmd_sn += 1; 68 sess->max_cmd_sn += 1;
65 pr_debug("Updated MaxCmdSN to 0x%08x\n", sess->max_cmd_sn); 69 pr_debug("Updated MaxCmdSN to 0x%08x\n", sess->max_cmd_sn);
66 mutex_unlock(&sess->cmdsn_mutex); 70 mutex_unlock(&sess->cmdsn_mutex);
67} 71}
72EXPORT_SYMBOL(iscsit_increment_maxcmdsn);
diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c
index 16ca0ef9266f..b997e5da47d3 100644
--- a/drivers/target/iscsi/iscsi_target_tmr.c
+++ b/drivers/target/iscsi/iscsi_target_tmr.c
@@ -472,6 +472,7 @@ int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
472 472
473 return 0; 473 return 0;
474} 474}
475EXPORT_SYMBOL(iscsit_tmr_post_handler);
475 476
476/* 477/*
477 * Nothing to do here, but leave it for good measure. :-) 478 * Nothing to do here, but leave it for good measure. :-)