diff options
author | Jie Yang <jie.yang@atheros.com> | 2009-12-06 18:16:58 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-08 23:48:07 -0500 |
commit | cb19054697e92a793f336380fd72c588521178ff (patch) | |
tree | e6bbbec3688aba8fb68eb54674e3f67a4c1f49d8 | |
parent | 4b45e3424e7210688f95039b8cdffb11d2e48934 (diff) |
atl1c:use common_task instead of reset_task and link_chg_task
use common_task instead of reset_task and link_chg_task, so it fix "call cancel_work_sync
from the work itself".
Signed-off-by: Jie Yang <jie.yang@atheros.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/atl1c/atl1c.h | 6 | ||||
-rw-r--r-- | drivers/net/atl1c/atl1c_main.c | 72 |
2 files changed, 37 insertions, 41 deletions
diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h index 7e09084f75a9..efe5435bc3d3 100644 --- a/drivers/net/atl1c/atl1c.h +++ b/drivers/net/atl1c/atl1c.h | |||
@@ -555,6 +555,9 @@ struct atl1c_adapter { | |||
555 | #define __AT_TESTING 0x0001 | 555 | #define __AT_TESTING 0x0001 |
556 | #define __AT_RESETTING 0x0002 | 556 | #define __AT_RESETTING 0x0002 |
557 | #define __AT_DOWN 0x0003 | 557 | #define __AT_DOWN 0x0003 |
558 | u8 work_event; | ||
559 | #define ATL1C_WORK_EVENT_RESET 0x01 | ||
560 | #define ATL1C_WORK_EVENT_LINK_CHANGE 0x02 | ||
558 | u32 msg_enable; | 561 | u32 msg_enable; |
559 | 562 | ||
560 | bool have_msi; | 563 | bool have_msi; |
@@ -566,8 +569,7 @@ struct atl1c_adapter { | |||
566 | spinlock_t tx_lock; | 569 | spinlock_t tx_lock; |
567 | atomic_t irq_sem; | 570 | atomic_t irq_sem; |
568 | 571 | ||
569 | struct work_struct reset_task; | 572 | struct work_struct common_task; |
570 | struct work_struct link_chg_task; | ||
571 | struct timer_list watchdog_timer; | 573 | struct timer_list watchdog_timer; |
572 | struct timer_list phy_config_timer; | 574 | struct timer_list phy_config_timer; |
573 | 575 | ||
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 1098dad3d381..666261b5851e 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c | |||
@@ -198,27 +198,12 @@ static void atl1c_phy_config(unsigned long data) | |||
198 | 198 | ||
199 | void atl1c_reinit_locked(struct atl1c_adapter *adapter) | 199 | void atl1c_reinit_locked(struct atl1c_adapter *adapter) |
200 | { | 200 | { |
201 | |||
202 | WARN_ON(in_interrupt()); | 201 | WARN_ON(in_interrupt()); |
203 | atl1c_down(adapter); | 202 | atl1c_down(adapter); |
204 | atl1c_up(adapter); | 203 | atl1c_up(adapter); |
205 | clear_bit(__AT_RESETTING, &adapter->flags); | 204 | clear_bit(__AT_RESETTING, &adapter->flags); |
206 | } | 205 | } |
207 | 206 | ||
208 | static void atl1c_reset_task(struct work_struct *work) | ||
209 | { | ||
210 | struct atl1c_adapter *adapter; | ||
211 | struct net_device *netdev; | ||
212 | |||
213 | adapter = container_of(work, struct atl1c_adapter, reset_task); | ||
214 | netdev = adapter->netdev; | ||
215 | |||
216 | netif_device_detach(netdev); | ||
217 | atl1c_down(adapter); | ||
218 | atl1c_up(adapter); | ||
219 | netif_device_attach(netdev); | ||
220 | } | ||
221 | |||
222 | static void atl1c_check_link_status(struct atl1c_adapter *adapter) | 207 | static void atl1c_check_link_status(struct atl1c_adapter *adapter) |
223 | { | 208 | { |
224 | struct atl1c_hw *hw = &adapter->hw; | 209 | struct atl1c_hw *hw = &adapter->hw; |
@@ -275,18 +260,6 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter) | |||
275 | } | 260 | } |
276 | } | 261 | } |
277 | 262 | ||
278 | /* | ||
279 | * atl1c_link_chg_task - deal with link change event Out of interrupt context | ||
280 | * @netdev: network interface device structure | ||
281 | */ | ||
282 | static void atl1c_link_chg_task(struct work_struct *work) | ||
283 | { | ||
284 | struct atl1c_adapter *adapter; | ||
285 | |||
286 | adapter = container_of(work, struct atl1c_adapter, link_chg_task); | ||
287 | atl1c_check_link_status(adapter); | ||
288 | } | ||
289 | |||
290 | static void atl1c_link_chg_event(struct atl1c_adapter *adapter) | 263 | static void atl1c_link_chg_event(struct atl1c_adapter *adapter) |
291 | { | 264 | { |
292 | struct net_device *netdev = adapter->netdev; | 265 | struct net_device *netdev = adapter->netdev; |
@@ -311,20 +284,40 @@ static void atl1c_link_chg_event(struct atl1c_adapter *adapter) | |||
311 | adapter->link_speed = SPEED_0; | 284 | adapter->link_speed = SPEED_0; |
312 | } | 285 | } |
313 | } | 286 | } |
314 | schedule_work(&adapter->link_chg_task); | 287 | |
288 | adapter->work_event |= ATL1C_WORK_EVENT_LINK_CHANGE; | ||
289 | schedule_work(&adapter->common_task); | ||
315 | } | 290 | } |
316 | 291 | ||
317 | static void atl1c_del_timer(struct atl1c_adapter *adapter) | 292 | static void atl1c_common_task(struct work_struct *work) |
318 | { | 293 | { |
319 | del_timer_sync(&adapter->phy_config_timer); | 294 | struct atl1c_adapter *adapter; |
295 | struct net_device *netdev; | ||
296 | |||
297 | adapter = container_of(work, struct atl1c_adapter, common_task); | ||
298 | netdev = adapter->netdev; | ||
299 | |||
300 | if (adapter->work_event & ATL1C_WORK_EVENT_RESET) { | ||
301 | netif_device_detach(netdev); | ||
302 | atl1c_down(adapter); | ||
303 | atl1c_up(adapter); | ||
304 | netif_device_attach(netdev); | ||
305 | return; | ||
306 | } | ||
307 | |||
308 | if (adapter->work_event & ATL1C_WORK_EVENT_LINK_CHANGE) | ||
309 | atl1c_check_link_status(adapter); | ||
310 | |||
311 | return; | ||
320 | } | 312 | } |
321 | 313 | ||
322 | static void atl1c_cancel_work(struct atl1c_adapter *adapter) | 314 | |
315 | static void atl1c_del_timer(struct atl1c_adapter *adapter) | ||
323 | { | 316 | { |
324 | cancel_work_sync(&adapter->reset_task); | 317 | del_timer_sync(&adapter->phy_config_timer); |
325 | cancel_work_sync(&adapter->link_chg_task); | ||
326 | } | 318 | } |
327 | 319 | ||
320 | |||
328 | /* | 321 | /* |
329 | * atl1c_tx_timeout - Respond to a Tx Hang | 322 | * atl1c_tx_timeout - Respond to a Tx Hang |
330 | * @netdev: network interface device structure | 323 | * @netdev: network interface device structure |
@@ -334,7 +327,8 @@ static void atl1c_tx_timeout(struct net_device *netdev) | |||
334 | struct atl1c_adapter *adapter = netdev_priv(netdev); | 327 | struct atl1c_adapter *adapter = netdev_priv(netdev); |
335 | 328 | ||
336 | /* Do the reset outside of interrupt context */ | 329 | /* Do the reset outside of interrupt context */ |
337 | schedule_work(&adapter->reset_task); | 330 | adapter->work_event |= ATL1C_WORK_EVENT_RESET; |
331 | schedule_work(&adapter->common_task); | ||
338 | } | 332 | } |
339 | 333 | ||
340 | /* | 334 | /* |
@@ -1539,7 +1533,8 @@ static irqreturn_t atl1c_intr(int irq, void *data) | |||
1539 | /* reset MAC */ | 1533 | /* reset MAC */ |
1540 | hw->intr_mask &= ~ISR_ERROR; | 1534 | hw->intr_mask &= ~ISR_ERROR; |
1541 | AT_WRITE_REG(hw, REG_IMR, hw->intr_mask); | 1535 | AT_WRITE_REG(hw, REG_IMR, hw->intr_mask); |
1542 | schedule_work(&adapter->reset_task); | 1536 | adapter->work_event |= ATL1C_WORK_EVENT_RESET; |
1537 | schedule_work(&adapter->common_task); | ||
1543 | break; | 1538 | break; |
1544 | } | 1539 | } |
1545 | 1540 | ||
@@ -2208,8 +2203,7 @@ void atl1c_down(struct atl1c_adapter *adapter) | |||
2208 | struct net_device *netdev = adapter->netdev; | 2203 | struct net_device *netdev = adapter->netdev; |
2209 | 2204 | ||
2210 | atl1c_del_timer(adapter); | 2205 | atl1c_del_timer(adapter); |
2211 | atl1c_cancel_work(adapter); | 2206 | adapter->work_event = 0; /* clear all event */ |
2212 | |||
2213 | /* signal that we're down so the interrupt handler does not | 2207 | /* signal that we're down so the interrupt handler does not |
2214 | * reschedule our watchdog timer */ | 2208 | * reschedule our watchdog timer */ |
2215 | set_bit(__AT_DOWN, &adapter->flags); | 2209 | set_bit(__AT_DOWN, &adapter->flags); |
@@ -2609,8 +2603,8 @@ static int __devinit atl1c_probe(struct pci_dev *pdev, | |||
2609 | adapter->hw.mac_addr[4], adapter->hw.mac_addr[5]); | 2603 | adapter->hw.mac_addr[4], adapter->hw.mac_addr[5]); |
2610 | 2604 | ||
2611 | atl1c_hw_set_mac_addr(&adapter->hw); | 2605 | atl1c_hw_set_mac_addr(&adapter->hw); |
2612 | INIT_WORK(&adapter->reset_task, atl1c_reset_task); | 2606 | INIT_WORK(&adapter->common_task, atl1c_common_task); |
2613 | INIT_WORK(&adapter->link_chg_task, atl1c_link_chg_task); | 2607 | adapter->work_event = 0; |
2614 | err = register_netdev(netdev); | 2608 | err = register_netdev(netdev); |
2615 | if (err) { | 2609 | if (err) { |
2616 | dev_err(&pdev->dev, "register netdevice failed\n"); | 2610 | dev_err(&pdev->dev, "register netdevice failed\n"); |