aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-card.c
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 /drivers/firewire/fw-card.c
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)
Diffstat (limited to 'drivers/firewire/fw-card.c')
-rw-r--r--drivers/firewire/fw-card.c18
1 files changed, 15 insertions, 3 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}