net/tg3: resolve deadlock in tg3_reset_task() during EEH
[platform/kernel/linux-rpi.git] / drivers / net / ethernet / broadcom / tg3.c
index 5e0e0e7..50f86be 100644 (file)
@@ -11176,7 +11176,7 @@ static void tg3_reset_task(struct work_struct *work)
        rtnl_lock();
        tg3_full_lock(tp, 0);
 
-       if (!netif_running(tp->dev)) {
+       if (tp->pcierr_recovery || !netif_running(tp->dev)) {
                tg3_flag_clear(tp, RESET_TASK_PENDING);
                tg3_full_unlock(tp);
                rtnl_unlock();
@@ -18078,16 +18078,20 @@ static void tg3_shutdown(struct pci_dev *pdev)
        struct net_device *dev = pci_get_drvdata(pdev);
        struct tg3 *tp = netdev_priv(dev);
 
+       tg3_reset_task_cancel(tp);
+
        rtnl_lock();
+
        netif_device_detach(dev);
 
        if (netif_running(dev))
                dev_close(dev);
 
-       if (system_state == SYSTEM_POWER_OFF)
-               tg3_power_down(tp);
+       tg3_power_down(tp);
 
        rtnl_unlock();
+
+       pci_disable_device(pdev);
 }
 
 /**
@@ -18107,6 +18111,9 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
 
        netdev_info(netdev, "PCI I/O error detected\n");
 
+       /* Want to make sure that the reset task doesn't run */
+       tg3_reset_task_cancel(tp);
+
        rtnl_lock();
 
        /* Could be second call or maybe we don't have netdev yet */
@@ -18123,9 +18130,6 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
 
        tg3_timer_stop(tp);
 
-       /* Want to make sure that the reset task doesn't run */
-       tg3_reset_task_cancel(tp);
-
        netif_device_detach(netdev);
 
        /* Clean up software state, even if MMIO is blocked */