aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-device.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-01-31 11:32:31 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-05 16:30:01 -0500
commit9d45cf9e36bf9bcf16df6e1cbf049807c8402823 (patch)
tree2118a16701418af10d215d2174df7ee0a5cbe6bd /drivers/firewire/fw-device.c
parenta146649bc19d5eba4f5bfac6720c5f252d517a71 (diff)
parent0cd5c3c80a0ebd68c08312fa7d8c13149cc61c4c (diff)
Merge branch 'x86/urgent' into x86/apic
Conflicts: arch/x86/mach-default/setup.c Semantic merge: arch/x86/kernel/irqinit_32.c Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/firewire/fw-device.c')
-rw-r--r--drivers/firewire/fw-device.c123
1 files changed, 101 insertions, 22 deletions
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index 2af5a8d1e012..bf53acb45652 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -25,6 +25,7 @@
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/idr.h> 27#include <linux/idr.h>
28#include <linux/jiffies.h>
28#include <linux/string.h> 29#include <linux/string.h>
29#include <linux/rwsem.h> 30#include <linux/rwsem.h>
30#include <linux/semaphore.h> 31#include <linux/semaphore.h>
@@ -634,12 +635,39 @@ struct fw_device *fw_device_get_by_devt(dev_t devt)
634 return device; 635 return device;
635} 636}
636 637
638/*
639 * These defines control the retry behavior for reading the config
640 * rom. It shouldn't be necessary to tweak these; if the device
641 * doesn't respond to a config rom read within 10 seconds, it's not
642 * going to respond at all. As for the initial delay, a lot of
643 * devices will be able to respond within half a second after bus
644 * reset. On the other hand, it's not really worth being more
645 * aggressive than that, since it scales pretty well; if 10 devices
646 * are plugged in, they're all getting read within one second.
647 */
648
649#define MAX_RETRIES 10
650#define RETRY_DELAY (3 * HZ)
651#define INITIAL_DELAY (HZ / 2)
652#define SHUTDOWN_DELAY (2 * HZ)
653
637static void fw_device_shutdown(struct work_struct *work) 654static void fw_device_shutdown(struct work_struct *work)
638{ 655{
639 struct fw_device *device = 656 struct fw_device *device =
640 container_of(work, struct fw_device, work.work); 657 container_of(work, struct fw_device, work.work);
641 int minor = MINOR(device->device.devt); 658 int minor = MINOR(device->device.devt);
642 659
660 if (time_is_after_jiffies(device->card->reset_jiffies + SHUTDOWN_DELAY)
661 && !list_empty(&device->card->link)) {
662 schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
663 return;
664 }
665
666 if (atomic_cmpxchg(&device->state,
667 FW_DEVICE_GONE,
668 FW_DEVICE_SHUTDOWN) != FW_DEVICE_GONE)
669 return;
670
643 fw_device_cdev_remove(device); 671 fw_device_cdev_remove(device);
644 device_for_each_child(&device->device, NULL, shutdown_unit); 672 device_for_each_child(&device->device, NULL, shutdown_unit);
645 device_unregister(&device->device); 673 device_unregister(&device->device);
@@ -647,6 +675,7 @@ static void fw_device_shutdown(struct work_struct *work)
647 down_write(&fw_device_rwsem); 675 down_write(&fw_device_rwsem);
648 idr_remove(&fw_device_idr, minor); 676 idr_remove(&fw_device_idr, minor);
649 up_write(&fw_device_rwsem); 677 up_write(&fw_device_rwsem);
678
650 fw_device_put(device); 679 fw_device_put(device);
651} 680}
652 681
@@ -654,25 +683,63 @@ static struct device_type fw_device_type = {
654 .release = fw_device_release, 683 .release = fw_device_release,
655}; 684};
656 685
686static void fw_device_update(struct work_struct *work);
687
657/* 688/*
658 * These defines control the retry behavior for reading the config 689 * If a device was pending for deletion because its node went away but its
659 * rom. It shouldn't be necessary to tweak these; if the device 690 * bus info block and root directory header matches that of a newly discovered
660 * doesn't respond to a config rom read within 10 seconds, it's not 691 * device, revive the existing fw_device.
661 * going to respond at all. As for the initial delay, a lot of 692 * The newly allocated fw_device becomes obsolete instead.
662 * devices will be able to respond within half a second after bus
663 * reset. On the other hand, it's not really worth being more
664 * aggressive than that, since it scales pretty well; if 10 devices
665 * are plugged in, they're all getting read within one second.
666 */ 693 */
694static int lookup_existing_device(struct device *dev, void *data)
695{
696 struct fw_device *old = fw_device(dev);
697 struct fw_device *new = data;
698 struct fw_card *card = new->card;
699 int match = 0;
700
701 down_read(&fw_device_rwsem); /* serialize config_rom access */
702 spin_lock_irq(&card->lock); /* serialize node access */
703
704 if (memcmp(old->config_rom, new->config_rom, 6 * 4) == 0 &&
705 atomic_cmpxchg(&old->state,
706 FW_DEVICE_GONE,
707 FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
708 struct fw_node *current_node = new->node;
709 struct fw_node *obsolete_node = old->node;
710
711 new->node = obsolete_node;
712 new->node->data = new;
713 old->node = current_node;
714 old->node->data = old;
715
716 old->max_speed = new->max_speed;
717 old->node_id = current_node->node_id;
718 smp_wmb(); /* update node_id before generation */
719 old->generation = card->generation;
720 old->config_rom_retries = 0;
721 fw_notify("rediscovered device %s\n", dev_name(dev));
667 722
668#define MAX_RETRIES 10 723 PREPARE_DELAYED_WORK(&old->work, fw_device_update);
669#define RETRY_DELAY (3 * HZ) 724 schedule_delayed_work(&old->work, 0);
670#define INITIAL_DELAY (HZ / 2) 725
726 if (current_node == card->root_node)
727 fw_schedule_bm_work(card, 0);
728
729 match = 1;
730 }
731
732 spin_unlock_irq(&card->lock);
733 up_read(&fw_device_rwsem);
734
735 return match;
736}
671 737
672static void fw_device_init(struct work_struct *work) 738static void fw_device_init(struct work_struct *work)
673{ 739{
674 struct fw_device *device = 740 struct fw_device *device =
675 container_of(work, struct fw_device, work.work); 741 container_of(work, struct fw_device, work.work);
742 struct device *revived_dev;
676 int minor, err; 743 int minor, err;
677 744
678 /* 745 /*
@@ -696,6 +763,15 @@ static void fw_device_init(struct work_struct *work)
696 return; 763 return;
697 } 764 }
698 765
766 revived_dev = device_find_child(device->card->device,
767 device, lookup_existing_device);
768 if (revived_dev) {
769 put_device(revived_dev);
770 fw_device_release(&device->device);
771
772 return;
773 }
774
699 device_initialize(&device->device); 775 device_initialize(&device->device);
700 776
701 fw_device_get(device); 777 fw_device_get(device);
@@ -734,9 +810,10 @@ static void fw_device_init(struct work_struct *work)
734 * fw_node_event(). 810 * fw_node_event().
735 */ 811 */
736 if (atomic_cmpxchg(&device->state, 812 if (atomic_cmpxchg(&device->state,
737 FW_DEVICE_INITIALIZING, 813 FW_DEVICE_INITIALIZING,
738 FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) { 814 FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
739 fw_device_shutdown(work); 815 PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
816 schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
740 } else { 817 } else {
741 if (device->config_rom_retries) 818 if (device->config_rom_retries)
742 fw_notify("created device %s: GUID %08x%08x, S%d00, " 819 fw_notify("created device %s: GUID %08x%08x, S%d00, "
@@ -847,8 +924,8 @@ static void fw_device_refresh(struct work_struct *work)
847 924
848 case REREAD_BIB_UNCHANGED: 925 case REREAD_BIB_UNCHANGED:
849 if (atomic_cmpxchg(&device->state, 926 if (atomic_cmpxchg(&device->state,
850 FW_DEVICE_INITIALIZING, 927 FW_DEVICE_INITIALIZING,
851 FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) 928 FW_DEVICE_RUNNING) == FW_DEVICE_GONE)
852 goto gone; 929 goto gone;
853 930
854 fw_device_update(work); 931 fw_device_update(work);
@@ -879,8 +956,8 @@ static void fw_device_refresh(struct work_struct *work)
879 create_units(device); 956 create_units(device);
880 957
881 if (atomic_cmpxchg(&device->state, 958 if (atomic_cmpxchg(&device->state,
882 FW_DEVICE_INITIALIZING, 959 FW_DEVICE_INITIALIZING,
883 FW_DEVICE_RUNNING) == FW_DEVICE_SHUTDOWN) 960 FW_DEVICE_RUNNING) == FW_DEVICE_GONE)
884 goto gone; 961 goto gone;
885 962
886 fw_notify("refreshed device %s\n", dev_name(&device->device)); 963 fw_notify("refreshed device %s\n", dev_name(&device->device));
@@ -890,8 +967,9 @@ static void fw_device_refresh(struct work_struct *work)
890 give_up: 967 give_up:
891 fw_notify("giving up on refresh of device %s\n", dev_name(&device->device)); 968 fw_notify("giving up on refresh of device %s\n", dev_name(&device->device));
892 gone: 969 gone:
893 atomic_set(&device->state, FW_DEVICE_SHUTDOWN); 970 atomic_set(&device->state, FW_DEVICE_GONE);
894 fw_device_shutdown(work); 971 PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
972 schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
895 out: 973 out:
896 if (node_id == card->root_node->node_id) 974 if (node_id == card->root_node->node_id)
897 fw_schedule_bm_work(card, 0); 975 fw_schedule_bm_work(card, 0);
@@ -995,9 +1073,10 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event)
995 */ 1073 */
996 device = node->data; 1074 device = node->data;
997 if (atomic_xchg(&device->state, 1075 if (atomic_xchg(&device->state,
998 FW_DEVICE_SHUTDOWN) == FW_DEVICE_RUNNING) { 1076 FW_DEVICE_GONE) == FW_DEVICE_RUNNING) {
999 PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown); 1077 PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
1000 schedule_delayed_work(&device->work, 0); 1078 schedule_delayed_work(&device->work,
1079 list_empty(&card->link) ? 0 : SHUTDOWN_DELAY);
1001 } 1080 }
1002 break; 1081 break;
1003 } 1082 }