diff options
author | Amit Kumar Salecha <amit@unm84.unmin.com> | 2009-12-02 10:46:19 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-02 22:57:18 -0500 |
commit | 8f9b3f69944ab7eacb9273b4723087c42b5f4046 (patch) | |
tree | b824149cb41ac31a5532e140e06c2dd77a266793 /drivers/net/netxen | |
parent | f58dbd7320e148b25cc0088ef37f524c99c6790f (diff) |
netxen: fix failure cases for fw hang recovery
Handle few corner cases in firmware hang detection and recovery:
o Don't mark device state as READY, till handshake with
firmware is done.
o During probe, if start_firmware fails, restore reference
count.
o Don't increment refernce count, if start_firmware fails
during firmware reset.
o Clear __NX_RESETTING bit, incase of fatal error or tempeature
reaches critical limit so that pci remove() doesn't poll on
this bit.
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 838420dbc633..e5d187fce51b 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -819,7 +819,7 @@ netxen_start_firmware(struct netxen_adapter *adapter) | |||
819 | if (err < 0) | 819 | if (err < 0) |
820 | goto err_out; | 820 | goto err_out; |
821 | if (err == 0) | 821 | if (err == 0) |
822 | goto ready; | 822 | goto wait_init; |
823 | 823 | ||
824 | if (first_boot != 0x55555555) { | 824 | if (first_boot != 0x55555555) { |
825 | NXWR32(adapter, CRB_CMDPEG_STATE, 0); | 825 | NXWR32(adapter, CRB_CMDPEG_STATE, 0); |
@@ -862,9 +862,6 @@ netxen_start_firmware(struct netxen_adapter *adapter) | |||
862 | | (_NETXEN_NIC_LINUX_SUBVERSION); | 862 | | (_NETXEN_NIC_LINUX_SUBVERSION); |
863 | NXWR32(adapter, CRB_DRIVER_VERSION, val); | 863 | NXWR32(adapter, CRB_DRIVER_VERSION, val); |
864 | 864 | ||
865 | ready: | ||
866 | NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY); | ||
867 | |||
868 | wait_init: | 865 | wait_init: |
869 | /* Handshake with the card before we register the devices. */ | 866 | /* Handshake with the card before we register the devices. */ |
870 | err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | 867 | err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); |
@@ -873,6 +870,8 @@ wait_init: | |||
873 | goto err_out; | 870 | goto err_out; |
874 | } | 871 | } |
875 | 872 | ||
873 | NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_READY); | ||
874 | |||
876 | nx_update_dma_mask(adapter); | 875 | nx_update_dma_mask(adapter); |
877 | 876 | ||
878 | netxen_check_options(adapter); | 877 | netxen_check_options(adapter); |
@@ -1282,7 +1281,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1282 | 1281 | ||
1283 | err = netxen_start_firmware(adapter); | 1282 | err = netxen_start_firmware(adapter); |
1284 | if (err) | 1283 | if (err) |
1285 | goto err_out_iounmap; | 1284 | goto err_out_decr_ref; |
1286 | 1285 | ||
1287 | /* | 1286 | /* |
1288 | * See if the firmware gave us a virtual-physical port mapping. | 1287 | * See if the firmware gave us a virtual-physical port mapping. |
@@ -1326,6 +1325,7 @@ err_out_disable_msi: | |||
1326 | 1325 | ||
1327 | netxen_free_dummy_dma(adapter); | 1326 | netxen_free_dummy_dma(adapter); |
1328 | 1327 | ||
1328 | err_out_decr_ref: | ||
1329 | nx_decr_dev_ref_cnt(adapter); | 1329 | nx_decr_dev_ref_cnt(adapter); |
1330 | 1330 | ||
1331 | err_out_iounmap: | 1331 | err_out_iounmap: |
@@ -2189,14 +2189,13 @@ netxen_fwinit_work(struct work_struct *work) | |||
2189 | netxen_fwinit_work, 2 * FW_POLL_DELAY); | 2189 | netxen_fwinit_work, 2 * FW_POLL_DELAY); |
2190 | return; | 2190 | return; |
2191 | } | 2191 | } |
2192 | break; | ||
2193 | 2192 | ||
2194 | case NX_DEV_FAILED: | 2193 | case NX_DEV_FAILED: |
2195 | default: | 2194 | default: |
2195 | nx_incr_dev_ref_cnt(adapter); | ||
2196 | break; | 2196 | break; |
2197 | } | 2197 | } |
2198 | 2198 | ||
2199 | nx_incr_dev_ref_cnt(adapter); | ||
2200 | clear_bit(__NX_RESETTING, &adapter->state); | 2199 | clear_bit(__NX_RESETTING, &adapter->state); |
2201 | } | 2200 | } |
2202 | 2201 | ||
@@ -2218,18 +2217,23 @@ netxen_detach_work(struct work_struct *work) | |||
2218 | 2217 | ||
2219 | status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1); | 2218 | status = NXRD32(adapter, NETXEN_PEG_HALT_STATUS1); |
2220 | 2219 | ||
2221 | ref_cnt = nx_decr_dev_ref_cnt(adapter); | ||
2222 | |||
2223 | if (status & NX_RCODE_FATAL_ERROR) | 2220 | if (status & NX_RCODE_FATAL_ERROR) |
2224 | return; | 2221 | goto err_ret; |
2225 | 2222 | ||
2226 | if (adapter->temp == NX_TEMP_PANIC) | 2223 | if (adapter->temp == NX_TEMP_PANIC) |
2227 | return; | 2224 | goto err_ret; |
2225 | |||
2226 | ref_cnt = nx_decr_dev_ref_cnt(adapter); | ||
2228 | 2227 | ||
2229 | delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY); | 2228 | delay = (ref_cnt == 0) ? 0 : (2 * FW_POLL_DELAY); |
2230 | 2229 | ||
2231 | adapter->fw_wait_cnt = 0; | 2230 | adapter->fw_wait_cnt = 0; |
2232 | netxen_schedule_work(adapter, netxen_fwinit_work, delay); | 2231 | netxen_schedule_work(adapter, netxen_fwinit_work, delay); |
2232 | |||
2233 | return; | ||
2234 | |||
2235 | err_ret: | ||
2236 | clear_bit(__NX_RESETTING, &adapter->state); | ||
2233 | } | 2237 | } |
2234 | 2238 | ||
2235 | static int | 2239 | static int |