aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-01-17 06:01:12 -0500
committerTakashi Iwai <tiwai@suse.de>2009-01-17 06:01:12 -0500
commitd1a020050c6ce1a0794ff73582ccf47e4db536f7 (patch)
tree1b7250410f24703cd77c76156e758db9887137aa /drivers/firewire
parentdc61b66fc724f89d357c43e2319d2cb7bec1e517 (diff)
parent641b4879444c0edb276fedca5c2fcbd2e5c70044 (diff)
Merge branch 'topic/usb-mixer-cache' into next/usb-audio
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/fw-card.c33
-rw-r--r--drivers/firewire/fw-device.c31
-rw-r--r--drivers/firewire/fw-device.h2
-rw-r--r--drivers/firewire/fw-sbp2.c21
-rw-r--r--drivers/firewire/fw-topology.c16
-rw-r--r--drivers/firewire/fw-transaction.c2
-rw-r--r--drivers/firewire/fw-transaction.h13
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
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{
@@ -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
360static void 374static 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 */
618DECLARE_RWSEM(fw_device_rwsem); 619DECLARE_RWSEM(fw_device_rwsem);
619 620
620static DEFINE_IDR(fw_device_idr); 621DEFINE_IDR(fw_device_idr);
621int fw_cdev_major; 622int fw_cdev_major;
622 623
623struct fw_device *fw_device_get_by_devt(dev_t devt) 624struct 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
898void fw_node_event(struct fw_card *card, struct fw_node *node, int event) 900void 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);
99void fw_device_cdev_remove(struct fw_device *device); 100void fw_device_cdev_remove(struct fw_device *device);
100 101
101extern struct rw_semaphore fw_device_rwsem; 102extern struct rw_semaphore fw_device_rwsem;
103extern struct idr fw_device_idr;
102extern int fw_cdev_major; 104extern 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
673static 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
684static inline void sbp2_allow_block(struct sbp2_logical_unit *lu) 673static 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
360static void 363static 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
379void fw_destroy_nodes(struct fw_card *card) 385void 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
976module_init(fw_core_init); 978module_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
267static inline struct fw_card *fw_card_get(struct fw_card *card) 262static 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
276extern 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