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