diff options
Diffstat (limited to 'drivers/net/e100.c')
-rw-r--r-- | drivers/net/e100.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 31ac001f5517..f37170cc1a37 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -2780,6 +2780,80 @@ static void e100_shutdown(struct pci_dev *pdev) | |||
2780 | DPRINTK(PROBE,ERR, "Error enabling wake\n"); | 2780 | DPRINTK(PROBE,ERR, "Error enabling wake\n"); |
2781 | } | 2781 | } |
2782 | 2782 | ||
2783 | /* ------------------ PCI Error Recovery infrastructure -------------- */ | ||
2784 | /** | ||
2785 | * e100_io_error_detected - called when PCI error is detected. | ||
2786 | * @pdev: Pointer to PCI device | ||
2787 | * @state: The current pci conneection state | ||
2788 | */ | ||
2789 | static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | ||
2790 | { | ||
2791 | struct net_device *netdev = pci_get_drvdata(pdev); | ||
2792 | |||
2793 | /* Similar to calling e100_down(), but avoids adpater I/O. */ | ||
2794 | netdev->stop(netdev); | ||
2795 | |||
2796 | /* Detach; put netif into state similar to hotplug unplug. */ | ||
2797 | netif_poll_enable(netdev); | ||
2798 | netif_device_detach(netdev); | ||
2799 | |||
2800 | /* Request a slot reset. */ | ||
2801 | return PCI_ERS_RESULT_NEED_RESET; | ||
2802 | } | ||
2803 | |||
2804 | /** | ||
2805 | * e100_io_slot_reset - called after the pci bus has been reset. | ||
2806 | * @pdev: Pointer to PCI device | ||
2807 | * | ||
2808 | * Restart the card from scratch. | ||
2809 | */ | ||
2810 | static pci_ers_result_t e100_io_slot_reset(struct pci_dev *pdev) | ||
2811 | { | ||
2812 | struct net_device *netdev = pci_get_drvdata(pdev); | ||
2813 | struct nic *nic = netdev_priv(netdev); | ||
2814 | |||
2815 | if (pci_enable_device(pdev)) { | ||
2816 | printk(KERN_ERR "e100: Cannot re-enable PCI device after reset.\n"); | ||
2817 | return PCI_ERS_RESULT_DISCONNECT; | ||
2818 | } | ||
2819 | pci_set_master(pdev); | ||
2820 | |||
2821 | /* Only one device per card can do a reset */ | ||
2822 | if (0 != PCI_FUNC(pdev->devfn)) | ||
2823 | return PCI_ERS_RESULT_RECOVERED; | ||
2824 | e100_hw_reset(nic); | ||
2825 | e100_phy_init(nic); | ||
2826 | |||
2827 | return PCI_ERS_RESULT_RECOVERED; | ||
2828 | } | ||
2829 | |||
2830 | /** | ||
2831 | * e100_io_resume - resume normal operations | ||
2832 | * @pdev: Pointer to PCI device | ||
2833 | * | ||
2834 | * Resume normal operations after an error recovery | ||
2835 | * sequence has been completed. | ||
2836 | */ | ||
2837 | static void e100_io_resume(struct pci_dev *pdev) | ||
2838 | { | ||
2839 | struct net_device *netdev = pci_get_drvdata(pdev); | ||
2840 | struct nic *nic = netdev_priv(netdev); | ||
2841 | |||
2842 | /* ack any pending wake events, disable PME */ | ||
2843 | pci_enable_wake(pdev, 0, 0); | ||
2844 | |||
2845 | netif_device_attach(netdev); | ||
2846 | if (netif_running(netdev)) { | ||
2847 | e100_open(netdev); | ||
2848 | mod_timer(&nic->watchdog, jiffies); | ||
2849 | } | ||
2850 | } | ||
2851 | |||
2852 | static struct pci_error_handlers e100_err_handler = { | ||
2853 | .error_detected = e100_io_error_detected, | ||
2854 | .slot_reset = e100_io_slot_reset, | ||
2855 | .resume = e100_io_resume, | ||
2856 | }; | ||
2783 | 2857 | ||
2784 | static struct pci_driver e100_driver = { | 2858 | static struct pci_driver e100_driver = { |
2785 | .name = DRV_NAME, | 2859 | .name = DRV_NAME, |
@@ -2791,6 +2865,7 @@ static struct pci_driver e100_driver = { | |||
2791 | .resume = e100_resume, | 2865 | .resume = e100_resume, |
2792 | #endif | 2866 | #endif |
2793 | .shutdown = e100_shutdown, | 2867 | .shutdown = e100_shutdown, |
2868 | .err_handler = &e100_err_handler, | ||
2794 | }; | 2869 | }; |
2795 | 2870 | ||
2796 | static int __init e100_init_module(void) | 2871 | static int __init e100_init_module(void) |