aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAuke Kok <auke-jan.h.kok@intel.com>2006-06-08 12:30:18 -0400
committerAuke Kok <juke-jan.h.kok@intel.com>2006-06-08 12:30:18 -0400
commit2cc304923d87403abc103a741382b9af08b6decc (patch)
treef14d99c13a1b8960964dcfdb6a3774c628ab7042 /drivers
parent983f27d37d4fc72c252835cb2ee3103b360735a6 (diff)
e100: add PCI Error Recovery
Various PCI bus errors can be signaled by newer PCI controllers. This patch adds the PCI error recovery callbacks to the intel ethernet e100 device driver. The patch has been tested, and appears to work well. Signed-off-by: Linas Vepstas <linas@linas.org> Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/e100.c75
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 */
2789static 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 */
2810static 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 */
2837static 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
2852static 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
2784static struct pci_driver e100_driver = { 2858static 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
2796static int __init e100_init_module(void) 2871static int __init e100_init_module(void)