aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bnx2i
diff options
context:
space:
mode:
authorEddie Wai <eddie.wai@broadcom.com>2010-11-23 18:29:30 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-12-21 13:24:15 -0500
commita91031a6526441ff36552d53363037c3bbca0c5b (patch)
treeaa1e70b241807bf19a78dffda99420bfe3ed60ed /drivers/scsi/bnx2i
parentbee348770dcaeafa57bbd32129ce0cb16a4342d6 (diff)
[SCSI] bnx2i: Cleaned up various error conditions in ep_connect/disconnect
Various error conditions inside ep_connect and ep_disconnect were either not being handled or not being handled correctly. This patch fixes all those issues. Signed-off-by: Eddie Wai <eddie.wai@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')
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c67
1 files changed, 40 insertions, 27 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index f622e89041cd..24997c679f3c 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -411,7 +411,9 @@ static void bnx2i_free_ep(struct iscsi_endpoint *ep)
411 bnx2i_ep->state = EP_STATE_IDLE; 411 bnx2i_ep->state = EP_STATE_IDLE;
412 bnx2i_ep->hba->ofld_conns_active--; 412 bnx2i_ep->hba->ofld_conns_active--;
413 413
414 bnx2i_free_iscsi_cid(bnx2i_ep->hba, bnx2i_ep->ep_iscsi_cid); 414 if (bnx2i_ep->ep_iscsi_cid != (u16) -1)
415 bnx2i_free_iscsi_cid(bnx2i_ep->hba, bnx2i_ep->ep_iscsi_cid);
416
415 if (bnx2i_ep->conn) { 417 if (bnx2i_ep->conn) {
416 bnx2i_ep->conn->ep = NULL; 418 bnx2i_ep->conn->ep = NULL;
417 bnx2i_ep->conn = NULL; 419 bnx2i_ep->conn = NULL;
@@ -1738,13 +1740,17 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
1738 */ 1740 */
1739 hba = bnx2i_check_route(dst_addr); 1741 hba = bnx2i_check_route(dst_addr);
1740 1742
1741 if (!hba || test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state)) { 1743 if (!hba) {
1742 rc = -EINVAL; 1744 rc = -EINVAL;
1743 goto nohba; 1745 goto nohba;
1744 } 1746 }
1747 mutex_lock(&hba->net_dev_lock);
1745 1748
1749 if (bnx2i_adapter_ready(hba) || !hba->cid_que.cid_free_cnt) {
1750 rc = -EPERM;
1751 goto check_busy;
1752 }
1746 cnic = hba->cnic; 1753 cnic = hba->cnic;
1747 mutex_lock(&hba->net_dev_lock);
1748 ep = bnx2i_alloc_ep(hba); 1754 ep = bnx2i_alloc_ep(hba);
1749 if (!ep) { 1755 if (!ep) {
1750 rc = -ENOMEM; 1756 rc = -ENOMEM;
@@ -1752,23 +1758,21 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
1752 } 1758 }
1753 bnx2i_ep = ep->dd_data; 1759 bnx2i_ep = ep->dd_data;
1754 1760
1755 if (bnx2i_adapter_ready(hba)) {
1756 rc = -EPERM;
1757 goto net_if_down;
1758 }
1759
1760 bnx2i_ep->num_active_cmds = 0; 1761 bnx2i_ep->num_active_cmds = 0;
1761 iscsi_cid = bnx2i_alloc_iscsi_cid(hba); 1762 iscsi_cid = bnx2i_alloc_iscsi_cid(hba);
1762 if (iscsi_cid == -1) { 1763 if (iscsi_cid == -1) {
1763 printk(KERN_ALERT "alloc_ep: unable to allocate iscsi cid\n"); 1764 printk(KERN_ALERT "bnx2i (%s): alloc_ep - unable to allocate "
1765 "iscsi cid\n", hba->netdev->name);
1764 rc = -ENOMEM; 1766 rc = -ENOMEM;
1765 goto iscsi_cid_err; 1767 bnx2i_free_ep(ep);
1768 goto check_busy;
1766 } 1769 }
1767 bnx2i_ep->hba_age = hba->age; 1770 bnx2i_ep->hba_age = hba->age;
1768 1771
1769 rc = bnx2i_alloc_qp_resc(hba, bnx2i_ep); 1772 rc = bnx2i_alloc_qp_resc(hba, bnx2i_ep);
1770 if (rc != 0) { 1773 if (rc != 0) {
1771 printk(KERN_ALERT "bnx2i: ep_conn, alloc QP resc error\n"); 1774 printk(KERN_ALERT "bnx2i (%s): ep_conn - alloc QP resc error"
1775 "\n", hba->netdev->name);
1772 rc = -ENOMEM; 1776 rc = -ENOMEM;
1773 goto qp_resc_err; 1777 goto qp_resc_err;
1774 } 1778 }
@@ -1807,7 +1811,12 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
1807 bnx2i_ep_ofld_list_del(hba, bnx2i_ep); 1811 bnx2i_ep_ofld_list_del(hba, bnx2i_ep);
1808 1812
1809 if (bnx2i_ep->state != EP_STATE_OFLD_COMPL) { 1813 if (bnx2i_ep->state != EP_STATE_OFLD_COMPL) {
1810 rc = -ENOSPC; 1814 if (bnx2i_ep->state == EP_STATE_OFLD_FAILED_CID_BUSY) {
1815 printk(KERN_ALERT "bnx2i (%s): iscsi cid %d is busy\n",
1816 hba->netdev->name, bnx2i_ep->ep_iscsi_cid);
1817 rc = -EBUSY;
1818 } else
1819 rc = -ENOSPC;
1811 goto conn_failed; 1820 goto conn_failed;
1812 } 1821 }
1813 1822
@@ -1815,7 +1824,8 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
1815 iscsi_cid, &bnx2i_ep->cm_sk, bnx2i_ep); 1824 iscsi_cid, &bnx2i_ep->cm_sk, bnx2i_ep);
1816 if (rc) { 1825 if (rc) {
1817 rc = -EINVAL; 1826 rc = -EINVAL;
1818 goto conn_failed; 1827 /* Need to terminate and cleanup the connection */
1828 goto release_ep;
1819 } 1829 }
1820 1830
1821 bnx2i_ep->cm_sk->rcv_buf = 256 * 1024; 1831 bnx2i_ep->cm_sk->rcv_buf = 256 * 1024;
@@ -1859,8 +1869,6 @@ release_ep:
1859 return ERR_PTR(rc); 1869 return ERR_PTR(rc);
1860 } 1870 }
1861conn_failed: 1871conn_failed:
1862net_if_down:
1863iscsi_cid_err:
1864 bnx2i_free_qp_resc(hba, bnx2i_ep); 1872 bnx2i_free_qp_resc(hba, bnx2i_ep);
1865qp_resc_err: 1873qp_resc_err:
1866 bnx2i_free_ep(ep); 1874 bnx2i_free_ep(ep);
@@ -1979,7 +1987,8 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
1979 if (!cnic) 1987 if (!cnic)
1980 return 0; 1988 return 0;
1981 1989
1982 if (bnx2i_ep->state == EP_STATE_IDLE) 1990 if (bnx2i_ep->state == EP_STATE_IDLE ||
1991 bnx2i_ep->state == EP_STATE_DISCONN_TIMEDOUT)
1983 return 0; 1992 return 0;
1984 1993
1985 if (!bnx2i_ep_tcp_conn_active(bnx2i_ep)) 1994 if (!bnx2i_ep_tcp_conn_active(bnx2i_ep))
@@ -2005,9 +2014,10 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
2005 if (session->state == ISCSI_STATE_LOGGING_OUT) { 2014 if (session->state == ISCSI_STATE_LOGGING_OUT) {
2006 if (bnx2i_ep->state == EP_STATE_LOGOUT_SENT) { 2015 if (bnx2i_ep->state == EP_STATE_LOGOUT_SENT) {
2007 /* Logout sent, but no resp */ 2016 /* Logout sent, but no resp */
2008 printk(KERN_ALERT "bnx2i - WARNING " 2017 printk(KERN_ALERT "bnx2i (%s): WARNING"
2009 "logout response was not " 2018 " logout response was not "
2010 "received!\n"); 2019 "received!\n",
2020 bnx2i_ep->hba->netdev->name);
2011 } else if (bnx2i_ep->state == 2021 } else if (bnx2i_ep->state ==
2012 EP_STATE_LOGOUT_RESP_RCVD) 2022 EP_STATE_LOGOUT_RESP_RCVD)
2013 close = 1; 2023 close = 1;
@@ -2025,9 +2035,8 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
2025 else 2035 else
2026 close_ret = cnic->cm_abort(bnx2i_ep->cm_sk); 2036 close_ret = cnic->cm_abort(bnx2i_ep->cm_sk);
2027 2037
2028 /* No longer allow CFC delete if cm_close/abort fails the request */
2029 if (close_ret) 2038 if (close_ret)
2030 printk(KERN_ALERT "bnx2i: %s close/abort(%d) returned %d\n", 2039 printk(KERN_ALERT "bnx2i (%s): close/abort(%d) returned %d\n",
2031 bnx2i_ep->hba->netdev->name, close, close_ret); 2040 bnx2i_ep->hba->netdev->name, close, close_ret);
2032 else 2041 else
2033 /* wait for option-2 conn teardown */ 2042 /* wait for option-2 conn teardown */
@@ -2041,7 +2050,7 @@ int bnx2i_hw_ep_disconnect(struct bnx2i_endpoint *bnx2i_ep)
2041destroy_conn: 2050destroy_conn:
2042 bnx2i_ep_active_list_del(hba, bnx2i_ep); 2051 bnx2i_ep_active_list_del(hba, bnx2i_ep);
2043 if (bnx2i_tear_down_conn(hba, bnx2i_ep)) 2052 if (bnx2i_tear_down_conn(hba, bnx2i_ep))
2044 ret = -EINVAL; 2053 return -EINVAL;
2045out: 2054out:
2046 bnx2i_ep->state = EP_STATE_IDLE; 2055 bnx2i_ep->state = EP_STATE_IDLE;
2047 return ret; 2056 return ret;
@@ -2080,14 +2089,17 @@ static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep)
2080 2089
2081 mutex_lock(&hba->net_dev_lock); 2090 mutex_lock(&hba->net_dev_lock);
2082 2091
2083 if (bnx2i_ep->state == EP_STATE_IDLE) 2092 if (bnx2i_ep->state == EP_STATE_DISCONN_TIMEDOUT)
2084 goto return_bnx2i_ep; 2093 goto out;
2085 2094
2086 if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state)) 2095 if (bnx2i_ep->state == EP_STATE_IDLE)
2087 goto free_resc; 2096 goto free_resc;
2088 2097
2089 if (bnx2i_ep->hba_age != hba->age) 2098 if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state) ||
2099 (bnx2i_ep->hba_age != hba->age)) {
2100 bnx2i_ep_active_list_del(hba, bnx2i_ep);
2090 goto free_resc; 2101 goto free_resc;
2102 }
2091 2103
2092 /* Do all chip cleanup here */ 2104 /* Do all chip cleanup here */
2093 if (bnx2i_hw_ep_disconnect(bnx2i_ep)) { 2105 if (bnx2i_hw_ep_disconnect(bnx2i_ep)) {
@@ -2096,11 +2108,12 @@ static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep)
2096 } 2108 }
2097free_resc: 2109free_resc:
2098 bnx2i_free_qp_resc(hba, bnx2i_ep); 2110 bnx2i_free_qp_resc(hba, bnx2i_ep);
2099return_bnx2i_ep: 2111
2100 if (bnx2i_conn) 2112 if (bnx2i_conn)
2101 bnx2i_conn->ep = NULL; 2113 bnx2i_conn->ep = NULL;
2102 2114
2103 bnx2i_free_ep(ep); 2115 bnx2i_free_ep(ep);
2116out:
2104 mutex_unlock(&hba->net_dev_lock); 2117 mutex_unlock(&hba->net_dev_lock);
2105 2118
2106 wake_up_interruptible(&hba->eh_wait); 2119 wake_up_interruptible(&hba->eh_wait);