xref: /freebsd/sys/dev/ow/ow.c (revision b64c5a0ace59af62eff52bfe110a521dc73c937b)
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/param.h>
27 #include <sys/systm.h>
28 #include <sys/kernel.h>
29 
30 #include <sys/bus.h>
31 #include <sys/errno.h>
32 #include <sys/libkern.h>
33 #include <sys/lock.h>
34 #include <sys/malloc.h>
35 #include <sys/module.h>
36 #include <sys/mutex.h>
37 #include <sys/sbuf.h>
38 #include <sys/sysctl.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 
50 typedef int ow_enum_fn(device_t, device_t);
51 typedef int ow_found_fn(device_t, romid_t);
52 
53 struct 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 
60 struct ow_devinfo
61 {
62 	romid_t	romid;
63 };
64 
65 static int ow_acquire_bus(device_t ndev, device_t pdev, int how);
66 static 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 
74 static MALLOC_DEFINE(M_OW, "ow", "House keeping data for 1wire bus");
75 
76 static const struct ow_timing timing_regular_min = {
77 	.t_slot = 60,
78 	.t_low0 = 60,
79 	.t_low1 = 1,
80 	.t_release = 0,
81 	.t_rec = 1,
82 	.t_rdv = 15,		/* fixed */
83 	.t_rstl = 480,
84 	.t_rsth = 480,
85 	.t_pdl = 60,
86 	.t_pdh = 15,
87 	.t_lowr = 1,
88 };
89 
90 static const struct ow_timing timing_regular_max = {
91 	.t_slot = 120,
92 	.t_low0 = 120,
93 	.t_low1 = 15,
94 	.t_release = 45,
95 	.t_rec = 960,		/* infinity */
96 	.t_rdv = 15,		/* fixed */
97 	.t_rstl = 960,		/* infinity */
98 	.t_rsth = 960,		/* infinity */
99 	.t_pdl = 240,		/* 60us to 240us */
100 	.t_pdh = 60,		/* 15us to 60us */
101 	.t_lowr = 15,		/* 1us */
102 };
103 
104 static struct ow_timing timing_regular = {
105 	.t_slot = 60,		/*  60 <= t < 120 */
106 	.t_low0 = 60,		/*  60 <= t < t_slot < 120 */
107 	.t_low1 = 1,		/*   1 <= t < 15 */
108 	.t_release = 45,	/*   0 <= t < 45 */
109 	.t_rec = 15,		/*   1 <= t < inf */
110 	.t_rdv = 15,		/* t == 15 */
111 	.t_rstl = 480,		/* 480 <= t < inf */
112 	.t_rsth = 480,		/* 480 <= t < inf */
113 	.t_pdl = 60,		/*  60 <= t < 240 */
114 	.t_pdh = 60,		/*  15 <= t < 60 */
115 	.t_lowr = 1,		/*   1 <= t < 15 */
116 };
117 
118 /* NB: Untested */
119 static const struct ow_timing timing_overdrive_min = {
120 	.t_slot = 6,
121 	.t_low0 = 6,
122 	.t_low1 = 1,
123 	.t_release = 0,
124 	.t_rec = 1,
125 	.t_rdv = 2,		/* fixed */
126 	.t_rstl = 48,
127 	.t_rsth = 48,
128 	.t_pdl = 8,
129 	.t_pdh = 2,
130 	.t_lowr = 1,
131 };
132 
133 static const struct ow_timing timing_overdrive_max = {
134 	.t_slot = 16,
135 	.t_low0 = 16,
136 	.t_low1 = 2,
137 	.t_release = 4,
138 	.t_rec = 960,		/* infinity */
139 	.t_rdv = 2,		/* fixed */
140 	.t_rstl = 80,
141 	.t_rsth = 960,		/* infinity */
142 	.t_pdl = 24,
143 	.t_pdh = 6,
144 	.t_lowr = 2,
145 };
146 
147 static struct ow_timing timing_overdrive = {
148 	.t_slot = 11,		/* 6 <= t < 16 */
149 	.t_low0 = 6,		/* 6 <= t < t_slot < 16 */
150 	.t_low1 = 1,		/* 1 <= t < 2 */
151 	.t_release = 4,		/* 0 <= t < 4 */
152 	.t_rec = 1,		/* 1 <= t < inf */
153 	.t_rdv = 2,		/* t == 2 */
154 	.t_rstl = 48,		/* 48 <= t < 80 */
155 	.t_rsth = 48,		/* 48 <= t < inf */
156 	.t_pdl = 8,		/* 8 <= t < 24 */
157 	.t_pdh = 2,		/* 2 <= t < 6 */
158 	.t_lowr = 1,		/* 1 <= t < 2 */
159 };
160 
161 SYSCTL_NODE(_hw, OID_AUTO, ow, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
162     "1-Wire protocol");
163 SYSCTL_NODE(_hw_ow, OID_AUTO, regular, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
164     "Regular mode timings");
165 SYSCTL_NODE(_hw_ow, OID_AUTO, overdrive, CTLFLAG_RD | CTLFLAG_MPSAFE, 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 | CTLFLAG_NEEDGIANT, 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, DEVICE_UNIT_ANY);
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 void
334 ow_child_deleted(device_t dev, device_t child)
335 {
336 	free(device_get_ivars(child), M_OW);
337 }
338 
339 static device_t
340 ow_child_by_romid(device_t dev, romid_t romid)
341 {
342 	device_t *children, retval, child;
343 	int nkid, i;
344 	struct ow_devinfo *di;
345 
346 	if (device_get_children(dev, &children, &nkid) != 0)
347 		return (NULL);
348 	retval = NULL;
349 	for (i = 0; i < nkid; i++) {
350 		child = children[i];
351 		di = device_get_ivars(child);
352 		if (di->romid == romid) {
353 			retval = child;
354 			break;
355 		}
356 	}
357 	free(children, M_TEMP);
358 
359 	return (retval);
360 }
361 
362 /*
363  * CRC generator table -- taken from AN937 DOW CRC LOOKUP FUNCTION Table 2
364  */
365 const uint8_t ow_crc_table[] = {
366 	0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
367 	157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
368 	35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
369 	190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
370 	70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
371 	219, 133,103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
372 	101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
373 	248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
374 	140,210, 48, 110, 237, 179, 81, 15, 78, 16, 242,  172, 47, 113,147, 205,
375 	17, 79, 173, 243, 112, 46, 204, 146, 211,141, 111, 49, 178, 236, 14, 80,
376 	175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82,176, 238,
377 	50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
378 	202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
379 	87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
380 	233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
381 	116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53
382 };
383 
384 /*
385  * Converted from DO_CRC page 131 ANN937
386  */
387 static uint8_t
388 ow_crc(device_t ndev, device_t pdev, uint8_t *buffer, size_t len)
389 {
390 	uint8_t crc = 0;
391 	int i;
392 
393 	for (i = 0; i < len; i++)
394 		crc = ow_crc_table[crc ^ buffer[i]];
395 	return crc;
396 }
397 
398 static int
399 ow_check_crc(romid_t romid)
400 {
401 	return ow_crc(NULL, NULL, (uint8_t *)&romid, sizeof(romid)) == 0;
402 }
403 
404 static int
405 ow_device_found(device_t dev, romid_t romid)
406 {
407 
408 	/* XXX Move this up into enumerate? */
409 	/*
410 	 * All valid ROM IDs have a valid CRC. Check that first.
411 	 */
412 	if (!ow_check_crc(romid)) {
413 		device_printf(dev, "Device romid %8D failed CRC.\n",
414 		    &romid, ":");
415 		return EINVAL;
416 	}
417 
418 	/*
419 	 * If we've seen this child before, don't add a new one for it.
420 	 */
421 	if (ow_child_by_romid(dev, romid) != NULL)
422 		return 0;
423 
424 	return ow_add_child(dev, romid);
425 }
426 
427 static int
428 ow_enumerate(device_t dev, ow_enum_fn *enumfp, ow_found_fn *foundfp)
429 {
430 	device_t lldev = device_get_parent(dev);
431 	int first, second, i, dir, prior, last, err, retries;
432 	uint64_t probed, last_mask;
433 	int sanity = 10;
434 
435 	prior = -1;
436 	last_mask = 0;
437 	retries = 0;
438 	last = -2;
439 	err = ow_acquire_bus(dev, dev, OWN_DONTWAIT);
440 	if (err != 0)
441 		return err;
442 	while (last != -1) {
443 		if (sanity-- < 0) {
444 			printf("Reached the sanity limit\n");
445 			return EIO;
446 		}
447 again:
448 		probed = 0;
449 		last = -1;
450 
451 		/*
452 		 * See AN397 section 5.II.C.3 for the algorithm (though a bit
453 		 * poorly stated). The search command forces each device to
454 		 * send ROM ID bits one at a time (first the bit, then the
455 		 * complement) the master (us) sends back a bit. If the
456 		 * device's bit doesn't match what we send back, that device
457 		 * stops sending bits back. So each time through we remember
458 		 * where we made the last decision (always 0). If there's a
459 		 * conflict there this time (and there will be in the absence
460 		 * of a hardware failure) we go with 1. This way, we prune the
461 		 * devices on the bus and wind up with a unique ROM. We know
462 		 * we're done when we detect no new conflicts. The same
463 		 * algorithm is used for devices in alarm state as well.
464 		 *
465 		 * In addition, experience has shown that sometimes devices
466 		 * stop responding in the middle of enumeration, so try this
467 		 * step again a few times when that happens. It is unclear if
468 		 * this is due to a nosiy electrical environment or some odd
469 		 * timing issue.
470 		 */
471 
472 		/*
473 		 * The enumeration command should be successfully sent, if not,
474 		 * we have big issues on the bus so punt. Lower layers report
475 		 * any unusual errors, so we don't need to here.
476 		 */
477 		err = enumfp(dev, dev);
478 		if (err != 0)
479 			return (err);
480 
481 		for (i = 0; i < 64; i++) {
482 			OWLL_READ_DATA(lldev, &timing_regular, &first);
483 			OWLL_READ_DATA(lldev, &timing_regular, &second);
484 			switch (first | second << 1) {
485 			case 0: /* Conflict */
486 				if (i < prior)
487 					dir = (last_mask >> i) & 1;
488 				else
489 					dir = i == prior;
490 
491 				if (dir == 0)
492 					last = i;
493 				break;
494 			case 1: /* 1 then 0 -> 1 for all */
495 				dir = 1;
496 				break;
497 			case 2: /* 0 then 1 -> 0 for all */
498 				dir = 0;
499 				break;
500 			case 3:
501 				/*
502 				 * No device responded. This is unexpected, but
503 				 * experience has shown that on some platforms
504 				 * we miss a timing window, or otherwise have
505 				 * an issue. Start this step over. Since we've
506 				 * not updated prior yet, we can just jump to
507 				 * the top of the loop for a re-do of this step.
508 				 */
509 				printf("oops, starting over\n");
510 				if (++retries > 5)
511 					return (EIO);
512 				goto again;
513 			default: /* NOTREACHED */
514 				__assert_unreachable();
515 			}
516 			if (dir) {
517 				OWLL_WRITE_ONE(lldev, &timing_regular);
518 				probed |= 1ull << i;
519 			} else {
520 				OWLL_WRITE_ZERO(lldev, &timing_regular);
521 			}
522 		}
523 		retries = 0;
524 		foundfp(dev, probed);
525 		last_mask = probed;
526 		prior = last;
527 	}
528 	ow_release_bus(dev, dev);
529 
530 	return (0);
531 }
532 
533 static int
534 ow_probe(device_t dev)
535 {
536 
537 	device_set_desc(dev, "1 Wire Bus");
538 	return (BUS_PROBE_GENERIC);
539 }
540 
541 static int
542 ow_attach(device_t ndev)
543 {
544 	struct ow_softc *sc;
545 
546 	/*
547 	 * Find all the devices on the bus. We don't probe / attach them in the
548 	 * enumeration phase. We do this because we want to allow the probe /
549 	 * attach routines of the child drivers to have as full an access to the
550 	 * bus as possible. While we reset things before the next step of the
551 	 * search (so it would likely be OK to allow access by the clients to
552 	 * the bus), it is more conservative to find them all, then to do the
553 	 * attach of the devices. This also allows the child devices to have
554 	 * more knowledge of the bus. We also ignore errors from the enumeration
555 	 * because they might happen after we've found a few devices.
556 	 */
557 	sc = device_get_softc(ndev);
558 	sc->dev = ndev;
559 	mtx_init(&sc->mtx, device_get_nameunit(sc->dev), "ow", MTX_DEF);
560 	ow_enumerate(ndev, ow_search_rom, ow_device_found);
561 	bus_attach_children(ndev);
562 	return (0);
563 }
564 
565 static int
566 ow_detach(device_t ndev)
567 {
568 	device_t *children, child;
569 	int nkid, i;
570 	struct ow_softc *sc;
571 
572 	sc = device_get_softc(ndev);
573 	/*
574 	 * detach all the children first. This is blocking until any threads
575 	 * have stopped, etc.
576 	 */
577 	bus_generic_detach(ndev);
578 
579 	/*
580 	 * We delete all the children, and free up the ivars
581 	 */
582 	if (device_get_children(ndev, &children, &nkid) != 0)
583 		return ENOMEM;
584 	for (i = 0; i < nkid; i++) {
585 		child = children[i];
586 		device_delete_child(ndev, child);
587 	}
588 	free(children, M_TEMP);
589 
590 	OW_LOCK_DESTROY(sc);
591 	return 0;
592 }
593 
594 static int
595 ow_child_pnpinfo(device_t dev, device_t child, struct sbuf *sb)
596 {
597 	struct ow_devinfo *di;
598 
599 	di = device_get_ivars(child);
600 	sbuf_printf(sb, "romid=%8D", &di->romid, ":");
601 	return (0);
602 }
603 
604 static int
605 ow_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
606 {
607 	struct ow_devinfo *di;
608 	romid_t **ptr;
609 
610 	di = device_get_ivars(child);
611 	switch (which) {
612 	case OW_IVAR_FAMILY:
613 		*result = di->romid & 0xff;
614 		break;
615 	case OW_IVAR_ROMID:
616 		ptr = (romid_t **)result;
617 		*ptr = &di->romid;
618 		break;
619 	default:
620 		return EINVAL;
621 	}
622 
623 	return 0;
624 }
625 
626 static int
627 ow_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
628 {
629 
630 	return EINVAL;
631 }
632 
633 static int
634 ow_print_child(device_t ndev, device_t pdev)
635 {
636 	int retval = 0;
637 	struct ow_devinfo *di;
638 
639 	di = device_get_ivars(pdev);
640 
641 	retval += bus_print_child_header(ndev, pdev);
642 	retval += printf(" romid %8D", &di->romid, ":");
643 	retval += bus_print_child_footer(ndev, pdev);
644 
645 	return retval;
646 }
647 
648 static void
649 ow_probe_nomatch(device_t ndev, device_t pdev)
650 {
651 	struct ow_devinfo *di;
652 
653 	di = device_get_ivars(pdev);
654 	device_printf(ndev, "romid %8D: no driver\n", &di->romid, ":");
655 }
656 
657 static int
658 ow_acquire_bus(device_t ndev, device_t pdev, int how)
659 {
660 	struct ow_softc *sc;
661 
662 	sc = device_get_softc(ndev);
663 	OW_ASSERT_UNLOCKED(sc);
664 	OW_LOCK(sc);
665 	if (sc->owner != NULL) {
666 		if (sc->owner == pdev)
667 			panic("%s: %s recursively acquiring the bus.\n",
668 			    device_get_nameunit(ndev),
669 			    device_get_nameunit(pdev));
670 		if (how == OWN_DONTWAIT) {
671 			OW_UNLOCK(sc);
672 			return EWOULDBLOCK;
673 		}
674 		while (sc->owner != NULL)
675 			mtx_sleep(sc, &sc->mtx, 0, "owbuswait", 0);
676 	}
677 	sc->owner = pdev;
678 	OW_UNLOCK(sc);
679 
680 	return 0;
681 }
682 
683 static void
684 ow_release_bus(device_t ndev, device_t pdev)
685 {
686 	struct ow_softc *sc;
687 
688 	sc = device_get_softc(ndev);
689 	OW_ASSERT_UNLOCKED(sc);
690 	OW_LOCK(sc);
691 	if (sc->owner == NULL)
692 		panic("%s: %s releasing unowned bus.", device_get_nameunit(ndev),
693 		    device_get_nameunit(pdev));
694 	if (sc->owner != pdev)
695 		panic("%s: %s don't own the bus. %s does. game over.",
696 		    device_get_nameunit(ndev), device_get_nameunit(pdev),
697 		    device_get_nameunit(sc->owner));
698 	sc->owner = NULL;
699 	wakeup(sc);
700 	OW_UNLOCK(sc);
701 }
702 
703 static device_method_t ow_methods[] = {
704 	/* Device interface */
705 	DEVMETHOD(device_probe,		ow_probe),
706 	DEVMETHOD(device_attach,	ow_attach),
707 	DEVMETHOD(device_detach,	ow_detach),
708 
709 	/* Bus interface */
710 	DEVMETHOD(bus_child_deleted,	ow_child_deleted),
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, 0, 0);
732 MODULE_VERSION(ow, 1);
733