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