diff options
Diffstat (limited to 'drivers/firewire/fw-card.c')
| -rw-r--r-- | drivers/firewire/fw-card.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 418c18f07e9d..799f94424c8a 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c | |||
| @@ -75,7 +75,7 @@ generate_config_rom(struct fw_card *card, size_t *config_rom_length) | |||
| 75 | * controller, block reads to the config rom accesses the host | 75 | * controller, block reads to the config rom accesses the host |
| 76 | * memory, but quadlet read access the hardware bus info block | 76 | * memory, but quadlet read access the hardware bus info block |
| 77 | * registers. That's just crack, but it means we should make | 77 | * registers. That's just crack, but it means we should make |
| 78 | * sure the contents of bus info block in host memory mathces | 78 | * sure the contents of bus info block in host memory matches |
| 79 | * the version stored in the OHCI registers. | 79 | * the version stored in the OHCI registers. |
| 80 | */ | 80 | */ |
| 81 | 81 | ||
| @@ -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 | ||
| 192 | void | ||
| 193 | fw_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 | |||
| 192 | static void | 203 | static void |
| 193 | fw_card_bm_work(struct work_struct *work) | 204 | fw_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 | ||
| 360 | static void | 373 | static 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 | } |
