Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev onewire:



details:   https://anonhg.NetBSD.org/src/rev/81e0f3347508
branches:  trunk
changeset: 846756:81e0f3347508
user:      ad <ad%NetBSD.org@localhost>
date:      Sat Nov 30 23:04:12 2019 +0000

description:
onewire:

- Re-do the signalling to be a little more forgiving and efficient.
- If bus reset fails during probe, try a second time.
- Spread out kernel threads for many busses to avoid thundering herd effect.

diffstat:

 sys/dev/gpio/gpioow.c             |   20 +++-
 sys/dev/onewire/onewire.c         |   96 +++++++++++++++++----
 sys/dev/onewire/onewire_bitbang.c |  161 +++++++++++++++++++++++++++++++------
 sys/dev/onewire/onewirevar.h      |   11 +-
 4 files changed, 230 insertions(+), 58 deletions(-)

diffs (truncated from 487 to 300 lines):

diff -r 67e9ad8381c4 -r 81e0f3347508 sys/dev/gpio/gpioow.c
--- a/sys/dev/gpio/gpioow.c     Sat Nov 30 22:50:11 2019 +0000
+++ b/sys/dev/gpio/gpioow.c     Sat Nov 30 23:04:12 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gpioow.c,v 1.15 2017/10/28 04:53:56 riastradh Exp $ */
+/* $NetBSD: gpioow.c,v 1.16 2019/11/30 23:04:12 ad Exp $ */
 /*     $OpenBSD: gpioow.c,v 1.1 2006/03/04 16:27:03 grange Exp $       */
 
 /*
@@ -18,7 +18,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gpioow.c,v 1.15 2017/10/28 04:53:56 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gpioow.c,v 1.16 2019/11/30 23:04:12 ad Exp $");
 
 /*
  * 1-Wire bus bit-banging through GPIO pin.
@@ -57,7 +57,8 @@
 int    gpioow_activate(device_t, enum devact);
 
 int    gpioow_ow_reset(void *);
-int    gpioow_ow_bit(void *, int);
+int    gpioow_ow_read_bit(void *);
+void   gpioow_ow_write_bit(void *, int);
 
 void   gpioow_bb_rx(void *);
 void   gpioow_bb_tx(void *);
@@ -143,7 +144,8 @@
        /* Attach 1-Wire bus */
        sc->sc_ow_bus.bus_cookie = sc;
        sc->sc_ow_bus.bus_reset = gpioow_ow_reset;
-       sc->sc_ow_bus.bus_bit = gpioow_ow_bit;
+       sc->sc_ow_bus.bus_read_bit = gpioow_ow_read_bit;
+       sc->sc_ow_bus.bus_write_bit = gpioow_ow_write_bit;
 
        memset(&oba, 0, sizeof(oba));
        oba.oba_bus = &sc->sc_ow_bus;
@@ -193,9 +195,15 @@
 }
 
 int
-gpioow_ow_bit(void *arg, int value)
+gpioow_ow_read_bit(void *arg)
 {
-       return (onewire_bb_bit(&gpioow_bbops, arg, value));
+       return (onewire_bb_read_bit(&gpioow_bbops, arg));
+}
+
+void
+gpioow_ow_write_bit(void *arg, int value)
+{
+       onewire_bb_write_bit(&gpioow_bbops, arg, value);
 }
 
 void
diff -r 67e9ad8381c4 -r 81e0f3347508 sys/dev/onewire/onewire.c
--- a/sys/dev/onewire/onewire.c Sat Nov 30 22:50:11 2019 +0000
+++ b/sys/dev/onewire/onewire.c Sat Nov 30 23:04:12 2019 +0000
@@ -1,6 +1,35 @@
-/*     $NetBSD: onewire.c,v 1.17 2019/10/25 16:25:14 martin Exp $      */
+/*     $NetBSD: onewire.c,v 1.18 2019/11/30 23:04:12 ad Exp $  */
 /*     $OpenBSD: onewire.c,v 1.1 2006/03/04 16:27:03 grange Exp $      */
 
+/*-
+ * Copyright (c) 2019 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
 /*
  * Copyright (c) 2006 Alexander Yurchenko <grange%openbsd.org@localhost>
  *
@@ -18,7 +47,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: onewire.c,v 1.17 2019/10/25 16:25:14 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: onewire.c,v 1.18 2019/11/30 23:04:12 ad Exp $");
 
 /*
  * 1-Wire bus driver.
@@ -202,14 +231,25 @@
 }
 
 int
-onewire_bit(void *arg, int value)
+onewire_read_bit(void *arg)
 {
        struct onewire_softc *sc = arg;
        struct onewire_bus *bus = sc->sc_bus;
 
        KASSERT(mutex_owned(&sc->sc_lock));
 
-       return bus->bus_bit(bus->bus_cookie, value);
+       return bus->bus_read_bit(bus->bus_cookie);
+}
+
+void
+onewire_write_bit(void *arg, int value)
+{
+       struct onewire_softc *sc = arg;
+       struct onewire_bus *bus = sc->sc_bus;
+
+       KASSERT(mutex_owned(&sc->sc_lock));
+
+       bus->bus_write_bit(bus->bus_cookie, value);
 }
 
 int
@@ -226,7 +266,7 @@
                return bus->bus_read_byte(bus->bus_cookie);
 
        for (i = 0; i < 8; i++)
-               value |= (bus->bus_bit(bus->bus_cookie, 1) << i);
+               value |= (bus->bus_read_bit(bus->bus_cookie) << i);
 
        return value;
 }
@@ -244,7 +284,7 @@
                return bus->bus_write_byte(bus->bus_cookie, value);
 
        for (i = 0; i < 8; i++)
-               bus->bus_bit(bus->bus_cookie, (value >> i) & 0x1);
+               bus->bus_write_bit(bus->bus_cookie, (value >> i) & 0x1);
 }
 
 int
@@ -259,19 +299,19 @@
        if (bus->bus_triplet != NULL)
                return bus->bus_triplet(bus->bus_cookie, dir);
 
-       rv = bus->bus_bit(bus->bus_cookie, 1);
+       rv = bus->bus_read_bit(bus->bus_cookie);
        rv <<= 1;
-       rv |= bus->bus_bit(bus->bus_cookie, 1);
+       rv |= bus->bus_read_bit(bus->bus_cookie);
 
        switch (rv) {
        case 0x0:
-               bus->bus_bit(bus->bus_cookie, dir);
+               bus->bus_write_bit(bus->bus_cookie, dir);
                break;
        case 0x1:
-               bus->bus_bit(bus->bus_cookie, 0);
+               bus->bus_write_bit(bus->bus_cookie, 0);
                break;
        default:
-               bus->bus_bit(bus->bus_cookie, 1);
+               bus->bus_write_bit(bus->bus_cookie, 1);
        }
 
        return rv;
@@ -318,6 +358,18 @@
 onewire_thread(void *arg)
 {
        struct onewire_softc *sc = arg;
+       int unit, dly;
+
+       /*
+        * There can be many onewire busses, potentially funneled through
+        * few GPIO controllers.  To avoid a thundering herd of kthreads and
+        * resulting contention for the GPIO controller, spread the probes
+        * out across an 8 second window.  The kthreads could converge later
+        * due to timing effects.
+        */
+       unit = device_unit(sc->sc_dev);
+       dly = (unit & 0x07) * hz + ((unit >> 3) * hz >> 3) + 1;
+       (void)kpause("owdly", false, dly, NULL);
 
        mutex_enter(&sc->sc_lock);
        while (!sc->sc_dying) {
@@ -354,13 +406,17 @@
 
        while (search && count++ < onewire_maxdevs) {
                /*
-                * Reset the bus. If there's no presence pulse
-                * don't search for any devices.
+                * Reset the bus, allowing for one retry if reset fails.  If
+                * there's no presence pulse don't search for any devices.
                 */
                if (onewire_reset(sc) != 0) {
                        DPRINTF(("%s: scan: no presence pulse\n",
                            device_xname(sc->sc_dev)));
-                       break;
+                       if (onewire_reset(sc) != 0) {
+                               DPRINTF(("%s: scan: retry failed\n",
+                                   device_xname(sc->sc_dev)));
+                               break;
+                       }
                }
 
                /*
@@ -405,6 +461,12 @@
                }
                lastd = i0;
 
+               /*
+                * Yield processor, but continue to hold the lock
+                * so that scan is not interrupted.
+                */
+               (void)kpause("owscan", false, 1, NULL);
+
                if (rom == 0)
                        continue;
 
@@ -437,12 +499,6 @@
                        nd->d_present = true;
                        TAILQ_INSERT_TAIL(&sc->sc_devs, nd, d_list);
                }
-
-               /*
-                * Yield processor, but continue to hold the lock
-                * so that scan is not interrupted.
-                */
-               kpause("owscan", false, 1, NULL);
        }
 
        /*
diff -r 67e9ad8381c4 -r 81e0f3347508 sys/dev/onewire/onewire_bitbang.c
--- a/sys/dev/onewire/onewire_bitbang.c Sat Nov 30 22:50:11 2019 +0000
+++ b/sys/dev/onewire/onewire_bitbang.c Sat Nov 30 23:04:12 2019 +0000
@@ -1,6 +1,35 @@
-/* $NetBSD: onewire_bitbang.c,v 1.1 2006/04/07 18:55:22 riz Exp $ */
+/*     $NetBSD: onewire_bitbang.c,v 1.2 2019/11/30 23:04:12 ad Exp $   */
 /*     $OpenBSD: onewire_bitbang.c,v 1.1 2006/03/04 16:27:03 grange Exp $      */
 
+/*-
+ * Copyright (c) 2019 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
 /*
  * Copyright (c) 2006 Alexander Yurchenko <grange%openbsd.org@localhost>
  *
@@ -18,7 +47,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: onewire_bitbang.c,v 1.1 2006/04/07 18:55:22 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: onewire_bitbang.c,v 1.2 2019/11/30 23:04:12 ad Exp $");
 
 /*
  * 1-Wire bus bit-banging routines.
@@ -27,55 +56,131 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/device.h>
+#include <sys/proc.h>
 
 #include <dev/onewire/onewirevar.h>
 
+ /*



Home | Main Index | Thread Index | Old Index