diff options
Diffstat (limited to 'drivers/net/e1000/e1000_main.c')
| -rw-r--r-- | drivers/net/e1000/e1000_main.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 5b4c6c061414..c88439deb7d8 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
| @@ -521,8 +521,21 @@ void e1000_down(struct e1000_adapter *adapter) | |||
| 521 | e1000_clean_all_rx_rings(adapter); | 521 | e1000_clean_all_rx_rings(adapter); |
| 522 | } | 522 | } |
| 523 | 523 | ||
| 524 | void e1000_reinit_safe(struct e1000_adapter *adapter) | ||
| 525 | { | ||
| 526 | while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) | ||
| 527 | msleep(1); | ||
| 528 | rtnl_lock(); | ||
| 529 | e1000_down(adapter); | ||
| 530 | e1000_up(adapter); | ||
| 531 | rtnl_unlock(); | ||
| 532 | clear_bit(__E1000_RESETTING, &adapter->flags); | ||
| 533 | } | ||
| 534 | |||
| 524 | void e1000_reinit_locked(struct e1000_adapter *adapter) | 535 | void e1000_reinit_locked(struct e1000_adapter *adapter) |
| 525 | { | 536 | { |
| 537 | /* if rtnl_lock is not held the call path is bogus */ | ||
| 538 | ASSERT_RTNL(); | ||
| 526 | WARN_ON(in_interrupt()); | 539 | WARN_ON(in_interrupt()); |
| 527 | while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) | 540 | while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) |
| 528 | msleep(1); | 541 | msleep(1); |
| @@ -2247,7 +2260,10 @@ static void e1000_update_phy_info_task(struct work_struct *work) | |||
| 2247 | struct e1000_adapter, | 2260 | struct e1000_adapter, |
| 2248 | phy_info_task); | 2261 | phy_info_task); |
| 2249 | struct e1000_hw *hw = &adapter->hw; | 2262 | struct e1000_hw *hw = &adapter->hw; |
| 2263 | |||
| 2264 | rtnl_lock(); | ||
| 2250 | e1000_phy_get_info(hw, &adapter->phy_info); | 2265 | e1000_phy_get_info(hw, &adapter->phy_info); |
| 2266 | rtnl_unlock(); | ||
| 2251 | } | 2267 | } |
| 2252 | 2268 | ||
| 2253 | /** | 2269 | /** |
| @@ -2273,6 +2289,7 @@ static void e1000_82547_tx_fifo_stall_task(struct work_struct *work) | |||
| 2273 | struct net_device *netdev = adapter->netdev; | 2289 | struct net_device *netdev = adapter->netdev; |
| 2274 | u32 tctl; | 2290 | u32 tctl; |
| 2275 | 2291 | ||
| 2292 | rtnl_lock(); | ||
| 2276 | if (atomic_read(&adapter->tx_fifo_stall)) { | 2293 | if (atomic_read(&adapter->tx_fifo_stall)) { |
| 2277 | if ((er32(TDT) == er32(TDH)) && | 2294 | if ((er32(TDT) == er32(TDH)) && |
| 2278 | (er32(TDFT) == er32(TDFH)) && | 2295 | (er32(TDFT) == er32(TDFH)) && |
| @@ -2293,6 +2310,7 @@ static void e1000_82547_tx_fifo_stall_task(struct work_struct *work) | |||
| 2293 | mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1); | 2310 | mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1); |
| 2294 | } | 2311 | } |
| 2295 | } | 2312 | } |
| 2313 | rtnl_unlock(); | ||
| 2296 | } | 2314 | } |
| 2297 | 2315 | ||
| 2298 | bool e1000_has_link(struct e1000_adapter *adapter) | 2316 | bool e1000_has_link(struct e1000_adapter *adapter) |
| @@ -3160,7 +3178,7 @@ static void e1000_reset_task(struct work_struct *work) | |||
| 3160 | struct e1000_adapter *adapter = | 3178 | struct e1000_adapter *adapter = |
| 3161 | container_of(work, struct e1000_adapter, reset_task); | 3179 | container_of(work, struct e1000_adapter, reset_task); |
| 3162 | 3180 | ||
| 3163 | e1000_reinit_locked(adapter); | 3181 | e1000_reinit_safe(adapter); |
| 3164 | } | 3182 | } |
| 3165 | 3183 | ||
| 3166 | /** | 3184 | /** |
