aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Fenlason <fenlason@redhat.com>2008-11-29 11:44:57 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-01-04 17:50:37 -0500
commit0fa1986f3a6c385b3bca0b6a051c30e548bda30d (patch)
tree5b61ce9579a520f89bc4c000bfe3496e58d4f47a
parent2cc489c21338950c2b4097dec48864bdf7b30f1b (diff)
firewire: improve refcounting of fw_card
Take a reference to the card whenever fw_card_bm_work() is scheduled on that card and release it when the work is done. This allows us to remove the cancel_delayed_work_sync() in fw_core_remove_card(). Signed-off-by: Jay Fenlason <fenlason@redhat.com> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (patch update)
-rw-r--r--drivers/firewire/fw-card.c18
-rw-r--r--drivers/firewire/fw-device.c6
-rw-r--r--drivers/firewire/fw-topology.c2
-rw-r--r--drivers/firewire/fw-transaction.h2
4 files changed, 21 insertions, 7 deletions
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index c7760794de0d..799f94424c8a 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -189,6 +189,17 @@ static const char gap_count_table[] = {
189 63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40 189 63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40
190}; 190};
191 191
192void
193fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
194{
195 int scheduled;
196
197 fw_card_get(card);
198 scheduled = schedule_delayed_work(&card->work, delay);
199 if (!scheduled)
200 fw_card_put(card);
201}
202
192static void 203static void
193fw_card_bm_work(struct work_struct *work) 204fw_card_bm_work(struct work_struct *work)
194{ 205{
@@ -206,7 +217,7 @@ fw_card_bm_work(struct work_struct *work)
206 217
207 if (local_node == NULL) { 218 if (local_node == NULL) {
208 spin_unlock_irqrestore(&card->lock, flags); 219 spin_unlock_irqrestore(&card->lock, flags);
209 return; 220 goto out_put_card;
210 } 221 }
211 fw_node_get(local_node); 222 fw_node_get(local_node);
212 fw_node_get(root_node); 223 fw_node_get(root_node);
@@ -280,7 +291,7 @@ fw_card_bm_work(struct work_struct *work)
280 * this task 100ms from now. 291 * this task 100ms from now.
281 */ 292 */
282 spin_unlock_irqrestore(&card->lock, flags); 293 spin_unlock_irqrestore(&card->lock, flags);
283 schedule_delayed_work(&card->work, DIV_ROUND_UP(HZ, 10)); 294 fw_schedule_bm_work(card, DIV_ROUND_UP(HZ, 10));
284 goto out; 295 goto out;
285 } 296 }
286 297
@@ -355,6 +366,8 @@ fw_card_bm_work(struct work_struct *work)
355 fw_device_put(root_device); 366 fw_device_put(root_device);
356 fw_node_put(root_node); 367 fw_node_put(root_node);
357 fw_node_put(local_node); 368 fw_node_put(local_node);
369 out_put_card:
370 fw_card_put(card);
358} 371}
359 372
360static void 373static void
@@ -510,7 +523,6 @@ fw_core_remove_card(struct fw_card *card)
510 fw_card_put(card); 523 fw_card_put(card);
511 wait_for_completion(&card->done); 524 wait_for_completion(&card->done);
512 525
513 cancel_delayed_work_sync(&card->work);
514 WARN_ON(!list_empty(&card->transaction_list)); 526 WARN_ON(!list_empty(&card->transaction_list));
515 del_timer_sync(&card->flush_timer); 527 del_timer_sync(&card->flush_timer);
516} 528}
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index 31b6c74d34df..c173be383725 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -689,7 +689,7 @@ static void fw_device_init(struct work_struct *work)
689 fw_notify("giving up on config rom for node id %x\n", 689 fw_notify("giving up on config rom for node id %x\n",
690 device->node_id); 690 device->node_id);
691 if (device->node == device->card->root_node) 691 if (device->node == device->card->root_node)
692 schedule_delayed_work(&device->card->work, 0); 692 fw_schedule_bm_work(device->card, 0);
693 fw_device_release(&device->device); 693 fw_device_release(&device->device);
694 } 694 }
695 return; 695 return;
@@ -758,7 +758,7 @@ static void fw_device_init(struct work_struct *work)
758 * pretty harmless. 758 * pretty harmless.
759 */ 759 */
760 if (device->node == device->card->root_node) 760 if (device->node == device->card->root_node)
761 schedule_delayed_work(&device->card->work, 0); 761 fw_schedule_bm_work(device->card, 0);
762 762
763 return; 763 return;
764 764
@@ -892,7 +892,7 @@ static void fw_device_refresh(struct work_struct *work)
892 fw_device_shutdown(work); 892 fw_device_shutdown(work);
893 out: 893 out:
894 if (node_id == card->root_node->node_id) 894 if (node_id == card->root_node->node_id)
895 schedule_delayed_work(&card->work, 0); 895 fw_schedule_bm_work(card, 0);
896} 896}
897 897
898void fw_node_event(struct fw_card *card, struct fw_node *node, int event) 898void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
index 5e204713002d..7687dca1a690 100644
--- a/drivers/firewire/fw-topology.c
+++ b/drivers/firewire/fw-topology.c
@@ -530,7 +530,7 @@ fw_core_handle_bus_reset(struct fw_card *card,
530 smp_wmb(); 530 smp_wmb();
531 card->generation = generation; 531 card->generation = generation;
532 card->reset_jiffies = jiffies; 532 card->reset_jiffies = jiffies;
533 schedule_delayed_work(&card->work, 0); 533 fw_schedule_bm_work(card, 0);
534 534
535 local_node = build_tree(card, self_ids, self_id_count); 535 local_node = build_tree(card, self_ids, self_id_count);
536 536
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
index 839466f0a795..0497a18dc59e 100644
--- a/drivers/firewire/fw-transaction.h
+++ b/drivers/firewire/fw-transaction.h
@@ -278,6 +278,8 @@ static inline void fw_card_put(struct fw_card *card)
278 kref_put(&card->kref, fw_card_release); 278 kref_put(&card->kref, fw_card_release);
279} 279}
280 280
281extern void fw_schedule_bm_work(struct fw_card *card, unsigned long delay);
282
281/* 283/*
282 * The iso packet format allows for an immediate header/payload part 284 * The iso packet format allows for an immediate header/payload part
283 * stored in 'header' immediately after the packet info plus an 285 * stored in 'header' immediately after the packet info plus an