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