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