aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2i/bnx2i_iscsi.c
diff options
context:
space:
mode:
authorEddie Wai <eddie.wai@broadcom.com>2010-07-01 18:34:54 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:04:00 -0400
commit2eefb20dbf3032da1ad111c1ce178f899bc4859a (patch)
treec358114448f68bc7d3ffb9c79202fd42b2a68e35 /drivers/scsi/bnx2i/bnx2i_iscsi.c
parente37d2c4791480e27c2e2e4a556e4d2ba1d353ff8 (diff)
[SCSI] bnx2i: Fixed the TCP graceful termination initiation
In compliance to RFC793, a TCP graceful termination will be used instead of an abortive termination for the case where the remote has initiated the close of the connection. Additionally, a TCP abortive termination will be used to close the connection when a logout response is not received in time after a logout request has been initiated. Signed-off-by: Eddie Wai <eddie.wai@broadcom.com> Reviewed-by: Michael Chan <mchan@broadcom.com> Reviewed-by: Benjamin Li <benli@broadcom.com> Acked-by: Anil Veerabhadrappa <anilgv@broadcom.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/bnx2i/bnx2i_iscsi.c')
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c53
1 files changed, 34 insertions, 19 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index f6eebb39fe5..c66c5a45aa2 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1890,6 +1890,8 @@ static int bnx2i_ep_tcp_conn_active(struct bnx2i_endpoint *bnx2i_ep)
1890 case EP_STATE_ULP_UPDATE_START: 1890 case EP_STATE_ULP_UPDATE_START:
1891 case EP_STATE_ULP_UPDATE_COMPL: 1891 case EP_STATE_ULP_UPDATE_COMPL:
1892 case EP_STATE_TCP_FIN_RCVD: 1892 case EP_STATE_TCP_FIN_RCVD:
1893 case EP_STATE_LOGOUT_SENT:
1894 case EP_STATE_LOGOUT_RESP_RCVD:
1893 case EP_STATE_ULP_UPDATE_FAILED: 1895 case EP_STATE_ULP_UPDATE_FAILED:
1894 ret = 1; 1896 ret = 1;
1895 break; 1897 break;
@@ -1923,6 +1925,8 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
1923 struct iscsi_session *session = NULL; 1925 struct iscsi_session *session = NULL;
1924 struct iscsi_conn *conn = NULL; 1926 struct iscsi_conn *conn = NULL;
1925 int ret = 0; 1927 int ret = 0;
1928 int close = 0;
1929 int close_ret = 0;
1926 1930
1927 if (!hba) 1931 if (!hba)
1928 return 0; 1932 return 0;
@@ -1939,33 +1943,44 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
1939 session = conn->session; 1943 session = conn->session;
1940 } 1944 }
1941 1945
1942 bnx2i_ep->state = EP_STATE_DISCONN_START;
1943
1944 init_timer(&bnx2i_ep->ofld_timer); 1946 init_timer(&bnx2i_ep->ofld_timer);
1945 bnx2i_ep->ofld_timer.expires = hba->conn_teardown_tmo + jiffies; 1947 bnx2i_ep->ofld_timer.expires = hba->conn_teardown_tmo + jiffies;
1946 bnx2i_ep->ofld_timer.function = bnx2i_ep_ofld_timer; 1948 bnx2i_ep->ofld_timer.function = bnx2i_ep_ofld_timer;
1947 bnx2i_ep->ofld_timer.data = (unsigned long) bnx2i_ep; 1949 bnx2i_ep->ofld_timer.data = (unsigned long) bnx2i_ep;
1948 add_timer(&bnx2i_ep->ofld_timer); 1950 add_timer(&bnx2i_ep->ofld_timer);
1949 1951
1950 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { 1952 if (!test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic))
1951 int close = 0;
1952 int close_ret = 0;
1953
1954 if (session) {
1955 spin_lock_bh(&session->lock);
1956 if (session->state == ISCSI_STATE_LOGGING_OUT)
1957 close = 1;
1958 spin_unlock_bh(&session->lock);
1959 }
1960 if (close)
1961 close_ret = cnic->cm_close(bnx2i_ep->cm_sk);
1962 else
1963 close_ret = cnic->cm_abort(bnx2i_ep->cm_sk);
1964 if (close_ret)
1965 bnx2i_ep->state = EP_STATE_DISCONN_COMPL;
1966 } else
1967 goto out; 1953 goto out;
1968 1954
1955 if (session) {
1956 spin_lock_bh(&session->lock);
1957 if (bnx2i_ep->state != EP_STATE_TCP_FIN_RCVD) {
1958 if (session->state == ISCSI_STATE_LOGGING_OUT) {
1959 if (bnx2i_ep->state == EP_STATE_LOGOUT_SENT) {
1960 /* Logout sent, but no resp */
1961 printk(KERN_ALERT "bnx2i - WARNING "
1962 "logout response was not "
1963 "received!\n");
1964 } else if (bnx2i_ep->state ==
1965 EP_STATE_LOGOUT_RESP_RCVD)
1966 close = 1;
1967 }
1968 } else
1969 close = 1;
1970
1971 spin_unlock_bh(&session->lock);
1972 }
1973
1974 bnx2i_ep->state = EP_STATE_DISCONN_START;
1975
1976 if (close)
1977 close_ret = cnic->cm_close(bnx2i_ep->cm_sk);
1978 else
1979 close_ret = cnic->cm_abort(bnx2i_ep->cm_sk);
1980
1981 if (close_ret)
1982 bnx2i_ep->state = EP_STATE_DISCONN_COMPL;
1983
1969 /* wait for option-2 conn teardown */ 1984 /* wait for option-2 conn teardown */
1970 wait_event_interruptible(bnx2i_ep->ofld_wait, 1985 wait_event_interruptible(bnx2i_ep->ofld_wait,
1971 bnx2i_ep->state != EP_STATE_DISCONN_START); 1986 bnx2i_ep->state != EP_STATE_DISCONN_START);