diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2008-05-24 10:50:22 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2008-07-14 07:06:03 -0400 |
commit | 459f79235d8faa0050180c7e0c7bb4b2b52cbdfd (patch) | |
tree | 97847b1b06ded6c136cdba73bc961a46a3e39a30 /drivers/firewire/fw-card.c | |
parent | 2147ef204f57191e0fff6d5d3d1a0336afa6cfae (diff) |
firewire: clean up fw_card reference counting
This is a functionally equivalent replacement of the current reference
counting of struct fw_card instances. It only converts it to common
idioms as suggested by Kristian Høgsberg:
- struct kref replaces atomic_t as the counter.
- wait_for_completion is used to wait for all card users to complete.
BTW, it may make sense to count card->flush_timer and card->work as
card users too.
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/fw-card.c')
-rw-r--r-- | drivers/firewire/fw-card.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 1332b66ae0b3..da873d795aad 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c | |||
@@ -16,12 +16,15 @@ | |||
16 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 16 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/module.h> | 19 | #include <linux/completion.h> |
20 | #include <linux/errno.h> | 20 | #include <linux/crc-itu-t.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/device.h> | 22 | #include <linux/device.h> |
23 | #include <linux/errno.h> | ||
24 | #include <linux/kref.h> | ||
25 | #include <linux/module.h> | ||
23 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
24 | #include <linux/crc-itu-t.h> | 27 | |
25 | #include "fw-transaction.h" | 28 | #include "fw-transaction.h" |
26 | #include "fw-topology.h" | 29 | #include "fw-topology.h" |
27 | #include "fw-device.h" | 30 | #include "fw-device.h" |
@@ -396,7 +399,6 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, | |||
396 | { | 399 | { |
397 | static atomic_t index = ATOMIC_INIT(-1); | 400 | static atomic_t index = ATOMIC_INIT(-1); |
398 | 401 | ||
399 | atomic_set(&card->device_count, 0); | ||
400 | card->index = atomic_inc_return(&index); | 402 | card->index = atomic_inc_return(&index); |
401 | card->driver = driver; | 403 | card->driver = driver; |
402 | card->device = device; | 404 | card->device = device; |
@@ -405,6 +407,8 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, | |||
405 | card->color = 0; | 407 | card->color = 0; |
406 | card->broadcast_channel = BROADCAST_CHANNEL_INITIAL; | 408 | card->broadcast_channel = BROADCAST_CHANNEL_INITIAL; |
407 | 409 | ||
410 | kref_init(&card->kref); | ||
411 | init_completion(&card->done); | ||
408 | INIT_LIST_HEAD(&card->transaction_list); | 412 | INIT_LIST_HEAD(&card->transaction_list); |
409 | spin_lock_init(&card->lock); | 413 | spin_lock_init(&card->lock); |
410 | setup_timer(&card->flush_timer, | 414 | setup_timer(&card->flush_timer, |
@@ -507,6 +511,14 @@ static struct fw_card_driver dummy_driver = { | |||
507 | }; | 511 | }; |
508 | 512 | ||
509 | void | 513 | void |
514 | fw_card_release(struct kref *kref) | ||
515 | { | ||
516 | struct fw_card *card = container_of(kref, struct fw_card, kref); | ||
517 | |||
518 | complete(&card->done); | ||
519 | } | ||
520 | |||
521 | void | ||
510 | fw_core_remove_card(struct fw_card *card) | 522 | fw_core_remove_card(struct fw_card *card) |
511 | { | 523 | { |
512 | card->driver->update_phy_reg(card, 4, | 524 | card->driver->update_phy_reg(card, 4, |
@@ -521,12 +533,10 @@ fw_core_remove_card(struct fw_card *card) | |||
521 | card->driver = &dummy_driver; | 533 | card->driver = &dummy_driver; |
522 | 534 | ||
523 | fw_destroy_nodes(card); | 535 | fw_destroy_nodes(card); |
524 | /* | 536 | |
525 | * Wait for all device workqueue jobs to finish. Otherwise the | 537 | /* Wait for all users, especially device workqueue jobs, to finish. */ |
526 | * firewire-core module could be unloaded before the jobs ran. | 538 | fw_card_put(card); |
527 | */ | 539 | wait_for_completion(&card->done); |
528 | while (atomic_read(&card->device_count) > 0) | ||
529 | msleep(100); | ||
530 | 540 | ||
531 | cancel_delayed_work_sync(&card->work); | 541 | cancel_delayed_work_sync(&card->work); |
532 | fw_flush_transactions(card); | 542 | fw_flush_transactions(card); |