diff options
author | Sathya Perla <sathyap@serverengines.com> | 2010-05-30 19:33:45 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-01 03:15:51 -0400 |
commit | 889cd4b2e529db4988525b0b3e6fb2c095760848 (patch) | |
tree | 0fc20cbaa3da75b2ac11bfccf80943503aa5539c | |
parent | db6f30078dcb0117336f20275e4828c86132e46e (diff) |
be2net: cleanup in case of error in be_open()
This patch adds cleanup code (things like unregistering irq,
disabling napi etc) to be_open() when an error occurs inside the
routine.
Signed-off-by: Sathya Perla <sathyap@serverengines.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/benet/be_main.c | 95 |
1 files changed, 49 insertions, 46 deletions
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 54b14272f333..322577469852 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -1735,6 +1735,44 @@ done: | |||
1735 | adapter->isr_registered = false; | 1735 | adapter->isr_registered = false; |
1736 | } | 1736 | } |
1737 | 1737 | ||
1738 | static int be_close(struct net_device *netdev) | ||
1739 | { | ||
1740 | struct be_adapter *adapter = netdev_priv(netdev); | ||
1741 | struct be_eq_obj *rx_eq = &adapter->rx_eq; | ||
1742 | struct be_eq_obj *tx_eq = &adapter->tx_eq; | ||
1743 | int vec; | ||
1744 | |||
1745 | cancel_delayed_work_sync(&adapter->work); | ||
1746 | |||
1747 | be_async_mcc_disable(adapter); | ||
1748 | |||
1749 | netif_stop_queue(netdev); | ||
1750 | netif_carrier_off(netdev); | ||
1751 | adapter->link_up = false; | ||
1752 | |||
1753 | be_intr_set(adapter, false); | ||
1754 | |||
1755 | if (adapter->msix_enabled) { | ||
1756 | vec = be_msix_vec_get(adapter, tx_eq->q.id); | ||
1757 | synchronize_irq(vec); | ||
1758 | vec = be_msix_vec_get(adapter, rx_eq->q.id); | ||
1759 | synchronize_irq(vec); | ||
1760 | } else { | ||
1761 | synchronize_irq(netdev->irq); | ||
1762 | } | ||
1763 | be_irq_unregister(adapter); | ||
1764 | |||
1765 | napi_disable(&rx_eq->napi); | ||
1766 | napi_disable(&tx_eq->napi); | ||
1767 | |||
1768 | /* Wait for all pending tx completions to arrive so that | ||
1769 | * all tx skbs are freed. | ||
1770 | */ | ||
1771 | be_tx_compl_clean(adapter); | ||
1772 | |||
1773 | return 0; | ||
1774 | } | ||
1775 | |||
1738 | static int be_open(struct net_device *netdev) | 1776 | static int be_open(struct net_device *netdev) |
1739 | { | 1777 | { |
1740 | struct be_adapter *adapter = netdev_priv(netdev); | 1778 | struct be_adapter *adapter = netdev_priv(netdev); |
@@ -1765,27 +1803,29 @@ static int be_open(struct net_device *netdev) | |||
1765 | /* Now that interrupts are on we can process async mcc */ | 1803 | /* Now that interrupts are on we can process async mcc */ |
1766 | be_async_mcc_enable(adapter); | 1804 | be_async_mcc_enable(adapter); |
1767 | 1805 | ||
1806 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); | ||
1807 | |||
1768 | status = be_cmd_link_status_query(adapter, &link_up, &mac_speed, | 1808 | status = be_cmd_link_status_query(adapter, &link_up, &mac_speed, |
1769 | &link_speed); | 1809 | &link_speed); |
1770 | if (status) | 1810 | if (status) |
1771 | goto ret_sts; | 1811 | goto err; |
1772 | be_link_status_update(adapter, link_up); | 1812 | be_link_status_update(adapter, link_up); |
1773 | 1813 | ||
1774 | if (be_physfn(adapter)) | 1814 | if (be_physfn(adapter)) { |
1775 | status = be_vid_config(adapter); | 1815 | status = be_vid_config(adapter); |
1776 | if (status) | 1816 | if (status) |
1777 | goto ret_sts; | 1817 | goto err; |
1778 | 1818 | ||
1779 | if (be_physfn(adapter)) { | ||
1780 | status = be_cmd_set_flow_control(adapter, | 1819 | status = be_cmd_set_flow_control(adapter, |
1781 | adapter->tx_fc, adapter->rx_fc); | 1820 | adapter->tx_fc, adapter->rx_fc); |
1782 | if (status) | 1821 | if (status) |
1783 | goto ret_sts; | 1822 | goto err; |
1784 | } | 1823 | } |
1785 | 1824 | ||
1786 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(100)); | 1825 | return 0; |
1787 | ret_sts: | 1826 | err: |
1788 | return status; | 1827 | be_close(adapter->netdev); |
1828 | return -EIO; | ||
1789 | } | 1829 | } |
1790 | 1830 | ||
1791 | static int be_setup_wol(struct be_adapter *adapter, bool enable) | 1831 | static int be_setup_wol(struct be_adapter *adapter, bool enable) |
@@ -1913,43 +1953,6 @@ static int be_clear(struct be_adapter *adapter) | |||
1913 | return 0; | 1953 | return 0; |
1914 | } | 1954 | } |
1915 | 1955 | ||
1916 | static int be_close(struct net_device *netdev) | ||
1917 | { | ||
1918 | struct be_adapter *adapter = netdev_priv(netdev); | ||
1919 | struct be_eq_obj *rx_eq = &adapter->rx_eq; | ||
1920 | struct be_eq_obj *tx_eq = &adapter->tx_eq; | ||
1921 | int vec; | ||
1922 | |||
1923 | cancel_delayed_work_sync(&adapter->work); | ||
1924 | |||
1925 | be_async_mcc_disable(adapter); | ||
1926 | |||
1927 | netif_stop_queue(netdev); | ||
1928 | netif_carrier_off(netdev); | ||
1929 | adapter->link_up = false; | ||
1930 | |||
1931 | be_intr_set(adapter, false); | ||
1932 | |||
1933 | if (adapter->msix_enabled) { | ||
1934 | vec = be_msix_vec_get(adapter, tx_eq->q.id); | ||
1935 | synchronize_irq(vec); | ||
1936 | vec = be_msix_vec_get(adapter, rx_eq->q.id); | ||
1937 | synchronize_irq(vec); | ||
1938 | } else { | ||
1939 | synchronize_irq(netdev->irq); | ||
1940 | } | ||
1941 | be_irq_unregister(adapter); | ||
1942 | |||
1943 | napi_disable(&rx_eq->napi); | ||
1944 | napi_disable(&tx_eq->napi); | ||
1945 | |||
1946 | /* Wait for all pending tx completions to arrive so that | ||
1947 | * all tx skbs are freed. | ||
1948 | */ | ||
1949 | be_tx_compl_clean(adapter); | ||
1950 | |||
1951 | return 0; | ||
1952 | } | ||
1953 | 1956 | ||
1954 | #define FW_FILE_HDR_SIGN "ServerEngines Corp. " | 1957 | #define FW_FILE_HDR_SIGN "ServerEngines Corp. " |
1955 | char flash_cookie[2][16] = {"*** SE FLAS", | 1958 | char flash_cookie[2][16] = {"*** SE FLAS", |