xref: /freebsd/sys/dev/ow/ow.c (revision 79dfe2b761891eb3ab1b6a769d4f6adc97335350)
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
ow_send_byte(device_t lldev,struct ow_timing * t,uint8_t byte)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
ow_read_byte(device_t lldev,struct ow_timing * t,uint8_t * bytep)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
ow_send_command(device_t ndev,device_t pdev,struct ow_cmd * cmd)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
ow_search_rom(device_t lldev,device_t dev)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
ow_add_child(device_t dev,romid_t romid)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
ow_child_deleted(device_t dev,device_t child)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
ow_child_by_romid(device_t dev,romid_t romid)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
ow_crc(device_t ndev,device_t pdev,uint8_t * buffer,size_t len)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
ow_check_crc(romid_t romid)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
ow_device_found(device_t dev,romid_t romid)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
ow_enumerate(device_t dev,ow_enum_fn * enumfp,ow_found_fn * foundfp)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
ow_probe(device_t dev)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
ow_attach(device_t ndev)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 	return bus_generic_attach(ndev);
562 }
563 
564 static int
ow_detach(device_t ndev)565 ow_detach(device_t ndev)
566 {
567 	device_t *children, child;
568 	int nkid, i;
569 	struct ow_softc *sc;
570 
571 	sc = device_get_softc(ndev);
572 	/*
573 	 * detach all the children first. This is blocking until any threads
574 	 * have stopped, etc.
575 	 */
576 	bus_generic_detach(ndev);
577 
578 	/*
579 	 * We delete all the children, and free up the ivars
580 	 */
581 	if (device_get_children(ndev, &children, &nkid) != 0)
582 		return ENOMEM;
583 	for (i = 0; i < nkid; i++) {
584 		child = children[i];
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
ow_child_pnpinfo(device_t dev,device_t child,struct sbuf * sb)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
ow_read_ivar(device_t dev,device_t child,int which,uintptr_t * result)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
ow_write_ivar(device_t dev,device_t child,int which,uintptr_t value)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
ow_print_child(device_t ndev,device_t pdev)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
ow_probe_nomatch(device_t ndev,device_t pdev)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
ow_acquire_bus(device_t ndev,device_t pdev,int how)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
ow_release_bus(device_t ndev,device_t pdev)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 static device_method_t ow_methods[] = {
703 	/* Device interface */
704 	DEVMETHOD(device_probe,		ow_probe),
705 	DEVMETHOD(device_attach,	ow_attach),
706 	DEVMETHOD(device_detach,	ow_detach),
707 
708 	/* Bus interface */
709 	DEVMETHOD(bus_child_deleted,	ow_child_deleted),
710 	DEVMETHOD(bus_child_pnpinfo,	ow_child_pnpinfo),
711 	DEVMETHOD(bus_read_ivar,	ow_read_ivar),
712 	DEVMETHOD(bus_write_ivar,	ow_write_ivar),
713 	DEVMETHOD(bus_print_child,	ow_print_child),
714 	DEVMETHOD(bus_probe_nomatch,	ow_probe_nomatch),
715 
716 	/* One Wire Network/Transport layer interface */
717 	DEVMETHOD(own_send_command,	ow_send_command),
718 	DEVMETHOD(own_acquire_bus,	ow_acquire_bus),
719 	DEVMETHOD(own_release_bus,	ow_release_bus),
720 	DEVMETHOD(own_crc,		ow_crc),
721 	{ 0, 0 }
722 };
723 
724 static driver_t ow_driver = {
725 	"ow",
726 	ow_methods,
727 	sizeof(struct ow_softc),
728 };
729 
730 DRIVER_MODULE(ow, owc, ow_driver, 0, 0);
731 MODULE_VERSION(ow, 1);
732