Commit 2eefb20dbf3032da1ad111c1ce178f899bc4859a

Authored by Eddie Wai
Committed by James Bottomley
1 parent e37d2c4791

[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>

Showing 3 changed files with 40 additions and 19 deletions Side-by-side Diff

drivers/scsi/bnx2i/bnx2i.h
... ... @@ -639,6 +639,8 @@
639 639 EP_STATE_CLEANUP_CMPL = 0x800,
640 640 EP_STATE_TCP_FIN_RCVD = 0x1000,
641 641 EP_STATE_TCP_RST_RCVD = 0x2000,
  642 + EP_STATE_LOGOUT_SENT = 0x4000,
  643 + EP_STATE_LOGOUT_RESP_RCVD = 0x8000,
642 644 EP_STATE_PG_OFLD_FAILED = 0x1000000,
643 645 EP_STATE_ULP_UPDATE_FAILED = 0x2000000,
644 646 EP_STATE_CLEANUP_FAILED = 0x4000000,
drivers/scsi/bnx2i/bnx2i_hwi.c
... ... @@ -562,6 +562,8 @@
562 562 logout_wqe->num_bds = 1;
563 563 logout_wqe->cq_index = 0; /* CQ# used for completion, 5771x only */
564 564  
  565 + bnx2i_conn->ep->state = EP_STATE_LOGOUT_SENT;
  566 +
565 567 bnx2i_ring_dbell_update_sq_params(bnx2i_conn, 1);
566 568 return 0;
567 569 }
... ... @@ -1482,6 +1484,8 @@
1482 1484 resp_hdr->t2retain = cpu_to_be32(logout->time_to_retain);
1483 1485  
1484 1486 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, NULL, 0);
  1487 +
  1488 + bnx2i_conn->ep->state = EP_STATE_LOGOUT_RESP_RCVD;
1485 1489 done:
1486 1490 spin_unlock(&session->lock);
1487 1491 return 0;
drivers/scsi/bnx2i/bnx2i_iscsi.c
... ... @@ -1890,6 +1890,8 @@
1890 1890 case EP_STATE_ULP_UPDATE_START:
1891 1891 case EP_STATE_ULP_UPDATE_COMPL:
1892 1892 case EP_STATE_TCP_FIN_RCVD:
  1893 + case EP_STATE_LOGOUT_SENT:
  1894 + case EP_STATE_LOGOUT_RESP_RCVD:
1893 1895 case EP_STATE_ULP_UPDATE_FAILED:
1894 1896 ret = 1;
1895 1897 break;
... ... @@ -1923,6 +1925,8 @@
1923 1925 struct iscsi_session *session = NULL;
1924 1926 struct iscsi_conn *conn = NULL;
1925 1927 int ret = 0;
  1928 + int close = 0;
  1929 + int close_ret = 0;
1926 1930  
1927 1931 if (!hba)
1928 1932 return 0;
1929 1933  
1930 1934  
... ... @@ -1939,32 +1943,43 @@
1939 1943 session = conn->session;
1940 1944 }
1941 1945  
1942   - bnx2i_ep->state = EP_STATE_DISCONN_START;
1943   -
1944 1946 init_timer(&bnx2i_ep->ofld_timer);
1945 1947 bnx2i_ep->ofld_timer.expires = hba->conn_teardown_tmo + jiffies;
1946 1948 bnx2i_ep->ofld_timer.function = bnx2i_ep_ofld_timer;
1947 1949 bnx2i_ep->ofld_timer.data = (unsigned long) bnx2i_ep;
1948 1950 add_timer(&bnx2i_ep->ofld_timer);
1949 1951  
1950   - 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
  1952 + if (!test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic))
1967 1953 goto out;
  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;
1968 1983  
1969 1984 /* wait for option-2 conn teardown */
1970 1985 wait_event_interruptible(bnx2i_ep->ofld_wait,