Root/
1 | /* |
2 | * w1.c |
3 | * |
4 | * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net> |
5 | * |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2 of the License, or |
10 | * (at your option) any later version. |
11 | * |
12 | * This program is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU General Public License |
18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ |
21 | |
22 | #include <linux/delay.h> |
23 | #include <linux/kernel.h> |
24 | #include <linux/module.h> |
25 | #include <linux/moduleparam.h> |
26 | #include <linux/list.h> |
27 | #include <linux/interrupt.h> |
28 | #include <linux/spinlock.h> |
29 | #include <linux/timer.h> |
30 | #include <linux/device.h> |
31 | #include <linux/slab.h> |
32 | #include <linux/sched.h> |
33 | #include <linux/kthread.h> |
34 | #include <linux/freezer.h> |
35 | |
36 | #include <linux/atomic.h> |
37 | |
38 | #include "w1.h" |
39 | #include "w1_log.h" |
40 | #include "w1_int.h" |
41 | #include "w1_family.h" |
42 | #include "w1_netlink.h" |
43 | |
44 | MODULE_LICENSE("GPL"); |
45 | MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); |
46 | MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol."); |
47 | |
48 | static int w1_timeout = 10; |
49 | int w1_max_slave_count = 10; |
50 | int w1_max_slave_ttl = 10; |
51 | |
52 | module_param_named(timeout, w1_timeout, int, 0); |
53 | module_param_named(max_slave_count, w1_max_slave_count, int, 0); |
54 | module_param_named(slave_ttl, w1_max_slave_ttl, int, 0); |
55 | |
56 | DEFINE_MUTEX(w1_mlock); |
57 | LIST_HEAD(w1_masters); |
58 | |
59 | static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn); |
60 | |
61 | static int w1_master_match(struct device *dev, struct device_driver *drv) |
62 | { |
63 | return 1; |
64 | } |
65 | |
66 | static int w1_master_probe(struct device *dev) |
67 | { |
68 | return -ENODEV; |
69 | } |
70 | |
71 | static void w1_master_release(struct device *dev) |
72 | { |
73 | struct w1_master *md = dev_to_w1_master(dev); |
74 | |
75 | dev_dbg(dev, "%s: Releasing %s.\n", __func__, md->name); |
76 | memset(md, 0, sizeof(struct w1_master) + sizeof(struct w1_bus_master)); |
77 | kfree(md); |
78 | } |
79 | |
80 | static void w1_slave_release(struct device *dev) |
81 | { |
82 | struct w1_slave *sl = dev_to_w1_slave(dev); |
83 | |
84 | dev_dbg(dev, "%s: Releasing %s.\n", __func__, sl->name); |
85 | |
86 | while (atomic_read(&sl->refcnt)) { |
87 | dev_dbg(dev, "Waiting for %s to become free: refcnt=%d.\n", |
88 | sl->name, atomic_read(&sl->refcnt)); |
89 | if (msleep_interruptible(1000)) |
90 | flush_signals(current); |
91 | } |
92 | |
93 | w1_family_put(sl->family); |
94 | sl->master->slave_count--; |
95 | |
96 | complete(&sl->released); |
97 | } |
98 | |
99 | static ssize_t w1_slave_read_name(struct device *dev, struct device_attribute *attr, char *buf) |
100 | { |
101 | struct w1_slave *sl = dev_to_w1_slave(dev); |
102 | |
103 | return sprintf(buf, "%s\n", sl->name); |
104 | } |
105 | |
106 | static ssize_t w1_slave_read_id(struct device *dev, |
107 | struct device_attribute *attr, char *buf) |
108 | { |
109 | struct w1_slave *sl = dev_to_w1_slave(dev); |
110 | ssize_t count = sizeof(sl->reg_num); |
111 | |
112 | memcpy(buf, (u8 *)&sl->reg_num, count); |
113 | return count; |
114 | } |
115 | |
116 | static struct device_attribute w1_slave_attr_name = |
117 | __ATTR(name, S_IRUGO, w1_slave_read_name, NULL); |
118 | static struct device_attribute w1_slave_attr_id = |
119 | __ATTR(id, S_IRUGO, w1_slave_read_id, NULL); |
120 | |
121 | /* Default family */ |
122 | |
123 | static ssize_t w1_default_write(struct file *filp, struct kobject *kobj, |
124 | struct bin_attribute *bin_attr, |
125 | char *buf, loff_t off, size_t count) |
126 | { |
127 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
128 | |
129 | mutex_lock(&sl->master->mutex); |
130 | if (w1_reset_select_slave(sl)) { |
131 | count = 0; |
132 | goto out_up; |
133 | } |
134 | |
135 | w1_write_block(sl->master, buf, count); |
136 | |
137 | out_up: |
138 | mutex_unlock(&sl->master->mutex); |
139 | return count; |
140 | } |
141 | |
142 | static ssize_t w1_default_read(struct file *filp, struct kobject *kobj, |
143 | struct bin_attribute *bin_attr, |
144 | char *buf, loff_t off, size_t count) |
145 | { |
146 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
147 | |
148 | mutex_lock(&sl->master->mutex); |
149 | w1_read_block(sl->master, buf, count); |
150 | mutex_unlock(&sl->master->mutex); |
151 | return count; |
152 | } |
153 | |
154 | static struct bin_attribute w1_default_attr = { |
155 | .attr = { |
156 | .name = "rw", |
157 | .mode = S_IRUGO | S_IWUSR, |
158 | }, |
159 | .size = PAGE_SIZE, |
160 | .read = w1_default_read, |
161 | .write = w1_default_write, |
162 | }; |
163 | |
164 | static int w1_default_add_slave(struct w1_slave *sl) |
165 | { |
166 | return sysfs_create_bin_file(&sl->dev.kobj, &w1_default_attr); |
167 | } |
168 | |
169 | static void w1_default_remove_slave(struct w1_slave *sl) |
170 | { |
171 | sysfs_remove_bin_file(&sl->dev.kobj, &w1_default_attr); |
172 | } |
173 | |
174 | static struct w1_family_ops w1_default_fops = { |
175 | .add_slave = w1_default_add_slave, |
176 | .remove_slave = w1_default_remove_slave, |
177 | }; |
178 | |
179 | static struct w1_family w1_default_family = { |
180 | .fops = &w1_default_fops, |
181 | }; |
182 | |
183 | static int w1_uevent(struct device *dev, struct kobj_uevent_env *env); |
184 | |
185 | static struct bus_type w1_bus_type = { |
186 | .name = "w1", |
187 | .match = w1_master_match, |
188 | .uevent = w1_uevent, |
189 | }; |
190 | |
191 | struct device_driver w1_master_driver = { |
192 | .name = "w1_master_driver", |
193 | .bus = &w1_bus_type, |
194 | .probe = w1_master_probe, |
195 | }; |
196 | |
197 | struct device w1_master_device = { |
198 | .parent = NULL, |
199 | .bus = &w1_bus_type, |
200 | .init_name = "w1 bus master", |
201 | .driver = &w1_master_driver, |
202 | .release = &w1_master_release |
203 | }; |
204 | |
205 | static struct device_driver w1_slave_driver = { |
206 | .name = "w1_slave_driver", |
207 | .bus = &w1_bus_type, |
208 | }; |
209 | |
210 | #if 0 |
211 | struct device w1_slave_device = { |
212 | .parent = NULL, |
213 | .bus = &w1_bus_type, |
214 | .init_name = "w1 bus slave", |
215 | .driver = &w1_slave_driver, |
216 | .release = &w1_slave_release |
217 | }; |
218 | #endif /* 0 */ |
219 | |
220 | static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_attribute *attr, char *buf) |
221 | { |
222 | struct w1_master *md = dev_to_w1_master(dev); |
223 | ssize_t count; |
224 | |
225 | mutex_lock(&md->mutex); |
226 | count = sprintf(buf, "%s\n", md->name); |
227 | mutex_unlock(&md->mutex); |
228 | |
229 | return count; |
230 | } |
231 | |
232 | static ssize_t w1_master_attribute_store_search(struct device * dev, |
233 | struct device_attribute *attr, |
234 | const char * buf, size_t count) |
235 | { |
236 | long tmp; |
237 | struct w1_master *md = dev_to_w1_master(dev); |
238 | |
239 | if (strict_strtol(buf, 0, &tmp) == -EINVAL) |
240 | return -EINVAL; |
241 | |
242 | mutex_lock(&md->mutex); |
243 | md->search_count = tmp; |
244 | mutex_unlock(&md->mutex); |
245 | wake_up_process(md->thread); |
246 | |
247 | return count; |
248 | } |
249 | |
250 | static ssize_t w1_master_attribute_show_search(struct device *dev, |
251 | struct device_attribute *attr, |
252 | char *buf) |
253 | { |
254 | struct w1_master *md = dev_to_w1_master(dev); |
255 | ssize_t count; |
256 | |
257 | mutex_lock(&md->mutex); |
258 | count = sprintf(buf, "%d\n", md->search_count); |
259 | mutex_unlock(&md->mutex); |
260 | |
261 | return count; |
262 | } |
263 | |
264 | static ssize_t w1_master_attribute_store_pullup(struct device *dev, |
265 | struct device_attribute *attr, |
266 | const char *buf, size_t count) |
267 | { |
268 | long tmp; |
269 | struct w1_master *md = dev_to_w1_master(dev); |
270 | |
271 | if (strict_strtol(buf, 0, &tmp) == -EINVAL) |
272 | return -EINVAL; |
273 | |
274 | mutex_lock(&md->mutex); |
275 | md->enable_pullup = tmp; |
276 | mutex_unlock(&md->mutex); |
277 | wake_up_process(md->thread); |
278 | |
279 | return count; |
280 | } |
281 | |
282 | static ssize_t w1_master_attribute_show_pullup(struct device *dev, |
283 | struct device_attribute *attr, |
284 | char *buf) |
285 | { |
286 | struct w1_master *md = dev_to_w1_master(dev); |
287 | ssize_t count; |
288 | |
289 | mutex_lock(&md->mutex); |
290 | count = sprintf(buf, "%d\n", md->enable_pullup); |
291 | mutex_unlock(&md->mutex); |
292 | |
293 | return count; |
294 | } |
295 | |
296 | static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct device_attribute *attr, char *buf) |
297 | { |
298 | struct w1_master *md = dev_to_w1_master(dev); |
299 | ssize_t count; |
300 | |
301 | mutex_lock(&md->mutex); |
302 | count = sprintf(buf, "0x%p\n", md->bus_master); |
303 | mutex_unlock(&md->mutex); |
304 | return count; |
305 | } |
306 | |
307 | static ssize_t w1_master_attribute_show_timeout(struct device *dev, struct device_attribute *attr, char *buf) |
308 | { |
309 | ssize_t count; |
310 | count = sprintf(buf, "%d\n", w1_timeout); |
311 | return count; |
312 | } |
313 | |
314 | static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, struct device_attribute *attr, char *buf) |
315 | { |
316 | struct w1_master *md = dev_to_w1_master(dev); |
317 | ssize_t count; |
318 | |
319 | mutex_lock(&md->mutex); |
320 | count = sprintf(buf, "%d\n", md->max_slave_count); |
321 | mutex_unlock(&md->mutex); |
322 | return count; |
323 | } |
324 | |
325 | static ssize_t w1_master_attribute_show_attempts(struct device *dev, struct device_attribute *attr, char *buf) |
326 | { |
327 | struct w1_master *md = dev_to_w1_master(dev); |
328 | ssize_t count; |
329 | |
330 | mutex_lock(&md->mutex); |
331 | count = sprintf(buf, "%lu\n", md->attempts); |
332 | mutex_unlock(&md->mutex); |
333 | return count; |
334 | } |
335 | |
336 | static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct device_attribute *attr, char *buf) |
337 | { |
338 | struct w1_master *md = dev_to_w1_master(dev); |
339 | ssize_t count; |
340 | |
341 | mutex_lock(&md->mutex); |
342 | count = sprintf(buf, "%d\n", md->slave_count); |
343 | mutex_unlock(&md->mutex); |
344 | return count; |
345 | } |
346 | |
347 | static ssize_t w1_master_attribute_show_slaves(struct device *dev, |
348 | struct device_attribute *attr, char *buf) |
349 | { |
350 | struct w1_master *md = dev_to_w1_master(dev); |
351 | int c = PAGE_SIZE; |
352 | |
353 | mutex_lock(&md->mutex); |
354 | |
355 | if (md->slave_count == 0) |
356 | c -= snprintf(buf + PAGE_SIZE - c, c, "not found.\n"); |
357 | else { |
358 | struct list_head *ent, *n; |
359 | struct w1_slave *sl; |
360 | |
361 | list_for_each_safe(ent, n, &md->slist) { |
362 | sl = list_entry(ent, struct w1_slave, w1_slave_entry); |
363 | |
364 | c -= snprintf(buf + PAGE_SIZE - c, c, "%s\n", sl->name); |
365 | } |
366 | } |
367 | |
368 | mutex_unlock(&md->mutex); |
369 | |
370 | return PAGE_SIZE - c; |
371 | } |
372 | |
373 | static ssize_t w1_master_attribute_show_add(struct device *dev, |
374 | struct device_attribute *attr, char *buf) |
375 | { |
376 | int c = PAGE_SIZE; |
377 | c -= snprintf(buf+PAGE_SIZE - c, c, |
378 | "write device id xx-xxxxxxxxxxxx to add slave\n"); |
379 | return PAGE_SIZE - c; |
380 | } |
381 | |
382 | static int w1_atoreg_num(struct device *dev, const char *buf, size_t count, |
383 | struct w1_reg_num *rn) |
384 | { |
385 | unsigned int family; |
386 | unsigned long long id; |
387 | int i; |
388 | u64 rn64_le; |
389 | |
390 | /* The CRC value isn't read from the user because the sysfs directory |
391 | * doesn't include it and most messages from the bus search don't |
392 | * print it either. It would be unreasonable for the user to then |
393 | * provide it. |
394 | */ |
395 | const char *error_msg = "bad slave string format, expecting " |
396 | "ff-dddddddddddd\n"; |
397 | |
398 | if (buf[2] != '-') { |
399 | dev_err(dev, "%s", error_msg); |
400 | return -EINVAL; |
401 | } |
402 | i = sscanf(buf, "%02x-%012llx", &family, &id); |
403 | if (i != 2) { |
404 | dev_err(dev, "%s", error_msg); |
405 | return -EINVAL; |
406 | } |
407 | rn->family = family; |
408 | rn->id = id; |
409 | |
410 | rn64_le = cpu_to_le64(*(u64 *)rn); |
411 | rn->crc = w1_calc_crc8((u8 *)&rn64_le, 7); |
412 | |
413 | #if 0 |
414 | dev_info(dev, "With CRC device is %02x.%012llx.%02x.\n", |
415 | rn->family, (unsigned long long)rn->id, rn->crc); |
416 | #endif |
417 | |
418 | return 0; |
419 | } |
420 | |
421 | /* Searches the slaves in the w1_master and returns a pointer or NULL. |
422 | * Note: must hold the mutex |
423 | */ |
424 | static struct w1_slave *w1_slave_search_device(struct w1_master *dev, |
425 | struct w1_reg_num *rn) |
426 | { |
427 | struct w1_slave *sl; |
428 | list_for_each_entry(sl, &dev->slist, w1_slave_entry) { |
429 | if (sl->reg_num.family == rn->family && |
430 | sl->reg_num.id == rn->id && |
431 | sl->reg_num.crc == rn->crc) { |
432 | return sl; |
433 | } |
434 | } |
435 | return NULL; |
436 | } |
437 | |
438 | static ssize_t w1_master_attribute_store_add(struct device *dev, |
439 | struct device_attribute *attr, |
440 | const char *buf, size_t count) |
441 | { |
442 | struct w1_master *md = dev_to_w1_master(dev); |
443 | struct w1_reg_num rn; |
444 | struct w1_slave *sl; |
445 | ssize_t result = count; |
446 | |
447 | if (w1_atoreg_num(dev, buf, count, &rn)) |
448 | return -EINVAL; |
449 | |
450 | mutex_lock(&md->mutex); |
451 | sl = w1_slave_search_device(md, &rn); |
452 | /* It would be nice to do a targeted search one the one-wire bus |
453 | * for the new device to see if it is out there or not. But the |
454 | * current search doesn't support that. |
455 | */ |
456 | if (sl) { |
457 | dev_info(dev, "Device %s already exists\n", sl->name); |
458 | result = -EINVAL; |
459 | } else { |
460 | w1_attach_slave_device(md, &rn); |
461 | } |
462 | mutex_unlock(&md->mutex); |
463 | |
464 | return result; |
465 | } |
466 | |
467 | static ssize_t w1_master_attribute_show_remove(struct device *dev, |
468 | struct device_attribute *attr, char *buf) |
469 | { |
470 | int c = PAGE_SIZE; |
471 | c -= snprintf(buf+PAGE_SIZE - c, c, |
472 | "write device id xx-xxxxxxxxxxxx to remove slave\n"); |
473 | return PAGE_SIZE - c; |
474 | } |
475 | |
476 | static ssize_t w1_master_attribute_store_remove(struct device *dev, |
477 | struct device_attribute *attr, |
478 | const char *buf, size_t count) |
479 | { |
480 | struct w1_master *md = dev_to_w1_master(dev); |
481 | struct w1_reg_num rn; |
482 | struct w1_slave *sl; |
483 | ssize_t result = count; |
484 | |
485 | if (w1_atoreg_num(dev, buf, count, &rn)) |
486 | return -EINVAL; |
487 | |
488 | mutex_lock(&md->mutex); |
489 | sl = w1_slave_search_device(md, &rn); |
490 | if (sl) { |
491 | w1_slave_detach(sl); |
492 | } else { |
493 | dev_info(dev, "Device %02x-%012llx doesn't exists\n", rn.family, |
494 | (unsigned long long)rn.id); |
495 | result = -EINVAL; |
496 | } |
497 | mutex_unlock(&md->mutex); |
498 | |
499 | return result; |
500 | } |
501 | |
502 | #define W1_MASTER_ATTR_RO(_name, _mode) \ |
503 | struct device_attribute w1_master_attribute_##_name = \ |
504 | __ATTR(w1_master_##_name, _mode, \ |
505 | w1_master_attribute_show_##_name, NULL) |
506 | |
507 | #define W1_MASTER_ATTR_RW(_name, _mode) \ |
508 | struct device_attribute w1_master_attribute_##_name = \ |
509 | __ATTR(w1_master_##_name, _mode, \ |
510 | w1_master_attribute_show_##_name, \ |
511 | w1_master_attribute_store_##_name) |
512 | |
513 | static W1_MASTER_ATTR_RO(name, S_IRUGO); |
514 | static W1_MASTER_ATTR_RO(slaves, S_IRUGO); |
515 | static W1_MASTER_ATTR_RO(slave_count, S_IRUGO); |
516 | static W1_MASTER_ATTR_RO(max_slave_count, S_IRUGO); |
517 | static W1_MASTER_ATTR_RO(attempts, S_IRUGO); |
518 | static W1_MASTER_ATTR_RO(timeout, S_IRUGO); |
519 | static W1_MASTER_ATTR_RO(pointer, S_IRUGO); |
520 | static W1_MASTER_ATTR_RW(search, S_IRUGO | S_IWUSR | S_IWGRP); |
521 | static W1_MASTER_ATTR_RW(pullup, S_IRUGO | S_IWUSR | S_IWGRP); |
522 | static W1_MASTER_ATTR_RW(add, S_IRUGO | S_IWUSR | S_IWGRP); |
523 | static W1_MASTER_ATTR_RW(remove, S_IRUGO | S_IWUSR | S_IWGRP); |
524 | |
525 | static struct attribute *w1_master_default_attrs[] = { |
526 | &w1_master_attribute_name.attr, |
527 | &w1_master_attribute_slaves.attr, |
528 | &w1_master_attribute_slave_count.attr, |
529 | &w1_master_attribute_max_slave_count.attr, |
530 | &w1_master_attribute_attempts.attr, |
531 | &w1_master_attribute_timeout.attr, |
532 | &w1_master_attribute_pointer.attr, |
533 | &w1_master_attribute_search.attr, |
534 | &w1_master_attribute_pullup.attr, |
535 | &w1_master_attribute_add.attr, |
536 | &w1_master_attribute_remove.attr, |
537 | NULL |
538 | }; |
539 | |
540 | static struct attribute_group w1_master_defattr_group = { |
541 | .attrs = w1_master_default_attrs, |
542 | }; |
543 | |
544 | int w1_create_master_attributes(struct w1_master *master) |
545 | { |
546 | return sysfs_create_group(&master->dev.kobj, &w1_master_defattr_group); |
547 | } |
548 | |
549 | void w1_destroy_master_attributes(struct w1_master *master) |
550 | { |
551 | sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group); |
552 | } |
553 | |
554 | #ifdef CONFIG_HOTPLUG |
555 | static int w1_uevent(struct device *dev, struct kobj_uevent_env *env) |
556 | { |
557 | struct w1_master *md = NULL; |
558 | struct w1_slave *sl = NULL; |
559 | char *event_owner, *name; |
560 | int err = 0; |
561 | |
562 | if (dev->driver == &w1_master_driver) { |
563 | md = container_of(dev, struct w1_master, dev); |
564 | event_owner = "master"; |
565 | name = md->name; |
566 | } else if (dev->driver == &w1_slave_driver) { |
567 | sl = container_of(dev, struct w1_slave, dev); |
568 | event_owner = "slave"; |
569 | name = sl->name; |
570 | } else { |
571 | dev_dbg(dev, "Unknown event.\n"); |
572 | return -EINVAL; |
573 | } |
574 | |
575 | dev_dbg(dev, "Hotplug event for %s %s, bus_id=%s.\n", |
576 | event_owner, name, dev_name(dev)); |
577 | |
578 | if (dev->driver != &w1_slave_driver || !sl) |
579 | goto end; |
580 | |
581 | err = add_uevent_var(env, "W1_FID=%02X", sl->reg_num.family); |
582 | if (err) |
583 | goto end; |
584 | |
585 | err = add_uevent_var(env, "W1_SLAVE_ID=%024LX", |
586 | (unsigned long long)sl->reg_num.id); |
587 | end: |
588 | return err; |
589 | } |
590 | #else |
591 | static int w1_uevent(struct device *dev, struct kobj_uevent_env *env) |
592 | { |
593 | return 0; |
594 | } |
595 | #endif |
596 | |
597 | static int __w1_attach_slave_device(struct w1_slave *sl) |
598 | { |
599 | int err; |
600 | |
601 | sl->dev.parent = &sl->master->dev; |
602 | sl->dev.driver = &w1_slave_driver; |
603 | sl->dev.bus = &w1_bus_type; |
604 | sl->dev.release = &w1_slave_release; |
605 | |
606 | dev_set_name(&sl->dev, "%02x-%012llx", |
607 | (unsigned int) sl->reg_num.family, |
608 | (unsigned long long) sl->reg_num.id); |
609 | snprintf(&sl->name[0], sizeof(sl->name), |
610 | "%02x-%012llx", |
611 | (unsigned int) sl->reg_num.family, |
612 | (unsigned long long) sl->reg_num.id); |
613 | |
614 | dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__, |
615 | dev_name(&sl->dev), sl); |
616 | |
617 | err = device_register(&sl->dev); |
618 | if (err < 0) { |
619 | dev_err(&sl->dev, |
620 | "Device registration [%s] failed. err=%d\n", |
621 | dev_name(&sl->dev), err); |
622 | return err; |
623 | } |
624 | |
625 | /* Create "name" entry */ |
626 | err = device_create_file(&sl->dev, &w1_slave_attr_name); |
627 | if (err < 0) { |
628 | dev_err(&sl->dev, |
629 | "sysfs file creation for [%s] failed. err=%d\n", |
630 | dev_name(&sl->dev), err); |
631 | goto out_unreg; |
632 | } |
633 | |
634 | /* Create "id" entry */ |
635 | err = device_create_file(&sl->dev, &w1_slave_attr_id); |
636 | if (err < 0) { |
637 | dev_err(&sl->dev, |
638 | "sysfs file creation for [%s] failed. err=%d\n", |
639 | dev_name(&sl->dev), err); |
640 | goto out_rem1; |
641 | } |
642 | |
643 | /* if the family driver needs to initialize something... */ |
644 | if (sl->family->fops && sl->family->fops->add_slave && |
645 | ((err = sl->family->fops->add_slave(sl)) < 0)) { |
646 | dev_err(&sl->dev, |
647 | "sysfs file creation for [%s] failed. err=%d\n", |
648 | dev_name(&sl->dev), err); |
649 | goto out_rem2; |
650 | } |
651 | |
652 | list_add_tail(&sl->w1_slave_entry, &sl->master->slist); |
653 | |
654 | return 0; |
655 | |
656 | out_rem2: |
657 | device_remove_file(&sl->dev, &w1_slave_attr_id); |
658 | out_rem1: |
659 | device_remove_file(&sl->dev, &w1_slave_attr_name); |
660 | out_unreg: |
661 | device_unregister(&sl->dev); |
662 | return err; |
663 | } |
664 | |
665 | static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) |
666 | { |
667 | struct w1_slave *sl; |
668 | struct w1_family *f; |
669 | int err; |
670 | struct w1_netlink_msg msg; |
671 | |
672 | sl = kzalloc(sizeof(struct w1_slave), GFP_KERNEL); |
673 | if (!sl) { |
674 | dev_err(&dev->dev, |
675 | "%s: failed to allocate new slave device.\n", |
676 | __func__); |
677 | return -ENOMEM; |
678 | } |
679 | |
680 | |
681 | sl->owner = THIS_MODULE; |
682 | sl->master = dev; |
683 | set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); |
684 | |
685 | memset(&msg, 0, sizeof(msg)); |
686 | memcpy(&sl->reg_num, rn, sizeof(sl->reg_num)); |
687 | atomic_set(&sl->refcnt, 0); |
688 | init_completion(&sl->released); |
689 | |
690 | spin_lock(&w1_flock); |
691 | f = w1_family_registered(rn->family); |
692 | if (!f) { |
693 | f= &w1_default_family; |
694 | dev_info(&dev->dev, "Family %x for %02x.%012llx.%02x is not registered.\n", |
695 | rn->family, rn->family, |
696 | (unsigned long long)rn->id, rn->crc); |
697 | } |
698 | __w1_family_get(f); |
699 | spin_unlock(&w1_flock); |
700 | |
701 | sl->family = f; |
702 | |
703 | |
704 | err = __w1_attach_slave_device(sl); |
705 | if (err < 0) { |
706 | dev_err(&dev->dev, "%s: Attaching %s failed.\n", __func__, |
707 | sl->name); |
708 | w1_family_put(sl->family); |
709 | kfree(sl); |
710 | return err; |
711 | } |
712 | |
713 | sl->ttl = dev->slave_ttl; |
714 | dev->slave_count++; |
715 | |
716 | memcpy(msg.id.id, rn, sizeof(msg.id)); |
717 | msg.type = W1_SLAVE_ADD; |
718 | w1_netlink_send(dev, &msg); |
719 | |
720 | return 0; |
721 | } |
722 | |
723 | void w1_slave_detach(struct w1_slave *sl) |
724 | { |
725 | struct w1_netlink_msg msg; |
726 | |
727 | dev_dbg(&sl->dev, "%s: detaching %s [%p].\n", __func__, sl->name, sl); |
728 | |
729 | list_del(&sl->w1_slave_entry); |
730 | |
731 | if (sl->family->fops && sl->family->fops->remove_slave) |
732 | sl->family->fops->remove_slave(sl); |
733 | |
734 | memset(&msg, 0, sizeof(msg)); |
735 | memcpy(msg.id.id, &sl->reg_num, sizeof(msg.id)); |
736 | msg.type = W1_SLAVE_REMOVE; |
737 | w1_netlink_send(sl->master, &msg); |
738 | |
739 | device_remove_file(&sl->dev, &w1_slave_attr_id); |
740 | device_remove_file(&sl->dev, &w1_slave_attr_name); |
741 | device_unregister(&sl->dev); |
742 | |
743 | wait_for_completion(&sl->released); |
744 | kfree(sl); |
745 | } |
746 | |
747 | struct w1_master *w1_search_master_id(u32 id) |
748 | { |
749 | struct w1_master *dev; |
750 | int found = 0; |
751 | |
752 | mutex_lock(&w1_mlock); |
753 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { |
754 | if (dev->id == id) { |
755 | found = 1; |
756 | atomic_inc(&dev->refcnt); |
757 | break; |
758 | } |
759 | } |
760 | mutex_unlock(&w1_mlock); |
761 | |
762 | return (found)?dev:NULL; |
763 | } |
764 | |
765 | struct w1_slave *w1_search_slave(struct w1_reg_num *id) |
766 | { |
767 | struct w1_master *dev; |
768 | struct w1_slave *sl = NULL; |
769 | int found = 0; |
770 | |
771 | mutex_lock(&w1_mlock); |
772 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { |
773 | mutex_lock(&dev->mutex); |
774 | list_for_each_entry(sl, &dev->slist, w1_slave_entry) { |
775 | if (sl->reg_num.family == id->family && |
776 | sl->reg_num.id == id->id && |
777 | sl->reg_num.crc == id->crc) { |
778 | found = 1; |
779 | atomic_inc(&dev->refcnt); |
780 | atomic_inc(&sl->refcnt); |
781 | break; |
782 | } |
783 | } |
784 | mutex_unlock(&dev->mutex); |
785 | |
786 | if (found) |
787 | break; |
788 | } |
789 | mutex_unlock(&w1_mlock); |
790 | |
791 | return (found)?sl:NULL; |
792 | } |
793 | |
794 | void w1_reconnect_slaves(struct w1_family *f, int attach) |
795 | { |
796 | struct w1_slave *sl, *sln; |
797 | struct w1_master *dev; |
798 | |
799 | mutex_lock(&w1_mlock); |
800 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { |
801 | dev_dbg(&dev->dev, "Reconnecting slaves in device %s " |
802 | "for family %02x.\n", dev->name, f->fid); |
803 | mutex_lock(&dev->mutex); |
804 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { |
805 | /* If it is a new family, slaves with the default |
806 | * family driver and are that family will be |
807 | * connected. If the family is going away, devices |
808 | * matching that family are reconneced. |
809 | */ |
810 | if ((attach && sl->family->fid == W1_FAMILY_DEFAULT |
811 | && sl->reg_num.family == f->fid) || |
812 | (!attach && sl->family->fid == f->fid)) { |
813 | struct w1_reg_num rn; |
814 | |
815 | memcpy(&rn, &sl->reg_num, sizeof(rn)); |
816 | w1_slave_detach(sl); |
817 | |
818 | w1_attach_slave_device(dev, &rn); |
819 | } |
820 | } |
821 | dev_dbg(&dev->dev, "Reconnecting slaves in device %s " |
822 | "has been finished.\n", dev->name); |
823 | mutex_unlock(&dev->mutex); |
824 | } |
825 | mutex_unlock(&w1_mlock); |
826 | } |
827 | |
828 | void w1_slave_found(struct w1_master *dev, u64 rn) |
829 | { |
830 | struct w1_slave *sl; |
831 | struct w1_reg_num *tmp; |
832 | u64 rn_le = cpu_to_le64(rn); |
833 | |
834 | atomic_inc(&dev->refcnt); |
835 | |
836 | tmp = (struct w1_reg_num *) &rn; |
837 | |
838 | sl = w1_slave_search_device(dev, tmp); |
839 | if (sl) { |
840 | set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); |
841 | } else { |
842 | if (rn && tmp->crc == w1_calc_crc8((u8 *)&rn_le, 7)) |
843 | w1_attach_slave_device(dev, tmp); |
844 | } |
845 | |
846 | atomic_dec(&dev->refcnt); |
847 | } |
848 | |
849 | /** |
850 | * Performs a ROM Search & registers any devices found. |
851 | * The 1-wire search is a simple binary tree search. |
852 | * For each bit of the address, we read two bits and write one bit. |
853 | * The bit written will put to sleep all devies that don't match that bit. |
854 | * When the two reads differ, the direction choice is obvious. |
855 | * When both bits are 0, we must choose a path to take. |
856 | * When we can scan all 64 bits without having to choose a path, we are done. |
857 | * |
858 | * See "Application note 187 1-wire search algorithm" at www.maxim-ic.com |
859 | * |
860 | * @dev The master device to search |
861 | * @cb Function to call when a device is found |
862 | */ |
863 | void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb) |
864 | { |
865 | u64 last_rn, rn, tmp64; |
866 | int i, slave_count = 0; |
867 | int last_zero, last_device; |
868 | int search_bit, desc_bit; |
869 | u8 triplet_ret = 0; |
870 | |
871 | search_bit = 0; |
872 | rn = last_rn = 0; |
873 | last_device = 0; |
874 | last_zero = -1; |
875 | |
876 | desc_bit = 64; |
877 | |
878 | while ( !last_device && (slave_count++ < dev->max_slave_count) ) { |
879 | last_rn = rn; |
880 | rn = 0; |
881 | |
882 | /* |
883 | * Reset bus and all 1-wire device state machines |
884 | * so they can respond to our requests. |
885 | * |
886 | * Return 0 - device(s) present, 1 - no devices present. |
887 | */ |
888 | mutex_lock(&dev->bus_mutex); |
889 | if (w1_reset_bus(dev)) { |
890 | mutex_unlock(&dev->bus_mutex); |
891 | dev_dbg(&dev->dev, "No devices present on the wire.\n"); |
892 | break; |
893 | } |
894 | |
895 | /* Do fast search on single slave bus */ |
896 | if (dev->max_slave_count == 1) { |
897 | int rv; |
898 | w1_write_8(dev, W1_READ_ROM); |
899 | rv = w1_read_block(dev, (u8 *)&rn, 8); |
900 | mutex_unlock(&dev->bus_mutex); |
901 | |
902 | if (rv == 8 && rn) |
903 | cb(dev, rn); |
904 | |
905 | break; |
906 | } |
907 | |
908 | /* Start the search */ |
909 | w1_write_8(dev, search_type); |
910 | for (i = 0; i < 64; ++i) { |
911 | /* Determine the direction/search bit */ |
912 | if (i == desc_bit) |
913 | search_bit = 1; /* took the 0 path last time, so take the 1 path */ |
914 | else if (i > desc_bit) |
915 | search_bit = 0; /* take the 0 path on the next branch */ |
916 | else |
917 | search_bit = ((last_rn >> i) & 0x1); |
918 | |
919 | /** Read two bits and write one bit */ |
920 | triplet_ret = w1_triplet(dev, search_bit); |
921 | |
922 | /* quit if no device responded */ |
923 | if ( (triplet_ret & 0x03) == 0x03 ) |
924 | break; |
925 | |
926 | /* If both directions were valid, and we took the 0 path... */ |
927 | if (triplet_ret == 0) |
928 | last_zero = i; |
929 | |
930 | /* extract the direction taken & update the device number */ |
931 | tmp64 = (triplet_ret >> 2); |
932 | rn |= (tmp64 << i); |
933 | |
934 | if (kthread_should_stop()) { |
935 | mutex_unlock(&dev->bus_mutex); |
936 | dev_dbg(&dev->dev, "Abort w1_search\n"); |
937 | return; |
938 | } |
939 | } |
940 | mutex_unlock(&dev->bus_mutex); |
941 | |
942 | if ( (triplet_ret & 0x03) != 0x03 ) { |
943 | if ( (desc_bit == last_zero) || (last_zero < 0)) |
944 | last_device = 1; |
945 | desc_bit = last_zero; |
946 | cb(dev, rn); |
947 | } |
948 | } |
949 | } |
950 | |
951 | void w1_search_process_cb(struct w1_master *dev, u8 search_type, |
952 | w1_slave_found_callback cb) |
953 | { |
954 | struct w1_slave *sl, *sln; |
955 | |
956 | list_for_each_entry(sl, &dev->slist, w1_slave_entry) |
957 | clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); |
958 | |
959 | w1_search_devices(dev, search_type, cb); |
960 | |
961 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { |
962 | if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) |
963 | w1_slave_detach(sl); |
964 | else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags)) |
965 | sl->ttl = dev->slave_ttl; |
966 | } |
967 | |
968 | if (dev->search_count > 0) |
969 | dev->search_count--; |
970 | } |
971 | |
972 | static void w1_search_process(struct w1_master *dev, u8 search_type) |
973 | { |
974 | w1_search_process_cb(dev, search_type, w1_slave_found); |
975 | } |
976 | |
977 | int w1_process(void *data) |
978 | { |
979 | struct w1_master *dev = (struct w1_master *) data; |
980 | /* As long as w1_timeout is only set by a module parameter the sleep |
981 | * time can be calculated in jiffies once. |
982 | */ |
983 | const unsigned long jtime = msecs_to_jiffies(w1_timeout * 1000); |
984 | |
985 | while (!kthread_should_stop()) { |
986 | if (dev->search_count) { |
987 | mutex_lock(&dev->mutex); |
988 | w1_search_process(dev, W1_SEARCH); |
989 | mutex_unlock(&dev->mutex); |
990 | } |
991 | |
992 | try_to_freeze(); |
993 | __set_current_state(TASK_INTERRUPTIBLE); |
994 | |
995 | if (kthread_should_stop()) |
996 | break; |
997 | |
998 | /* Only sleep when the search is active. */ |
999 | if (dev->search_count) |
1000 | schedule_timeout(jtime); |
1001 | else |
1002 | schedule(); |
1003 | } |
1004 | |
1005 | atomic_dec(&dev->refcnt); |
1006 | |
1007 | return 0; |
1008 | } |
1009 | |
1010 | static int __init w1_init(void) |
1011 | { |
1012 | int retval; |
1013 | |
1014 | printk(KERN_INFO "Driver for 1-wire Dallas network protocol.\n"); |
1015 | |
1016 | w1_init_netlink(); |
1017 | |
1018 | retval = bus_register(&w1_bus_type); |
1019 | if (retval) { |
1020 | printk(KERN_ERR "Failed to register bus. err=%d.\n", retval); |
1021 | goto err_out_exit_init; |
1022 | } |
1023 | |
1024 | retval = driver_register(&w1_master_driver); |
1025 | if (retval) { |
1026 | printk(KERN_ERR |
1027 | "Failed to register master driver. err=%d.\n", |
1028 | retval); |
1029 | goto err_out_bus_unregister; |
1030 | } |
1031 | |
1032 | retval = driver_register(&w1_slave_driver); |
1033 | if (retval) { |
1034 | printk(KERN_ERR |
1035 | "Failed to register slave driver. err=%d.\n", |
1036 | retval); |
1037 | goto err_out_master_unregister; |
1038 | } |
1039 | |
1040 | return 0; |
1041 | |
1042 | #if 0 |
1043 | /* For undoing the slave register if there was a step after it. */ |
1044 | err_out_slave_unregister: |
1045 | driver_unregister(&w1_slave_driver); |
1046 | #endif |
1047 | |
1048 | err_out_master_unregister: |
1049 | driver_unregister(&w1_master_driver); |
1050 | |
1051 | err_out_bus_unregister: |
1052 | bus_unregister(&w1_bus_type); |
1053 | |
1054 | err_out_exit_init: |
1055 | return retval; |
1056 | } |
1057 | |
1058 | static void __exit w1_fini(void) |
1059 | { |
1060 | struct w1_master *dev; |
1061 | |
1062 | /* Set netlink removal messages and some cleanup */ |
1063 | list_for_each_entry(dev, &w1_masters, w1_master_entry) |
1064 | __w1_remove_master_device(dev); |
1065 | |
1066 | w1_fini_netlink(); |
1067 | |
1068 | driver_unregister(&w1_slave_driver); |
1069 | driver_unregister(&w1_master_driver); |
1070 | bus_unregister(&w1_bus_type); |
1071 | } |
1072 | |
1073 | module_init(w1_init); |
1074 | module_exit(w1_fini); |
1075 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9