Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/onewire Make owtemp reliable for me:
details: https://anonhg.NetBSD.org/src/rev/91162b60ddaa
branches: trunk
changeset: 465634:91162b60ddaa
user: ad <ad%NetBSD.org@localhost>
date: Sat Nov 30 23:06:52 2019 +0000
description:
Make owtemp reliable for me:
- Don't do the calculation if there is a CRC error.
- If we get any kind of error during a refresh, retry up to three times.
- Add event counters to report what's going on.
diffstat:
sys/dev/onewire/owtemp.c | 119 +++++++++++++++++++++++++++++++++-------------
1 files changed, 84 insertions(+), 35 deletions(-)
diffs (203 lines):
diff -r d1970148ccb1 -r 91162b60ddaa sys/dev/onewire/owtemp.c
--- a/sys/dev/onewire/owtemp.c Sat Nov 30 23:04:12 2019 +0000
+++ b/sys/dev/onewire/owtemp.c Sat Nov 30 23:06:52 2019 +0000
@@ -1,6 +1,35 @@
-/* $NetBSD: owtemp.c,v 1.18 2019/10/25 16:25:14 martin Exp $ */
+/* $NetBSD: owtemp.c,v 1.19 2019/11/30 23:06:52 ad Exp $ */
/* $OpenBSD: owtemp.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>
*
@@ -22,7 +51,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: owtemp.c,v 1.18 2019/10/25 16:25:14 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: owtemp.c,v 1.19 2019/11/30 23:06:52 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -51,14 +80,20 @@
uint32_t (*sc_owtemp_decode)(const uint8_t *);
int sc_dying;
+
+ struct evcnt sc_ev_update;
+ struct evcnt sc_ev_rsterr;
+ struct evcnt sc_ev_crcerr;
};
static int owtemp_match(device_t, cfdata_t, void *);
static void owtemp_attach(device_t, device_t, void *);
static int owtemp_detach(device_t, int);
static int owtemp_activate(device_t, enum devact);
-
-static void owtemp_update(void *);
+static bool owtemp_update(struct owtemp_softc *sc, uint32_t *temp);
+static void owtemp_refresh(struct sysmon_envsys *, envsys_data_t *);
+static uint32_t owtemp_decode_ds18b20(const uint8_t *);
+static uint32_t owtemp_decode_ds1920(const uint8_t *);
CFATTACH_DECL_NEW(owtemp, sizeof(struct owtemp_softc),
owtemp_match, owtemp_attach, owtemp_detach, owtemp_activate);
@@ -71,10 +106,7 @@
{ ONEWIRE_FAMILY_DS1822 },
};
-static void owtemp_refresh(struct sysmon_envsys *, envsys_data_t *);
-
-static uint32_t owtemp_decode_ds18b20(const uint8_t *);
-static uint32_t owtemp_decode_ds1920(const uint8_t *);
+int owtemp_retries = 3;
static int
owtemp_match(device_t parent, cfdata_t match, void *aux)
@@ -110,6 +142,13 @@
break;
}
+ evcnt_attach_dynamic(&sc->sc_ev_update, EVCNT_TYPE_MISC, NULL,
+ device_xname(self), "update");
+ evcnt_attach_dynamic(&sc->sc_ev_rsterr, EVCNT_TYPE_MISC, NULL,
+ device_xname(self), "reset error");
+ evcnt_attach_dynamic(&sc->sc_ev_crcerr, EVCNT_TYPE_MISC, NULL,
+ device_xname(self), "crc error");
+
sc->sc_sme = sysmon_envsys_create();
/* Initialize sensor */
@@ -144,6 +183,9 @@
struct owtemp_softc *sc = device_private(self);
sysmon_envsys_unregister(sc->sc_sme);
+ evcnt_detach(&sc->sc_ev_rsterr);
+ evcnt_detach(&sc->sc_ev_update);
+ evcnt_detach(&sc->sc_ev_crcerr);
return 0;
}
@@ -162,18 +204,12 @@
}
}
-static void
-owtemp_update(void *arg)
+static bool
+owtemp_update(struct owtemp_softc *sc, uint32_t *temp)
{
- struct owtemp_softc *sc = arg;
u_int8_t data[9];
- onewire_lock(sc->sc_onewire);
- if (onewire_reset(sc->sc_onewire) != 0) {
- aprint_error_dev(sc->sc_dv, "owtemp_update: 1st reset failed\n");
- goto done;
- }
- onewire_matchrom(sc->sc_onewire, sc->sc_rom);
+ sc->sc_ev_update.ev_count++;
/*
* Start temperature conversion. The conversion takes up to 750ms.
@@ -182,41 +218,54 @@
* As such, no other activity may take place on the 1-Wire bus for
* at least this period. Keep the parent bus locked while waiting.
*/
- onewire_write_byte(sc->sc_onewire, DS_CMD_CONVERT);
- kpause("owtemp", false, mstohz(750 + 10), NULL);
-
if (onewire_reset(sc->sc_onewire) != 0) {
- aprint_error_dev(sc->sc_dv, "owtemp_update: 2nd reset failed\n");
- goto done;
+ sc->sc_ev_rsterr.ev_count++;
+ return false;
}
onewire_matchrom(sc->sc_onewire, sc->sc_rom);
+ onewire_write_byte(sc->sc_onewire, DS_CMD_CONVERT);
+ (void)kpause("owtemp", false, mstohz(750 + 10), NULL);
/*
* The result of the temperature measurement is placed in the
- * first two bytes of the scratchpad.
+ * first two bytes of the scratchpad. Perform the caculation
+ * only if the CRC is correct.
*/
+ if (onewire_reset(sc->sc_onewire) != 0) {
+ sc->sc_ev_rsterr.ev_count++;
+ return false;
+ }
+ onewire_matchrom(sc->sc_onewire, sc->sc_rom);
onewire_write_byte(sc->sc_onewire, DS_CMD_READ_SCRATCHPAD);
onewire_read_block(sc->sc_onewire, data, 9);
-#if 0
- if (onewire_crc(data, 8) == data[8]) {
- sc->sc_sensor.value = 273150000 +
- (int)((u_int16_t)data[1] << 8 | data[0]) * 500000;
+ if (onewire_crc(data, 8) != data[8]) {
+ sc->sc_ev_crcerr.ev_count++;
+ return false;
}
-#endif
-
- sc->sc_sensor.value_cur = sc->sc_owtemp_decode(data);
- sc->sc_sensor.state = ENVSYS_SVALID;
-
-done:
- onewire_unlock(sc->sc_onewire);
+ *temp = sc->sc_owtemp_decode(data);
+ return true;
}
static void
owtemp_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
{
struct owtemp_softc *sc = sme->sme_cookie;
+ uint32_t reading;
+ int retry;
- owtemp_update(sc);
+ onewire_lock(sc->sc_onewire);
+ for (retry = 0; retry < owtemp_retries; retry++) {
+ if (owtemp_update(sc, &reading)) {
+ onewire_unlock(sc->sc_onewire);
+ sc->sc_sensor.value_cur = reading;
+ sc->sc_sensor.state = ENVSYS_SVALID;
+ return;
+ }
+ }
+ onewire_unlock(sc->sc_onewire);
+ aprint_error_dev(sc->sc_dv,
+ "update failed - use vmstat(8) to check event counters\n");
+ sc->sc_sensor.state = ENVSYS_SINVALID;
}
static uint32_t
Home |
Main Index |
Thread Index |
Old Index