aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2009-03-10 16:08:37 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-03-24 15:56:51 -0400
commitcbae787c0f288c3ad385ad4165ae30b5500a1f23 (patch)
tree89946d56640109660ddba5e90dc10ce5249cf265
parente1dc7cab43619a2fbc90fd4cd712bd3fff703768 (diff)
firewire: core: simplify broadcast channel allocation
fw-iso.c has channel allocation code now, use it. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
-rw-r--r--drivers/firewire/fw-card.c126
1 files changed, 34 insertions, 92 deletions
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index b3463b8d8c60..d63d0ed9e048 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -181,10 +181,6 @@ void fw_core_remove_descriptor(struct fw_descriptor *desc)
181 mutex_unlock(&card_mutex); 181 mutex_unlock(&card_mutex);
182} 182}
183 183
184/* ------------------------------------------------------------------ */
185/* Code to handle 1394a broadcast channel */
186
187#define THIRTY_TWO_CHANNELS (0xFFFFFFFFU)
188#define IRM_RETRIES 2 184#define IRM_RETRIES 2
189 185
190/* 186/*
@@ -265,62 +261,18 @@ tryagain_w:
265 return 0; 261 return 0;
266} 262}
267 263
268static void 264static void allocate_broadcast_channel(struct fw_card *card, int generation)
269irm_allocate_broadcast(struct fw_device *irm_dev, struct device *locald)
270{ 265{
271 u32 generation; 266 int channel, bandwidth = 0;
272 u32 node_id; 267
273 u32 max_speed; 268 fw_iso_resource_manage(card, generation, 1ULL << 31,
274 u32 retries; 269 &channel, &bandwidth, true);
275 __be32 old_data; 270 if (channel == 31) {
276 __be32 lock_data[2]; 271 card->is_irm = true;
277 int rcode; 272 device_for_each_child(card->device, NULL,
278 273 fw_irm_set_broadcast_channel_register);
279 /*
280 * The device we are updating is the IRM, so we must do
281 * some extra work.
282 */
283 retries = IRM_RETRIES;
284 generation = irm_dev->generation;
285 /* FIXME: do we need locking here? */
286 smp_rmb();
287 node_id = irm_dev->node_id;
288 max_speed = irm_dev->max_speed;
289
290 lock_data[0] = cpu_to_be32(THIRTY_TWO_CHANNELS);
291 lock_data[1] = cpu_to_be32(THIRTY_TWO_CHANNELS & ~1);
292tryagain:
293 old_data = lock_data[0];
294 rcode = fw_run_transaction(irm_dev->card, TCODE_LOCK_COMPARE_SWAP,
295 node_id, generation, max_speed,
296 CSR_REGISTER_BASE+CSR_CHANNELS_AVAILABLE_HI,
297 &lock_data[0], 8);
298 switch (rcode) {
299 case RCODE_BUSY:
300 if (retries--)
301 goto tryagain;
302 /* fallthrough */
303 default:
304 fw_error("node %x: allocate broadcast channel failed (%x)\n",
305 node_id, rcode);
306 return;
307
308 case RCODE_COMPLETE:
309 if (lock_data[0] == old_data)
310 break;
311 if (retries--) {
312 lock_data[1] = cpu_to_be32(be32_to_cpu(lock_data[0])&~1);
313 goto tryagain;
314 }
315 fw_error("node %x: allocate broadcast channel failed: too many"
316 " retries\n", node_id);
317 return;
318 } 274 }
319 irm_dev->card->is_irm = true;
320 device_for_each_child(locald, NULL, fw_irm_set_broadcast_channel_register);
321} 275}
322/* ------------------------------------------------------------------ */
323
324 276
325static const char gap_count_table[] = { 277static const char gap_count_table[] = {
326 63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40 278 63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40
@@ -339,10 +291,11 @@ void fw_schedule_bm_work(struct fw_card *card, unsigned long delay)
339static void fw_card_bm_work(struct work_struct *work) 291static void fw_card_bm_work(struct work_struct *work)
340{ 292{
341 struct fw_card *card = container_of(work, struct fw_card, work.work); 293 struct fw_card *card = container_of(work, struct fw_card, work.work);
342 struct fw_device *root_device, *irm_device, *local_device; 294 struct fw_device *root_device;
343 struct fw_node *root_node, *local_node, *irm_node; 295 struct fw_node *root_node;
344 unsigned long flags; 296 unsigned long flags;
345 int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode; 297 int root_id, new_root_id, irm_id, local_id;
298 int gap_count, generation, grace, rcode;
346 bool do_reset = false; 299 bool do_reset = false;
347 bool root_device_is_running; 300 bool root_device_is_running;
348 bool root_device_is_cmc; 301 bool root_device_is_cmc;
@@ -350,26 +303,22 @@ static void fw_card_bm_work(struct work_struct *work)
350 303
351 spin_lock_irqsave(&card->lock, flags); 304 spin_lock_irqsave(&card->lock, flags);
352 card->is_irm = false; 305 card->is_irm = false;
353 local_node = card->local_node;
354 root_node = card->root_node;
355 irm_node = card->irm_node;
356 306
357 if (local_node == NULL) { 307 if (card->local_node == NULL) {
358 spin_unlock_irqrestore(&card->lock, flags); 308 spin_unlock_irqrestore(&card->lock, flags);
359 goto out_put_card; 309 goto out_put_card;
360 } 310 }
361 fw_node_get(local_node);
362 fw_node_get(root_node);
363 fw_node_get(irm_node);
364 311
365 generation = card->generation; 312 generation = card->generation;
313 root_node = card->root_node;
314 fw_node_get(root_node);
366 root_device = root_node->data; 315 root_device = root_node->data;
367 root_device_is_running = root_device && 316 root_device_is_running = root_device &&
368 atomic_read(&root_device->state) == FW_DEVICE_RUNNING; 317 atomic_read(&root_device->state) == FW_DEVICE_RUNNING;
369 root_device_is_cmc = root_device && root_device->cmc; 318 root_device_is_cmc = root_device && root_device->cmc;
370 root_id = root_node->node_id; 319 root_id = root_node->node_id;
371 irm_device = irm_node->data; 320 irm_id = card->irm_node->node_id;
372 local_device = local_node->data; 321 local_id = card->local_node->node_id;
373 322
374 grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 8)); 323 grace = time_after(jiffies, card->reset_jiffies + DIV_ROUND_UP(HZ, 8));
375 324
@@ -387,16 +336,15 @@ static void fw_card_bm_work(struct work_struct *work)
387 * next generation. 336 * next generation.
388 */ 337 */
389 338
390 irm_id = irm_node->node_id; 339 if (!card->irm_node->link_on) {
391 if (!irm_node->link_on) { 340 new_root_id = local_id;
392 new_root_id = local_node->node_id;
393 fw_notify("IRM has link off, making local node (%02x) root.\n", 341 fw_notify("IRM has link off, making local node (%02x) root.\n",
394 new_root_id); 342 new_root_id);
395 goto pick_me; 343 goto pick_me;
396 } 344 }
397 345
398 lock_data[0] = cpu_to_be32(0x3f); 346 lock_data[0] = cpu_to_be32(0x3f);
399 lock_data[1] = cpu_to_be32(local_node->node_id); 347 lock_data[1] = cpu_to_be32(local_id);
400 348
401 spin_unlock_irqrestore(&card->lock, flags); 349 spin_unlock_irqrestore(&card->lock, flags);
402 350
@@ -411,12 +359,11 @@ static void fw_card_bm_work(struct work_struct *work)
411 359
412 if (rcode == RCODE_COMPLETE && 360 if (rcode == RCODE_COMPLETE &&
413 lock_data[0] != cpu_to_be32(0x3f)) { 361 lock_data[0] != cpu_to_be32(0x3f)) {
414 /* Somebody else is BM, let them do the work. */ 362
415 if (irm_id == local_node->node_id) { 363 /* Somebody else is BM. Only act as IRM. */
416 /* But we are IRM, so do irm-y things */ 364 if (local_id == irm_id)
417 irm_allocate_broadcast(irm_device, 365 allocate_broadcast_channel(card, generation);
418 card->device); 366
419 }
420 goto out; 367 goto out;
421 } 368 }
422 369
@@ -429,7 +376,7 @@ static void fw_card_bm_work(struct work_struct *work)
429 * do a bus reset and pick the local node as 376 * do a bus reset and pick the local node as
430 * root, and thus, IRM. 377 * root, and thus, IRM.
431 */ 378 */
432 new_root_id = local_node->node_id; 379 new_root_id = local_id;
433 fw_notify("BM lock failed, making local node (%02x) root.\n", 380 fw_notify("BM lock failed, making local node (%02x) root.\n",
434 new_root_id); 381 new_root_id);
435 goto pick_me; 382 goto pick_me;
@@ -456,7 +403,7 @@ static void fw_card_bm_work(struct work_struct *work)
456 * Either link_on is false, or we failed to read the 403 * Either link_on is false, or we failed to read the
457 * config rom. In either case, pick another root. 404 * config rom. In either case, pick another root.
458 */ 405 */
459 new_root_id = local_node->node_id; 406 new_root_id = local_id;
460 } else if (!root_device_is_running) { 407 } else if (!root_device_is_running) {
461 /* 408 /*
462 * If we haven't probed this device yet, bail out now 409 * If we haven't probed this device yet, bail out now
@@ -478,7 +425,7 @@ static void fw_card_bm_work(struct work_struct *work)
478 * successfully read the config rom, but it's not 425 * successfully read the config rom, but it's not
479 * cycle master capable. 426 * cycle master capable.
480 */ 427 */
481 new_root_id = local_node->node_id; 428 new_root_id = local_id;
482 } 429 }
483 430
484 pick_me: 431 pick_me:
@@ -509,19 +456,14 @@ static void fw_card_bm_work(struct work_struct *work)
509 card->index, new_root_id, gap_count); 456 card->index, new_root_id, gap_count);
510 fw_send_phy_config(card, new_root_id, generation, gap_count); 457 fw_send_phy_config(card, new_root_id, generation, gap_count);
511 fw_core_initiate_bus_reset(card, 1); 458 fw_core_initiate_bus_reset(card, 1);
512 } else if (irm_node->node_id == local_node->node_id) { 459 /* Will allocate broadcast channel after the reset. */
513 /* 460 } else {
514 * We are IRM, so do irm-y things. 461 if (local_id == irm_id)
515 * There's no reason to do this if we're doing a reset. . . 462 allocate_broadcast_channel(card, generation);
516 * We'll be back.
517 */
518 irm_allocate_broadcast(irm_device, card->device);
519 } 463 }
520 464
521 out: 465 out:
522 fw_node_put(root_node); 466 fw_node_put(root_node);
523 fw_node_put(local_node);
524 fw_node_put(irm_node);
525 out_put_card: 467 out_put_card:
526 fw_card_put(card); 468 fw_card_put(card);
527} 469}