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