mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 08:44:21 +08:00
atl1: fix kernel panic in case of DMA errors
Problem: There was two separate work_struct structures which share one handler. Unfortunately getting atl1_adapter structure from work_struct in case of DMA error was done from incorrect offset which cause kernel panics. Solution: The useless work_struct for DMA error removed and handler name changed to more generic one. Signed-off-by: Tony Zelenoff <antonz@parallels.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ca8f4fb21d
commit
03662e41c7
@ -2476,7 +2476,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
|
||||
"pcie phy link down %x\n", status);
|
||||
if (netif_running(adapter->netdev)) { /* reset MAC */
|
||||
iowrite32(0, adapter->hw.hw_addr + REG_IMR);
|
||||
schedule_work(&adapter->pcie_dma_to_rst_task);
|
||||
schedule_work(&adapter->reset_dev_task);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
}
|
||||
@ -2488,7 +2488,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
|
||||
"pcie DMA r/w error (status = 0x%x)\n",
|
||||
status);
|
||||
iowrite32(0, adapter->hw.hw_addr + REG_IMR);
|
||||
schedule_work(&adapter->pcie_dma_to_rst_task);
|
||||
schedule_work(&adapter->reset_dev_task);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -2633,10 +2633,10 @@ static void atl1_down(struct atl1_adapter *adapter)
|
||||
atl1_clean_rx_ring(adapter);
|
||||
}
|
||||
|
||||
static void atl1_tx_timeout_task(struct work_struct *work)
|
||||
static void atl1_reset_dev_task(struct work_struct *work)
|
||||
{
|
||||
struct atl1_adapter *adapter =
|
||||
container_of(work, struct atl1_adapter, tx_timeout_task);
|
||||
container_of(work, struct atl1_adapter, reset_dev_task);
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
|
||||
netif_device_detach(netdev);
|
||||
@ -3038,12 +3038,10 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
|
||||
(unsigned long)adapter);
|
||||
adapter->phy_timer_pending = false;
|
||||
|
||||
INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task);
|
||||
INIT_WORK(&adapter->reset_dev_task, atl1_reset_dev_task);
|
||||
|
||||
INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task);
|
||||
|
||||
INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task);
|
||||
|
||||
err = register_netdev(netdev);
|
||||
if (err)
|
||||
goto err_common;
|
||||
|
@ -758,9 +758,8 @@ struct atl1_adapter {
|
||||
u16 link_speed;
|
||||
u16 link_duplex;
|
||||
spinlock_t lock;
|
||||
struct work_struct tx_timeout_task;
|
||||
struct work_struct reset_dev_task;
|
||||
struct work_struct link_chg_task;
|
||||
struct work_struct pcie_dma_to_rst_task;
|
||||
|
||||
struct timer_list phy_config_timer;
|
||||
bool phy_timer_pending;
|
||||
|
@ -194,7 +194,7 @@ static void atlx_tx_timeout(struct net_device *netdev)
|
||||
{
|
||||
struct atlx_adapter *adapter = netdev_priv(netdev);
|
||||
/* Do the reset outside of interrupt context */
|
||||
schedule_work(&adapter->tx_timeout_task);
|
||||
schedule_work(&adapter->reset_dev_task);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user