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