diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-01-17 06:01:12 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-01-17 06:01:12 -0500 |
commit | d1a020050c6ce1a0794ff73582ccf47e4db536f7 (patch) | |
tree | 1b7250410f24703cd77c76156e758db9887137aa /drivers/firewire | |
parent | dc61b66fc724f89d357c43e2319d2cb7bec1e517 (diff) | |
parent | 641b4879444c0edb276fedca5c2fcbd2e5c70044 (diff) |
Merge branch 'topic/usb-mixer-cache' into next/usb-audio
Diffstat (limited to 'drivers/firewire')
-rw-r--r-- | drivers/firewire/fw-card.c | 33 | ||||
-rw-r--r-- | drivers/firewire/fw-device.c | 31 | ||||
-rw-r--r-- | drivers/firewire/fw-device.h | 2 | ||||
-rw-r--r-- | drivers/firewire/fw-sbp2.c | 21 | ||||
-rw-r--r-- | drivers/firewire/fw-topology.c | 16 | ||||
-rw-r--r-- | drivers/firewire/fw-transaction.c | 2 | ||||
-rw-r--r-- | drivers/firewire/fw-transaction.h | 13 |
7 files changed, 62 insertions, 56 deletions
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 418c18f07e9d..6bd91a15d5e6 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 | { |
@@ -198,6 +209,8 @@ fw_card_bm_work(struct work_struct *work) | |||
198 | unsigned long flags; | 209 | unsigned long flags; |
199 | int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode; | 210 | int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode; |
200 | bool do_reset = false; | 211 | bool do_reset = false; |
212 | bool root_device_is_running; | ||
213 | bool root_device_is_cmc; | ||
201 | __be32 lock_data[2]; | 214 | __be32 lock_data[2]; |
202 | 215 | ||
203 | spin_lock_irqsave(&card->lock, flags); | 216 | spin_lock_irqsave(&card->lock, flags); |
@@ -206,15 +219,16 @@ fw_card_bm_work(struct work_struct *work) | |||
206 | 219 | ||
207 | if (local_node == NULL) { | 220 | if (local_node == NULL) { |
208 | spin_unlock_irqrestore(&card->lock, flags); | 221 | spin_unlock_irqrestore(&card->lock, flags); |
209 | return; | 222 | goto out_put_card; |
210 | } | 223 | } |
211 | fw_node_get(local_node); | 224 | fw_node_get(local_node); |
212 | fw_node_get(root_node); | 225 | fw_node_get(root_node); |
213 | 226 | ||
214 | generation = card->generation; | 227 | generation = card->generation; |
215 | root_device = root_node->data; | 228 | root_device = root_node->data; |
216 | if (root_device) | 229 | root_device_is_running = root_device && |
217 | fw_device_get(root_device); | 230 | atomic_read(&root_device->state) == FW_DEVICE_RUNNING; |
231 | root_device_is_cmc = root_device && root_device->cmc; | ||
218 | root_id = root_node->node_id; | 232 | root_id = root_node->node_id; |
219 | grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10)); | 233 | grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 10)); |
220 | 234 | ||
@@ -280,7 +294,7 @@ fw_card_bm_work(struct work_struct *work) | |||
280 | * this task 100ms from now. | 294 | * this task 100ms from now. |
281 | */ | 295 | */ |
282 | spin_unlock_irqrestore(&card->lock, flags); | 296 | spin_unlock_irqrestore(&card->lock, flags); |
283 | schedule_delayed_work(&card->work, DIV_ROUND_UP(HZ, 10)); | 297 | fw_schedule_bm_work(card, DIV_ROUND_UP(HZ, 10)); |
284 | goto out; | 298 | goto out; |
285 | } | 299 | } |
286 | 300 | ||
@@ -297,14 +311,14 @@ fw_card_bm_work(struct work_struct *work) | |||
297 | * config rom. In either case, pick another root. | 311 | * config rom. In either case, pick another root. |
298 | */ | 312 | */ |
299 | new_root_id = local_node->node_id; | 313 | new_root_id = local_node->node_id; |
300 | } else if (atomic_read(&root_device->state) != FW_DEVICE_RUNNING) { | 314 | } else if (!root_device_is_running) { |
301 | /* | 315 | /* |
302 | * If we haven't probed this device yet, bail out now | 316 | * If we haven't probed this device yet, bail out now |
303 | * and let's try again once that's done. | 317 | * and let's try again once that's done. |
304 | */ | 318 | */ |
305 | spin_unlock_irqrestore(&card->lock, flags); | 319 | spin_unlock_irqrestore(&card->lock, flags); |
306 | goto out; | 320 | goto out; |
307 | } else if (root_device->cmc) { | 321 | } else if (root_device_is_cmc) { |
308 | /* | 322 | /* |
309 | * FIXME: I suppose we should set the cmstr bit in the | 323 | * FIXME: I suppose we should set the cmstr bit in the |
310 | * STATE_CLEAR register of this node, as described in | 324 | * STATE_CLEAR register of this node, as described in |
@@ -351,10 +365,10 @@ fw_card_bm_work(struct work_struct *work) | |||
351 | fw_core_initiate_bus_reset(card, 1); | 365 | fw_core_initiate_bus_reset(card, 1); |
352 | } | 366 | } |
353 | out: | 367 | out: |
354 | if (root_device) | ||
355 | fw_device_put(root_device); | ||
356 | fw_node_put(root_node); | 368 | fw_node_put(root_node); |
357 | fw_node_put(local_node); | 369 | fw_node_put(local_node); |
370 | out_put_card: | ||
371 | fw_card_put(card); | ||
358 | } | 372 | } |
359 | 373 | ||
360 | static void | 374 | static void |
@@ -510,7 +524,6 @@ fw_core_remove_card(struct fw_card *card) | |||
510 | fw_card_put(card); | 524 | fw_card_put(card); |
511 | wait_for_completion(&card->done); | 525 | wait_for_completion(&card->done); |
512 | 526 | ||
513 | cancel_delayed_work_sync(&card->work); | ||
514 | WARN_ON(!list_empty(&card->transaction_list)); | 527 | WARN_ON(!list_empty(&card->transaction_list)); |
515 | del_timer_sync(&card->flush_timer); | 528 | del_timer_sync(&card->flush_timer); |
516 | } | 529 | } |
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index 6b9be42c7b98..2af5a8d1e012 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c | |||
@@ -159,7 +159,8 @@ static void fw_device_release(struct device *dev) | |||
159 | 159 | ||
160 | /* | 160 | /* |
161 | * Take the card lock so we don't set this to NULL while a | 161 | * Take the card lock so we don't set this to NULL while a |
162 | * FW_NODE_UPDATED callback is being handled. | 162 | * FW_NODE_UPDATED callback is being handled or while the |
163 | * bus manager work looks at this node. | ||
163 | */ | 164 | */ |
164 | spin_lock_irqsave(&card->lock, flags); | 165 | spin_lock_irqsave(&card->lock, flags); |
165 | device->node->data = NULL; | 166 | device->node->data = NULL; |
@@ -617,7 +618,7 @@ static int shutdown_unit(struct device *device, void *data) | |||
617 | */ | 618 | */ |
618 | DECLARE_RWSEM(fw_device_rwsem); | 619 | DECLARE_RWSEM(fw_device_rwsem); |
619 | 620 | ||
620 | static DEFINE_IDR(fw_device_idr); | 621 | DEFINE_IDR(fw_device_idr); |
621 | int fw_cdev_major; | 622 | int fw_cdev_major; |
622 | 623 | ||
623 | struct fw_device *fw_device_get_by_devt(dev_t devt) | 624 | struct fw_device *fw_device_get_by_devt(dev_t devt) |
@@ -689,18 +690,19 @@ static void fw_device_init(struct work_struct *work) | |||
689 | fw_notify("giving up on config rom for node id %x\n", | 690 | fw_notify("giving up on config rom for node id %x\n", |
690 | device->node_id); | 691 | device->node_id); |
691 | if (device->node == device->card->root_node) | 692 | if (device->node == device->card->root_node) |
692 | schedule_delayed_work(&device->card->work, 0); | 693 | fw_schedule_bm_work(device->card, 0); |
693 | fw_device_release(&device->device); | 694 | fw_device_release(&device->device); |
694 | } | 695 | } |
695 | return; | 696 | return; |
696 | } | 697 | } |
697 | 698 | ||
698 | err = -ENOMEM; | 699 | device_initialize(&device->device); |
699 | 700 | ||
700 | fw_device_get(device); | 701 | fw_device_get(device); |
701 | down_write(&fw_device_rwsem); | 702 | down_write(&fw_device_rwsem); |
702 | if (idr_pre_get(&fw_device_idr, GFP_KERNEL)) | 703 | err = idr_pre_get(&fw_device_idr, GFP_KERNEL) ? |
703 | err = idr_get_new(&fw_device_idr, device, &minor); | 704 | idr_get_new(&fw_device_idr, device, &minor) : |
705 | -ENOMEM; | ||
704 | up_write(&fw_device_rwsem); | 706 | up_write(&fw_device_rwsem); |
705 | 707 | ||
706 | if (err < 0) | 708 | if (err < 0) |
@@ -758,7 +760,7 @@ static void fw_device_init(struct work_struct *work) | |||
758 | * pretty harmless. | 760 | * pretty harmless. |
759 | */ | 761 | */ |
760 | if (device->node == device->card->root_node) | 762 | if (device->node == device->card->root_node) |
761 | schedule_delayed_work(&device->card->work, 0); | 763 | fw_schedule_bm_work(device->card, 0); |
762 | 764 | ||
763 | return; | 765 | return; |
764 | 766 | ||
@@ -892,7 +894,7 @@ static void fw_device_refresh(struct work_struct *work) | |||
892 | fw_device_shutdown(work); | 894 | fw_device_shutdown(work); |
893 | out: | 895 | out: |
894 | if (node_id == card->root_node->node_id) | 896 | if (node_id == card->root_node->node_id) |
895 | schedule_delayed_work(&card->work, 0); | 897 | fw_schedule_bm_work(card, 0); |
896 | } | 898 | } |
897 | 899 | ||
898 | void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | 900 | void fw_node_event(struct fw_card *card, struct fw_node *node, int event) |
@@ -911,13 +913,14 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | |||
911 | 913 | ||
912 | /* | 914 | /* |
913 | * Do minimal intialization of the device here, the | 915 | * Do minimal intialization of the device here, the |
914 | * rest will happen in fw_device_init(). We need the | 916 | * rest will happen in fw_device_init(). |
915 | * card and node so we can read the config rom and we | 917 | * |
916 | * need to do device_initialize() now so | 918 | * Attention: A lot of things, even fw_device_get(), |
917 | * device_for_each_child() in FW_NODE_UPDATED is | 919 | * cannot be done before fw_device_init() finished! |
918 | * doesn't freak out. | 920 | * You can basically just check device->state and |
921 | * schedule work until then, but only while holding | ||
922 | * card->lock. | ||
919 | */ | 923 | */ |
920 | device_initialize(&device->device); | ||
921 | atomic_set(&device->state, FW_DEVICE_INITIALIZING); | 924 | atomic_set(&device->state, FW_DEVICE_INITIALIZING); |
922 | device->card = fw_card_get(card); | 925 | device->card = fw_card_get(card); |
923 | device->node = fw_node_get(node); | 926 | device->node = fw_node_get(node); |
diff --git a/drivers/firewire/fw-device.h b/drivers/firewire/fw-device.h index 42305bbac72f..df51732608d9 100644 --- a/drivers/firewire/fw-device.h +++ b/drivers/firewire/fw-device.h | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
23 | #include <linux/cdev.h> | 23 | #include <linux/cdev.h> |
24 | #include <linux/idr.h> | ||
24 | #include <linux/rwsem.h> | 25 | #include <linux/rwsem.h> |
25 | #include <asm/atomic.h> | 26 | #include <asm/atomic.h> |
26 | 27 | ||
@@ -99,6 +100,7 @@ void fw_device_cdev_update(struct fw_device *device); | |||
99 | void fw_device_cdev_remove(struct fw_device *device); | 100 | void fw_device_cdev_remove(struct fw_device *device); |
100 | 101 | ||
101 | extern struct rw_semaphore fw_device_rwsem; | 102 | extern struct rw_semaphore fw_device_rwsem; |
103 | extern struct idr fw_device_idr; | ||
102 | extern int fw_cdev_major; | 104 | extern int fw_cdev_major; |
103 | 105 | ||
104 | /* | 106 | /* |
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index e54403ee59e7..e88d5067448c 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c | |||
@@ -670,17 +670,6 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu) | |||
670 | &d, sizeof(d), complete_agent_reset_write_no_wait, t); | 670 | &d, sizeof(d), complete_agent_reset_write_no_wait, t); |
671 | } | 671 | } |
672 | 672 | ||
673 | static void sbp2_set_generation(struct sbp2_logical_unit *lu, int generation) | ||
674 | { | ||
675 | struct fw_card *card = fw_device(lu->tgt->unit->device.parent)->card; | ||
676 | unsigned long flags; | ||
677 | |||
678 | /* serialize with comparisons of lu->generation and card->generation */ | ||
679 | spin_lock_irqsave(&card->lock, flags); | ||
680 | lu->generation = generation; | ||
681 | spin_unlock_irqrestore(&card->lock, flags); | ||
682 | } | ||
683 | |||
684 | static inline void sbp2_allow_block(struct sbp2_logical_unit *lu) | 673 | static inline void sbp2_allow_block(struct sbp2_logical_unit *lu) |
685 | { | 674 | { |
686 | /* | 675 | /* |
@@ -884,7 +873,7 @@ static void sbp2_login(struct work_struct *work) | |||
884 | goto out; | 873 | goto out; |
885 | 874 | ||
886 | generation = device->generation; | 875 | generation = device->generation; |
887 | smp_rmb(); /* node_id must not be older than generation */ | 876 | smp_rmb(); /* node IDs must not be older than generation */ |
888 | node_id = device->node_id; | 877 | node_id = device->node_id; |
889 | local_node_id = device->card->node_id; | 878 | local_node_id = device->card->node_id; |
890 | 879 | ||
@@ -908,7 +897,8 @@ static void sbp2_login(struct work_struct *work) | |||
908 | 897 | ||
909 | tgt->node_id = node_id; | 898 | tgt->node_id = node_id; |
910 | tgt->address_high = local_node_id << 16; | 899 | tgt->address_high = local_node_id << 16; |
911 | sbp2_set_generation(lu, generation); | 900 | smp_wmb(); /* node IDs must not be older than generation */ |
901 | lu->generation = generation; | ||
912 | 902 | ||
913 | lu->command_block_agent_address = | 903 | lu->command_block_agent_address = |
914 | ((u64)(be32_to_cpu(response.command_block_agent.high) & 0xffff) | 904 | ((u64)(be32_to_cpu(response.command_block_agent.high) & 0xffff) |
@@ -1201,7 +1191,7 @@ static void sbp2_reconnect(struct work_struct *work) | |||
1201 | goto out; | 1191 | goto out; |
1202 | 1192 | ||
1203 | generation = device->generation; | 1193 | generation = device->generation; |
1204 | smp_rmb(); /* node_id must not be older than generation */ | 1194 | smp_rmb(); /* node IDs must not be older than generation */ |
1205 | node_id = device->node_id; | 1195 | node_id = device->node_id; |
1206 | local_node_id = device->card->node_id; | 1196 | local_node_id = device->card->node_id; |
1207 | 1197 | ||
@@ -1228,7 +1218,8 @@ static void sbp2_reconnect(struct work_struct *work) | |||
1228 | 1218 | ||
1229 | tgt->node_id = node_id; | 1219 | tgt->node_id = node_id; |
1230 | tgt->address_high = local_node_id << 16; | 1220 | tgt->address_high = local_node_id << 16; |
1231 | sbp2_set_generation(lu, generation); | 1221 | smp_wmb(); /* node IDs must not be older than generation */ |
1222 | lu->generation = generation; | ||
1232 | 1223 | ||
1233 | fw_notify("%s: reconnected to LUN %04x (%d retries)\n", | 1224 | fw_notify("%s: reconnected to LUN %04x (%d retries)\n", |
1234 | tgt->bus_id, lu->lun, lu->retries); | 1225 | tgt->bus_id, lu->lun, lu->retries); |
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c index 5e204713002d..c9be6e6948c4 100644 --- a/drivers/firewire/fw-topology.c +++ b/drivers/firewire/fw-topology.c | |||
@@ -355,6 +355,9 @@ report_lost_node(struct fw_card *card, | |||
355 | { | 355 | { |
356 | fw_node_event(card, node, FW_NODE_DESTROYED); | 356 | fw_node_event(card, node, FW_NODE_DESTROYED); |
357 | fw_node_put(node); | 357 | fw_node_put(node); |
358 | |||
359 | /* Topology has changed - reset bus manager retry counter */ | ||
360 | card->bm_retries = 0; | ||
358 | } | 361 | } |
359 | 362 | ||
360 | static void | 363 | static void |
@@ -374,6 +377,9 @@ report_found_node(struct fw_card *card, | |||
374 | } | 377 | } |
375 | 378 | ||
376 | fw_node_event(card, node, FW_NODE_CREATED); | 379 | fw_node_event(card, node, FW_NODE_CREATED); |
380 | |||
381 | /* Topology has changed - reset bus manager retry counter */ | ||
382 | card->bm_retries = 0; | ||
377 | } | 383 | } |
378 | 384 | ||
379 | void fw_destroy_nodes(struct fw_card *card) | 385 | void fw_destroy_nodes(struct fw_card *card) |
@@ -514,14 +520,6 @@ fw_core_handle_bus_reset(struct fw_card *card, | |||
514 | 520 | ||
515 | spin_lock_irqsave(&card->lock, flags); | 521 | spin_lock_irqsave(&card->lock, flags); |
516 | 522 | ||
517 | /* | ||
518 | * If the new topology has a different self_id_count the topology | ||
519 | * changed, either nodes were added or removed. In that case we | ||
520 | * reset the IRM reset counter. | ||
521 | */ | ||
522 | if (card->self_id_count != self_id_count) | ||
523 | card->bm_retries = 0; | ||
524 | |||
525 | card->node_id = node_id; | 523 | card->node_id = node_id; |
526 | /* | 524 | /* |
527 | * Update node_id before generation to prevent anybody from using | 525 | * Update node_id before generation to prevent anybody from using |
@@ -530,7 +528,7 @@ fw_core_handle_bus_reset(struct fw_card *card, | |||
530 | smp_wmb(); | 528 | smp_wmb(); |
531 | card->generation = generation; | 529 | card->generation = generation; |
532 | card->reset_jiffies = jiffies; | 530 | card->reset_jiffies = jiffies; |
533 | schedule_delayed_work(&card->work, 0); | 531 | fw_schedule_bm_work(card, 0); |
534 | 532 | ||
535 | local_node = build_tree(card, self_ids, self_id_count); | 533 | local_node = build_tree(card, self_ids, self_id_count); |
536 | 534 | ||
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c index 2884f876397b..699ac041f39a 100644 --- a/drivers/firewire/fw-transaction.c +++ b/drivers/firewire/fw-transaction.c | |||
@@ -19,6 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/completion.h> | 21 | #include <linux/completion.h> |
22 | #include <linux/idr.h> | ||
22 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
23 | #include <linux/kref.h> | 24 | #include <linux/kref.h> |
24 | #include <linux/module.h> | 25 | #include <linux/module.h> |
@@ -971,6 +972,7 @@ static void __exit fw_core_cleanup(void) | |||
971 | { | 972 | { |
972 | unregister_chrdev(fw_cdev_major, "firewire"); | 973 | unregister_chrdev(fw_cdev_major, "firewire"); |
973 | bus_unregister(&fw_bus_type); | 974 | bus_unregister(&fw_bus_type); |
975 | idr_destroy(&fw_device_idr); | ||
974 | } | 976 | } |
975 | 977 | ||
976 | module_init(fw_core_init); | 978 | module_init(fw_core_init); |
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index 839466f0a795..c9ab12a15f6e 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h | |||
@@ -237,14 +237,6 @@ struct fw_card { | |||
237 | int link_speed; | 237 | int link_speed; |
238 | int config_rom_generation; | 238 | int config_rom_generation; |
239 | 239 | ||
240 | /* | ||
241 | * We need to store up to 4 self ID for a maximum of 63 | ||
242 | * devices plus 3 words for the topology map header. | ||
243 | */ | ||
244 | int self_id_count; | ||
245 | u32 topology_map[252 + 3]; | ||
246 | u32 broadcast_channel; | ||
247 | |||
248 | spinlock_t lock; /* Take this lock when handling the lists in | 240 | spinlock_t lock; /* Take this lock when handling the lists in |
249 | * this struct. */ | 241 | * this struct. */ |
250 | struct fw_node *local_node; | 242 | struct fw_node *local_node; |
@@ -262,6 +254,9 @@ struct fw_card { | |||
262 | struct delayed_work work; | 254 | struct delayed_work work; |
263 | int bm_retries; | 255 | int bm_retries; |
264 | int bm_generation; | 256 | int bm_generation; |
257 | |||
258 | u32 broadcast_channel; | ||
259 | u32 topology_map[(CSR_TOPOLOGY_MAP_END - CSR_TOPOLOGY_MAP) / 4]; | ||
265 | }; | 260 | }; |
266 | 261 | ||
267 | static inline struct fw_card *fw_card_get(struct fw_card *card) | 262 | static inline struct fw_card *fw_card_get(struct fw_card *card) |
@@ -278,6 +273,8 @@ static inline void fw_card_put(struct fw_card *card) | |||
278 | kref_put(&card->kref, fw_card_release); | 273 | kref_put(&card->kref, fw_card_release); |
279 | } | 274 | } |
280 | 275 | ||
276 | extern void fw_schedule_bm_work(struct fw_card *card, unsigned long delay); | ||
277 | |||
281 | /* | 278 | /* |
282 | * The iso packet format allows for an immediate header/payload part | 279 | * The iso packet format allows for an immediate header/payload part |
283 | * stored in 'header' immediately after the packet info plus an | 280 | * stored in 'header' immediately after the packet info plus an |