diff options
Diffstat (limited to 'drivers/w1/w1.c')
-rw-r--r-- | drivers/w1/w1.c | 263 |
1 files changed, 176 insertions, 87 deletions
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index a698b517e863..de3e9791f80d 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <asm/atomic.h> | 35 | #include <asm/atomic.h> |
36 | 36 | ||
37 | #include "w1.h" | 37 | #include "w1.h" |
38 | #include "w1_io.h" | ||
39 | #include "w1_log.h" | 38 | #include "w1_log.h" |
40 | #include "w1_int.h" | 39 | #include "w1_int.h" |
41 | #include "w1_family.h" | 40 | #include "w1_family.h" |
@@ -55,7 +54,7 @@ module_param_named(control_timeout, w1_control_timeout, int, 0); | |||
55 | module_param_named(max_slave_count, w1_max_slave_count, int, 0); | 54 | module_param_named(max_slave_count, w1_max_slave_count, int, 0); |
56 | module_param_named(slave_ttl, w1_max_slave_ttl, int, 0); | 55 | module_param_named(slave_ttl, w1_max_slave_ttl, int, 0); |
57 | 56 | ||
58 | DEFINE_SPINLOCK(w1_mlock); | 57 | DEFINE_MUTEX(w1_mlock); |
59 | LIST_HEAD(w1_masters); | 58 | LIST_HEAD(w1_masters); |
60 | 59 | ||
61 | static struct task_struct *w1_control_thread; | 60 | static struct task_struct *w1_control_thread; |
@@ -75,8 +74,6 @@ static void w1_master_release(struct device *dev) | |||
75 | struct w1_master *md = dev_to_w1_master(dev); | 74 | struct w1_master *md = dev_to_w1_master(dev); |
76 | 75 | ||
77 | dev_dbg(dev, "%s: Releasing %s.\n", __func__, md->name); | 76 | dev_dbg(dev, "%s: Releasing %s.\n", __func__, md->name); |
78 | |||
79 | dev_fini_netlink(md); | ||
80 | memset(md, 0, sizeof(struct w1_master) + sizeof(struct w1_bus_master)); | 77 | memset(md, 0, sizeof(struct w1_master) + sizeof(struct w1_bus_master)); |
81 | kfree(md); | 78 | kfree(md); |
82 | } | 79 | } |
@@ -85,10 +82,10 @@ static void w1_slave_release(struct device *dev) | |||
85 | { | 82 | { |
86 | struct w1_slave *sl = dev_to_w1_slave(dev); | 83 | struct w1_slave *sl = dev_to_w1_slave(dev); |
87 | 84 | ||
88 | dev_dbg(dev, "%s: Releasing %s.\n", __func__, sl->name); | 85 | printk("%s: Releasing %s.\n", __func__, sl->name); |
89 | 86 | ||
90 | while (atomic_read(&sl->refcnt)) { | 87 | while (atomic_read(&sl->refcnt)) { |
91 | dev_dbg(dev, "Waiting for %s to become free: refcnt=%d.\n", | 88 | printk("Waiting for %s to become free: refcnt=%d.\n", |
92 | sl->name, atomic_read(&sl->refcnt)); | 89 | sl->name, atomic_read(&sl->refcnt)); |
93 | if (msleep_interruptible(1000)) | 90 | if (msleep_interruptible(1000)) |
94 | flush_signals(current); | 91 | flush_signals(current); |
@@ -111,7 +108,6 @@ static ssize_t w1_slave_read_id(struct kobject *kobj, char *buf, loff_t off, siz | |||
111 | { | 108 | { |
112 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 109 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
113 | 110 | ||
114 | atomic_inc(&sl->refcnt); | ||
115 | if (off > 8) { | 111 | if (off > 8) { |
116 | count = 0; | 112 | count = 0; |
117 | } else { | 113 | } else { |
@@ -120,7 +116,6 @@ static ssize_t w1_slave_read_id(struct kobject *kobj, char *buf, loff_t off, siz | |||
120 | 116 | ||
121 | memcpy(buf, (u8 *)&sl->reg_num, count); | 117 | memcpy(buf, (u8 *)&sl->reg_num, count); |
122 | } | 118 | } |
123 | atomic_dec(&sl->refcnt); | ||
124 | 119 | ||
125 | return count; | 120 | return count; |
126 | } | 121 | } |
@@ -139,7 +134,63 @@ static struct bin_attribute w1_slave_attr_bin_id = { | |||
139 | }; | 134 | }; |
140 | 135 | ||
141 | /* Default family */ | 136 | /* Default family */ |
142 | static struct w1_family w1_default_family; | 137 | |
138 | static ssize_t w1_default_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | ||
139 | { | ||
140 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | ||
141 | |||
142 | mutex_lock(&sl->master->mutex); | ||
143 | if (w1_reset_select_slave(sl)) { | ||
144 | count = 0; | ||
145 | goto out_up; | ||
146 | } | ||
147 | |||
148 | w1_write_block(sl->master, buf, count); | ||
149 | |||
150 | out_up: | ||
151 | mutex_unlock(&sl->master->mutex); | ||
152 | return count; | ||
153 | } | ||
154 | |||
155 | static ssize_t w1_default_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | ||
156 | { | ||
157 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | ||
158 | |||
159 | mutex_lock(&sl->master->mutex); | ||
160 | w1_read_block(sl->master, buf, count); | ||
161 | mutex_unlock(&sl->master->mutex); | ||
162 | return count; | ||
163 | } | ||
164 | |||
165 | static struct bin_attribute w1_default_attr = { | ||
166 | .attr = { | ||
167 | .name = "rw", | ||
168 | .mode = S_IRUGO | S_IWUSR, | ||
169 | .owner = THIS_MODULE, | ||
170 | }, | ||
171 | .size = PAGE_SIZE, | ||
172 | .read = w1_default_read, | ||
173 | .write = w1_default_write, | ||
174 | }; | ||
175 | |||
176 | static int w1_default_add_slave(struct w1_slave *sl) | ||
177 | { | ||
178 | return sysfs_create_bin_file(&sl->dev.kobj, &w1_default_attr); | ||
179 | } | ||
180 | |||
181 | static void w1_default_remove_slave(struct w1_slave *sl) | ||
182 | { | ||
183 | sysfs_remove_bin_file(&sl->dev.kobj, &w1_default_attr); | ||
184 | } | ||
185 | |||
186 | static struct w1_family_ops w1_default_fops = { | ||
187 | .add_slave = w1_default_add_slave, | ||
188 | .remove_slave = w1_default_remove_slave, | ||
189 | }; | ||
190 | |||
191 | static struct w1_family w1_default_family = { | ||
192 | .fops = &w1_default_fops, | ||
193 | }; | ||
143 | 194 | ||
144 | static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); | 195 | static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); |
145 | 196 | ||
@@ -183,12 +234,9 @@ static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_a | |||
183 | struct w1_master *md = dev_to_w1_master(dev); | 234 | struct w1_master *md = dev_to_w1_master(dev); |
184 | ssize_t count; | 235 | ssize_t count; |
185 | 236 | ||
186 | if (down_interruptible (&md->mutex)) | 237 | mutex_lock(&md->mutex); |
187 | return -EBUSY; | ||
188 | |||
189 | count = sprintf(buf, "%s\n", md->name); | 238 | count = sprintf(buf, "%s\n", md->name); |
190 | 239 | mutex_unlock(&md->mutex); | |
191 | up(&md->mutex); | ||
192 | 240 | ||
193 | return count; | 241 | return count; |
194 | } | 242 | } |
@@ -199,12 +247,9 @@ static ssize_t w1_master_attribute_store_search(struct device * dev, | |||
199 | { | 247 | { |
200 | struct w1_master *md = dev_to_w1_master(dev); | 248 | struct w1_master *md = dev_to_w1_master(dev); |
201 | 249 | ||
202 | if (down_interruptible (&md->mutex)) | 250 | mutex_lock(&md->mutex); |
203 | return -EBUSY; | ||
204 | |||
205 | md->search_count = simple_strtol(buf, NULL, 0); | 251 | md->search_count = simple_strtol(buf, NULL, 0); |
206 | 252 | mutex_unlock(&md->mutex); | |
207 | up(&md->mutex); | ||
208 | 253 | ||
209 | return count; | 254 | return count; |
210 | } | 255 | } |
@@ -216,12 +261,9 @@ static ssize_t w1_master_attribute_show_search(struct device *dev, | |||
216 | struct w1_master *md = dev_to_w1_master(dev); | 261 | struct w1_master *md = dev_to_w1_master(dev); |
217 | ssize_t count; | 262 | ssize_t count; |
218 | 263 | ||
219 | if (down_interruptible (&md->mutex)) | 264 | mutex_lock(&md->mutex); |
220 | return -EBUSY; | ||
221 | |||
222 | count = sprintf(buf, "%d\n", md->search_count); | 265 | count = sprintf(buf, "%d\n", md->search_count); |
223 | 266 | mutex_unlock(&md->mutex); | |
224 | up(&md->mutex); | ||
225 | 267 | ||
226 | return count; | 268 | return count; |
227 | } | 269 | } |
@@ -231,12 +273,9 @@ static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct devic | |||
231 | struct w1_master *md = dev_to_w1_master(dev); | 273 | struct w1_master *md = dev_to_w1_master(dev); |
232 | ssize_t count; | 274 | ssize_t count; |
233 | 275 | ||
234 | if (down_interruptible(&md->mutex)) | 276 | mutex_lock(&md->mutex); |
235 | return -EBUSY; | ||
236 | |||
237 | count = sprintf(buf, "0x%p\n", md->bus_master); | 277 | count = sprintf(buf, "0x%p\n", md->bus_master); |
238 | 278 | mutex_unlock(&md->mutex); | |
239 | up(&md->mutex); | ||
240 | return count; | 279 | return count; |
241 | } | 280 | } |
242 | 281 | ||
@@ -252,12 +291,9 @@ static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, stru | |||
252 | struct w1_master *md = dev_to_w1_master(dev); | 291 | struct w1_master *md = dev_to_w1_master(dev); |
253 | ssize_t count; | 292 | ssize_t count; |
254 | 293 | ||
255 | if (down_interruptible(&md->mutex)) | 294 | mutex_lock(&md->mutex); |
256 | return -EBUSY; | ||
257 | |||
258 | count = sprintf(buf, "%d\n", md->max_slave_count); | 295 | count = sprintf(buf, "%d\n", md->max_slave_count); |
259 | 296 | mutex_unlock(&md->mutex); | |
260 | up(&md->mutex); | ||
261 | return count; | 297 | return count; |
262 | } | 298 | } |
263 | 299 | ||
@@ -266,12 +302,9 @@ static ssize_t w1_master_attribute_show_attempts(struct device *dev, struct devi | |||
266 | struct w1_master *md = dev_to_w1_master(dev); | 302 | struct w1_master *md = dev_to_w1_master(dev); |
267 | ssize_t count; | 303 | ssize_t count; |
268 | 304 | ||
269 | if (down_interruptible(&md->mutex)) | 305 | mutex_lock(&md->mutex); |
270 | return -EBUSY; | ||
271 | |||
272 | count = sprintf(buf, "%lu\n", md->attempts); | 306 | count = sprintf(buf, "%lu\n", md->attempts); |
273 | 307 | mutex_unlock(&md->mutex); | |
274 | up(&md->mutex); | ||
275 | return count; | 308 | return count; |
276 | } | 309 | } |
277 | 310 | ||
@@ -280,12 +313,9 @@ static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct d | |||
280 | struct w1_master *md = dev_to_w1_master(dev); | 313 | struct w1_master *md = dev_to_w1_master(dev); |
281 | ssize_t count; | 314 | ssize_t count; |
282 | 315 | ||
283 | if (down_interruptible(&md->mutex)) | 316 | mutex_lock(&md->mutex); |
284 | return -EBUSY; | ||
285 | |||
286 | count = sprintf(buf, "%d\n", md->slave_count); | 317 | count = sprintf(buf, "%d\n", md->slave_count); |
287 | 318 | mutex_unlock(&md->mutex); | |
288 | up(&md->mutex); | ||
289 | return count; | 319 | return count; |
290 | } | 320 | } |
291 | 321 | ||
@@ -294,8 +324,7 @@ static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device | |||
294 | struct w1_master *md = dev_to_w1_master(dev); | 324 | struct w1_master *md = dev_to_w1_master(dev); |
295 | int c = PAGE_SIZE; | 325 | int c = PAGE_SIZE; |
296 | 326 | ||
297 | if (down_interruptible(&md->mutex)) | 327 | mutex_lock(&md->mutex); |
298 | return -EBUSY; | ||
299 | 328 | ||
300 | if (md->slave_count == 0) | 329 | if (md->slave_count == 0) |
301 | c -= snprintf(buf + PAGE_SIZE - c, c, "not found.\n"); | 330 | c -= snprintf(buf + PAGE_SIZE - c, c, "not found.\n"); |
@@ -310,7 +339,7 @@ static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device | |||
310 | } | 339 | } |
311 | } | 340 | } |
312 | 341 | ||
313 | up(&md->mutex); | 342 | mutex_unlock(&md->mutex); |
314 | 343 | ||
315 | return PAGE_SIZE - c; | 344 | return PAGE_SIZE - c; |
316 | } | 345 | } |
@@ -362,7 +391,8 @@ static void w1_destroy_master_attributes(struct w1_master *master) | |||
362 | } | 391 | } |
363 | 392 | ||
364 | #ifdef CONFIG_HOTPLUG | 393 | #ifdef CONFIG_HOTPLUG |
365 | static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) | 394 | static int w1_uevent(struct device *dev, char **envp, int num_envp, |
395 | char *buffer, int buffer_size) | ||
366 | { | 396 | { |
367 | struct w1_master *md = NULL; | 397 | struct w1_master *md = NULL; |
368 | struct w1_slave *sl = NULL; | 398 | struct w1_slave *sl = NULL; |
@@ -382,7 +412,8 @@ static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer | |||
382 | return -EINVAL; | 412 | return -EINVAL; |
383 | } | 413 | } |
384 | 414 | ||
385 | dev_dbg(dev, "Hotplug event for %s %s, bus_id=%s.\n", event_owner, name, dev->bus_id); | 415 | dev_dbg(dev, "Hotplug event for %s %s, bus_id=%s.\n", |
416 | event_owner, name, dev->bus_id); | ||
386 | 417 | ||
387 | if (dev->driver != &w1_slave_driver || !sl) | 418 | if (dev->driver != &w1_slave_driver || !sl) |
388 | return 0; | 419 | return 0; |
@@ -401,7 +432,8 @@ static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer | |||
401 | return 0; | 432 | return 0; |
402 | }; | 433 | }; |
403 | #else | 434 | #else |
404 | static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) | 435 | static int w1_uevent(struct device *dev, char **envp, int num_envp, |
436 | char *buffer, int buffer_size) | ||
405 | { | 437 | { |
406 | return 0; | 438 | return 0; |
407 | } | 439 | } |
@@ -425,7 +457,8 @@ static int __w1_attach_slave_device(struct w1_slave *sl) | |||
425 | (unsigned int) sl->reg_num.family, | 457 | (unsigned int) sl->reg_num.family, |
426 | (unsigned long long) sl->reg_num.id); | 458 | (unsigned long long) sl->reg_num.id); |
427 | 459 | ||
428 | dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__, &sl->dev.bus_id[0]); | 460 | dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__, |
461 | &sl->dev.bus_id[0]); | ||
429 | 462 | ||
430 | err = device_register(&sl->dev); | 463 | err = device_register(&sl->dev); |
431 | if (err < 0) { | 464 | if (err < 0) { |
@@ -496,6 +529,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) | |||
496 | sl->master = dev; | 529 | sl->master = dev; |
497 | set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); | 530 | set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); |
498 | 531 | ||
532 | memset(&msg, 0, sizeof(msg)); | ||
499 | memcpy(&sl->reg_num, rn, sizeof(sl->reg_num)); | 533 | memcpy(&sl->reg_num, rn, sizeof(sl->reg_num)); |
500 | atomic_set(&sl->refcnt, 0); | 534 | atomic_set(&sl->refcnt, 0); |
501 | init_completion(&sl->released); | 535 | init_completion(&sl->released); |
@@ -526,7 +560,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) | |||
526 | sl->ttl = dev->slave_ttl; | 560 | sl->ttl = dev->slave_ttl; |
527 | dev->slave_count++; | 561 | dev->slave_count++; |
528 | 562 | ||
529 | memcpy(&msg.id.id, rn, sizeof(msg.id.id)); | 563 | memcpy(msg.id.id, rn, sizeof(msg.id)); |
530 | msg.type = W1_SLAVE_ADD; | 564 | msg.type = W1_SLAVE_ADD; |
531 | w1_netlink_send(dev, &msg); | 565 | w1_netlink_send(dev, &msg); |
532 | 566 | ||
@@ -544,7 +578,8 @@ static void w1_slave_detach(struct w1_slave *sl) | |||
544 | if (sl->family->fops && sl->family->fops->remove_slave) | 578 | if (sl->family->fops && sl->family->fops->remove_slave) |
545 | sl->family->fops->remove_slave(sl); | 579 | sl->family->fops->remove_slave(sl); |
546 | 580 | ||
547 | memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id)); | 581 | memset(&msg, 0, sizeof(msg)); |
582 | memcpy(msg.id.id, &sl->reg_num, sizeof(msg.id)); | ||
548 | msg.type = W1_SLAVE_REMOVE; | 583 | msg.type = W1_SLAVE_REMOVE; |
549 | w1_netlink_send(sl->master, &msg); | 584 | w1_netlink_send(sl->master, &msg); |
550 | 585 | ||
@@ -561,7 +596,7 @@ static struct w1_master *w1_search_master(void *data) | |||
561 | struct w1_master *dev; | 596 | struct w1_master *dev; |
562 | int found = 0; | 597 | int found = 0; |
563 | 598 | ||
564 | spin_lock_bh(&w1_mlock); | 599 | mutex_lock(&w1_mlock); |
565 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { | 600 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { |
566 | if (dev->bus_master->data == data) { | 601 | if (dev->bus_master->data == data) { |
567 | found = 1; | 602 | found = 1; |
@@ -569,22 +604,69 @@ static struct w1_master *w1_search_master(void *data) | |||
569 | break; | 604 | break; |
570 | } | 605 | } |
571 | } | 606 | } |
572 | spin_unlock_bh(&w1_mlock); | 607 | mutex_unlock(&w1_mlock); |
608 | |||
609 | return (found)?dev:NULL; | ||
610 | } | ||
611 | |||
612 | struct w1_master *w1_search_master_id(u32 id) | ||
613 | { | ||
614 | struct w1_master *dev; | ||
615 | int found = 0; | ||
616 | |||
617 | mutex_lock(&w1_mlock); | ||
618 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { | ||
619 | if (dev->id == id) { | ||
620 | found = 1; | ||
621 | atomic_inc(&dev->refcnt); | ||
622 | break; | ||
623 | } | ||
624 | } | ||
625 | mutex_unlock(&w1_mlock); | ||
573 | 626 | ||
574 | return (found)?dev:NULL; | 627 | return (found)?dev:NULL; |
575 | } | 628 | } |
576 | 629 | ||
630 | struct w1_slave *w1_search_slave(struct w1_reg_num *id) | ||
631 | { | ||
632 | struct w1_master *dev; | ||
633 | struct w1_slave *sl = NULL; | ||
634 | int found = 0; | ||
635 | |||
636 | mutex_lock(&w1_mlock); | ||
637 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { | ||
638 | mutex_lock(&dev->mutex); | ||
639 | list_for_each_entry(sl, &dev->slist, w1_slave_entry) { | ||
640 | if (sl->reg_num.family == id->family && | ||
641 | sl->reg_num.id == id->id && | ||
642 | sl->reg_num.crc == id->crc) { | ||
643 | found = 1; | ||
644 | atomic_inc(&dev->refcnt); | ||
645 | atomic_inc(&sl->refcnt); | ||
646 | break; | ||
647 | } | ||
648 | } | ||
649 | mutex_unlock(&dev->mutex); | ||
650 | |||
651 | if (found) | ||
652 | break; | ||
653 | } | ||
654 | mutex_unlock(&w1_mlock); | ||
655 | |||
656 | return (found)?sl:NULL; | ||
657 | } | ||
658 | |||
577 | void w1_reconnect_slaves(struct w1_family *f) | 659 | void w1_reconnect_slaves(struct w1_family *f) |
578 | { | 660 | { |
579 | struct w1_master *dev; | 661 | struct w1_master *dev; |
580 | 662 | ||
581 | spin_lock_bh(&w1_mlock); | 663 | mutex_lock(&w1_mlock); |
582 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { | 664 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { |
583 | dev_dbg(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n", | 665 | dev_dbg(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n", |
584 | dev->name, f->fid); | 666 | dev->name, f->fid); |
585 | set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); | 667 | set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); |
586 | } | 668 | } |
587 | spin_unlock_bh(&w1_mlock); | 669 | mutex_unlock(&w1_mlock); |
588 | } | 670 | } |
589 | 671 | ||
590 | static void w1_slave_found(void *data, u64 rn) | 672 | static void w1_slave_found(void *data, u64 rn) |
@@ -646,7 +728,7 @@ static void w1_slave_found(void *data, u64 rn) | |||
646 | * @dev The master device to search | 728 | * @dev The master device to search |
647 | * @cb Function to call when a device is found | 729 | * @cb Function to call when a device is found |
648 | */ | 730 | */ |
649 | void w1_search(struct w1_master *dev, w1_slave_found_callback cb) | 731 | void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb) |
650 | { | 732 | { |
651 | u64 last_rn, rn, tmp64; | 733 | u64 last_rn, rn, tmp64; |
652 | int i, slave_count = 0; | 734 | int i, slave_count = 0; |
@@ -677,7 +759,7 @@ void w1_search(struct w1_master *dev, w1_slave_found_callback cb) | |||
677 | } | 759 | } |
678 | 760 | ||
679 | /* Start the search */ | 761 | /* Start the search */ |
680 | w1_write_8(dev, W1_SEARCH); | 762 | w1_write_8(dev, search_type); |
681 | for (i = 0; i < 64; ++i) { | 763 | for (i = 0; i < 64; ++i) { |
682 | /* Determine the direction/search bit */ | 764 | /* Determine the direction/search bit */ |
683 | if (i == desc_bit) | 765 | if (i == desc_bit) |
@@ -739,23 +821,23 @@ static int w1_control(void *data) | |||
739 | if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { | 821 | if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { |
740 | set_bit(W1_MASTER_NEED_EXIT, &dev->flags); | 822 | set_bit(W1_MASTER_NEED_EXIT, &dev->flags); |
741 | 823 | ||
742 | spin_lock(&w1_mlock); | 824 | mutex_lock(&w1_mlock); |
743 | list_del(&dev->w1_master_entry); | 825 | list_del(&dev->w1_master_entry); |
744 | spin_unlock(&w1_mlock); | 826 | mutex_unlock(&w1_mlock); |
745 | 827 | ||
746 | down(&dev->mutex); | 828 | mutex_lock(&dev->mutex); |
747 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { | 829 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { |
748 | w1_slave_detach(sl); | 830 | w1_slave_detach(sl); |
749 | } | 831 | } |
750 | w1_destroy_master_attributes(dev); | 832 | w1_destroy_master_attributes(dev); |
751 | up(&dev->mutex); | 833 | mutex_unlock(&dev->mutex); |
752 | atomic_dec(&dev->refcnt); | 834 | atomic_dec(&dev->refcnt); |
753 | continue; | 835 | continue; |
754 | } | 836 | } |
755 | 837 | ||
756 | if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) { | 838 | if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) { |
757 | dev_dbg(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name); | 839 | dev_dbg(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name); |
758 | down(&dev->mutex); | 840 | mutex_lock(&dev->mutex); |
759 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { | 841 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { |
760 | if (sl->family->fid == W1_FAMILY_DEFAULT) { | 842 | if (sl->family->fid == W1_FAMILY_DEFAULT) { |
761 | struct w1_reg_num rn; | 843 | struct w1_reg_num rn; |
@@ -768,7 +850,7 @@ static int w1_control(void *data) | |||
768 | } | 850 | } |
769 | dev_dbg(&dev->dev, "Reconnecting slaves in device %s has been finished.\n", dev->name); | 851 | dev_dbg(&dev->dev, "Reconnecting slaves in device %s has been finished.\n", dev->name); |
770 | clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); | 852 | clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); |
771 | up(&dev->mutex); | 853 | mutex_unlock(&dev->mutex); |
772 | } | 854 | } |
773 | } | 855 | } |
774 | } | 856 | } |
@@ -776,10 +858,31 @@ static int w1_control(void *data) | |||
776 | return 0; | 858 | return 0; |
777 | } | 859 | } |
778 | 860 | ||
861 | void w1_search_process(struct w1_master *dev, u8 search_type) | ||
862 | { | ||
863 | struct w1_slave *sl, *sln; | ||
864 | |||
865 | list_for_each_entry(sl, &dev->slist, w1_slave_entry) | ||
866 | clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); | ||
867 | |||
868 | w1_search_devices(dev, search_type, w1_slave_found); | ||
869 | |||
870 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { | ||
871 | if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) { | ||
872 | w1_slave_detach(sl); | ||
873 | |||
874 | dev->slave_count--; | ||
875 | } else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags)) | ||
876 | sl->ttl = dev->slave_ttl; | ||
877 | } | ||
878 | |||
879 | if (dev->search_count > 0) | ||
880 | dev->search_count--; | ||
881 | } | ||
882 | |||
779 | int w1_process(void *data) | 883 | int w1_process(void *data) |
780 | { | 884 | { |
781 | struct w1_master *dev = (struct w1_master *) data; | 885 | struct w1_master *dev = (struct w1_master *) data; |
782 | struct w1_slave *sl, *sln; | ||
783 | 886 | ||
784 | while (!kthread_should_stop() && !test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { | 887 | while (!kthread_should_stop() && !test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { |
785 | try_to_freeze(); | 888 | try_to_freeze(); |
@@ -794,27 +897,9 @@ int w1_process(void *data) | |||
794 | if (dev->search_count == 0) | 897 | if (dev->search_count == 0) |
795 | continue; | 898 | continue; |
796 | 899 | ||
797 | if (down_interruptible(&dev->mutex)) | 900 | mutex_lock(&dev->mutex); |
798 | continue; | 901 | w1_search_process(dev, W1_SEARCH); |
799 | 902 | mutex_unlock(&dev->mutex); | |
800 | list_for_each_entry(sl, &dev->slist, w1_slave_entry) | ||
801 | clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); | ||
802 | |||
803 | w1_search_devices(dev, w1_slave_found); | ||
804 | |||
805 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { | ||
806 | if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) { | ||
807 | w1_slave_detach(sl); | ||
808 | |||
809 | dev->slave_count--; | ||
810 | } else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags)) | ||
811 | sl->ttl = dev->slave_ttl; | ||
812 | } | ||
813 | |||
814 | if (dev->search_count > 0) | ||
815 | dev->search_count--; | ||
816 | |||
817 | up(&dev->mutex); | ||
818 | } | 903 | } |
819 | 904 | ||
820 | atomic_dec(&dev->refcnt); | 905 | atomic_dec(&dev->refcnt); |
@@ -828,6 +913,8 @@ static int w1_init(void) | |||
828 | 913 | ||
829 | printk(KERN_INFO "Driver for 1-wire Dallas network protocol.\n"); | 914 | printk(KERN_INFO "Driver for 1-wire Dallas network protocol.\n"); |
830 | 915 | ||
916 | w1_init_netlink(); | ||
917 | |||
831 | retval = bus_register(&w1_bus_type); | 918 | retval = bus_register(&w1_bus_type); |
832 | if (retval) { | 919 | if (retval) { |
833 | printk(KERN_ERR "Failed to register bus. err=%d.\n", retval); | 920 | printk(KERN_ERR "Failed to register bus. err=%d.\n", retval); |
@@ -880,6 +967,8 @@ static void w1_fini(void) | |||
880 | list_for_each_entry(dev, &w1_masters, w1_master_entry) | 967 | list_for_each_entry(dev, &w1_masters, w1_master_entry) |
881 | __w1_remove_master_device(dev); | 968 | __w1_remove_master_device(dev); |
882 | 969 | ||
970 | w1_fini_netlink(); | ||
971 | |||
883 | kthread_stop(w1_control_thread); | 972 | kthread_stop(w1_control_thread); |
884 | 973 | ||
885 | driver_unregister(&w1_slave_driver); | 974 | driver_unregister(&w1_slave_driver); |