diff options
Diffstat (limited to 'drivers/firewire/fw-device.c')
-rw-r--r-- | drivers/firewire/fw-device.c | 101 |
1 files changed, 66 insertions, 35 deletions
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c index 99d1c418d2b0..8e5f17f5e98a 100644 --- a/drivers/firewire/fw-device.c +++ b/drivers/firewire/fw-device.c | |||
@@ -1,6 +1,5 @@ | |||
1 | /* -*- c-basic-offset: 8 -*- | 1 | /* |
2 | * | 2 | * Device probing and sysfs code. |
3 | * fw-device.c - Device probing and sysfs code. | ||
4 | * | 3 | * |
5 | * Copyright (C) 2005-2006 Kristian Hoegsberg <krh@bitplanet.net> | 4 | * Copyright (C) 2005-2006 Kristian Hoegsberg <krh@bitplanet.net> |
6 | * | 5 | * |
@@ -174,8 +173,10 @@ static void fw_device_release(struct device *dev) | |||
174 | struct fw_device *device = fw_device(dev); | 173 | struct fw_device *device = fw_device(dev); |
175 | unsigned long flags; | 174 | unsigned long flags; |
176 | 175 | ||
177 | /* Take the card lock so we don't set this to NULL while a | 176 | /* |
178 | * FW_NODE_UPDATED callback is being handled. */ | 177 | * Take the card lock so we don't set this to NULL while a |
178 | * FW_NODE_UPDATED callback is being handled. | ||
179 | */ | ||
179 | spin_lock_irqsave(&device->card->lock, flags); | 180 | spin_lock_irqsave(&device->card->lock, flags); |
180 | device->node->data = NULL; | 181 | device->node->data = NULL; |
181 | spin_unlock_irqrestore(&device->card->lock, flags); | 182 | spin_unlock_irqrestore(&device->card->lock, flags); |
@@ -421,34 +422,42 @@ static int read_bus_info_block(struct fw_device *device) | |||
421 | for (i = 0; i < 5; i++) { | 422 | for (i = 0; i < 5; i++) { |
422 | if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE) | 423 | if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE) |
423 | return -1; | 424 | return -1; |
424 | /* As per IEEE1212 7.2, during power-up, devices can | 425 | /* |
426 | * As per IEEE1212 7.2, during power-up, devices can | ||
425 | * reply with a 0 for the first quadlet of the config | 427 | * reply with a 0 for the first quadlet of the config |
426 | * rom to indicate that they are booting (for example, | 428 | * rom to indicate that they are booting (for example, |
427 | * if the firmware is on the disk of a external | 429 | * if the firmware is on the disk of a external |
428 | * harddisk). In that case we just fail, and the | 430 | * harddisk). In that case we just fail, and the |
429 | * retry mechanism will try again later. */ | 431 | * retry mechanism will try again later. |
432 | */ | ||
430 | if (i == 0 && rom[i] == 0) | 433 | if (i == 0 && rom[i] == 0) |
431 | return -1; | 434 | return -1; |
432 | } | 435 | } |
433 | 436 | ||
434 | /* Now parse the config rom. The config rom is a recursive | 437 | /* |
438 | * Now parse the config rom. The config rom is a recursive | ||
435 | * directory structure so we parse it using a stack of | 439 | * directory structure so we parse it using a stack of |
436 | * references to the blocks that make up the structure. We | 440 | * references to the blocks that make up the structure. We |
437 | * push a reference to the root directory on the stack to | 441 | * push a reference to the root directory on the stack to |
438 | * start things off. */ | 442 | * start things off. |
443 | */ | ||
439 | length = i; | 444 | length = i; |
440 | sp = 0; | 445 | sp = 0; |
441 | stack[sp++] = 0xc0000005; | 446 | stack[sp++] = 0xc0000005; |
442 | while (sp > 0) { | 447 | while (sp > 0) { |
443 | /* Pop the next block reference of the stack. The | 448 | /* |
449 | * Pop the next block reference of the stack. The | ||
444 | * lower 24 bits is the offset into the config rom, | 450 | * lower 24 bits is the offset into the config rom, |
445 | * the upper 8 bits are the type of the reference the | 451 | * the upper 8 bits are the type of the reference the |
446 | * block. */ | 452 | * block. |
453 | */ | ||
447 | key = stack[--sp]; | 454 | key = stack[--sp]; |
448 | i = key & 0xffffff; | 455 | i = key & 0xffffff; |
449 | if (i >= ARRAY_SIZE(rom)) | 456 | if (i >= ARRAY_SIZE(rom)) |
450 | /* The reference points outside the standard | 457 | /* |
451 | * config rom area, something's fishy. */ | 458 | * The reference points outside the standard |
459 | * config rom area, something's fishy. | ||
460 | */ | ||
452 | return -1; | 461 | return -1; |
453 | 462 | ||
454 | /* Read header quadlet for the block to get the length. */ | 463 | /* Read header quadlet for the block to get the length. */ |
@@ -457,15 +466,19 @@ static int read_bus_info_block(struct fw_device *device) | |||
457 | end = i + (rom[i] >> 16) + 1; | 466 | end = i + (rom[i] >> 16) + 1; |
458 | i++; | 467 | i++; |
459 | if (end > ARRAY_SIZE(rom)) | 468 | if (end > ARRAY_SIZE(rom)) |
460 | /* This block extends outside standard config | 469 | /* |
470 | * This block extends outside standard config | ||
461 | * area (and the array we're reading it | 471 | * area (and the array we're reading it |
462 | * into). That's broken, so ignore this | 472 | * into). That's broken, so ignore this |
463 | * device. */ | 473 | * device. |
474 | */ | ||
464 | return -1; | 475 | return -1; |
465 | 476 | ||
466 | /* Now read in the block. If this is a directory | 477 | /* |
478 | * Now read in the block. If this is a directory | ||
467 | * block, check the entries as we read them to see if | 479 | * block, check the entries as we read them to see if |
468 | * it references another block, and push it in that case. */ | 480 | * it references another block, and push it in that case. |
481 | */ | ||
469 | while (i < end) { | 482 | while (i < end) { |
470 | if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE) | 483 | if (read_rom(device, i, &rom[i]) != RCODE_COMPLETE) |
471 | return -1; | 484 | return -1; |
@@ -516,8 +529,10 @@ static void create_units(struct fw_device *device) | |||
516 | if (key != (CSR_UNIT | CSR_DIRECTORY)) | 529 | if (key != (CSR_UNIT | CSR_DIRECTORY)) |
517 | continue; | 530 | continue; |
518 | 531 | ||
519 | /* Get the address of the unit directory and try to | 532 | /* |
520 | * match the drivers id_tables against it. */ | 533 | * Get the address of the unit directory and try to |
534 | * match the drivers id_tables against it. | ||
535 | */ | ||
521 | unit = kzalloc(sizeof *unit, GFP_KERNEL); | 536 | unit = kzalloc(sizeof *unit, GFP_KERNEL); |
522 | if (unit == NULL) { | 537 | if (unit == NULL) { |
523 | fw_error("failed to allocate memory for unit\n"); | 538 | fw_error("failed to allocate memory for unit\n"); |
@@ -585,14 +600,16 @@ static struct device_type fw_device_type = { | |||
585 | .release = fw_device_release, | 600 | .release = fw_device_release, |
586 | }; | 601 | }; |
587 | 602 | ||
588 | /* These defines control the retry behavior for reading the config | 603 | /* |
604 | * These defines control the retry behavior for reading the config | ||
589 | * rom. It shouldn't be necessary to tweak these; if the device | 605 | * rom. It shouldn't be necessary to tweak these; if the device |
590 | * doesn't respond to a config rom read within 10 seconds, it's not | 606 | * doesn't respond to a config rom read within 10 seconds, it's not |
591 | * going to respond at all. As for the initial delay, a lot of | 607 | * going to respond at all. As for the initial delay, a lot of |
592 | * devices will be able to respond within half a second after bus | 608 | * devices will be able to respond within half a second after bus |
593 | * reset. On the other hand, it's not really worth being more | 609 | * reset. On the other hand, it's not really worth being more |
594 | * aggressive than that, since it scales pretty well; if 10 devices | 610 | * aggressive than that, since it scales pretty well; if 10 devices |
595 | * are plugged in, they're all getting read within one second. */ | 611 | * are plugged in, they're all getting read within one second. |
612 | */ | ||
596 | 613 | ||
597 | #define MAX_RETRIES 10 | 614 | #define MAX_RETRIES 10 |
598 | #define RETRY_DELAY (3 * HZ) | 615 | #define RETRY_DELAY (3 * HZ) |
@@ -604,9 +621,11 @@ static void fw_device_init(struct work_struct *work) | |||
604 | container_of(work, struct fw_device, work.work); | 621 | container_of(work, struct fw_device, work.work); |
605 | int minor, err; | 622 | int minor, err; |
606 | 623 | ||
607 | /* All failure paths here set node->data to NULL, so that we | 624 | /* |
625 | * All failure paths here set node->data to NULL, so that we | ||
608 | * don't try to do device_for_each_child() on a kfree()'d | 626 | * don't try to do device_for_each_child() on a kfree()'d |
609 | * device. */ | 627 | * device. |
628 | */ | ||
610 | 629 | ||
611 | if (read_bus_info_block(device) < 0) { | 630 | if (read_bus_info_block(device) < 0) { |
612 | if (device->config_rom_retries < MAX_RETRIES) { | 631 | if (device->config_rom_retries < MAX_RETRIES) { |
@@ -647,13 +666,15 @@ static void fw_device_init(struct work_struct *work) | |||
647 | 666 | ||
648 | create_units(device); | 667 | create_units(device); |
649 | 668 | ||
650 | /* Transition the device to running state. If it got pulled | 669 | /* |
670 | * Transition the device to running state. If it got pulled | ||
651 | * out from under us while we did the intialization work, we | 671 | * out from under us while we did the intialization work, we |
652 | * have to shut down the device again here. Normally, though, | 672 | * have to shut down the device again here. Normally, though, |
653 | * fw_node_event will be responsible for shutting it down when | 673 | * fw_node_event will be responsible for shutting it down when |
654 | * necessary. We have to use the atomic cmpxchg here to avoid | 674 | * necessary. We have to use the atomic cmpxchg here to avoid |
655 | * racing with the FW_NODE_DESTROYED case in | 675 | * racing with the FW_NODE_DESTROYED case in |
656 | * fw_node_event(). */ | 676 | * fw_node_event(). |
677 | */ | ||
657 | if (atomic_cmpxchg(&device->state, | 678 | if (atomic_cmpxchg(&device->state, |
658 | FW_DEVICE_INITIALIZING, | 679 | FW_DEVICE_INITIALIZING, |
659 | FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) | 680 | FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) |
@@ -662,10 +683,12 @@ static void fw_device_init(struct work_struct *work) | |||
662 | fw_notify("created new fw device %s (%d config rom retries)\n", | 683 | fw_notify("created new fw device %s (%d config rom retries)\n", |
663 | device->device.bus_id, device->config_rom_retries); | 684 | device->device.bus_id, device->config_rom_retries); |
664 | 685 | ||
665 | /* Reschedule the IRM work if we just finished reading the | 686 | /* |
687 | * Reschedule the IRM work if we just finished reading the | ||
666 | * root node config rom. If this races with a bus reset we | 688 | * root node config rom. If this races with a bus reset we |
667 | * just end up running the IRM work a couple of extra times - | 689 | * just end up running the IRM work a couple of extra times - |
668 | * pretty harmless. */ | 690 | * pretty harmless. |
691 | */ | ||
669 | if (device->node == device->card->root_node) | 692 | if (device->node == device->card->root_node) |
670 | schedule_delayed_work(&device->card->work, 0); | 693 | schedule_delayed_work(&device->card->work, 0); |
671 | 694 | ||
@@ -716,12 +739,14 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | |||
716 | if (device == NULL) | 739 | if (device == NULL) |
717 | break; | 740 | break; |
718 | 741 | ||
719 | /* Do minimal intialization of the device here, the | 742 | /* |
743 | * Do minimal intialization of the device here, the | ||
720 | * rest will happen in fw_device_init(). We need the | 744 | * rest will happen in fw_device_init(). We need the |
721 | * card and node so we can read the config rom and we | 745 | * card and node so we can read the config rom and we |
722 | * need to do device_initialize() now so | 746 | * need to do device_initialize() now so |
723 | * device_for_each_child() in FW_NODE_UPDATED is | 747 | * device_for_each_child() in FW_NODE_UPDATED is |
724 | * doesn't freak out. */ | 748 | * doesn't freak out. |
749 | */ | ||
725 | device_initialize(&device->device); | 750 | device_initialize(&device->device); |
726 | atomic_set(&device->state, FW_DEVICE_INITIALIZING); | 751 | atomic_set(&device->state, FW_DEVICE_INITIALIZING); |
727 | device->card = fw_card_get(card); | 752 | device->card = fw_card_get(card); |
@@ -730,15 +755,19 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | |||
730 | device->generation = card->generation; | 755 | device->generation = card->generation; |
731 | INIT_LIST_HEAD(&device->client_list); | 756 | INIT_LIST_HEAD(&device->client_list); |
732 | 757 | ||
733 | /* Set the node data to point back to this device so | 758 | /* |
759 | * Set the node data to point back to this device so | ||
734 | * FW_NODE_UPDATED callbacks can update the node_id | 760 | * FW_NODE_UPDATED callbacks can update the node_id |
735 | * and generation for the device. */ | 761 | * and generation for the device. |
762 | */ | ||
736 | node->data = device; | 763 | node->data = device; |
737 | 764 | ||
738 | /* Many devices are slow to respond after bus resets, | 765 | /* |
766 | * Many devices are slow to respond after bus resets, | ||
739 | * especially if they are bus powered and go through | 767 | * especially if they are bus powered and go through |
740 | * power-up after getting plugged in. We schedule the | 768 | * power-up after getting plugged in. We schedule the |
741 | * first config rom scan half a second after bus reset. */ | 769 | * first config rom scan half a second after bus reset. |
770 | */ | ||
742 | INIT_DELAYED_WORK(&device->work, fw_device_init); | 771 | INIT_DELAYED_WORK(&device->work, fw_device_init); |
743 | schedule_delayed_work(&device->work, INITIAL_DELAY); | 772 | schedule_delayed_work(&device->work, INITIAL_DELAY); |
744 | break; | 773 | break; |
@@ -761,7 +790,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | |||
761 | if (!node->data) | 790 | if (!node->data) |
762 | break; | 791 | break; |
763 | 792 | ||
764 | /* Destroy the device associated with the node. There | 793 | /* |
794 | * Destroy the device associated with the node. There | ||
765 | * are two cases here: either the device is fully | 795 | * are two cases here: either the device is fully |
766 | * initialized (FW_DEVICE_RUNNING) or we're in the | 796 | * initialized (FW_DEVICE_RUNNING) or we're in the |
767 | * process of reading its config rom | 797 | * process of reading its config rom |
@@ -770,7 +800,8 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) | |||
770 | * full fw_device_shutdown(). If not, there's work | 800 | * full fw_device_shutdown(). If not, there's work |
771 | * scheduled to read it's config rom, and we just put | 801 | * scheduled to read it's config rom, and we just put |
772 | * the device in shutdown state to have that code fail | 802 | * the device in shutdown state to have that code fail |
773 | * to create the device. */ | 803 | * to create the device. |
804 | */ | ||
774 | device = node->data; | 805 | device = node->data; |
775 | if (atomic_xchg(&device->state, | 806 | if (atomic_xchg(&device->state, |
776 | FW_DEVICE_SHUTDOWN) == FW_DEVICE_RUNNING) { | 807 | FW_DEVICE_SHUTDOWN) == FW_DEVICE_RUNNING) { |