From: Michael Chan Date: Mon, 16 Jul 2012 14:25:56 +0000 (+0000) Subject: bnx2: Try to recover from PCI block reset X-Git-Tag: v2.6.39-400.9.0~338^2~126 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=affe6eef38966f661fc31e474075c02e9d205e56;p=users%2Fjedix%2Flinux-maple.git bnx2: Try to recover from PCI block reset If the PCI block has reset, the memory enable bit will be reset and the device will not respond to MMIO access. bnx2_reset_task() currently will not recover when this happens. Add code to detect this condition and restore the PCI state. This scenario has been reported by some users. (cherry picked from commit efdfad3205403e1d1c5c0bdcbdb647ddd89bfaa3) Signed-off-by: Michael Chan Signed-off-by: David S. Miller Signed-off-by: Joe Jin --- diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 4cf9ae0ce478..b0c9ddfba092 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -6387,6 +6387,7 @@ bnx2_reset_task(struct work_struct *work) { struct bnx2 *bp = container_of(work, struct bnx2, reset_task); int rc; + u16 pcicmd; rtnl_lock(); if (!netif_running(bp->dev)) { @@ -6396,6 +6397,12 @@ bnx2_reset_task(struct work_struct *work) bnx2_netif_stop(bp, true); + pci_read_config_word(bp->pdev, PCI_COMMAND, &pcicmd); + if (!(pcicmd & PCI_COMMAND_MEMORY)) { + /* in case PCI block has reset */ + pci_restore_state(bp->pdev); + pci_save_state(bp->pdev); + } rc = bnx2_init_nic(bp, 1); if (rc) { netdev_err(bp->dev, "failed to reset NIC, closing\n");