diff -uprN -X dontdiff src/e1000.h modified_src/e1000.h --- src/e1000.h 2005-05-18 00:31:44.000000000 +0300 +++ modified_src/e1000.h 2005-08-15 09:09:40.792696903 +0300 @@ -232,6 +232,7 @@ struct e1000_adapter { spinlock_t stats_lock; atomic_t irq_sem; struct work_struct tx_timeout_task; + struct work_struct watchdog_task; uint8_t fc_autoneg; #ifdef ETHTOOL_PHYS_ID diff -uprN -X dontdiff src/e1000_main.c modified_src/e1000_main.c --- src/e1000_main.c 2005-05-18 00:31:44.000000000 +0300 +++ modified_src/e1000_main.c 2005-08-15 09:09:40.883695280 +0300 @@ -176,6 +176,7 @@ static void e1000_clean_rx_ring(struct e static void e1000_set_multi(struct net_device *netdev); static void e1000_update_phy_info(unsigned long data); static void e1000_watchdog(unsigned long data); +static void e1000_watchdog_task(struct e1000_adapter *adapter); static void e1000_82547_tx_fifo_stall(unsigned long data); static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev); static struct net_device_stats * e1000_get_stats(struct net_device *netdev); @@ -715,6 +716,9 @@ e1000_probe(struct pci_dev *pdev, adapter->watchdog_timer.function = &e1000_watchdog; adapter->watchdog_timer.data = (unsigned long) adapter; + INIT_WORK(&adapter->watchdog_task, + (void (*)(void *))e1000_watchdog_task, adapter); + init_timer(&adapter->phy_info_timer); adapter->phy_info_timer.function = &e1000_update_phy_info; adapter->phy_info_timer.data = (unsigned long) adapter; @@ -812,6 +816,8 @@ e1000_remove(struct pci_dev *pdev) struct e1000_adapter *adapter = netdev_priv(netdev); uint32_t manc, swsm; + flush_scheduled_work(); + if(adapter->hw.mac_type >= e1000_82540 && adapter->hw.media_type == e1000_media_type_copper) { manc = E1000_READ_REG(&adapter->hw, MANC); @@ -1829,6 +1835,14 @@ static void e1000_watchdog(unsigned long data) { struct e1000_adapter *adapter = (struct e1000_adapter *) data; + + /* Do the rest outside of interrupt context */ + schedule_work(&adapter->watchdog_task); +} + +static void +e1000_watchdog_task(struct e1000_adapter *adapter) +{ struct net_device *netdev = adapter->netdev; struct e1000_desc_ring *txdr = &adapter->tx_ring; uint32_t link; @@ -2392,6 +2406,9 @@ e1000_xmit_frame(struct sk_buff *skb, st tso = e1000_tso(adapter, skb); if(tso < 0) { dev_kfree_skb_any(skb); +#ifdef NETIF_F_LLTX + spin_unlock_irqrestore(&adapter->tx_lock, flags); +#endif return NETDEV_TX_OK; }