xref: /freebsd/sys/dev/ow/ow.c (revision 069ac18495ad8fde2748bc94b0f80a50250bb01d)
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, -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 static int
591 ow_child_pnpinfo(device_t dev, device_t child, struct sbuf *sb)
592 {
593 	struct ow_devinfo *di;
594 
595 	di = device_get_ivars(child);
596 	sbuf_printf(sb, "romid=%8D", &di->romid, ":");
597 	return (0);
598 }
599 
600 static int
601 ow_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
602 {
603 	struct ow_devinfo *di;
604 	romid_t **ptr;
605 
606 	di = device_get_ivars(child);
607 	switch (which) {
608 	case OW_IVAR_FAMILY:
609 		*result = di->romid & 0xff;
610 		break;
611 	case OW_IVAR_ROMID:
612 		ptr = (romid_t **)result;
613 		*ptr = &di->romid;
614 		break;
615 	default:
616 		return EINVAL;
617 	}
618 
619 	return 0;
620 }
621 
622 static int
623 ow_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
624 {
625 
626 	return EINVAL;
627 }
628 
629 static int
630 ow_print_child(device_t ndev, device_t pdev)
631 {
632 	int retval = 0;
633 	struct ow_devinfo *di;
634 
635 	di = device_get_ivars(pdev);
636 
637 	retval += bus_print_child_header(ndev, pdev);
638 	retval += printf(" romid %8D", &di->romid, ":");
639 	retval += bus_print_child_footer(ndev, pdev);
640 
641 	return retval;
642 }
643 
644 static void
645 ow_probe_nomatch(device_t ndev, device_t pdev)
646 {
647 	struct ow_devinfo *di;
648 
649 	di = device_get_ivars(pdev);
650 	device_printf(ndev, "romid %8D: no driver\n", &di->romid, ":");
651 }
652 
653 static int
654 ow_acquire_bus(device_t ndev, device_t pdev, int how)
655 {
656 	struct ow_softc *sc;
657 
658 	sc = device_get_softc(ndev);
659 	OW_ASSERT_UNLOCKED(sc);
660 	OW_LOCK(sc);
661 	if (sc->owner != NULL) {
662 		if (sc->owner == pdev)
663 			panic("%s: %s recursively acquiring the bus.\n",
664 			    device_get_nameunit(ndev),
665 			    device_get_nameunit(pdev));
666 		if (how == OWN_DONTWAIT) {
667 			OW_UNLOCK(sc);
668 			return EWOULDBLOCK;
669 		}
670 		while (sc->owner != NULL)
671 			mtx_sleep(sc, &sc->mtx, 0, "owbuswait", 0);
672 	}
673 	sc->owner = pdev;
674 	OW_UNLOCK(sc);
675 
676 	return 0;
677 }
678 
679 static void
680 ow_release_bus(device_t ndev, device_t pdev)
681 {
682 	struct ow_softc *sc;
683 
684 	sc = device_get_softc(ndev);
685 	OW_ASSERT_UNLOCKED(sc);
686 	OW_LOCK(sc);
687 	if (sc->owner == NULL)
688 		panic("%s: %s releasing unowned bus.", device_get_nameunit(ndev),
689 		    device_get_nameunit(pdev));
690 	if (sc->owner != pdev)
691 		panic("%s: %s don't own the bus. %s does. game over.",
692 		    device_get_nameunit(ndev), device_get_nameunit(pdev),
693 		    device_get_nameunit(sc->owner));
694 	sc->owner = NULL;
695 	wakeup(sc);
696 	OW_UNLOCK(sc);
697 }
698 
699 static device_method_t ow_methods[] = {
700 	/* Device interface */
701 	DEVMETHOD(device_probe,		ow_probe),
702 	DEVMETHOD(device_attach,	ow_attach),
703 	DEVMETHOD(device_detach,	ow_detach),
704 
705 	/* Bus interface */
706 	DEVMETHOD(bus_child_pnpinfo,	ow_child_pnpinfo),
707 	DEVMETHOD(bus_read_ivar,	ow_read_ivar),
708 	DEVMETHOD(bus_write_ivar,	ow_write_ivar),
709 	DEVMETHOD(bus_print_child,	ow_print_child),
710 	DEVMETHOD(bus_probe_nomatch,	ow_probe_nomatch),
711 
712 	/* One Wire Network/Transport layer interface */
713 	DEVMETHOD(own_send_command,	ow_send_command),
714 	DEVMETHOD(own_acquire_bus,	ow_acquire_bus),
715 	DEVMETHOD(own_release_bus,	ow_release_bus),
716 	DEVMETHOD(own_crc,		ow_crc),
717 	{ 0, 0 }
718 };
719 
720 static driver_t ow_driver = {
721 	"ow",
722 	ow_methods,
723 	sizeof(struct ow_softc),
724 };
725 
726 DRIVER_MODULE(ow, owc, ow_driver, 0, 0);
727 MODULE_VERSION(ow, 1);
728