aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Zelenoff <antonz@parallels.com>2012-04-11 02:15:03 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-27 12:51:20 -0400
commitbb2f6102c815c14572642205191eb0fa883d8723 (patch)
tree4158479d3746658d5b2c1efcf3c9c86010105be5
parent4a1abcbd24d856fe49029c3dc6f7fe8dc66ddaac (diff)
atl1: fix kernel panic in case of DMA errors
[ Upstream commit 03662e41c7cff64a776bfb1b3816de4be43de881 ] 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/net/atlx/atl1.c12
-rw-r--r--drivers/net/atlx/atl1.h3
-rw-r--r--drivers/net/atlx/atlx.c2
3 files changed, 7 insertions, 10 deletions
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index cd5789ff372..48c27d34eac 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -2476,7 +2476,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
2476 "pcie phy link down %x\n", status); 2476 "pcie phy link down %x\n", status);
2477 if (netif_running(adapter->netdev)) { /* reset MAC */ 2477 if (netif_running(adapter->netdev)) { /* reset MAC */
2478 iowrite32(0, adapter->hw.hw_addr + REG_IMR); 2478 iowrite32(0, adapter->hw.hw_addr + REG_IMR);
2479 schedule_work(&adapter->pcie_dma_to_rst_task); 2479 schedule_work(&adapter->reset_dev_task);
2480 return IRQ_HANDLED; 2480 return IRQ_HANDLED;
2481 } 2481 }
2482 } 2482 }
@@ -2488,7 +2488,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
2488 "pcie DMA r/w error (status = 0x%x)\n", 2488 "pcie DMA r/w error (status = 0x%x)\n",
2489 status); 2489 status);
2490 iowrite32(0, adapter->hw.hw_addr + REG_IMR); 2490 iowrite32(0, adapter->hw.hw_addr + REG_IMR);
2491 schedule_work(&adapter->pcie_dma_to_rst_task); 2491 schedule_work(&adapter->reset_dev_task);
2492 return IRQ_HANDLED; 2492 return IRQ_HANDLED;
2493 } 2493 }
2494 2494
@@ -2633,10 +2633,10 @@ static void atl1_down(struct atl1_adapter *adapter)
2633 atl1_clean_rx_ring(adapter); 2633 atl1_clean_rx_ring(adapter);
2634} 2634}
2635 2635
2636static void atl1_tx_timeout_task(struct work_struct *work) 2636static void atl1_reset_dev_task(struct work_struct *work)
2637{ 2637{
2638 struct atl1_adapter *adapter = 2638 struct atl1_adapter *adapter =
2639 container_of(work, struct atl1_adapter, tx_timeout_task); 2639 container_of(work, struct atl1_adapter, reset_dev_task);
2640 struct net_device *netdev = adapter->netdev; 2640 struct net_device *netdev = adapter->netdev;
2641 2641
2642 netif_device_detach(netdev); 2642 netif_device_detach(netdev);
@@ -3034,12 +3034,10 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
3034 (unsigned long)adapter); 3034 (unsigned long)adapter);
3035 adapter->phy_timer_pending = false; 3035 adapter->phy_timer_pending = false;
3036 3036
3037 INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task); 3037 INIT_WORK(&adapter->reset_dev_task, atl1_reset_dev_task);
3038 3038
3039 INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task); 3039 INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task);
3040 3040
3041 INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task);
3042
3043 err = register_netdev(netdev); 3041 err = register_netdev(netdev);
3044 if (err) 3042 if (err)
3045 goto err_common; 3043 goto err_common;
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
index 68de8cbfb3e..c27b724a834 100644
--- a/drivers/net/atlx/atl1.h
+++ b/drivers/net/atlx/atl1.h
@@ -759,9 +759,8 @@ struct atl1_adapter {
759 u16 link_speed; 759 u16 link_speed;
760 u16 link_duplex; 760 u16 link_duplex;
761 spinlock_t lock; 761 spinlock_t lock;
762 struct work_struct tx_timeout_task; 762 struct work_struct reset_dev_task;
763 struct work_struct link_chg_task; 763 struct work_struct link_chg_task;
764 struct work_struct pcie_dma_to_rst_task;
765 764
766 struct timer_list phy_config_timer; 765 struct timer_list phy_config_timer;
767 bool phy_timer_pending; 766 bool phy_timer_pending;
diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c
index afb7f7dd1bb..2b7af060d49 100644
--- a/drivers/net/atlx/atlx.c
+++ b/drivers/net/atlx/atlx.c
@@ -193,7 +193,7 @@ static void atlx_tx_timeout(struct net_device *netdev)
193{ 193{
194 struct atlx_adapter *adapter = netdev_priv(netdev); 194 struct atlx_adapter *adapter = netdev_priv(netdev);
195 /* Do the reset outside of interrupt context */ 195 /* Do the reset outside of interrupt context */
196 schedule_work(&adapter->tx_timeout_task); 196 schedule_work(&adapter->reset_dev_task);
197} 197}
198 198
199/* 199/*