aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/w1/w1.c
diff options
context:
space:
mode:
authorEvgeniy Polyakov <johnpol@2ka.mipt.ru>2005-08-11 09:27:50 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-09-08 17:41:26 -0400
commit3aca692d3ec7cf89da4575f598e41f74502b22d7 (patch)
tree84740dbcf1ea648b303020f2106e7f9e46f92835 /drivers/w1/w1.c
parentd2a4ef6a0ce4d841293b49bf2cdc17a0ebfaaf9d (diff)
[PATCH] w1: Detouching bug fixed.
Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/w1/w1.c')
-rw-r--r--drivers/w1/w1.c93
1 files changed, 49 insertions, 44 deletions
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index e592ca2edd49..4e98ab1aa2f2 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -45,10 +45,12 @@ MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
45MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol."); 45MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol.");
46 46
47static int w1_timeout = 10; 47static int w1_timeout = 10;
48static int w1_control_timeout = 1;
48int w1_max_slave_count = 10; 49int w1_max_slave_count = 10;
49int w1_max_slave_ttl = 10; 50int w1_max_slave_ttl = 10;
50 51
51module_param_named(timeout, w1_timeout, int, 0); 52module_param_named(timeout, w1_timeout, int, 0);
53module_param_named(control_timeout, w1_control_timeout, int, 0);
52module_param_named(max_slave_count, w1_max_slave_count, int, 0); 54module_param_named(max_slave_count, w1_max_slave_count, int, 0);
53module_param_named(slave_ttl, w1_max_slave_ttl, int, 0); 55module_param_named(slave_ttl, w1_max_slave_ttl, int, 0);
54 56
@@ -69,37 +71,51 @@ static int w1_master_probe(struct device *dev)
69 return -ENODEV; 71 return -ENODEV;
70} 72}
71 73
72static int w1_master_remove(struct device *dev)
73{
74 return 0;
75}
76
77static void w1_master_release(struct device *dev) 74static void w1_master_release(struct device *dev)
78{ 75{
79 struct w1_master *md = dev_to_w1_master(dev); 76 struct w1_master *md = dev_to_w1_master(dev);
80 complete(&md->dev_released); 77
78 dev_dbg(dev, "%s: Releasing %s.\n", __func__, md->name);
79
80 if (md->nls && md->nls->sk_socket)
81 sock_release(md->nls->sk_socket);
82 memset(md, 0, sizeof(struct w1_master) + sizeof(struct w1_bus_master));
83 kfree(md);
81} 84}
82 85
83static void w1_slave_release(struct device *dev) 86static void w1_slave_release(struct device *dev)
84{ 87{
85 struct w1_slave *sl = dev_to_w1_slave(dev); 88 struct w1_slave *sl = dev_to_w1_slave(dev);
86 complete(&sl->dev_released); 89
90 dev_dbg(dev, "%s: Releasing %s.\n", __func__, sl->name);
91
92 while (atomic_read(&sl->refcnt)) {
93 dev_dbg(dev, "Waiting for %s to become free: refcnt=%d.\n",
94 sl->name, atomic_read(&sl->refcnt));
95 if (msleep_interruptible(1000))
96 flush_signals(current);
97 }
98
99 w1_family_put(sl->family);
100 sl->master->slave_count--;
101
102 complete(&sl->released);
87} 103}
88 104
89static ssize_t w1_slave_read_name(struct device *dev, struct device_attribute *attr, char *buf) 105static ssize_t w1_slave_read_name(struct device *dev, struct device_attribute *attr, char *buf)
90{ 106{
91 struct w1_slave *sl = dev_to_w1_slave(dev); 107 struct w1_slave *sl = dev_to_w1_slave(dev);
92 108
93 return sprintf(buf, "%s\n", sl->name); 109 return sprintf(buf, "%s\n", sl->name);
94} 110}
95 111
96static ssize_t w1_slave_read_id(struct kobject *kobj, char *buf, loff_t off, size_t count) 112static ssize_t w1_slave_read_id(struct kobject *kobj, char *buf, loff_t off, size_t count)
97{ 113{
98 struct w1_slave *sl = kobj_to_w1_slave(kobj); 114 struct w1_slave *sl = kobj_to_w1_slave(kobj);
99 115
100 atomic_inc(&sl->refcnt); 116 atomic_inc(&sl->refcnt);
101 if (off > 8) { 117 if (off > 8) {
102 count = 0; 118 count = 0;
103 } else { 119 } else {
104 if (off + count > 8) 120 if (off + count > 8)
105 count = 8 - off; 121 count = 8 - off;
@@ -109,7 +125,7 @@ static ssize_t w1_slave_read_id(struct kobject *kobj, char *buf, loff_t off, siz
109 atomic_dec(&sl->refcnt); 125 atomic_dec(&sl->refcnt);
110 126
111 return count; 127 return count;
112 } 128}
113 129
114static struct device_attribute w1_slave_attr_name = 130static struct device_attribute w1_slave_attr_name =
115 __ATTR(name, S_IRUGO, w1_slave_read_name, NULL); 131 __ATTR(name, S_IRUGO, w1_slave_read_name, NULL);
@@ -139,7 +155,6 @@ struct device_driver w1_master_driver = {
139 .name = "w1_master_driver", 155 .name = "w1_master_driver",
140 .bus = &w1_bus_type, 156 .bus = &w1_bus_type,
141 .probe = w1_master_probe, 157 .probe = w1_master_probe,
142 .remove = w1_master_remove,
143}; 158};
144 159
145struct device w1_master_device = { 160struct device w1_master_device = {
@@ -160,6 +175,7 @@ struct device w1_slave_device = {
160 .bus = &w1_bus_type, 175 .bus = &w1_bus_type,
161 .bus_id = "w1 bus slave", 176 .bus_id = "w1 bus slave",
162 .driver = &w1_slave_driver, 177 .driver = &w1_slave_driver,
178 .release = &w1_slave_release
163}; 179};
164 180
165static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf) 181static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf)
@@ -406,8 +422,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
406 (unsigned int) sl->reg_num.family, 422 (unsigned int) sl->reg_num.family,
407 (unsigned long long) sl->reg_num.id); 423 (unsigned long long) sl->reg_num.id);
408 424
409 dev_dbg(&sl->dev, "%s: registering %s.\n", __func__, 425 dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__, &sl->dev.bus_id[0]);
410 &sl->dev.bus_id[0]);
411 426
412 err = device_register(&sl->dev); 427 err = device_register(&sl->dev);
413 if (err < 0) { 428 if (err < 0) {
@@ -480,7 +495,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
480 495
481 memcpy(&sl->reg_num, rn, sizeof(sl->reg_num)); 496 memcpy(&sl->reg_num, rn, sizeof(sl->reg_num));
482 atomic_set(&sl->refcnt, 0); 497 atomic_set(&sl->refcnt, 0);
483 init_completion(&sl->dev_released); 498 init_completion(&sl->released);
484 499
485 spin_lock(&w1_flock); 500 spin_lock(&w1_flock);
486 f = w1_family_registered(rn->family); 501 f = w1_family_registered(rn->family);
@@ -512,6 +527,8 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
512 msg.type = W1_SLAVE_ADD; 527 msg.type = W1_SLAVE_ADD;
513 w1_netlink_send(dev, &msg); 528 w1_netlink_send(dev, &msg);
514 529
530 dev_info(&dev->dev, "Finished %s for sl=%p.\n", __func__, sl);
531
515 return 0; 532 return 0;
516} 533}
517 534
@@ -519,29 +536,23 @@ static void w1_slave_detach(struct w1_slave *sl)
519{ 536{
520 struct w1_netlink_msg msg; 537 struct w1_netlink_msg msg;
521 538
522 dev_info(&sl->dev, "%s: detaching %s.\n", __func__, sl->name); 539 dev_info(&sl->dev, "%s: detaching %s [%p].\n", __func__, sl->name, sl);
523 540
524 while (atomic_read(&sl->refcnt)) { 541 list_del(&sl->w1_slave_entry);
525 printk(KERN_INFO "Waiting for %s to become free: refcnt=%d.\n",
526 sl->name, atomic_read(&sl->refcnt));
527
528 if (msleep_interruptible(1000))
529 flush_signals(current);
530 }
531 542
532 if (sl->family->fops && sl->family->fops->remove_slave) 543 if (sl->family->fops && sl->family->fops->remove_slave)
533 sl->family->fops->remove_slave(sl); 544 sl->family->fops->remove_slave(sl);
534 545
546 memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id));
547 msg.type = W1_SLAVE_REMOVE;
548 w1_netlink_send(sl->master, &msg);
549
535 sysfs_remove_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id); 550 sysfs_remove_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
536 device_remove_file(&sl->dev, &w1_slave_attr_name); 551 device_remove_file(&sl->dev, &w1_slave_attr_name);
537 device_unregister(&sl->dev); 552 device_unregister(&sl->dev);
538 w1_family_put(sl->family);
539 553
540 sl->master->slave_count--; 554 wait_for_completion(&sl->released);
541 555 kfree(sl);
542 memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id));
543 msg.type = W1_SLAVE_REMOVE;
544 w1_netlink_send(sl->master, &msg);
545} 556}
546 557
547static struct w1_master *w1_search_master(unsigned long data) 558static struct w1_master *w1_search_master(unsigned long data)
@@ -713,7 +724,7 @@ static int w1_control(void *data)
713 have_to_wait = 0; 724 have_to_wait = 0;
714 725
715 try_to_freeze(); 726 try_to_freeze();
716 msleep_interruptible(w1_timeout * 1000); 727 msleep_interruptible(w1_control_timeout * 1000);
717 728
718 if (signal_pending(current)) 729 if (signal_pending(current))
719 flush_signals(current); 730 flush_signals(current);
@@ -746,13 +757,12 @@ static int w1_control(void *data)
746 list_del(&dev->w1_master_entry); 757 list_del(&dev->w1_master_entry);
747 spin_unlock_bh(&w1_mlock); 758 spin_unlock_bh(&w1_mlock);
748 759
760 down(&dev->mutex);
749 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { 761 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
750 list_del(&sl->w1_slave_entry);
751
752 w1_slave_detach(sl); 762 w1_slave_detach(sl);
753 kfree(sl);
754 } 763 }
755 w1_destroy_master_attributes(dev); 764 w1_destroy_master_attributes(dev);
765 up(&dev->mutex);
756 atomic_dec(&dev->refcnt); 766 atomic_dec(&dev->refcnt);
757 continue; 767 continue;
758 } 768 }
@@ -760,19 +770,17 @@ static int w1_control(void *data)
760 if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) { 770 if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) {
761 dev_info(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name); 771 dev_info(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name);
762 down(&dev->mutex); 772 down(&dev->mutex);
763 list_for_each_entry(sl, &dev->slist, w1_slave_entry) { 773 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
764 if (sl->family->fid == W1_FAMILY_DEFAULT) { 774 if (sl->family->fid == W1_FAMILY_DEFAULT) {
765 struct w1_reg_num rn; 775 struct w1_reg_num rn;
766 list_del(&sl->w1_slave_entry);
767 w1_slave_detach(sl);
768 776
769 memcpy(&rn, &sl->reg_num, sizeof(rn)); 777 memcpy(&rn, &sl->reg_num, sizeof(rn));
770 778 w1_slave_detach(sl);
771 kfree(sl);
772 779
773 w1_attach_slave_device(dev, &rn); 780 w1_attach_slave_device(dev, &rn);
774 } 781 }
775 } 782 }
783 dev_info(&dev->dev, "Reconnecting slaves in device %s has been finished.\n", dev->name);
776 clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); 784 clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
777 up(&dev->mutex); 785 up(&dev->mutex);
778 } 786 }
@@ -816,10 +824,7 @@ int w1_process(void *data)
816 824
817 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { 825 list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
818 if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) { 826 if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) {
819 list_del (&sl->w1_slave_entry);
820
821 w1_slave_detach(sl); 827 w1_slave_detach(sl);
822 kfree(sl);
823 828
824 dev->slave_count--; 829 dev->slave_count--;
825 } else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags)) 830 } else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags))