aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libiscsi.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2007-12-13 13:43:20 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-11 19:28:19 -0500
commit843c0a8a76078cf961b244b839683d0667313740 (patch)
tree3feaf71c8e67f38e10e78e315bbc8623dcf38a3d /drivers/scsi/libiscsi.c
parent8ae732a91df051aba6820068a47b631a06599d84 (diff)
[SCSI] libiscsi, iscsi_tcp: add device support
This patch adds logical unit reset support. This should work for ib_iser, but I have not finished testing that driver so it is not hooked in yet. This patch also temporarily reverts the iscsi_tcp r2t write out patch. That code is completely rewritten in this patchset. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r--drivers/scsi/libiscsi.c494
1 files changed, 281 insertions, 213 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 8b57af5baaec..176458f35316 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -86,7 +86,7 @@ iscsi_update_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr)
86 * xmit thread 86 * xmit thread
87 */ 87 */
88 if (!list_empty(&session->leadconn->xmitqueue) || 88 if (!list_empty(&session->leadconn->xmitqueue) ||
89 __kfifo_len(session->leadconn->mgmtqueue)) 89 !list_empty(&session->leadconn->mgmtqueue))
90 scsi_queue_work(session->host, 90 scsi_queue_work(session->host,
91 &session->leadconn->xmitwork); 91 &session->leadconn->xmitwork);
92 } 92 }
@@ -318,15 +318,15 @@ static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
318 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; 318 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
319 conn->tmfrsp_pdus_cnt++; 319 conn->tmfrsp_pdus_cnt++;
320 320
321 if (conn->tmabort_state != TMABORT_INITIAL) 321 if (conn->tmf_state != TMF_QUEUED)
322 return; 322 return;
323 323
324 if (tmf->response == ISCSI_TMF_RSP_COMPLETE) 324 if (tmf->response == ISCSI_TMF_RSP_COMPLETE)
325 conn->tmabort_state = TMABORT_SUCCESS; 325 conn->tmf_state = TMF_SUCCESS;
326 else if (tmf->response == ISCSI_TMF_RSP_NO_TASK) 326 else if (tmf->response == ISCSI_TMF_RSP_NO_TASK)
327 conn->tmabort_state = TMABORT_NOT_FOUND; 327 conn->tmf_state = TMF_NOT_FOUND;
328 else 328 else
329 conn->tmabort_state = TMABORT_FAILED; 329 conn->tmf_state = TMF_FAILED;
330 wake_up(&conn->ehwait); 330 wake_up(&conn->ehwait);
331} 331}
332 332
@@ -429,7 +429,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
429 */ 429 */
430 if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) 430 if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen))
431 rc = ISCSI_ERR_CONN_FAILED; 431 rc = ISCSI_ERR_CONN_FAILED;
432 list_del(&mtask->running); 432 list_del_init(&mtask->running);
433 if (conn->login_mtask != mtask) 433 if (conn->login_mtask != mtask)
434 __kfifo_put(session->mgmtpool.queue, 434 __kfifo_put(session->mgmtpool.queue,
435 (void*)&mtask, sizeof(void*)); 435 (void*)&mtask, sizeof(void*));
@@ -451,10 +451,9 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
451 451
452 if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) 452 if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen))
453 rc = ISCSI_ERR_CONN_FAILED; 453 rc = ISCSI_ERR_CONN_FAILED;
454 list_del(&mtask->running); 454 list_del_init(&mtask->running);
455 if (conn->login_mtask != mtask) 455 __kfifo_put(session->mgmtpool.queue,
456 __kfifo_put(session->mgmtpool.queue, 456 (void*)&mtask, sizeof(void*));
457 (void*)&mtask, sizeof(void*));
458 break; 457 break;
459 default: 458 default:
460 rc = ISCSI_ERR_BAD_OPCODE; 459 rc = ISCSI_ERR_BAD_OPCODE;
@@ -609,7 +608,8 @@ static void iscsi_prep_mtask(struct iscsi_conn *conn,
609 session->tt->init_mgmt_task(conn, mtask); 608 session->tt->init_mgmt_task(conn, mtask);
610 609
611 debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n", 610 debug_scsi("mgmtpdu [op 0x%x hdr->itt 0x%x datalen %d]\n",
612 hdr->opcode, hdr->itt, mtask->data_count); 611 hdr->opcode & ISCSI_OPCODE_MASK, hdr->itt,
612 mtask->data_count);
613} 613}
614 614
615static int iscsi_xmit_mtask(struct iscsi_conn *conn) 615static int iscsi_xmit_mtask(struct iscsi_conn *conn)
@@ -658,21 +658,13 @@ static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn)
658static int iscsi_xmit_ctask(struct iscsi_conn *conn) 658static int iscsi_xmit_ctask(struct iscsi_conn *conn)
659{ 659{
660 struct iscsi_cmd_task *ctask = conn->ctask; 660 struct iscsi_cmd_task *ctask = conn->ctask;
661 int rc = 0; 661 int rc;
662
663 /*
664 * serialize with TMF AbortTask
665 */
666 if (ctask->state == ISCSI_TASK_ABORTING)
667 goto done;
668 662
669 __iscsi_get_ctask(ctask); 663 __iscsi_get_ctask(ctask);
670 spin_unlock_bh(&conn->session->lock); 664 spin_unlock_bh(&conn->session->lock);
671 rc = conn->session->tt->xmit_cmd_task(conn, ctask); 665 rc = conn->session->tt->xmit_cmd_task(conn, ctask);
672 spin_lock_bh(&conn->session->lock); 666 spin_lock_bh(&conn->session->lock);
673 __iscsi_put_ctask(ctask); 667 __iscsi_put_ctask(ctask);
674
675done:
676 if (!rc) 668 if (!rc)
677 /* done with this ctask */ 669 /* done with this ctask */
678 conn->ctask = NULL; 670 conn->ctask = NULL;
@@ -680,6 +672,22 @@ done:
680} 672}
681 673
682/** 674/**
675 * iscsi_requeue_ctask - requeue ctask to run from session workqueue
676 * @ctask: ctask to requeue
677 *
678 * LLDs that need to run a ctask from the session workqueue should call
679 * this. The session lock must be held.
680 */
681void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask)
682{
683 struct iscsi_conn *conn = ctask->conn;
684
685 list_move_tail(&ctask->running, &conn->requeue);
686 scsi_queue_work(conn->session->host, &conn->xmitwork);
687}
688EXPORT_SYMBOL_GPL(iscsi_requeue_ctask);
689
690/**
683 * iscsi_data_xmit - xmit any command into the scheduled connection 691 * iscsi_data_xmit - xmit any command into the scheduled connection
684 * @conn: iscsi connection 692 * @conn: iscsi connection
685 * 693 *
@@ -717,36 +725,27 @@ static int iscsi_data_xmit(struct iscsi_conn *conn)
717 * overflow us with nop-ins 725 * overflow us with nop-ins
718 */ 726 */
719check_mgmt: 727check_mgmt:
720 while (__kfifo_get(conn->mgmtqueue, (void*)&conn->mtask, 728 while (!list_empty(&conn->mgmtqueue)) {
721 sizeof(void*))) { 729 conn->mtask = list_entry(conn->mgmtqueue.next,
730 struct iscsi_mgmt_task, running);
722 iscsi_prep_mtask(conn, conn->mtask); 731 iscsi_prep_mtask(conn, conn->mtask);
723 list_add_tail(&conn->mtask->running, &conn->mgmt_run_list); 732 list_move_tail(conn->mgmtqueue.next, &conn->mgmt_run_list);
724 rc = iscsi_xmit_mtask(conn); 733 rc = iscsi_xmit_mtask(conn);
725 if (rc) 734 if (rc)
726 goto again; 735 goto again;
727 } 736 }
728 737
729 /* process command queue */ 738 /* process pending command queue */
730 while (!list_empty(&conn->xmitqueue)) { 739 while (!list_empty(&conn->xmitqueue)) {
731 /* 740 if (conn->tmf_state == TMF_QUEUED)
732 * iscsi tcp may readd the task to the xmitqueue to send 741 break;
733 * write data 742
734 */
735 conn->ctask = list_entry(conn->xmitqueue.next, 743 conn->ctask = list_entry(conn->xmitqueue.next,
736 struct iscsi_cmd_task, running); 744 struct iscsi_cmd_task, running);
737 switch (conn->ctask->state) { 745 iscsi_prep_scsi_cmd_pdu(conn->ctask);
738 case ISCSI_TASK_ABORTING: 746 conn->session->tt->init_cmd_task(conn->ctask);
739 break; 747 conn->ctask->state = ISCSI_TASK_RUNNING;
740 case ISCSI_TASK_PENDING:
741 iscsi_prep_scsi_cmd_pdu(conn->ctask);
742 conn->session->tt->init_cmd_task(conn->ctask);
743 /* fall through */
744 default:
745 conn->ctask->state = ISCSI_TASK_RUNNING;
746 break;
747 }
748 list_move_tail(conn->xmitqueue.next, &conn->run_list); 748 list_move_tail(conn->xmitqueue.next, &conn->run_list);
749
750 rc = iscsi_xmit_ctask(conn); 749 rc = iscsi_xmit_ctask(conn);
751 if (rc) 750 if (rc)
752 goto again; 751 goto again;
@@ -755,7 +754,22 @@ check_mgmt:
755 * we need to check the mgmt queue for nops that need to 754 * we need to check the mgmt queue for nops that need to
756 * be sent to aviod starvation 755 * be sent to aviod starvation
757 */ 756 */
758 if (__kfifo_len(conn->mgmtqueue)) 757 if (!list_empty(&conn->mgmtqueue))
758 goto check_mgmt;
759 }
760
761 while (!list_empty(&conn->requeue)) {
762 if (conn->session->fast_abort && conn->tmf_state != TMF_INITIAL)
763 break;
764
765 conn->ctask = list_entry(conn->requeue.next,
766 struct iscsi_cmd_task, running);
767 conn->ctask->state = ISCSI_TASK_RUNNING;
768 list_move_tail(conn->requeue.next, &conn->run_list);
769 rc = iscsi_xmit_ctask(conn);
770 if (rc)
771 goto again;
772 if (!list_empty(&conn->mgmtqueue))
759 goto check_mgmt; 773 goto check_mgmt;
760 } 774 }
761 spin_unlock_bh(&conn->session->lock); 775 spin_unlock_bh(&conn->session->lock);
@@ -859,7 +873,6 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
859 873
860 atomic_set(&ctask->refcount, 1); 874 atomic_set(&ctask->refcount, 1);
861 ctask->state = ISCSI_TASK_PENDING; 875 ctask->state = ISCSI_TASK_PENDING;
862 ctask->mtask = NULL;
863 ctask->conn = conn; 876 ctask->conn = conn;
864 ctask->sc = sc; 877 ctask->sc = sc;
865 INIT_LIST_HEAD(&ctask->running); 878 INIT_LIST_HEAD(&ctask->running);
@@ -929,9 +942,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
929 } else 942 } else
930 mtask->data_count = 0; 943 mtask->data_count = 0;
931 944
932 INIT_LIST_HEAD(&mtask->running);
933 memcpy(mtask->hdr, hdr, sizeof(struct iscsi_hdr)); 945 memcpy(mtask->hdr, hdr, sizeof(struct iscsi_hdr));
934 __kfifo_put(conn->mgmtqueue, (void*)&mtask, sizeof(void*)); 946 INIT_LIST_HEAD(&mtask->running);
947 list_add_tail(&mtask->running, &conn->mgmtqueue);
935 return mtask; 948 return mtask;
936} 949}
937 950
@@ -954,13 +967,12 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu);
954void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session) 967void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session)
955{ 968{
956 struct iscsi_session *session = class_to_transport_session(cls_session); 969 struct iscsi_session *session = class_to_transport_session(cls_session);
957 struct iscsi_conn *conn = session->leadconn;
958 970
959 spin_lock_bh(&session->lock); 971 spin_lock_bh(&session->lock);
960 if (session->state != ISCSI_STATE_LOGGED_IN) { 972 if (session->state != ISCSI_STATE_LOGGED_IN) {
961 session->state = ISCSI_STATE_RECOVERY_FAILED; 973 session->state = ISCSI_STATE_RECOVERY_FAILED;
962 if (conn) 974 if (session->leadconn)
963 wake_up(&conn->ehwait); 975 wake_up(&session->leadconn->ehwait);
964 } 976 }
965 spin_unlock_bh(&session->lock); 977 spin_unlock_bh(&session->lock);
966} 978}
@@ -971,7 +983,6 @@ int iscsi_eh_host_reset(struct scsi_cmnd *sc)
971 struct Scsi_Host *host = sc->device->host; 983 struct Scsi_Host *host = sc->device->host;
972 struct iscsi_session *session = iscsi_hostdata(host->hostdata); 984 struct iscsi_session *session = iscsi_hostdata(host->hostdata);
973 struct iscsi_conn *conn = session->leadconn; 985 struct iscsi_conn *conn = session->leadconn;
974 int fail_session = 0;
975 986
976 spin_lock_bh(&session->lock); 987 spin_lock_bh(&session->lock);
977 if (session->state == ISCSI_STATE_TERMINATE) { 988 if (session->state == ISCSI_STATE_TERMINATE) {
@@ -982,19 +993,13 @@ failed:
982 return FAILED; 993 return FAILED;
983 } 994 }
984 995
985 if (sc->SCp.phase == session->age) {
986 debug_scsi("failing connection CID %d due to SCSI host reset\n",
987 conn->id);
988 fail_session = 1;
989 }
990 spin_unlock_bh(&session->lock); 996 spin_unlock_bh(&session->lock);
991 997
992 /* 998 /*
993 * we drop the lock here but the leadconn cannot be destoyed while 999 * we drop the lock here but the leadconn cannot be destoyed while
994 * we are in the scsi eh 1000 * we are in the scsi eh
995 */ 1001 */
996 if (fail_session) 1002 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
997 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
998 1003
999 debug_scsi("iscsi_eh_host_reset wait for relogin\n"); 1004 debug_scsi("iscsi_eh_host_reset wait for relogin\n");
1000 wait_event_interruptible(conn->ehwait, 1005 wait_event_interruptible(conn->ehwait,
@@ -1015,62 +1020,43 @@ failed:
1015} 1020}
1016EXPORT_SYMBOL_GPL(iscsi_eh_host_reset); 1021EXPORT_SYMBOL_GPL(iscsi_eh_host_reset);
1017 1022
1018static void iscsi_tmabort_timedout(unsigned long data) 1023static void iscsi_tmf_timedout(unsigned long data)
1019{ 1024{
1020 struct iscsi_cmd_task *ctask = (struct iscsi_cmd_task *)data; 1025 struct iscsi_conn *conn = (struct iscsi_conn *)data;
1021 struct iscsi_conn *conn = ctask->conn;
1022 struct iscsi_session *session = conn->session; 1026 struct iscsi_session *session = conn->session;
1023 1027
1024 spin_lock(&session->lock); 1028 spin_lock(&session->lock);
1025 if (conn->tmabort_state == TMABORT_INITIAL) { 1029 if (conn->tmf_state == TMF_QUEUED) {
1026 conn->tmabort_state = TMABORT_TIMEDOUT; 1030 conn->tmf_state = TMF_TIMEDOUT;
1027 debug_scsi("tmabort timedout [sc %p itt 0x%x]\n", 1031 debug_scsi("tmf timedout\n");
1028 ctask->sc, ctask->itt);
1029 /* unblock eh_abort() */ 1032 /* unblock eh_abort() */
1030 wake_up(&conn->ehwait); 1033 wake_up(&conn->ehwait);
1031 } 1034 }
1032 spin_unlock(&session->lock); 1035 spin_unlock(&session->lock);
1033} 1036}
1034 1037
1035static int iscsi_exec_abort_task(struct scsi_cmnd *sc, 1038static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
1036 struct iscsi_cmd_task *ctask) 1039 struct iscsi_tm *hdr, int age)
1037{ 1040{
1038 struct iscsi_conn *conn = ctask->conn;
1039 struct iscsi_session *session = conn->session; 1041 struct iscsi_session *session = conn->session;
1040 struct iscsi_tm *hdr = &conn->tmhdr; 1042 struct iscsi_mgmt_task *mtask;
1041
1042 /*
1043 * ctask timed out but session is OK requests must be serialized.
1044 */
1045 memset(hdr, 0, sizeof(struct iscsi_tm));
1046 hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE;
1047 hdr->flags = ISCSI_TM_FUNC_ABORT_TASK;
1048 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
1049 memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
1050 hdr->rtt = ctask->hdr->itt;
1051 hdr->refcmdsn = ctask->hdr->cmdsn;
1052 1043
1053 ctask->mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, 1044 mtask = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr,
1054 NULL, 0); 1045 NULL, 0);
1055 if (!ctask->mtask) { 1046 if (!mtask) {
1056 spin_unlock_bh(&session->lock); 1047 spin_unlock_bh(&session->lock);
1057 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); 1048 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
1058 spin_lock_bh(&session->lock) 1049 spin_lock_bh(&session->lock);
1059 debug_scsi("abort sent failure [itt 0x%x]\n", ctask->itt); 1050 debug_scsi("tmf exec failure\n");
1060 return -EPERM; 1051 return -EPERM;
1061 } 1052 }
1062 ctask->state = ISCSI_TASK_ABORTING; 1053 conn->tmfcmd_pdus_cnt++;
1063 1054 conn->tmf_timer.expires = 30 * HZ + jiffies;
1064 debug_scsi("abort sent [itt 0x%x]\n", ctask->itt); 1055 conn->tmf_timer.function = iscsi_tmf_timedout;
1056 conn->tmf_timer.data = (unsigned long)conn;
1057 add_timer(&conn->tmf_timer);
1058 debug_scsi("tmf set timeout\n");
1065 1059
1066 if (conn->tmabort_state == TMABORT_INITIAL) {
1067 conn->tmfcmd_pdus_cnt++;
1068 conn->tmabort_timer.expires = 20*HZ + jiffies;
1069 conn->tmabort_timer.function = iscsi_tmabort_timedout;
1070 conn->tmabort_timer.data = (unsigned long)ctask;
1071 add_timer(&conn->tmabort_timer);
1072 debug_scsi("abort set timeout [itt 0x%x]\n", ctask->itt);
1073 }
1074 spin_unlock_bh(&session->lock); 1060 spin_unlock_bh(&session->lock);
1075 mutex_unlock(&session->eh_mutex); 1061 mutex_unlock(&session->eh_mutex);
1076 scsi_queue_work(session->host, &conn->xmitwork); 1062 scsi_queue_work(session->host, &conn->xmitwork);
@@ -1078,61 +1064,30 @@ static int iscsi_exec_abort_task(struct scsi_cmnd *sc,
1078 /* 1064 /*
1079 * block eh thread until: 1065 * block eh thread until:
1080 * 1066 *
1081 * 1) abort response 1067 * 1) tmf response
1082 * 2) abort timeout 1068 * 2) tmf timeout
1083 * 3) session is terminated or restarted or userspace has 1069 * 3) session is terminated or restarted or userspace has
1084 * given up on recovery 1070 * given up on recovery
1085 */ 1071 */
1086 wait_event_interruptible(conn->ehwait, 1072 wait_event_interruptible(conn->ehwait, age != session->age ||
1087 sc->SCp.phase != session->age ||
1088 session->state != ISCSI_STATE_LOGGED_IN || 1073 session->state != ISCSI_STATE_LOGGED_IN ||
1089 conn->tmabort_state != TMABORT_INITIAL); 1074 conn->tmf_state != TMF_QUEUED);
1090 if (signal_pending(current)) 1075 if (signal_pending(current))
1091 flush_signals(current); 1076 flush_signals(current);
1092 del_timer_sync(&conn->tmabort_timer); 1077 del_timer_sync(&conn->tmf_timer);
1078
1093 mutex_lock(&session->eh_mutex); 1079 mutex_lock(&session->eh_mutex);
1094 spin_lock_bh(&session->lock); 1080 spin_lock_bh(&session->lock);
1095 return 0; 1081 /* if the session drops it will clean up the mtask */
1096} 1082 if (age != session->age ||
1097 1083 session->state != ISCSI_STATE_LOGGED_IN)
1098/* 1084 return -ENOTCONN;
1099 * session lock must be held
1100 */
1101static struct iscsi_mgmt_task *
1102iscsi_remove_mgmt_task(struct kfifo *fifo, uint32_t itt)
1103{
1104 int i, nr_tasks = __kfifo_len(fifo) / sizeof(void*);
1105 struct iscsi_mgmt_task *task;
1106
1107 debug_scsi("searching %d tasks\n", nr_tasks);
1108
1109 for (i = 0; i < nr_tasks; i++) {
1110 __kfifo_get(fifo, (void*)&task, sizeof(void*));
1111 debug_scsi("check task %u\n", task->itt);
1112
1113 if (task->itt == itt) {
1114 debug_scsi("matched task\n");
1115 return task;
1116 }
1117 1085
1118 __kfifo_put(fifo, (void*)&task, sizeof(void*)); 1086 if (!list_empty(&mtask->running)) {
1087 list_del_init(&mtask->running);
1088 __kfifo_put(session->mgmtpool.queue, (void*)&mtask,
1089 sizeof(void*));
1119 } 1090 }
1120 return NULL;
1121}
1122
1123static int iscsi_ctask_mtask_cleanup(struct iscsi_cmd_task *ctask)
1124{
1125 struct iscsi_conn *conn = ctask->conn;
1126 struct iscsi_session *session = conn->session;
1127
1128 if (!ctask->mtask)
1129 return -EINVAL;
1130
1131 if (!iscsi_remove_mgmt_task(conn->mgmtqueue, ctask->mtask->itt))
1132 list_del(&ctask->mtask->running);
1133 __kfifo_put(session->mgmtpool.queue, (void*)&ctask->mtask,
1134 sizeof(void*));
1135 ctask->mtask = NULL;
1136 return 0; 1091 return 0;
1137} 1092}
1138 1093
@@ -1156,7 +1111,6 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1156 conn->session->queued_cmdsn--; 1111 conn->session->queued_cmdsn--;
1157 else 1112 else
1158 conn->session->tt->cleanup_cmd_task(conn, ctask); 1113 conn->session->tt->cleanup_cmd_task(conn, ctask);
1159 iscsi_ctask_mtask_cleanup(ctask);
1160 1114
1161 sc->result = err; 1115 sc->result = err;
1162 scsi_set_resid(sc, scsi_bufflen(sc)); 1116 scsi_set_resid(sc, scsi_bufflen(sc));
@@ -1166,6 +1120,44 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1166 __iscsi_put_ctask(ctask); 1120 __iscsi_put_ctask(ctask);
1167} 1121}
1168 1122
1123/*
1124 * Fail commands. session lock held and recv side suspended and xmit
1125 * thread flushed
1126 */
1127static void fail_all_commands(struct iscsi_conn *conn, unsigned lun)
1128{
1129 struct iscsi_cmd_task *ctask, *tmp;
1130
1131 if (conn->ctask && (conn->ctask->sc->device->lun == lun || lun == -1))
1132 conn->ctask = NULL;
1133
1134 /* flush pending */
1135 list_for_each_entry_safe(ctask, tmp, &conn->xmitqueue, running) {
1136 if (lun == ctask->sc->device->lun || lun == -1) {
1137 debug_scsi("failing pending sc %p itt 0x%x\n",
1138 ctask->sc, ctask->itt);
1139 fail_command(conn, ctask, DID_BUS_BUSY << 16);
1140 }
1141 }
1142
1143 list_for_each_entry_safe(ctask, tmp, &conn->requeue, running) {
1144 if (lun == ctask->sc->device->lun || lun == -1) {
1145 debug_scsi("failing requeued sc %p itt 0x%x\n",
1146 ctask->sc, ctask->itt);
1147 fail_command(conn, ctask, DID_BUS_BUSY << 16);
1148 }
1149 }
1150
1151 /* fail all other running */
1152 list_for_each_entry_safe(ctask, tmp, &conn->run_list, running) {
1153 if (lun == ctask->sc->device->lun || lun == -1) {
1154 debug_scsi("failing in progress sc %p itt 0x%x\n",
1155 ctask->sc, ctask->itt);
1156 fail_command(conn, ctask, DID_BUS_BUSY << 16);
1157 }
1158 }
1159}
1160
1169static void iscsi_suspend_tx(struct iscsi_conn *conn) 1161static void iscsi_suspend_tx(struct iscsi_conn *conn)
1170{ 1162{
1171 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); 1163 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
@@ -1178,13 +1170,26 @@ static void iscsi_start_tx(struct iscsi_conn *conn)
1178 scsi_queue_work(conn->session->host, &conn->xmitwork); 1170 scsi_queue_work(conn->session->host, &conn->xmitwork);
1179} 1171}
1180 1172
1173static void iscsi_prep_abort_task_pdu(struct iscsi_cmd_task *ctask,
1174 struct iscsi_tm *hdr)
1175{
1176 memset(hdr, 0, sizeof(*hdr));
1177 hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE;
1178 hdr->flags = ISCSI_TM_FUNC_ABORT_TASK & ISCSI_FLAG_TM_FUNC_MASK;
1179 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
1180 memcpy(hdr->lun, ctask->hdr->lun, sizeof(hdr->lun));
1181 hdr->rtt = ctask->hdr->itt;
1182 hdr->refcmdsn = ctask->hdr->cmdsn;
1183}
1184
1181int iscsi_eh_abort(struct scsi_cmnd *sc) 1185int iscsi_eh_abort(struct scsi_cmnd *sc)
1182{ 1186{
1183 struct Scsi_Host *host = sc->device->host; 1187 struct Scsi_Host *host = sc->device->host;
1184 struct iscsi_session *session = iscsi_hostdata(host->hostdata); 1188 struct iscsi_session *session = iscsi_hostdata(host->hostdata);
1185 struct iscsi_cmd_task *ctask;
1186 struct iscsi_conn *conn; 1189 struct iscsi_conn *conn;
1187 int rc; 1190 struct iscsi_cmd_task *ctask;
1191 struct iscsi_tm *hdr;
1192 int rc, age;
1188 1193
1189 mutex_lock(&session->eh_mutex); 1194 mutex_lock(&session->eh_mutex);
1190 spin_lock_bh(&session->lock); 1195 spin_lock_bh(&session->lock);
@@ -1199,19 +1204,23 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
1199 return SUCCESS; 1204 return SUCCESS;
1200 } 1205 }
1201 1206
1202 ctask = (struct iscsi_cmd_task *)sc->SCp.ptr;
1203 conn = ctask->conn;
1204
1205 conn->eh_abort_cnt++;
1206 debug_scsi("aborting [sc %p itt 0x%x]\n", sc, ctask->itt);
1207
1208 /* 1207 /*
1209 * If we are not logged in or we have started a new session 1208 * If we are not logged in or we have started a new session
1210 * then let the host reset code handle this 1209 * then let the host reset code handle this
1211 */ 1210 */
1212 if (session->state != ISCSI_STATE_LOGGED_IN || 1211 if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN ||
1213 sc->SCp.phase != session->age) 1212 sc->SCp.phase != session->age) {
1214 goto failed; 1213 spin_unlock_bh(&session->lock);
1214 mutex_unlock(&session->eh_mutex);
1215 return FAILED;
1216 }
1217
1218 conn = session->leadconn;
1219 conn->eh_abort_cnt++;
1220 age = session->age;
1221
1222 ctask = (struct iscsi_cmd_task *)sc->SCp.ptr;
1223 debug_scsi("aborting [sc %p itt 0x%x]\n", sc, ctask->itt);
1215 1224
1216 /* ctask completed before time out */ 1225 /* ctask completed before time out */
1217 if (!ctask->sc) { 1226 if (!ctask->sc) {
@@ -1219,27 +1228,26 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
1219 goto success; 1228 goto success;
1220 } 1229 }
1221 1230
1222 /* what should we do here ? */
1223 if (conn->ctask == ctask) {
1224 printk(KERN_INFO "iscsi: sc %p itt 0x%x partially sent. "
1225 "Failing abort\n", sc, ctask->itt);
1226 goto failed;
1227 }
1228
1229 if (ctask->state == ISCSI_TASK_PENDING) { 1231 if (ctask->state == ISCSI_TASK_PENDING) {
1230 fail_command(conn, ctask, DID_ABORT << 16); 1232 fail_command(conn, ctask, DID_ABORT << 16);
1231 goto success; 1233 goto success;
1232 } 1234 }
1233 1235
1234 conn->tmabort_state = TMABORT_INITIAL; 1236 /* only have one tmf outstanding at a time */
1235 rc = iscsi_exec_abort_task(sc, ctask); 1237 if (conn->tmf_state != TMF_INITIAL)
1236 if (rc || sc->SCp.phase != session->age ||
1237 session->state != ISCSI_STATE_LOGGED_IN)
1238 goto failed; 1238 goto failed;
1239 iscsi_ctask_mtask_cleanup(ctask); 1239 conn->tmf_state = TMF_QUEUED;
1240 1240
1241 switch (conn->tmabort_state) { 1241 hdr = &conn->tmhdr;
1242 case TMABORT_SUCCESS: 1242 iscsi_prep_abort_task_pdu(ctask, hdr);
1243
1244 if (iscsi_exec_task_mgmt_fn(conn, hdr, age)) {
1245 rc = FAILED;
1246 goto failed;
1247 }
1248
1249 switch (conn->tmf_state) {
1250 case TMF_SUCCESS:
1243 spin_unlock_bh(&session->lock); 1251 spin_unlock_bh(&session->lock);
1244 iscsi_suspend_tx(conn); 1252 iscsi_suspend_tx(conn);
1245 /* 1253 /*
@@ -1248,22 +1256,26 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
1248 write_lock_bh(conn->recv_lock); 1256 write_lock_bh(conn->recv_lock);
1249 spin_lock(&session->lock); 1257 spin_lock(&session->lock);
1250 fail_command(conn, ctask, DID_ABORT << 16); 1258 fail_command(conn, ctask, DID_ABORT << 16);
1259 conn->tmf_state = TMF_INITIAL;
1251 spin_unlock(&session->lock); 1260 spin_unlock(&session->lock);
1252 write_unlock_bh(conn->recv_lock); 1261 write_unlock_bh(conn->recv_lock);
1253 iscsi_start_tx(conn); 1262 iscsi_start_tx(conn);
1254 goto success_unlocked; 1263 goto success_unlocked;
1255 case TMABORT_NOT_FOUND: 1264 case TMF_TIMEDOUT:
1256 if (!ctask->sc) { 1265 spin_unlock_bh(&session->lock);
1266 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
1267 goto failed_unlocked;
1268 case TMF_NOT_FOUND:
1269 if (!sc->SCp.ptr) {
1270 conn->tmf_state = TMF_INITIAL;
1257 /* ctask completed before tmf abort response */ 1271 /* ctask completed before tmf abort response */
1258 debug_scsi("sc completed while abort in progress\n"); 1272 debug_scsi("sc completed while abort in progress\n");
1259 goto success; 1273 goto success;
1260 } 1274 }
1261 /* fall through */ 1275 /* fall through */
1262 default: 1276 default:
1263 /* timedout or failed */ 1277 conn->tmf_state = TMF_INITIAL;
1264 spin_unlock_bh(&session->lock); 1278 goto failed;
1265 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
1266 goto failed_unlocked;
1267 } 1279 }
1268 1280
1269success: 1281success:
@@ -1276,12 +1288,93 @@ success_unlocked:
1276failed: 1288failed:
1277 spin_unlock_bh(&session->lock); 1289 spin_unlock_bh(&session->lock);
1278failed_unlocked: 1290failed_unlocked:
1279 debug_scsi("abort failed [sc %lx itt 0x%x]\n", (long)sc, ctask->itt); 1291 debug_scsi("abort failed [sc %p itt 0x%x]\n", sc,
1292 ctask ? ctask->itt : 0);
1280 mutex_unlock(&session->eh_mutex); 1293 mutex_unlock(&session->eh_mutex);
1281 return FAILED; 1294 return FAILED;
1282} 1295}
1283EXPORT_SYMBOL_GPL(iscsi_eh_abort); 1296EXPORT_SYMBOL_GPL(iscsi_eh_abort);
1284 1297
1298static void iscsi_prep_lun_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr)
1299{
1300 memset(hdr, 0, sizeof(*hdr));
1301 hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE;
1302 hdr->flags = ISCSI_TM_FUNC_LOGICAL_UNIT_RESET & ISCSI_FLAG_TM_FUNC_MASK;
1303 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
1304 int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun);
1305 hdr->rtt = ISCSI_RESERVED_TAG;
1306}
1307
1308int iscsi_eh_device_reset(struct scsi_cmnd *sc)
1309{
1310 struct Scsi_Host *host = sc->device->host;
1311 struct iscsi_session *session = iscsi_hostdata(host->hostdata);
1312 struct iscsi_conn *conn;
1313 struct iscsi_tm *hdr;
1314 int rc = FAILED;
1315
1316 debug_scsi("LU Reset [sc %p lun %u]\n", sc, sc->device->lun);
1317
1318 mutex_lock(&session->eh_mutex);
1319 spin_lock_bh(&session->lock);
1320 /*
1321 * Just check if we are not logged in. We cannot check for
1322 * the phase because the reset could come from a ioctl.
1323 */
1324 if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN)
1325 goto unlock;
1326 conn = session->leadconn;
1327
1328 /* only have one tmf outstanding at a time */
1329 if (conn->tmf_state != TMF_INITIAL)
1330 goto unlock;
1331 conn->tmf_state = TMF_QUEUED;
1332
1333 hdr = &conn->tmhdr;
1334 iscsi_prep_lun_reset_pdu(sc, hdr);
1335
1336 if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age)) {
1337 rc = FAILED;
1338 goto unlock;
1339 }
1340
1341 switch (conn->tmf_state) {
1342 case TMF_SUCCESS:
1343 break;
1344 case TMF_TIMEDOUT:
1345 spin_unlock_bh(&session->lock);
1346 iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
1347 goto done;
1348 default:
1349 conn->tmf_state = TMF_INITIAL;
1350 goto unlock;
1351 }
1352
1353 rc = SUCCESS;
1354 spin_unlock_bh(&session->lock);
1355
1356 iscsi_suspend_tx(conn);
1357 /* need to grab the recv lock then session lock */
1358 write_lock_bh(conn->recv_lock);
1359 spin_lock(&session->lock);
1360 fail_all_commands(conn, sc->device->lun);
1361 conn->tmf_state = TMF_INITIAL;
1362 spin_unlock(&session->lock);
1363 write_unlock_bh(conn->recv_lock);
1364
1365 iscsi_start_tx(conn);
1366 goto done;
1367
1368unlock:
1369 spin_unlock_bh(&session->lock);
1370done:
1371 debug_scsi("iscsi_eh_device_reset %s\n",
1372 rc == SUCCESS ? "SUCCESS" : "FAILED");
1373 mutex_unlock(&session->eh_mutex);
1374 return rc;
1375}
1376EXPORT_SYMBOL_GPL(iscsi_eh_device_reset);
1377
1285int 1378int
1286iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size) 1379iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size)
1287{ 1380{
@@ -1546,17 +1639,12 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
1546 conn->c_stage = ISCSI_CONN_INITIAL_STAGE; 1639 conn->c_stage = ISCSI_CONN_INITIAL_STAGE;
1547 conn->id = conn_idx; 1640 conn->id = conn_idx;
1548 conn->exp_statsn = 0; 1641 conn->exp_statsn = 0;
1549 conn->tmabort_state = TMABORT_INITIAL; 1642 conn->tmf_state = TMF_INITIAL;
1550 INIT_LIST_HEAD(&conn->run_list); 1643 INIT_LIST_HEAD(&conn->run_list);
1551 INIT_LIST_HEAD(&conn->mgmt_run_list); 1644 INIT_LIST_HEAD(&conn->mgmt_run_list);
1645 INIT_LIST_HEAD(&conn->mgmtqueue);
1552 INIT_LIST_HEAD(&conn->xmitqueue); 1646 INIT_LIST_HEAD(&conn->xmitqueue);
1553 1647 INIT_LIST_HEAD(&conn->requeue);
1554 /* initialize general immediate & non-immediate PDU commands queue */
1555 conn->mgmtqueue = kfifo_alloc(session->mgmtpool_max * sizeof(void*),
1556 GFP_KERNEL, NULL);
1557 if (conn->mgmtqueue == ERR_PTR(-ENOMEM))
1558 goto mgmtqueue_alloc_fail;
1559
1560 INIT_WORK(&conn->xmitwork, iscsi_xmitworker); 1648 INIT_WORK(&conn->xmitwork, iscsi_xmitworker);
1561 1649
1562 /* allocate login_mtask used for the login/text sequences */ 1650 /* allocate login_mtask used for the login/text sequences */
@@ -1574,7 +1662,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
1574 goto login_mtask_data_alloc_fail; 1662 goto login_mtask_data_alloc_fail;
1575 conn->login_mtask->data = conn->data = data; 1663 conn->login_mtask->data = conn->data = data;
1576 1664
1577 init_timer(&conn->tmabort_timer); 1665 init_timer(&conn->tmf_timer);
1578 init_waitqueue_head(&conn->ehwait); 1666 init_waitqueue_head(&conn->ehwait);
1579 1667
1580 return cls_conn; 1668 return cls_conn;
@@ -1583,8 +1671,6 @@ login_mtask_data_alloc_fail:
1583 __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, 1671 __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
1584 sizeof(void*)); 1672 sizeof(void*));
1585login_mtask_alloc_fail: 1673login_mtask_alloc_fail:
1586 kfifo_free(conn->mgmtqueue);
1587mgmtqueue_alloc_fail:
1588 iscsi_destroy_conn(cls_conn); 1674 iscsi_destroy_conn(cls_conn);
1589 return NULL; 1675 return NULL;
1590} 1676}
@@ -1604,7 +1690,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
1604 unsigned long flags; 1690 unsigned long flags;
1605 1691
1606 spin_lock_bh(&session->lock); 1692 spin_lock_bh(&session->lock);
1607 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
1608 conn->c_stage = ISCSI_CONN_CLEANUP_WAIT; 1693 conn->c_stage = ISCSI_CONN_CLEANUP_WAIT;
1609 if (session->leadconn == conn) { 1694 if (session->leadconn == conn) {
1610 /* 1695 /*
@@ -1637,7 +1722,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
1637 } 1722 }
1638 1723
1639 /* flush queued up work because we free the connection below */ 1724 /* flush queued up work because we free the connection below */
1640 scsi_flush_work(session->host); 1725 iscsi_suspend_tx(conn);
1641 1726
1642 spin_lock_bh(&session->lock); 1727 spin_lock_bh(&session->lock);
1643 kfree(conn->data); 1728 kfree(conn->data);
@@ -1648,8 +1733,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
1648 session->leadconn = NULL; 1733 session->leadconn = NULL;
1649 spin_unlock_bh(&session->lock); 1734 spin_unlock_bh(&session->lock);
1650 1735
1651 kfifo_free(conn->mgmtqueue);
1652
1653 iscsi_destroy_conn(cls_conn); 1736 iscsi_destroy_conn(cls_conn);
1654} 1737}
1655EXPORT_SYMBOL_GPL(iscsi_conn_teardown); 1738EXPORT_SYMBOL_GPL(iscsi_conn_teardown);
@@ -1684,7 +1767,7 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn)
1684 * commands after successful recovery 1767 * commands after successful recovery
1685 */ 1768 */
1686 conn->stop_stage = 0; 1769 conn->stop_stage = 0;
1687 conn->tmabort_state = TMABORT_INITIAL; 1770 conn->tmf_state = TMF_INITIAL;
1688 session->age++; 1771 session->age++;
1689 spin_unlock_bh(&session->lock); 1772 spin_unlock_bh(&session->lock);
1690 1773
@@ -1709,10 +1792,11 @@ flush_control_queues(struct iscsi_session *session, struct iscsi_conn *conn)
1709 struct iscsi_mgmt_task *mtask, *tmp; 1792 struct iscsi_mgmt_task *mtask, *tmp;
1710 1793
1711 /* handle pending */ 1794 /* handle pending */
1712 while (__kfifo_get(conn->mgmtqueue, (void*)&mtask, sizeof(void*))) { 1795 list_for_each_entry_safe(mtask, tmp, &conn->mgmtqueue, running) {
1796 debug_scsi("flushing pending mgmt task itt 0x%x\n", mtask->itt);
1797 list_del_init(&mtask->running);
1713 if (mtask == conn->login_mtask) 1798 if (mtask == conn->login_mtask)
1714 continue; 1799 continue;
1715 debug_scsi("flushing pending mgmt task itt 0x%x\n", mtask->itt);
1716 __kfifo_put(session->mgmtpool.queue, (void*)&mtask, 1800 __kfifo_put(session->mgmtpool.queue, (void*)&mtask,
1717 sizeof(void*)); 1801 sizeof(void*));
1718 } 1802 }
@@ -1720,7 +1804,7 @@ flush_control_queues(struct iscsi_session *session, struct iscsi_conn *conn)
1720 /* handle running */ 1804 /* handle running */
1721 list_for_each_entry_safe(mtask, tmp, &conn->mgmt_run_list, running) { 1805 list_for_each_entry_safe(mtask, tmp, &conn->mgmt_run_list, running) {
1722 debug_scsi("flushing running mgmt task itt 0x%x\n", mtask->itt); 1806 debug_scsi("flushing running mgmt task itt 0x%x\n", mtask->itt);
1723 list_del(&mtask->running); 1807 list_del_init(&mtask->running);
1724 1808
1725 if (mtask == conn->login_mtask) 1809 if (mtask == conn->login_mtask)
1726 continue; 1810 continue;
@@ -1731,28 +1815,6 @@ flush_control_queues(struct iscsi_session *session, struct iscsi_conn *conn)
1731 conn->mtask = NULL; 1815 conn->mtask = NULL;
1732} 1816}
1733 1817
1734/* Fail commands. Mutex and session lock held and recv side suspended */
1735static void fail_all_commands(struct iscsi_conn *conn)
1736{
1737 struct iscsi_cmd_task *ctask, *tmp;
1738
1739 /* flush pending */
1740 list_for_each_entry_safe(ctask, tmp, &conn->xmitqueue, running) {
1741 debug_scsi("failing pending sc %p itt 0x%x\n", ctask->sc,
1742 ctask->itt);
1743 fail_command(conn, ctask, DID_BUS_BUSY << 16);
1744 }
1745
1746 /* fail all other running */
1747 list_for_each_entry_safe(ctask, tmp, &conn->run_list, running) {
1748 debug_scsi("failing in progress sc %p itt 0x%x\n",
1749 ctask->sc, ctask->itt);
1750 fail_command(conn, ctask, DID_BUS_BUSY << 16);
1751 }
1752
1753 conn->ctask = NULL;
1754}
1755
1756static void iscsi_start_session_recovery(struct iscsi_session *session, 1818static void iscsi_start_session_recovery(struct iscsi_session *session,
1757 struct iscsi_conn *conn, int flag) 1819 struct iscsi_conn *conn, int flag)
1758{ 1820{
@@ -1818,7 +1880,7 @@ static void iscsi_start_session_recovery(struct iscsi_session *session,
1818 * flush queues. 1880 * flush queues.
1819 */ 1881 */
1820 spin_lock_bh(&session->lock); 1882 spin_lock_bh(&session->lock);
1821 fail_all_commands(conn); 1883 fail_all_commands(conn, -1);
1822 flush_control_queues(session, conn); 1884 flush_control_queues(session, conn);
1823 spin_unlock_bh(&session->lock); 1885 spin_unlock_bh(&session->lock);
1824 mutex_unlock(&session->eh_mutex); 1886 mutex_unlock(&session->eh_mutex);
@@ -1869,6 +1931,9 @@ int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
1869 uint32_t value; 1931 uint32_t value;
1870 1932
1871 switch(param) { 1933 switch(param) {
1934 case ISCSI_PARAM_FAST_ABORT:
1935 sscanf(buf, "%d", &session->fast_abort);
1936 break;
1872 case ISCSI_PARAM_MAX_RECV_DLENGTH: 1937 case ISCSI_PARAM_MAX_RECV_DLENGTH:
1873 sscanf(buf, "%d", &conn->max_recv_dlength); 1938 sscanf(buf, "%d", &conn->max_recv_dlength);
1874 break; 1939 break;
@@ -1983,6 +2048,9 @@ int iscsi_session_get_param(struct iscsi_cls_session *cls_session,
1983 int len; 2048 int len;
1984 2049
1985 switch(param) { 2050 switch(param) {
2051 case ISCSI_PARAM_FAST_ABORT:
2052 len = sprintf(buf, "%d\n", session->fast_abort);
2053 break;
1986 case ISCSI_PARAM_INITIAL_R2T_EN: 2054 case ISCSI_PARAM_INITIAL_R2T_EN:
1987 len = sprintf(buf, "%d\n", session->initial_r2t_en); 2055 len = sprintf(buf, "%d\n", session->initial_r2t_en);
1988 break; 2056 break;