aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2i
diff options
context:
space:
mode:
authorEddie Wai <eddie.wai@broadcom.com>2010-07-01 18:34:50 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-27 13:03:56 -0400
commit6447f286326690a936c35f9f913499307f869934 (patch)
tree5232176f4fef9d62fdab968e43fca18bacefc4de /drivers/scsi/bnx2i
parent9ab98f57b3e1d73cd0720d29c21b687ba609cde9 (diff)
[SCSI] bnx2i: Separated the hardware's cleanup procedure from ep_disconnect
This patch introduces a new bnx2i_hw_ep_disconnect routine which contains all chip related disconnect and clean up procedure of iSCSI offload connections. This separation is intended as a preparation for the subsequent bnx2i_stop patch. Signed-off-by: Eddie Wai <eddie.wai@broadcom.com> Reviewed-by: Michael Chan <mchan@broadcom.com> Reviewed-by: Benjamin Li <benli@broadcom.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Acked-by: Anil Veerabhadrappa <anilgv@broadcom.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/bnx2i')
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c119
1 files changed, 76 insertions, 43 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index fa68ab34b998..6edfde5f2e09 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1866,54 +1866,35 @@ static int bnx2i_ep_tcp_conn_active(struct bnx2i_endpoint *bnx2i_ep)
1866} 1866}
1867 1867
1868 1868
1869/** 1869/*
1870 * bnx2i_ep_disconnect - executes TCP connection teardown process 1870 * bnx2i_hw_ep_disconnect - executes TCP connection teardown process in the hw
1871 * @ep: TCP connection (endpoint) handle 1871 * @ep: TCP connection (bnx2i endpoint) handle
1872 * 1872 *
1873 * executes TCP connection teardown process 1873 * executes TCP connection teardown process
1874 */ 1874 */
1875static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep) 1875int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
1876{ 1876{
1877 struct bnx2i_endpoint *bnx2i_ep; 1877 struct bnx2i_hba *hba = bnx2i_ep->hba;
1878 struct bnx2i_conn *bnx2i_conn = NULL;
1879 struct iscsi_session *session = NULL;
1880 struct iscsi_conn *conn;
1881 struct cnic_dev *cnic; 1878 struct cnic_dev *cnic;
1882 struct bnx2i_hba *hba; 1879 struct iscsi_session *session = NULL;
1880 struct iscsi_conn *conn = NULL;
1881 int ret = 0;
1883 1882
1884 bnx2i_ep = ep->dd_data; 1883 if (!hba)
1884 return 0;
1885 1885
1886 /* driver should not attempt connection cleanup until TCP_CONNECT 1886 cnic = hba->cnic;
1887 * completes either successfully or fails. Timeout is 9-secs, so 1887 if (!cnic)
1888 * wait for it to complete 1888 return 0;
1889 */ 1889
1890 while ((bnx2i_ep->state == EP_STATE_CONNECT_START) && 1890 if (!bnx2i_ep_tcp_conn_active(bnx2i_ep))
1891 !time_after(jiffies, bnx2i_ep->timestamp + (12 * HZ))) 1891 goto destroy_conn;
1892 msleep(250);
1893 1892
1894 if (bnx2i_ep->conn) { 1893 if (bnx2i_ep->conn) {
1895 bnx2i_conn = bnx2i_ep->conn; 1894 conn = bnx2i_ep->conn->cls_conn->dd_data;
1896 conn = bnx2i_conn->cls_conn->dd_data;
1897 session = conn->session; 1895 session = conn->session;
1898
1899 iscsi_suspend_queue(conn);
1900 } 1896 }
1901 1897
1902 hba = bnx2i_ep->hba;
1903 if (bnx2i_ep->state == EP_STATE_IDLE)
1904 goto return_bnx2i_ep;
1905 cnic = hba->cnic;
1906
1907 mutex_lock(&hba->net_dev_lock);
1908
1909 if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state))
1910 goto free_resc;
1911 if (bnx2i_ep->hba_age != hba->age)
1912 goto free_resc;
1913
1914 if (!bnx2i_ep_tcp_conn_active(bnx2i_ep))
1915 goto destory_conn;
1916
1917 bnx2i_ep->state = EP_STATE_DISCONN_START; 1898 bnx2i_ep->state = EP_STATE_DISCONN_START;
1918 1899
1919 init_timer(&bnx2i_ep->ofld_timer); 1900 init_timer(&bnx2i_ep->ofld_timer);
@@ -1924,6 +1905,7 @@ static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep)
1924 1905
1925 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { 1906 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) {
1926 int close = 0; 1907 int close = 0;
1908 int close_ret = 0;
1927 1909
1928 if (session) { 1910 if (session) {
1929 spin_lock_bh(&session->lock); 1911 spin_lock_bh(&session->lock);
@@ -1932,11 +1914,13 @@ static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep)
1932 spin_unlock_bh(&session->lock); 1914 spin_unlock_bh(&session->lock);
1933 } 1915 }
1934 if (close) 1916 if (close)
1935 cnic->cm_close(bnx2i_ep->cm_sk); 1917 close_ret = cnic->cm_close(bnx2i_ep->cm_sk);
1936 else 1918 else
1937 cnic->cm_abort(bnx2i_ep->cm_sk); 1919 close_ret = cnic->cm_abort(bnx2i_ep->cm_sk);
1920 if (close_ret)
1921 bnx2i_ep->state = EP_STATE_DISCONN_COMPL;
1938 } else 1922 } else
1939 goto free_resc; 1923 goto out;
1940 1924
1941 /* wait for option-2 conn teardown */ 1925 /* wait for option-2 conn teardown */
1942 wait_event_interruptible(bnx2i_ep->ofld_wait, 1926 wait_event_interruptible(bnx2i_ep->ofld_wait,
@@ -1946,20 +1930,69 @@ static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep)
1946 flush_signals(current); 1930 flush_signals(current);
1947 del_timer_sync(&bnx2i_ep->ofld_timer); 1931 del_timer_sync(&bnx2i_ep->ofld_timer);
1948 1932
1949destory_conn: 1933destroy_conn:
1950 if (bnx2i_tear_down_conn(hba, bnx2i_ep)) { 1934 if (bnx2i_tear_down_conn(hba, bnx2i_ep))
1935 ret = -EINVAL;
1936out:
1937 bnx2i_ep->state = EP_STATE_IDLE;
1938 return ret;
1939}
1940
1941
1942/**
1943 * bnx2i_ep_disconnect - executes TCP connection teardown process
1944 * @ep: TCP connection (iscsi endpoint) handle
1945 *
1946 * executes TCP connection teardown process
1947 */
1948static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep)
1949{
1950 struct bnx2i_endpoint *bnx2i_ep;
1951 struct bnx2i_conn *bnx2i_conn = NULL;
1952 struct iscsi_conn *conn = NULL;
1953 struct bnx2i_hba *hba;
1954
1955 bnx2i_ep = ep->dd_data;
1956
1957 /* driver should not attempt connection cleanup until TCP_CONNECT
1958 * completes either successfully or fails. Timeout is 9-secs, so
1959 * wait for it to complete
1960 */
1961 while ((bnx2i_ep->state == EP_STATE_CONNECT_START) &&
1962 !time_after(jiffies, bnx2i_ep->timestamp + (12 * HZ)))
1963 msleep(250);
1964
1965 if (bnx2i_ep->conn) {
1966 bnx2i_conn = bnx2i_ep->conn;
1967 conn = bnx2i_conn->cls_conn->dd_data;
1968 iscsi_suspend_queue(conn);
1969 }
1970 hba = bnx2i_ep->hba;
1971
1972 mutex_lock(&hba->net_dev_lock);
1973
1974 if (bnx2i_ep->state == EP_STATE_IDLE)
1975 goto return_bnx2i_ep;
1976
1977 if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state))
1978 goto free_resc;
1979
1980 if (bnx2i_ep->hba_age != hba->age)
1981 goto free_resc;
1982
1983 /* Do all chip cleanup here */
1984 if (bnx2i_hw_ep_disconnect(bnx2i_ep)) {
1951 mutex_unlock(&hba->net_dev_lock); 1985 mutex_unlock(&hba->net_dev_lock);
1952 return; 1986 return;
1953 } 1987 }
1954free_resc: 1988free_resc:
1955 mutex_unlock(&hba->net_dev_lock);
1956 bnx2i_free_qp_resc(hba, bnx2i_ep); 1989 bnx2i_free_qp_resc(hba, bnx2i_ep);
1957return_bnx2i_ep: 1990return_bnx2i_ep:
1958 if (bnx2i_conn) 1991 if (bnx2i_conn)
1959 bnx2i_conn->ep = NULL; 1992 bnx2i_conn->ep = NULL;
1960 1993
1961 bnx2i_free_ep(ep); 1994 bnx2i_free_ep(ep);
1962 1995 mutex_unlock(&hba->net_dev_lock);
1963 if (!hba->ofld_conns_active) 1996 if (!hba->ofld_conns_active)
1964 bnx2i_unreg_dev_all(); 1997 bnx2i_unreg_dev_all();
1965 1998