1 /* $NetBSD: onewire.c,v 1.22 2021/08/07 16:19:14 thorpej 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@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.22 2021/08/07 16:19:14 thorpej 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 #ifdef _KERNEL_OPT 68 #include "opt_onewire.h" 69 #endif 70 71 #include <dev/onewire/onewirereg.h> 72 #include <dev/onewire/onewirevar.h> 73 74 #ifdef ONEWIRE_DEBUG 75 #define DPRINTF(x) printf x 76 #else 77 #define DPRINTF(x) 78 #endif 79 80 int onewire_maxdevs = 8; 81 int onewire_scantime = 10; /* was 3 seconds - too often */ 82 83 struct onewire_softc { 84 device_t sc_dev; 85 struct onewire_bus * sc_bus; 86 kmutex_t sc_lock; 87 kcondvar_t sc_scancv; 88 struct lwp * sc_thread; 89 TAILQ_HEAD(, onewire_device) sc_devs; 90 int sc_dying; 91 }; 92 93 struct onewire_device { 94 TAILQ_ENTRY(onewire_device) d_list; 95 device_t d_dev; 96 u_int64_t d_rom; 97 bool d_present; 98 }; 99 100 static int onewire_match(device_t, cfdata_t, void *); 101 static void onewire_attach(device_t, device_t, void *); 102 static int onewire_detach(device_t, int); 103 static int onewire_activate(device_t, enum devact); 104 int onewire_print(void *, const char *); 105 106 static void onewire_thread(void *); 107 static void onewire_scan(struct onewire_softc *); 108 109 CFATTACH_DECL_NEW(onewire, sizeof(struct onewire_softc), 110 onewire_match, onewire_attach, onewire_detach, onewire_activate); 111 112 extern struct cfdriver onewire_cd; 113 114 static int 115 onewire_match(device_t parent, cfdata_t cf, void *aux) 116 { 117 return 1; 118 } 119 120 static void 121 onewire_attach(device_t parent, device_t self, void *aux) 122 { 123 struct onewire_softc *sc = device_private(self); 124 struct onewirebus_attach_args *oba = aux; 125 126 sc->sc_dev = self; 127 sc->sc_bus = oba->oba_bus; 128 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 129 cv_init(&sc->sc_scancv, "owscan"); 130 TAILQ_INIT(&sc->sc_devs); 131 132 aprint_normal("\n"); 133 134 if (kthread_create(PRI_NONE, KTHREAD_MUSTJOIN | KTHREAD_MPSAFE, NULL, 135 onewire_thread, sc, &sc->sc_thread, "%s", device_xname(self)) != 0) { 136 aprint_error_dev(self, "can't create kernel thread\n"); 137 /* Normally the kthread destroys these. */ 138 mutex_destroy(&sc->sc_lock); 139 cv_destroy(&sc->sc_scancv); 140 } 141 } 142 143 static int 144 onewire_detach(device_t self, int flags) 145 { 146 struct onewire_softc *sc = device_private(self); 147 int rv; 148 149 if (sc->sc_thread != NULL) { 150 mutex_enter(&sc->sc_lock); 151 sc->sc_dying = 1; 152 cv_broadcast(&sc->sc_scancv); 153 mutex_exit(&sc->sc_lock); 154 /* Must no longer touch sc_lock nor sc_scancv. */ 155 kthread_join(sc->sc_thread); 156 } 157 158 //rv = config_detach_children(self, flags); 159 rv = 0; /* XXX riz */ 160 161 return rv; 162 } 163 164 static int 165 onewire_activate(device_t self, enum devact act) 166 { 167 struct onewire_softc *sc = device_private(self); 168 169 switch (act) { 170 case DVACT_DEACTIVATE: 171 sc->sc_dying = 1; 172 return 0; 173 default: 174 return EOPNOTSUPP; 175 } 176 } 177 178 int 179 onewire_print(void *aux, const char *pnp) 180 { 181 struct onewire_attach_args *oa = aux; 182 const char *famname; 183 184 if (pnp == NULL) 185 aprint_normal(" "); 186 187 famname = onewire_famname(ONEWIRE_ROM_FAMILY_TYPE(oa->oa_rom)); 188 if (famname == NULL) 189 aprint_normal("family 0x%02x", 190 (uint)ONEWIRE_ROM_FAMILY_TYPE(oa->oa_rom)); 191 else 192 aprint_normal("\"%s\"", famname); 193 aprint_normal(" sn %012" PRIx64, ONEWIRE_ROM_SN(oa->oa_rom)); 194 195 if (pnp != NULL) 196 aprint_normal(" at %s", pnp); 197 198 return UNCONF; 199 } 200 201 int 202 onewirebus_print(void *aux, const char *pnp) 203 { 204 if (pnp != NULL) 205 aprint_normal("onewire at %s", pnp); 206 207 return UNCONF; 208 } 209 210 void 211 onewire_lock(void *arg) 212 { 213 struct onewire_softc *sc = arg; 214 215 mutex_enter(&sc->sc_lock); 216 } 217 218 void 219 onewire_unlock(void *arg) 220 { 221 struct onewire_softc *sc = arg; 222 223 mutex_exit(&sc->sc_lock); 224 } 225 226 int 227 onewire_reset(void *arg) 228 { 229 struct onewire_softc *sc = arg; 230 struct onewire_bus *bus = sc->sc_bus; 231 232 KASSERT(mutex_owned(&sc->sc_lock)); 233 234 return bus->bus_reset(bus->bus_cookie); 235 } 236 237 int 238 onewire_read_bit(void *arg) 239 { 240 struct onewire_softc *sc = arg; 241 struct onewire_bus *bus = sc->sc_bus; 242 243 KASSERT(mutex_owned(&sc->sc_lock)); 244 245 return bus->bus_read_bit(bus->bus_cookie); 246 } 247 248 void 249 onewire_write_bit(void *arg, int value) 250 { 251 struct onewire_softc *sc = arg; 252 struct onewire_bus *bus = sc->sc_bus; 253 254 KASSERT(mutex_owned(&sc->sc_lock)); 255 256 bus->bus_write_bit(bus->bus_cookie, value); 257 } 258 259 int 260 onewire_read_byte(void *arg) 261 { 262 struct onewire_softc *sc = arg; 263 struct onewire_bus *bus = sc->sc_bus; 264 uint8_t value = 0; 265 int i; 266 267 KASSERT(mutex_owned(&sc->sc_lock)); 268 269 if (bus->bus_read_byte != NULL) 270 return bus->bus_read_byte(bus->bus_cookie); 271 272 for (i = 0; i < 8; i++) 273 value |= (bus->bus_read_bit(bus->bus_cookie) << i); 274 275 return value; 276 } 277 278 void 279 onewire_write_byte(void *arg, int value) 280 { 281 struct onewire_softc *sc = arg; 282 struct onewire_bus *bus = sc->sc_bus; 283 int i; 284 285 KASSERT(mutex_owned(&sc->sc_lock)); 286 287 if (bus->bus_write_byte != NULL) 288 return bus->bus_write_byte(bus->bus_cookie, value); 289 290 for (i = 0; i < 8; i++) 291 bus->bus_write_bit(bus->bus_cookie, (value >> i) & 0x1); 292 } 293 294 int 295 onewire_triplet(void *arg, int dir) 296 { 297 struct onewire_softc *sc = arg; 298 struct onewire_bus *bus = sc->sc_bus; 299 int rv; 300 301 KASSERT(mutex_owned(&sc->sc_lock)); 302 303 if (bus->bus_triplet != NULL) 304 return bus->bus_triplet(bus->bus_cookie, dir); 305 306 rv = bus->bus_read_bit(bus->bus_cookie); 307 rv <<= 1; 308 rv |= bus->bus_read_bit(bus->bus_cookie); 309 310 switch (rv) { 311 case 0x0: 312 bus->bus_write_bit(bus->bus_cookie, dir); 313 break; 314 case 0x1: 315 bus->bus_write_bit(bus->bus_cookie, 0); 316 break; 317 default: 318 bus->bus_write_bit(bus->bus_cookie, 1); 319 } 320 321 return rv; 322 } 323 324 void 325 onewire_read_block(void *arg, void *buf, int len) 326 { 327 struct onewire_softc *sc = arg; 328 uint8_t *p = buf; 329 330 KASSERT(mutex_owned(&sc->sc_lock)); 331 332 while (len--) 333 *p++ = onewire_read_byte(sc); 334 } 335 336 void 337 onewire_write_block(void *arg, const void *buf, int len) 338 { 339 struct onewire_softc *sc = arg; 340 const uint8_t *p = buf; 341 342 KASSERT(mutex_owned(&sc->sc_lock)); 343 344 while (len--) 345 onewire_write_byte(sc, *p++); 346 } 347 348 void 349 onewire_matchrom(void *arg, u_int64_t rom) 350 { 351 struct onewire_softc *sc = arg; 352 int i; 353 354 KASSERT(mutex_owned(&sc->sc_lock)); 355 356 onewire_write_byte(sc, ONEWIRE_CMD_MATCH_ROM); 357 for (i = 0; i < 8; i++) 358 onewire_write_byte(sc, (rom >> (i * 8)) & 0xff); 359 } 360 361 static void 362 onewire_thread(void *arg) 363 { 364 struct onewire_softc *sc = arg; 365 int unit, dly; 366 367 /* 368 * There can be many onewire busses, potentially funneled through 369 * few GPIO controllers. To avoid a thundering herd of kthreads and 370 * resulting contention for the GPIO controller, spread the probes 371 * out across an 8 second window. The kthreads could converge later 372 * due to timing effects. 373 */ 374 unit = device_unit(sc->sc_dev); 375 dly = (unit & 0x07) * hz + ((unit >> 3) * hz >> 3) + 1; 376 (void)kpause("owdly", false, dly, NULL); 377 378 mutex_enter(&sc->sc_lock); 379 while (!sc->sc_dying) { 380 onewire_scan(sc); 381 (void)cv_timedwait(&sc->sc_scancv, &sc->sc_lock, 382 onewire_scantime * hz); 383 } 384 mutex_exit(&sc->sc_lock); 385 386 /* Caller has set sc_dying and will no longer touch these. */ 387 cv_destroy(&sc->sc_scancv); 388 mutex_destroy(&sc->sc_lock); 389 kthread_exit(0); 390 } 391 392 static void 393 onewire_scan(struct onewire_softc *sc) 394 { 395 struct onewire_device *d, *next, *nd; 396 struct onewire_attach_args oa; 397 int search = 1, count = 0, present; 398 int dir, rv; 399 uint64_t mask, rom = 0, lastrom; 400 uint8_t data[8]; 401 int i, i0 = -1, lastd = -1; 402 403 TAILQ_FOREACH(d, &sc->sc_devs, d_list) { 404 d->d_present = false; 405 KASSERT(d->d_dev != NULL); 406 } 407 408 KASSERT(mutex_owned(&sc->sc_lock)); 409 KASSERT(curlwp == sc->sc_thread); 410 411 while (search && count++ < onewire_maxdevs) { 412 /* 413 * Reset the bus, allowing for one retry if reset fails. If 414 * there's no presence pulse don't search for any devices. 415 */ 416 if (onewire_reset(sc) != 0) { 417 DPRINTF(("%s: scan: no presence pulse\n", 418 device_xname(sc->sc_dev))); 419 if (onewire_reset(sc) != 0) { 420 DPRINTF(("%s: scan: retry failed\n", 421 device_xname(sc->sc_dev))); 422 break; 423 } 424 } 425 426 /* 427 * Start new search. Go through the previous path to 428 * the point we made a decision last time and make an 429 * opposite decision. If we didn't make any decision 430 * stop searching. 431 */ 432 search = 0; 433 lastrom = rom; 434 rom = 0; 435 onewire_write_byte(sc, ONEWIRE_CMD_SEARCH_ROM); 436 for (i = 0,i0 = -1; i < 64; i++) { 437 dir = (lastrom >> i) & 0x1; 438 if (i == lastd) 439 dir = 1; 440 else if (i > lastd) 441 dir = 0; 442 rv = onewire_triplet(sc, dir); 443 switch (rv) { 444 case 0x0: 445 if (i != lastd) { 446 if (dir == 0) 447 i0 = i; 448 search = 1; 449 } 450 mask = dir; 451 break; 452 case 0x1: 453 mask = 0; 454 break; 455 case 0x2: 456 mask = 1; 457 break; 458 default: 459 DPRINTF(("%s: scan: triplet error 0x%x, " 460 "step %d\n", 461 device_xname(sc->sc_dev), rv, i)); 462 return; 463 } 464 rom |= (mask << i); 465 } 466 lastd = i0; 467 468 /* 469 * Yield processor, but continue to hold the lock 470 * so that scan is not interrupted. 471 */ 472 (void)kpause("owscan", false, 1, NULL); 473 474 if (rom == 0) 475 continue; 476 477 /* 478 * The last byte of the ROM code contains a CRC calculated 479 * from the first 7 bytes. Re-calculate it to make sure 480 * we found a valid device. 481 */ 482 for (i = 0; i < 8; i++) 483 data[i] = (rom >> (i * 8)) & 0xff; 484 if (onewire_crc(data, 7) != data[7]) 485 continue; 486 487 /* 488 * Go through the list of attached devices to see if we 489 * found a new one. 490 */ 491 present = 0; 492 TAILQ_FOREACH(d, &sc->sc_devs, d_list) { 493 if (d->d_rom == rom) { 494 d->d_present = true; 495 present = 1; 496 break; 497 } 498 } 499 if (!present) { 500 nd = kmem_alloc(sizeof(*nd), KM_SLEEP); 501 nd->d_dev = NULL; 502 nd->d_rom = rom; 503 nd->d_present = true; 504 TAILQ_INSERT_TAIL(&sc->sc_devs, nd, d_list); 505 } 506 } 507 508 /* 509 * Detach disappeared devices, and attach new devices. Drop the 510 * lock when doing this in order to prevent lock order reversal 511 * against sysmon. This is safe because nothing other than this 512 * kthread modifies our device list. 513 */ 514 for (d = TAILQ_FIRST(&sc->sc_devs); d != NULL; d = next) { 515 next = TAILQ_NEXT(d, d_list); 516 if (!d->d_present) { 517 mutex_exit(&sc->sc_lock); 518 519 KERNEL_LOCK(1, NULL); /* XXXSMP */ 520 config_detach(d->d_dev, DETACH_FORCE); 521 d->d_dev = NULL; 522 KERNEL_UNLOCK_ONE(NULL); /* XXXSMP */ 523 524 mutex_enter(&sc->sc_lock); 525 } else if (d->d_dev == NULL) { 526 memset(&oa, 0, sizeof(oa)); 527 oa.oa_onewire = sc; 528 oa.oa_rom = d->d_rom; 529 mutex_exit(&sc->sc_lock); 530 531 KERNEL_LOCK(1, NULL); /* XXXSMP */ 532 d->d_dev = config_found(sc->sc_dev, &oa, onewire_print, 533 CFARGS_NONE); 534 KERNEL_UNLOCK_ONE(NULL); /* XXXSMP */ 535 536 mutex_enter(&sc->sc_lock); 537 } 538 if (d->d_dev == NULL) { 539 TAILQ_REMOVE(&sc->sc_devs, d, d_list); 540 kmem_free(d, sizeof(*d)); 541 } 542 } 543 } 544 545 MODULE(MODULE_CLASS_DRIVER, onewire, NULL); 546 547 #ifdef _MODULE 548 #include "ioconf.c" 549 #endif 550 551 static int 552 onewire_modcmd(modcmd_t cmd, void *opaque) 553 { 554 int error; 555 556 error = 0; 557 switch (cmd) { 558 case MODULE_CMD_INIT: 559 #ifdef _MODULE 560 error = config_init_component(cfdriver_ioconf_onewire, 561 cfattach_ioconf_onewire, cfdata_ioconf_onewire); 562 if (error) 563 aprint_error("%s: unable to init component\n", 564 onewire_cd.cd_name); 565 #endif 566 break; 567 case MODULE_CMD_FINI: 568 #ifdef _MODULE 569 config_fini_component(cfdriver_ioconf_onewire, 570 cfattach_ioconf_onewire, cfdata_ioconf_onewire); 571 #endif 572 break; 573 default: 574 error = ENOTTY; 575 } 576 return error; 577 } 578