From 459f79235d8faa0050180c7e0c7bb4b2b52cbdfd Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 24 May 2008 16:50:22 +0200 Subject: firewire: clean up fw_card reference counting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- drivers/firewire/fw-card.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'drivers/firewire/fw-card.c') diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 1332b66ae0b..da873d795aa 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c @@ -16,12 +16,15 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include -#include +#include +#include #include #include +#include +#include +#include #include -#include + #include "fw-transaction.h" #include "fw-topology.h" #include "fw-device.h" @@ -396,7 +399,6 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, { static atomic_t index = ATOMIC_INIT(-1); - atomic_set(&card->device_count, 0); card->index = atomic_inc_return(&index); card->driver = driver; card->device = device; @@ -405,6 +407,8 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, card->color = 0; card->broadcast_channel = BROADCAST_CHANNEL_INITIAL; + kref_init(&card->kref); + init_completion(&card->done); INIT_LIST_HEAD(&card->transaction_list); spin_lock_init(&card->lock); setup_timer(&card->flush_timer, @@ -506,6 +510,14 @@ static struct fw_card_driver dummy_driver = { .enable_phys_dma = dummy_enable_phys_dma, }; +void +fw_card_release(struct kref *kref) +{ + struct fw_card *card = container_of(kref, struct fw_card, kref); + + complete(&card->done); +} + void fw_core_remove_card(struct fw_card *card) { @@ -521,12 +533,10 @@ fw_core_remove_card(struct fw_card *card) card->driver = &dummy_driver; fw_destroy_nodes(card); - /* - * Wait for all device workqueue jobs to finish. Otherwise the - * firewire-core module could be unloaded before the jobs ran. - */ - while (atomic_read(&card->device_count) > 0) - msleep(100); + + /* Wait for all users, especially device workqueue jobs, to finish. */ + fw_card_put(card); + wait_for_completion(&card->done); cancel_delayed_work_sync(&card->work); fw_flush_transactions(card); -- cgit v1.2.3