aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlge/qlge_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/qlge/qlge_main.c')
-rw-r--r--drivers/net/qlge/qlge_main.c78
1 files changed, 52 insertions, 26 deletions
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index dd0ea0277550..42ad811ec313 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -4101,6 +4101,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
4101 goto err_out; 4101 goto err_out;
4102 } 4102 }
4103 4103
4104 pci_save_state(pdev);
4104 qdev->reg_base = 4105 qdev->reg_base =
4105 ioremap_nocache(pci_resource_start(pdev, 1), 4106 ioremap_nocache(pci_resource_start(pdev, 1),
4106 pci_resource_len(pdev, 1)); 4107 pci_resource_len(pdev, 1));
@@ -4255,6 +4256,33 @@ static void __devexit qlge_remove(struct pci_dev *pdev)
4255 free_netdev(ndev); 4256 free_netdev(ndev);
4256} 4257}
4257 4258
4259/* Clean up resources without touching hardware. */
4260static void ql_eeh_close(struct net_device *ndev)
4261{
4262 int i;
4263 struct ql_adapter *qdev = netdev_priv(ndev);
4264
4265 if (netif_carrier_ok(ndev)) {
4266 netif_carrier_off(ndev);
4267 netif_stop_queue(ndev);
4268 }
4269
4270 if (test_bit(QL_ADAPTER_UP, &qdev->flags))
4271 cancel_delayed_work_sync(&qdev->asic_reset_work);
4272 cancel_delayed_work_sync(&qdev->mpi_reset_work);
4273 cancel_delayed_work_sync(&qdev->mpi_work);
4274 cancel_delayed_work_sync(&qdev->mpi_idc_work);
4275 cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
4276
4277 for (i = 0; i < qdev->rss_ring_count; i++)
4278 netif_napi_del(&qdev->rx_ring[i].napi);
4279
4280 clear_bit(QL_ADAPTER_UP, &qdev->flags);
4281 ql_tx_ring_clean(qdev);
4282 ql_free_rx_buffers(qdev);
4283 ql_release_adapter_resources(qdev);
4284}
4285
4258/* 4286/*
4259 * This callback is called by the PCI subsystem whenever 4287 * This callback is called by the PCI subsystem whenever
4260 * a PCI bus error is detected. 4288 * a PCI bus error is detected.
@@ -4263,17 +4291,21 @@ static pci_ers_result_t qlge_io_error_detected(struct pci_dev *pdev,
4263 enum pci_channel_state state) 4291 enum pci_channel_state state)
4264{ 4292{
4265 struct net_device *ndev = pci_get_drvdata(pdev); 4293 struct net_device *ndev = pci_get_drvdata(pdev);
4266 struct ql_adapter *qdev = netdev_priv(ndev);
4267
4268 netif_device_detach(ndev);
4269 4294
4270 if (state == pci_channel_io_perm_failure) 4295 switch (state) {
4296 case pci_channel_io_normal:
4297 return PCI_ERS_RESULT_CAN_RECOVER;
4298 case pci_channel_io_frozen:
4299 netif_device_detach(ndev);
4300 if (netif_running(ndev))
4301 ql_eeh_close(ndev);
4302 pci_disable_device(pdev);
4303 return PCI_ERS_RESULT_NEED_RESET;
4304 case pci_channel_io_perm_failure:
4305 dev_err(&pdev->dev,
4306 "%s: pci_channel_io_perm_failure.\n", __func__);
4271 return PCI_ERS_RESULT_DISCONNECT; 4307 return PCI_ERS_RESULT_DISCONNECT;
4272 4308 }
4273 if (netif_running(ndev))
4274 ql_adapter_down(qdev);
4275
4276 pci_disable_device(pdev);
4277 4309
4278 /* Request a slot reset. */ 4310 /* Request a slot reset. */
4279 return PCI_ERS_RESULT_NEED_RESET; 4311 return PCI_ERS_RESULT_NEED_RESET;
@@ -4290,25 +4322,15 @@ static pci_ers_result_t qlge_io_slot_reset(struct pci_dev *pdev)
4290 struct net_device *ndev = pci_get_drvdata(pdev); 4322 struct net_device *ndev = pci_get_drvdata(pdev);
4291 struct ql_adapter *qdev = netdev_priv(ndev); 4323 struct ql_adapter *qdev = netdev_priv(ndev);
4292 4324
4325 pdev->error_state = pci_channel_io_normal;
4326
4327 pci_restore_state(pdev);
4293 if (pci_enable_device(pdev)) { 4328 if (pci_enable_device(pdev)) {
4294 QPRINTK(qdev, IFUP, ERR, 4329 QPRINTK(qdev, IFUP, ERR,
4295 "Cannot re-enable PCI device after reset.\n"); 4330 "Cannot re-enable PCI device after reset.\n");
4296 return PCI_ERS_RESULT_DISCONNECT; 4331 return PCI_ERS_RESULT_DISCONNECT;
4297 } 4332 }
4298
4299 pci_set_master(pdev); 4333 pci_set_master(pdev);
4300
4301 netif_carrier_off(ndev);
4302 ql_adapter_reset(qdev);
4303
4304 /* Make sure the EEPROM is good */
4305 memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len);
4306
4307 if (!is_valid_ether_addr(ndev->perm_addr)) {
4308 QPRINTK(qdev, IFUP, ERR, "After reset, invalid MAC address.\n");
4309 return PCI_ERS_RESULT_DISCONNECT;
4310 }
4311
4312 return PCI_ERS_RESULT_RECOVERED; 4334 return PCI_ERS_RESULT_RECOVERED;
4313} 4335}
4314 4336
@@ -4316,17 +4338,21 @@ static void qlge_io_resume(struct pci_dev *pdev)
4316{ 4338{
4317 struct net_device *ndev = pci_get_drvdata(pdev); 4339 struct net_device *ndev = pci_get_drvdata(pdev);
4318 struct ql_adapter *qdev = netdev_priv(ndev); 4340 struct ql_adapter *qdev = netdev_priv(ndev);
4341 int err = 0;
4319 4342
4320 pci_set_master(pdev); 4343 if (ql_adapter_reset(qdev))
4321 4344 QPRINTK(qdev, DRV, ERR, "reset FAILED!\n");
4322 if (netif_running(ndev)) { 4345 if (netif_running(ndev)) {
4323 if (ql_adapter_up(qdev)) { 4346 err = qlge_open(ndev);
4347 if (err) {
4324 QPRINTK(qdev, IFUP, ERR, 4348 QPRINTK(qdev, IFUP, ERR,
4325 "Device initialization failed after reset.\n"); 4349 "Device initialization failed after reset.\n");
4326 return; 4350 return;
4327 } 4351 }
4352 } else {
4353 QPRINTK(qdev, IFUP, ERR,
4354 "Device was not running prior to EEH.\n");
4328 } 4355 }
4329
4330 netif_device_attach(ndev); 4356 netif_device_attach(ndev);
4331} 4357}
4332 4358