Deleted Added
sdiff udiff text old ( 299973 ) new ( 300050 )
full compact
1/*-
2 * Copyright (c) 2015 M. Warner Losh <imp@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice unmodified, this list of conditions, and the following
10 * disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/dev/ow/ow.c 300050 2016-05-17 12:52:31Z eadler $");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/kernel.h>
33
34#include <sys/bus.h>
35#include <sys/errno.h>
36#include <sys/libkern.h>
37#include <sys/malloc.h>
38#include <sys/module.h>
39
40#include <dev/ow/ow.h>
41#include <dev/ow/owll.h>
42#include <dev/ow/own.h>
43
44/*
45 * lldev - link level device
46 * ndev - network / transport device (this module)
47 * pdev - presentation device (children of this module)
48 */
49
50typedef int ow_enum_fn(device_t, device_t);
51typedef int ow_found_fn(device_t, romid_t);
52
53struct ow_softc
54{
55 device_t dev; /* Newbus driver back pointer */
56 struct mtx mtx; /* bus mutex */
57 device_t owner; /* bus owner, if != NULL */
58};
59
60struct ow_devinfo
61{
62 romid_t romid;
63};
64
65static int ow_acquire_bus(device_t ndev, device_t pdev, int how);
66static void ow_release_bus(device_t ndev, device_t pdev);
67
68#define OW_LOCK(_sc) mtx_lock(&(_sc)->mtx)
69#define OW_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx)
70#define OW_LOCK_DESTROY(_sc) mtx_destroy(&_sc->mtx)
71#define OW_ASSERT_LOCKED(_sc) mtx_assert(&_sc->mtx, MA_OWNED)
72#define OW_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->mtx, MA_NOTOWNED)
73
74static MALLOC_DEFINE(M_OW, "ow", "House keeping data for 1wire bus");
75
76static struct ow_timing timing_regular = {
77 .t_slot = 60, /* 60 to 120 */
78 .t_low0 = 60, /* really 60 to 120 */
79 .t_low1 = 1, /* really 1 to 15 */
80 .t_release = 45, /* <= 45us */
81 .t_rec = 1, /* at least 1us */
82 .t_rdv = 15, /* 15us */
83 .t_rstl = 480, /* 480us or more */
84 .t_rsth = 480, /* 480us or more */
85 .t_pdl = 60, /* 60us to 240us */
86 .t_pdh = 60, /* 15us to 60us */
87 .t_lowr = 1, /* 1us */
88};
89
90/* NB: Untested */
91static struct ow_timing timing_overdrive = {
92 .t_slot = 11, /* 6us to 16us */
93 .t_low0 = 6, /* really 6 to 16 */
94 .t_low1 = 1, /* really 1 to 2 */
95 .t_release = 4, /* <= 4us */
96 .t_rec = 1, /* at least 1us */
97 .t_rdv = 2, /* 2us */
98 .t_rstl = 48, /* 48us to 80us */
99 .t_rsth = 48, /* 48us or more */
100 .t_pdl = 8, /* 8us to 24us */
101 .t_pdh = 2, /* 2us to 6us */
102 .t_lowr = 1, /* 1us */
103};
104
105static void
106ow_send_byte(device_t lldev, struct ow_timing *t, uint8_t byte)
107{
108 int i;
109
110 for (i = 0; i < 8; i++)
111 if (byte & (1 << i))
112 OWLL_WRITE_ONE(lldev, t);
113 else
114 OWLL_WRITE_ZERO(lldev, t);
115}
116
117static void
118ow_read_byte(device_t lldev, struct ow_timing *t, uint8_t *bytep)
119{
120 int i;
121 uint8_t byte = 0;
122 int bit;
123
124 for (i = 0; i < 8; i++) {
125 OWLL_READ_DATA(lldev, t, &bit);
126 byte |= bit << i;
127 }
128 *bytep = byte;
129}
130
131static int
132ow_send_command(device_t ndev, device_t pdev, struct ow_cmd *cmd)
133{
134 int present, i, bit, tries;
135 device_t lldev;
136 struct ow_timing *t;
137
138 lldev = device_get_parent(ndev);
139
140 /*
141 * Retry the reset a couple of times before giving up.
142 */
143 tries = 4;
144 do {
145 OWLL_RESET_AND_PRESENCE(lldev, &timing_regular, &present);
146 if (present == 1)
147 device_printf(ndev, "Reset said no device on bus?.\n");
148 } while (present == 1 && tries-- > 0);
149 if (present == 1) {
150 device_printf(ndev, "Reset said the device wasn't there.\n");
151 return ENOENT; /* No devices acked the RESET */
152 }
153 if (present == -1) {
154 device_printf(ndev, "Reset discovered bus wired wrong.\n");
155 return ENOENT;
156 }
157
158 for (i = 0; i < cmd->rom_len; i++)
159 ow_send_byte(lldev, &timing_regular, cmd->rom_cmd[i]);
160 for (i = 0; i < cmd->rom_read_len; i++)
161 ow_read_byte(lldev, &timing_regular, cmd->rom_read + i);
162 if (cmd->xpt_len) {
163 /*
164 * Per AN937, the reset pulse and ROM level are always
165 * done with the regular timings. Certain ROM commands
166 * put the device into overdrive mode for the remainder
167 * of the data transfer, which is why we have to pass the
168 * timings here. Commands that need to be handled like this
169 * are expected to be flagged by the client.
170 */
171 t = (cmd->flags & OW_FLAG_OVERDRIVE) ?
172 &timing_overdrive : &timing_regular;
173 for (i = 0; i < cmd->xpt_len; i++)
174 ow_send_byte(lldev, t, cmd->xpt_cmd[i]);
175 if (cmd->flags & OW_FLAG_READ_BIT) {
176 memset(cmd->xpt_read, 0, (cmd->xpt_read_len + 7) / 8);
177 for (i = 0; i < cmd->xpt_read_len; i++) {
178 OWLL_READ_DATA(lldev, t, &bit);
179 cmd->xpt_read[i / 8] |= bit << (i % 8);
180 }
181 } else {
182 for (i = 0; i < cmd->xpt_read_len; i++)
183 ow_read_byte(lldev, t, cmd->xpt_read + i);
184 }
185 }
186 return 0;
187}
188
189static int
190ow_search_rom(device_t lldev, device_t dev)
191{
192 struct ow_cmd cmd;
193
194 memset(&cmd, 0, sizeof(cmd));
195 cmd.rom_cmd[0] = SEARCH_ROM;
196 cmd.rom_len = 1;
197 return ow_send_command(lldev, dev, &cmd);
198}
199
200#if 0
201static int
202ow_alarm_search(device_t lldev, device_t dev)
203{
204 struct ow_cmd cmd;
205
206 memset(&cmd, 0, sizeof(cmd));
207 cmd.rom_cmd[0] = ALARM_SEARCH;
208 cmd.rom_len = 1;
209 return ow_send_command(lldev, dev, &cmd);
210}
211#endif
212
213static int
214ow_add_child(device_t dev, romid_t romid)
215{
216 struct ow_devinfo *di;
217 device_t child;
218
219 di = malloc(sizeof(*di), M_OW, M_WAITOK);
220 di->romid = romid;
221 child = device_add_child(dev, NULL, -1);
222 if (child == NULL) {
223 free(di, M_OW);
224 return ENOMEM;
225 }
226 device_set_ivars(child, di);
227 return (0);
228}
229
230static device_t
231ow_child_by_romid(device_t dev, romid_t romid)
232{
233 device_t *children, retval, child;
234 int nkid, i;
235 struct ow_devinfo *di;
236
237 if (device_get_children(dev, &children, &nkid) != 0)
238 return (NULL);
239 retval = NULL;
240 for (i = 0; i < nkid; i++) {
241 child = children[i];
242 di = device_get_ivars(child);
243 if (di->romid == romid) {
244 retval = child;
245 break;
246 }
247 }
248 free(children, M_TEMP);
249
250 return (retval);
251}
252
253/*
254 * CRC generator table -- taken from AN937 DOW CRC LOOKUP FUNCTION Table 2
255 */
256const uint8_t ow_crc_table[] = {
257 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
258 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
259 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
260 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
261 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
262 219, 133,103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
263 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
264 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
265 140,210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113,147, 205,
266 17, 79, 173, 243, 112, 46, 204, 146, 211,141, 111, 49, 178, 236, 14, 80,
267 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82,176, 238,
268 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
269 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
270 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
271 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
272 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53
273};
274
275/*
276 * Converted from DO_CRC page 131 ANN937
277 */
278static uint8_t
279ow_crc(device_t ndev, device_t pdev, uint8_t *buffer, size_t len)
280{
281 uint8_t crc = 0;
282 int i;
283
284 for (i = 0; i < len; i++)
285 crc = ow_crc_table[crc ^ buffer[i]];
286 return crc;
287}
288
289static int
290ow_check_crc(romid_t romid)
291{
292 return ow_crc(NULL, NULL, (uint8_t *)&romid, sizeof(romid)) == 0;
293}
294
295static int
296ow_device_found(device_t dev, romid_t romid)
297{
298
299 /* XXX Move this up into enumerate? */
300 /*
301 * All valid ROM IDs have a valid CRC. Check that first.
302 */
303 if (!ow_check_crc(romid)) {
304 device_printf(dev, "Device romid %8D failed CRC.\n",
305 &romid, ":");
306 return EINVAL;
307 }
308
309 /*
310 * If we've seen this child before, don't add a new one for it.
311 */
312 if (ow_child_by_romid(dev, romid) != NULL)
313 return 0;
314
315 return ow_add_child(dev, romid);
316}
317
318static int
319ow_enumerate(device_t dev, ow_enum_fn *enumfp, ow_found_fn *foundfp)
320{
321 device_t lldev = device_get_parent(dev);
322 int first, second, i, dir, prior, last, err, retries;
323 uint64_t probed, last_mask;
324 int sanity = 10;
325
326 prior = -1;
327 last_mask = 0;
328 retries = 0;
329 last = -2;
330 err = ow_acquire_bus(dev, dev, OWN_DONTWAIT);
331 if (err != 0)
332 return err;
333 while (last != -1) {
334 if (sanity-- < 0) {
335 printf("Reached the sanity limit\n");
336 return EIO;
337 }
338again:
339 probed = 0;
340 last = -1;
341
342 /*
343 * See AN397 section 5.II.C.3 for the algorithm (though a bit
344 * poorly stated). The search command forces each device to
345 * send ROM ID bits one at a time (first the bit, then the
346 * complement) the master (us) sends back a bit. If the
347 * device's bit doesn't match what we send back, that device
348 * stops sending bits back. So each time through we remember
349 * where we made the last decision (always 0). If there's a
350 * conflict there this time (and there will be in the absence
351 * of a hardware failure) we go with 1. This way, we prune the
352 * devices on the bus and wind up with a unique ROM. We know
353 * we're done when we detect no new conflicts. The same
354 * algorithm is used for devices in alarm state as well.
355 *
356 * In addition, experience has shown that sometimes devices
357 * stop responding in the middle of enumeration, so try this
358 * step again a few times when that happens. It is unclear if
359 * this is due to a nosiy electrical environment or some odd
360 * timing issue.
361 */
362
363 /*
364 * The enumeration command should be successfully sent, if not,
365 * we have big issues on the bus so punt. Lower layers report
366 * any unusual errors, so we don't need to here.
367 */
368 err = enumfp(dev, dev);
369 if (err != 0)
370 return (err);
371
372 for (i = 0; i < 64; i++) {
373 OWLL_READ_DATA(lldev, &timing_regular, &first);
374 OWLL_READ_DATA(lldev, &timing_regular, &second);
375 switch (first | second << 1) {
376 case 0: /* Conflict */
377 if (i < prior)
378 dir = (last_mask >> i) & 1;
379 else
380 dir = i == prior;
381
382 if (dir == 0)
383 last = i;
384 break;
385 case 1: /* 1 then 0 -> 1 for all */
386 dir = 1;
387 break;
388 case 2: /* 0 then 1 -> 0 for all */
389 dir = 0;
390 break;
391 case 3:
392 /*
393 * No device responded. This is unexpected, but
394 * experience has shown that on some platforms
395 * we miss a timing window, or otherwise have
396 * an issue. Start this step over. Since we've
397 * not updated prior yet, we can just jump to
398 * the top of the loop for a re-do of this step.
399 */
400 printf("oops, starting over\n");
401 if (++retries > 5)
402 return (EIO);
403 goto again;
404 default: /* NOTREACHED */
405 __unreachable();
406 }
407 if (dir) {
408 OWLL_WRITE_ONE(lldev, &timing_regular);
409 probed |= 1ull << i;
410 } else {
411 OWLL_WRITE_ZERO(lldev, &timing_regular);
412 }
413 }
414 retries = 0;
415 foundfp(dev, probed);
416 last_mask = probed;
417 prior = last;
418 }
419 ow_release_bus(dev, dev);
420
421 return (0);
422}
423
424static int
425ow_probe(device_t dev)
426{
427
428 device_set_desc(dev, "1 Wire Bus");
429 return (BUS_PROBE_GENERIC);
430}
431
432static int
433ow_attach(device_t ndev)
434{
435 struct ow_softc *sc;
436
437 /*
438 * Find all the devices on the bus. We don't probe / attach them in the
439 * enumeration phase. We do this because we want to allow the probe /
440 * attach routines of the child drivers to have as full an access to the
441 * bus as possible. While we reset things before the next step of the
442 * search (so it would likely be OK to allow access by the clients to
443 * the bus), it is more conservative to find them all, then to do the
444 * attach of the devices. This also allows the child devices to have
445 * more knowledge of the bus. We also ignore errors from the enumeration
446 * because they might happen after we've found a few devices.
447 */
448 sc = device_get_softc(ndev);
449 sc->dev = ndev;
450 mtx_init(&sc->mtx, device_get_nameunit(sc->dev), "ow", MTX_DEF);
451 ow_enumerate(ndev, ow_search_rom, ow_device_found);
452 return bus_generic_attach(ndev);
453}
454
455static int
456ow_detach(device_t ndev)
457{
458 device_t *children, child;
459 int nkid, i;
460 struct ow_devinfo *di;
461 struct ow_softc *sc;
462
463 sc = device_get_softc(ndev);
464 /*
465 * detach all the children first. This is blocking until any threads
466 * have stopped, etc.
467 */
468 bus_generic_detach(ndev);
469
470 /*
471 * We delete all the children, and free up the ivars
472 */
473 if (device_get_children(ndev, &children, &nkid) != 0)
474 return ENOMEM;
475 for (i = 0; i < nkid; i++) {
476 child = children[i];
477 di = device_get_ivars(child);
478 free(di, M_OW);
479 device_delete_child(ndev, child);
480 }
481 free(children, M_TEMP);
482
483 OW_LOCK_DESTROY(sc);
484 return 0;
485}
486
487/*
488 * Not sure this is really needed. I'm having trouble figuring out what
489 * location means in the context of the one wire bus.
490 */
491static int
492ow_child_location_str(device_t dev, device_t child, char *buf,
493 size_t buflen)
494{
495
496 *buf = '\0';
497 return (0);
498}
499
500static int
501ow_child_pnpinfo_str(device_t dev, device_t child, char *buf,
502 size_t buflen)
503{
504 struct ow_devinfo *di;
505
506 di = device_get_ivars(child);
507 snprintf(buf, buflen, "romid=%8D", &di->romid, ":");
508 return (0);
509}
510
511static int
512ow_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
513{
514 struct ow_devinfo *di;
515 romid_t **ptr;
516
517 di = device_get_ivars(child);
518 switch (which) {
519 case OW_IVAR_FAMILY:
520 *result = di->romid & 0xff;
521 break;
522 case OW_IVAR_ROMID:
523 ptr = (romid_t **)result;
524 *ptr = &di->romid;
525 break;
526 default:
527 return EINVAL;
528 }
529
530 return 0;
531}
532
533static int
534ow_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
535{
536
537 return EINVAL;
538}
539
540static int
541ow_print_child(device_t ndev, device_t pdev)
542{
543 int retval = 0;
544 struct ow_devinfo *di;
545
546 di = device_get_ivars(pdev);
547
548 retval += bus_print_child_header(ndev, pdev);
549 retval += printf(" romid %8D", &di->romid, ":");
550 retval += bus_print_child_footer(ndev, pdev);
551
552 return retval;
553}
554
555static void
556ow_probe_nomatch(device_t ndev, device_t pdev)
557{
558 struct ow_devinfo *di;
559
560 di = device_get_ivars(pdev);
561 device_printf(ndev, "romid %8D: no driver\n", &di->romid, ":");
562}
563
564static int
565ow_acquire_bus(device_t ndev, device_t pdev, int how)
566{
567 struct ow_softc *sc;
568
569 sc = device_get_softc(ndev);
570 OW_ASSERT_UNLOCKED(sc);
571 OW_LOCK(sc);
572 if (sc->owner != NULL) {
573 if (sc->owner == pdev)
574 panic("%s: %s recursively acquiring the bus.\n",
575 device_get_nameunit(ndev),
576 device_get_nameunit(pdev));
577 if (how == OWN_DONTWAIT) {
578 OW_UNLOCK(sc);
579 return EWOULDBLOCK;
580 }
581 while (sc->owner != NULL)
582 mtx_sleep(sc, &sc->mtx, 0, "owbuswait", 0);
583 }
584 sc->owner = pdev;
585 OW_UNLOCK(sc);
586
587 return 0;
588}
589
590static void
591ow_release_bus(device_t ndev, device_t pdev)
592{
593 struct ow_softc *sc;
594
595 sc = device_get_softc(ndev);
596 OW_ASSERT_UNLOCKED(sc);
597 OW_LOCK(sc);
598 if (sc->owner == NULL)
599 panic("%s: %s releasing unowned bus.", device_get_nameunit(ndev),
600 device_get_nameunit(pdev));
601 if (sc->owner != pdev)
602 panic("%s: %s don't own the bus. %s does. game over.",
603 device_get_nameunit(ndev), device_get_nameunit(pdev),
604 device_get_nameunit(sc->owner));
605 sc->owner = NULL;
606 wakeup(sc);
607 OW_UNLOCK(sc);
608}
609
610devclass_t ow_devclass;
611
612static device_method_t ow_methods[] = {
613 /* Device interface */
614 DEVMETHOD(device_probe, ow_probe),
615 DEVMETHOD(device_attach, ow_attach),
616 DEVMETHOD(device_detach, ow_detach),
617
618 /* Bus interface */
619 DEVMETHOD(bus_child_pnpinfo_str, ow_child_pnpinfo_str),
620 DEVMETHOD(bus_child_location_str, ow_child_location_str),
621 DEVMETHOD(bus_read_ivar, ow_read_ivar),
622 DEVMETHOD(bus_write_ivar, ow_write_ivar),
623 DEVMETHOD(bus_print_child, ow_print_child),
624 DEVMETHOD(bus_probe_nomatch, ow_probe_nomatch),
625
626 /* One Wire Network/Transport layer interface */
627 DEVMETHOD(own_send_command, ow_send_command),
628 DEVMETHOD(own_acquire_bus, ow_acquire_bus),
629 DEVMETHOD(own_release_bus, ow_release_bus),
630 DEVMETHOD(own_crc, ow_crc),
631 { 0, 0 }
632};
633
634static driver_t ow_driver = {
635 "ow",
636 ow_methods,
637 sizeof(struct ow_softc),
638};
639
640DRIVER_MODULE(ow, owc, ow_driver, ow_devclass, 0, 0);
641MODULE_VERSION(ow, 1);