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