onewire.c revision 1.19 1 /* $NetBSD: onewire.c,v 1.19 2020/04/14 13:36:51 macallan Exp $ */
2 /* $OpenBSD: onewire.c,v 1.1 2006/03/04 16:27:03 grange Exp $ */
3
4 /*-
5 * Copyright (c) 2019 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Andrew Doran.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /*
34 * Copyright (c) 2006 Alexander Yurchenko <grange (at) openbsd.org>
35 *
36 * Permission to use, copy, modify, and distribute this software for any
37 * purpose with or without fee is hereby granted, provided that the above
38 * copyright notice and this permission notice appear in all copies.
39 *
40 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
41 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
42 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
43 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
44 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
45 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
46 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
47 */
48
49 #include <sys/cdefs.h>
50 __KERNEL_RCSID(0, "$NetBSD: onewire.c,v 1.19 2020/04/14 13:36:51 macallan Exp $");
51
52 /*
53 * 1-Wire bus driver.
54 */
55
56 #include <sys/param.h>
57 #include <sys/systm.h>
58 #include <sys/conf.h>
59 #include <sys/device.h>
60 #include <sys/kernel.h>
61 #include <sys/kthread.h>
62 #include <sys/kmem.h>
63 #include <sys/proc.h>
64 #include <sys/queue.h>
65 #include <sys/module.h>
66
67 #include "opt_onewire.h"
68
69 #include <dev/onewire/onewirereg.h>
70 #include <dev/onewire/onewirevar.h>
71
72 #ifdef ONEWIRE_DEBUG
73 #define DPRINTF(x) printf x
74 #else
75 #define DPRINTF(x)
76 #endif
77
78 int onewire_maxdevs = 8;
79 int onewire_scantime = 10; /* was 3 seconds - too often */
80
81 struct onewire_softc {
82 device_t sc_dev;
83 struct onewire_bus * sc_bus;
84 kmutex_t sc_lock;
85 kcondvar_t sc_scancv;
86 struct lwp * sc_thread;
87 TAILQ_HEAD(, onewire_device) sc_devs;
88 int sc_dying;
89 };
90
91 struct onewire_device {
92 TAILQ_ENTRY(onewire_device) d_list;
93 device_t d_dev;
94 u_int64_t d_rom;
95 bool d_present;
96 };
97
98 static int onewire_match(device_t, cfdata_t, void *);
99 static void onewire_attach(device_t, device_t, void *);
100 static int onewire_detach(device_t, int);
101 static int onewire_activate(device_t, enum devact);
102 int onewire_print(void *, const char *);
103
104 static void onewire_thread(void *);
105 static void onewire_scan(struct onewire_softc *);
106
107 CFATTACH_DECL_NEW(onewire, sizeof(struct onewire_softc),
108 onewire_match, onewire_attach, onewire_detach, onewire_activate);
109
110 extern struct cfdriver onewire_cd;
111
112 static int
113 onewire_match(device_t parent, cfdata_t cf, void *aux)
114 {
115 return 1;
116 }
117
118 static void
119 onewire_attach(device_t parent, device_t self, void *aux)
120 {
121 struct onewire_softc *sc = device_private(self);
122 struct onewirebus_attach_args *oba = aux;
123
124 sc->sc_dev = self;
125 sc->sc_bus = oba->oba_bus;
126 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
127 cv_init(&sc->sc_scancv, "owscan");
128 TAILQ_INIT(&sc->sc_devs);
129
130 aprint_normal("\n");
131
132 if (kthread_create(PRI_NONE, KTHREAD_MUSTJOIN | KTHREAD_MPSAFE, NULL,
133 onewire_thread, sc, &sc->sc_thread, "%s", device_xname(self)) != 0) {
134 aprint_error_dev(self, "can't create kernel thread\n");
135 /* Normally the kthread destroys these. */
136 mutex_destroy(&sc->sc_lock);
137 cv_destroy(&sc->sc_scancv);
138 }
139 }
140
141 static int
142 onewire_detach(device_t self, int flags)
143 {
144 struct onewire_softc *sc = device_private(self);
145 int rv;
146
147 if (sc->sc_thread != NULL) {
148 mutex_enter(&sc->sc_lock);
149 sc->sc_dying = 1;
150 cv_broadcast(&sc->sc_scancv);
151 mutex_exit(&sc->sc_lock);
152 /* Must no longer touch sc_lock nor sc_scancv. */
153 kthread_join(sc->sc_thread);
154 }
155
156 //rv = config_detach_children(self, flags);
157 rv = 0; /* XXX riz */
158
159 return rv;
160 }
161
162 static int
163 onewire_activate(device_t self, enum devact act)
164 {
165 struct onewire_softc *sc = device_private(self);
166
167 switch (act) {
168 case DVACT_DEACTIVATE:
169 sc->sc_dying = 1;
170 return 0;
171 default:
172 return EOPNOTSUPP;
173 }
174 }
175
176 int
177 onewire_print(void *aux, const char *pnp)
178 {
179 struct onewire_attach_args *oa = aux;
180 const char *famname;
181
182 if (pnp == NULL)
183 aprint_normal(" ");
184
185 famname = onewire_famname(ONEWIRE_ROM_FAMILY_TYPE(oa->oa_rom));
186 if (famname == NULL)
187 aprint_normal("family 0x%02x",
188 (uint)ONEWIRE_ROM_FAMILY_TYPE(oa->oa_rom));
189 else
190 aprint_normal("\"%s\"", famname);
191 aprint_normal(" sn %012" PRIx64, ONEWIRE_ROM_SN(oa->oa_rom));
192
193 if (pnp != NULL)
194 aprint_normal(" at %s", pnp);
195
196 return UNCONF;
197 }
198
199 int
200 onewirebus_print(void *aux, const char *pnp)
201 {
202 if (pnp != NULL)
203 aprint_normal("onewire at %s", pnp);
204
205 return UNCONF;
206 }
207
208 void
209 onewire_lock(void *arg)
210 {
211 struct onewire_softc *sc = arg;
212
213 mutex_enter(&sc->sc_lock);
214 }
215
216 void
217 onewire_unlock(void *arg)
218 {
219 struct onewire_softc *sc = arg;
220
221 mutex_exit(&sc->sc_lock);
222 }
223
224 int
225 onewire_reset(void *arg)
226 {
227 struct onewire_softc *sc = arg;
228 struct onewire_bus *bus = sc->sc_bus;
229
230 KASSERT(mutex_owned(&sc->sc_lock));
231
232 return bus->bus_reset(bus->bus_cookie);
233 }
234
235 int
236 onewire_read_bit(void *arg)
237 {
238 struct onewire_softc *sc = arg;
239 struct onewire_bus *bus = sc->sc_bus;
240
241 KASSERT(mutex_owned(&sc->sc_lock));
242
243 return bus->bus_read_bit(bus->bus_cookie);
244 }
245
246 void
247 onewire_write_bit(void *arg, int value)
248 {
249 struct onewire_softc *sc = arg;
250 struct onewire_bus *bus = sc->sc_bus;
251
252 KASSERT(mutex_owned(&sc->sc_lock));
253
254 bus->bus_write_bit(bus->bus_cookie, value);
255 }
256
257 int
258 onewire_read_byte(void *arg)
259 {
260 struct onewire_softc *sc = arg;
261 struct onewire_bus *bus = sc->sc_bus;
262 uint8_t value = 0;
263 int i;
264
265 KASSERT(mutex_owned(&sc->sc_lock));
266
267 if (bus->bus_read_byte != NULL)
268 return bus->bus_read_byte(bus->bus_cookie);
269
270 for (i = 0; i < 8; i++)
271 value |= (bus->bus_read_bit(bus->bus_cookie) << i);
272
273 return value;
274 }
275
276 void
277 onewire_write_byte(void *arg, int value)
278 {
279 struct onewire_softc *sc = arg;
280 struct onewire_bus *bus = sc->sc_bus;
281 int i;
282
283 KASSERT(mutex_owned(&sc->sc_lock));
284
285 if (bus->bus_write_byte != NULL)
286 return bus->bus_write_byte(bus->bus_cookie, value);
287
288 for (i = 0; i < 8; i++)
289 bus->bus_write_bit(bus->bus_cookie, (value >> i) & 0x1);
290 }
291
292 int
293 onewire_triplet(void *arg, int dir)
294 {
295 struct onewire_softc *sc = arg;
296 struct onewire_bus *bus = sc->sc_bus;
297 int rv;
298
299 KASSERT(mutex_owned(&sc->sc_lock));
300
301 if (bus->bus_triplet != NULL)
302 return bus->bus_triplet(bus->bus_cookie, dir);
303
304 rv = bus->bus_read_bit(bus->bus_cookie);
305 rv <<= 1;
306 rv |= bus->bus_read_bit(bus->bus_cookie);
307
308 switch (rv) {
309 case 0x0:
310 bus->bus_write_bit(bus->bus_cookie, dir);
311 break;
312 case 0x1:
313 bus->bus_write_bit(bus->bus_cookie, 0);
314 break;
315 default:
316 bus->bus_write_bit(bus->bus_cookie, 1);
317 }
318
319 return rv;
320 }
321
322 void
323 onewire_read_block(void *arg, void *buf, int len)
324 {
325 struct onewire_softc *sc = arg;
326 uint8_t *p = buf;
327
328 KASSERT(mutex_owned(&sc->sc_lock));
329
330 while (len--)
331 *p++ = onewire_read_byte(sc);
332 }
333
334 void
335 onewire_write_block(void *arg, const void *buf, int len)
336 {
337 struct onewire_softc *sc = arg;
338 const uint8_t *p = buf;
339
340 KASSERT(mutex_owned(&sc->sc_lock));
341
342 while (len--)
343 onewire_write_byte(sc, *p++);
344 }
345
346 void
347 onewire_matchrom(void *arg, u_int64_t rom)
348 {
349 struct onewire_softc *sc = arg;
350 int i;
351
352 KASSERT(mutex_owned(&sc->sc_lock));
353
354 onewire_write_byte(sc, ONEWIRE_CMD_MATCH_ROM);
355 for (i = 0; i < 8; i++)
356 onewire_write_byte(sc, (rom >> (i * 8)) & 0xff);
357 }
358
359 static void
360 onewire_thread(void *arg)
361 {
362 struct onewire_softc *sc = arg;
363 int unit, dly;
364
365 /*
366 * There can be many onewire busses, potentially funneled through
367 * few GPIO controllers. To avoid a thundering herd of kthreads and
368 * resulting contention for the GPIO controller, spread the probes
369 * out across an 8 second window. The kthreads could converge later
370 * due to timing effects.
371 */
372 unit = device_unit(sc->sc_dev);
373 dly = (unit & 0x07) * hz + ((unit >> 3) * hz >> 3) + 1;
374 (void)kpause("owdly", false, dly, NULL);
375
376 mutex_enter(&sc->sc_lock);
377 while (!sc->sc_dying) {
378 onewire_scan(sc);
379 (void)cv_timedwait(&sc->sc_scancv, &sc->sc_lock,
380 onewire_scantime * hz);
381 }
382 mutex_exit(&sc->sc_lock);
383
384 /* Caller has set sc_dying and will no longer touch these. */
385 cv_destroy(&sc->sc_scancv);
386 mutex_destroy(&sc->sc_lock);
387 kthread_exit(0);
388 }
389
390 static void
391 onewire_scan(struct onewire_softc *sc)
392 {
393 struct onewire_device *d, *next, *nd;
394 struct onewire_attach_args oa;
395 int search = 1, count = 0, present;
396 int dir, rv;
397 uint64_t mask, rom = 0, lastrom;
398 uint8_t data[8];
399 int i, i0 = -1, lastd = -1;
400
401 TAILQ_FOREACH(d, &sc->sc_devs, d_list) {
402 d->d_present = false;
403 KASSERT(d->d_dev != NULL);
404 }
405
406 KASSERT(mutex_owned(&sc->sc_lock));
407 KASSERT(curlwp == sc->sc_thread);
408
409 while (search && count++ < onewire_maxdevs) {
410 /*
411 * Reset the bus, allowing for one retry if reset fails. If
412 * there's no presence pulse don't search for any devices.
413 */
414 if (onewire_reset(sc) != 0) {
415 DPRINTF(("%s: scan: no presence pulse\n",
416 device_xname(sc->sc_dev)));
417 if (onewire_reset(sc) != 0) {
418 DPRINTF(("%s: scan: retry failed\n",
419 device_xname(sc->sc_dev)));
420 break;
421 }
422 }
423
424 /*
425 * Start new search. Go through the previous path to
426 * the point we made a decision last time and make an
427 * opposite decision. If we didn't make any decision
428 * stop searching.
429 */
430 search = 0;
431 lastrom = rom;
432 rom = 0;
433 onewire_write_byte(sc, ONEWIRE_CMD_SEARCH_ROM);
434 for (i = 0,i0 = -1; i < 64; i++) {
435 dir = (lastrom >> i) & 0x1;
436 if (i == lastd)
437 dir = 1;
438 else if (i > lastd)
439 dir = 0;
440 rv = onewire_triplet(sc, dir);
441 switch (rv) {
442 case 0x0:
443 if (i != lastd) {
444 if (dir == 0)
445 i0 = i;
446 search = 1;
447 }
448 mask = dir;
449 break;
450 case 0x1:
451 mask = 0;
452 break;
453 case 0x2:
454 mask = 1;
455 break;
456 default:
457 DPRINTF(("%s: scan: triplet error 0x%x, "
458 "step %d\n",
459 device_xname(sc->sc_dev), rv, i));
460 return;
461 }
462 rom |= (mask << i);
463 }
464 lastd = i0;
465
466 /*
467 * Yield processor, but continue to hold the lock
468 * so that scan is not interrupted.
469 */
470 (void)kpause("owscan", false, 1, NULL);
471
472 if (rom == 0)
473 continue;
474
475 /*
476 * The last byte of the ROM code contains a CRC calculated
477 * from the first 7 bytes. Re-calculate it to make sure
478 * we found a valid device.
479 */
480 for (i = 0; i < 8; i++)
481 data[i] = (rom >> (i * 8)) & 0xff;
482 if (onewire_crc(data, 7) != data[7])
483 continue;
484
485 /*
486 * Go through the list of attached devices to see if we
487 * found a new one.
488 */
489 present = 0;
490 TAILQ_FOREACH(d, &sc->sc_devs, d_list) {
491 if (d->d_rom == rom) {
492 d->d_present = true;
493 present = 1;
494 break;
495 }
496 }
497 if (!present) {
498 nd = kmem_alloc(sizeof(*nd), KM_SLEEP);
499 nd->d_dev = NULL;
500 nd->d_rom = rom;
501 nd->d_present = true;
502 TAILQ_INSERT_TAIL(&sc->sc_devs, nd, d_list);
503 }
504 }
505
506 /*
507 * Detach disappeared devices, and attach new devices. Drop the
508 * lock when doing this in order to prevent lock order reversal
509 * against sysmon. This is safe because nothing other than this
510 * kthread modifies our device list.
511 */
512 for (d = TAILQ_FIRST(&sc->sc_devs); d != NULL; d = next) {
513 next = TAILQ_NEXT(d, d_list);
514 if (!d->d_present) {
515 mutex_exit(&sc->sc_lock);
516
517 KERNEL_LOCK(1, NULL); /* XXXSMP */
518 config_detach(d->d_dev, DETACH_FORCE);
519 d->d_dev = NULL;
520 KERNEL_UNLOCK_ONE(NULL); /* XXXSMP */
521
522 mutex_enter(&sc->sc_lock);
523 } else if (d->d_dev == NULL) {
524 memset(&oa, 0, sizeof(oa));
525 oa.oa_onewire = sc;
526 oa.oa_rom = d->d_rom;
527 mutex_exit(&sc->sc_lock);
528
529 KERNEL_LOCK(1, NULL); /* XXXSMP */
530 d->d_dev = config_found(sc->sc_dev, &oa, onewire_print);
531 KERNEL_UNLOCK_ONE(NULL); /* XXXSMP */
532
533 mutex_enter(&sc->sc_lock);
534 }
535 if (d->d_dev == NULL) {
536 TAILQ_REMOVE(&sc->sc_devs, d, d_list);
537 kmem_free(d, sizeof(*d));
538 }
539 }
540 }
541
542 MODULE(MODULE_CLASS_DRIVER, onewire, NULL);
543
544 #ifdef _MODULE
545 #include "ioconf.c"
546 #endif
547
548 static int
549 onewire_modcmd(modcmd_t cmd, void *opaque)
550 {
551 int error;
552
553 error = 0;
554 switch (cmd) {
555 case MODULE_CMD_INIT:
556 #ifdef _MODULE
557 error = config_init_component(cfdriver_ioconf_onewire,
558 cfattach_ioconf_onewire, cfdata_ioconf_onewire);
559 if (error)
560 aprint_error("%s: unable to init component\n",
561 onewire_cd.cd_name);
562 #endif
563 break;
564 case MODULE_CMD_FINI:
565 #ifdef _MODULE
566 config_fini_component(cfdriver_ioconf_onewire,
567 cfattach_ioconf_onewire, cfdata_ioconf_onewire);
568 #endif
569 break;
570 default:
571 error = ENOTTY;
572 }
573 return error;
574 }
575