aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/fw-device.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index 872df2238609..de9066e69adf 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -390,12 +390,12 @@ complete_transaction(struct fw_card *card, int rcode,
390 complete(&callback_data->done); 390 complete(&callback_data->done);
391} 391}
392 392
393static int read_rom(struct fw_device *device, int index, u32 * data) 393static int
394read_rom(struct fw_device *device, int generation, int index, u32 *data)
394{ 395{
395 struct read_quadlet_callback_data callback_data; 396 struct read_quadlet_callback_data callback_data;
396 struct fw_transaction t; 397 struct fw_transaction t;
397 u64 offset; 398 u64 offset;
398 int generation = device->generation;
399 399
400 /* device->node_id, accessed below, must not be older than generation */ 400 /* device->node_id, accessed below, must not be older than generation */
401 smp_rmb(); 401 smp_rmb();
@@ -414,7 +414,14 @@ static int read_rom(struct fw_device *device, int index, u32 * data)
414 return callback_data.rcode; 414 return callback_data.rcode;
415} 415}
416 416
417static int read_bus_info_block(struct fw_device *device) 417/*
418 * Read the bus info block, perform a speed probe, and read all of the rest of
419 * the config ROM. We do all this with a cached bus generation. If the bus
420 * generation changes under us, read_bus_info_block will fail and get retried.
421 * It's better to start all over in this case because the node from which we
422 * are reading the ROM may have changed the ROM during the reset.
423 */
424static int read_bus_info_block(struct fw_device *device, int generation)
418{ 425{
419 static u32 rom[256]; 426 static u32 rom[256];
420 u32 stack[16], sp, key; 427 u32 stack[16], sp, key;
@@ -424,7 +431,7 @@ static int read_bus_info_block(struct fw_device *device)
424 431
425 /* First read the bus info block. */ 432 /* First read the bus info block. */
426 for (i = 0; i < 5; i++) { 433 for (i = 0; i < 5; i++) {
427 if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE) 434 if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE)
428 return -1; 435 return -1;
429 /* 436 /*
430 * As per IEEE1212 7.2, during power-up, devices can 437 * As per IEEE1212 7.2, during power-up, devices can
@@ -459,7 +466,8 @@ static int read_bus_info_block(struct fw_device *device)
459 device->max_speed = device->card->link_speed; 466 device->max_speed = device->card->link_speed;
460 467
461 while (device->max_speed > SCODE_100) { 468 while (device->max_speed > SCODE_100) {
462 if (read_rom(device, 0, &dummy) == RCODE_COMPLETE) 469 if (read_rom(device, generation, 0, &dummy) ==
470 RCODE_COMPLETE)
463 break; 471 break;
464 device->max_speed--; 472 device->max_speed--;
465 } 473 }
@@ -492,7 +500,7 @@ static int read_bus_info_block(struct fw_device *device)
492 return -1; 500 return -1;
493 501
494 /* Read header quadlet for the block to get the length. */ 502 /* Read header quadlet for the block to get the length. */
495 if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE) 503 if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE)
496 return -1; 504 return -1;
497 end = i + (rom[i] >> 16) + 1; 505 end = i + (rom[i] >> 16) + 1;
498 i++; 506 i++;
@@ -511,7 +519,8 @@ static int read_bus_info_block(struct fw_device *device)
511 * it references another block, and push it in that case. 519 * it references another block, and push it in that case.
512 */ 520 */
513 while (i < end) { 521 while (i < end) {
514 if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE) 522 if (read_rom(device, generation, i, &rom[i]) !=
523 RCODE_COMPLETE)
515 return -1; 524 return -1;
516 if ((key >> 30) == 3 && (rom[i] >> 30) > 1 && 525 if ((key >> 30) == 3 && (rom[i] >> 30) > 1 &&
517 sp < ARRAY_SIZE(stack)) 526 sp < ARRAY_SIZE(stack))
@@ -658,7 +667,7 @@ static void fw_device_init(struct work_struct *work)
658 * device. 667 * device.
659 */ 668 */
660 669
661 if (read_bus_info_block(device) < 0) { 670 if (read_bus_info_block(device, device->generation) < 0) {
662 if (device->config_rom_retries < MAX_RETRIES) { 671 if (device->config_rom_retries < MAX_RETRIES) {
663 device->config_rom_retries++; 672 device->config_rom_retries++;
664 schedule_delayed_work(&device->work, RETRY_DELAY); 673 schedule_delayed_work(&device->work, RETRY_DELAY);