- just use a buffer and make onewire_crc16() operate like onewire_crc() - some style cleanups - build for i386 GENERIC (only arch tested)
Index: onewire_subr.c =================================================================== RCS file: /cvs/src/sys/dev/onewire/onewire_subr.c,v retrieving revision 1.3 diff -N -u -p onewire_subr.c --- onewire_subr.c 6 Jul 2010 19:59:59 -0000 1.3 +++ onewire_subr.c 17 Jul 2010 19:09:16 -0000 @@ -150,15 +150,21 @@ onewire_crc(const void *buf, int len) } u_int16_t -onewire_crc16(u_int16_t crc16, u_int8_t data) +onewire_crc16(const void *buf, int len) { + const u_int8_t *p = buf; + u_int16_t crc = 0; + u_int16_t tmpcrc; int idx; - u_int16_t newcrc16; - idx = (crc16 & 0xff) ^ data; - newcrc16 = crc16_table_high[idx] << 8; - newcrc16 |= crc16_table_low[idx] ^ (crc16 >> 8); - return (newcrc16); + while (len--) { + idx = (crc & 0xff) ^ *p++; + tmpcrc = crc16_table_high[idx] << 8; + tmpcrc |= crc16_table_low[idx] ^ (crc >> 8); + crc = tmpcrc; + } + + return (crc); } const char * Index: onewirevar.h =================================================================== RCS file: /cvs/src/sys/dev/onewire/onewirevar.h,v retrieving revision 1.6 diff -N -u -p onewirevar.h --- onewirevar.h 6 Jul 2010 19:59:59 -0000 1.6 +++ onewirevar.h 17 Jul 2010 19:09:16 -0000 @@ -77,7 +77,7 @@ struct onewire_matchfam { /* Miscellaneous routines */ int onewire_crc(const void *, int); -u_int16_t onewire_crc16(u_int16_t, u_int8_t); +u_int16_t onewire_crc16(const void *, int); const char * onewire_famname(int); int onewire_matchbyfam(struct onewire_attach_args *, const struct onewire_matchfam *, int); Index: owctr.c =================================================================== RCS file: /cvs/src/sys/dev/onewire/owctr.c,v retrieving revision 1.3 diff -N -u -p owctr.c --- owctr.c 8 Jul 2010 07:19:54 -0000 1.3 +++ owctr.c 17 Jul 2010 19:09:16 -0000 @@ -26,6 +26,7 @@ #include <sys/systm.h> #include <sys/device.h> #include <sys/kernel.h> +#include <sys/malloc.h> #include <sys/proc.h> #include <sys/rwlock.h> #include <sys/sensors.h> @@ -41,6 +42,12 @@ #define DS2423_COUNTER_BANK_A 0x1c0 #define DS2423_COUNTER_BANK_B 0x1e0 +/* Buffer offsets */ +#define DS2423_COUNTER_BUF_COUNTER 35 +#define DS2423_COUNTER_BUF_CRC 43 + +#define DS2423_COUNTER_BUFSZ 45 + struct owctr_softc { struct device sc_dev; @@ -153,78 +160,60 @@ owctr_update_counter(void *arg, int bank) struct owctr_softc *sc = arg; u_int32_t counter; u_int16_t crc; - int data; - int i; + u_int8_t *buf; rw_enter_write(&sc->sc_lock); onewire_lock(sc->sc_onewire, 0); if (onewire_reset(sc->sc_onewire) != 0) goto done; - onewire_matchrom(sc->sc_onewire, sc->sc_rom); - onewire_write_byte(sc->sc_onewire, DSCTR_CMD_READ_MEMCOUNTER); - crc = onewire_crc16(0, DSCTR_CMD_READ_MEMCOUNTER); - onewire_write_byte(sc->sc_onewire, bank); - crc = onewire_crc16(crc, bank); - onewire_write_byte(sc->sc_onewire, bank >> 8); - crc = onewire_crc16(crc, bank >> 8); - for (i=0; i<32; ++i) - { - data = onewire_read_byte(sc->sc_onewire); - crc = onewire_crc16(crc, data); + buf = malloc(DS2423_COUNTER_BUFSZ, M_DEVBUF, M_NOWAIT); + if (buf == NULL) { + printf("%s: malloc() failed\n", sc->sc_dev.dv_xname); + goto done; } - data = onewire_read_byte(sc->sc_onewire); - crc = onewire_crc16(crc, data); - counter = data; - data = onewire_read_byte(sc->sc_onewire); - crc = onewire_crc16(crc, data); - counter |= data << 8; - data = onewire_read_byte(sc->sc_onewire); - crc = onewire_crc16(crc, data); - counter |= data << 16; - data = onewire_read_byte(sc->sc_onewire); - crc = onewire_crc16(crc, data); - counter |= data << 24; - for (i=0; i<4; ++i) - { - onewire_read_byte(sc->sc_onewire); - crc = onewire_crc16(crc, data); - } - data = onewire_read_byte(sc->sc_onewire); - crc ^= data; - data = onewire_read_byte(sc->sc_onewire); - crc ^= data << 8; - if ( crc != 0xffff) - { + + onewire_matchrom(sc->sc_onewire, sc->sc_rom); + buf[0] = DSCTR_CMD_READ_MEMCOUNTER; + buf[1] = bank; + buf[2] = bank >> 8; + onewire_write_byte(sc->sc_onewire, buf[0]); + onewire_write_byte(sc->sc_onewire, buf[1]); + onewire_write_byte(sc->sc_onewire, buf[2]); + onewire_read_block(sc->sc_onewire, &buf[3], DS2423_COUNTER_BUFSZ-3); + + crc = onewire_crc16(buf, DS2423_COUNTER_BUFSZ-2); + crc ^= buf[DS2423_COUNTER_BUF_CRC] + | (buf[DS2423_COUNTER_BUF_CRC+1] << 8); + if ( crc != 0xffff) { printf("%s: invalid CRC\n", sc->sc_dev.dv_xname); if (bank == DS2423_COUNTER_BANK_A) { sc->sc_counterA.value = 0; sc->sc_counterA.status = SENSOR_S_UNKNOWN; sc->sc_counterA.flags |= SENSOR_FUNKNOWN; - } - else - { + } else { sc->sc_counterB.value = 0; sc->sc_counterB.status = SENSOR_S_UNKNOWN; sc->sc_counterB.flags |= SENSOR_FUNKNOWN; } - } - else - { - if (bank == DS2423_COUNTER_BANK_A) - { + } else { + counter = buf[DS2423_COUNTER_BUF_COUNTER] + | (buf[DS2423_COUNTER_BUF_COUNTER+1] << 8) + | (buf[DS2423_COUNTER_BUF_COUNTER+2] << 16) + | (buf[DS2423_COUNTER_BUF_COUNTER+3] << 24); + if (bank == DS2423_COUNTER_BANK_A) { sc->sc_counterA.value = counter; sc->sc_counterA.status = SENSOR_S_UNSPEC; sc->sc_counterA.flags &= ~SENSOR_FUNKNOWN; - } - else - { + } else { sc->sc_counterB.value = counter; sc->sc_counterB.status = SENSOR_S_UNSPEC; sc->sc_counterB.flags &= ~SENSOR_FUNKNOWN; } } + onewire_reset(sc->sc_onewire); + free(buf, M_DEVBUF); done: onewire_unlock(sc->sc_onewire); Index: GENERIC =================================================================== RCS file: /cvs/src/sys/arch/i386/conf/GENERIC,v retrieving revision 1.688 diff -N -u -p GENERIC --- GENERIC 5 Jul 2010 22:20:22 -0000 1.688 +++ GENERIC 7 Jul 2010 13:35:47 -0000 @@ -837,6 +837,7 @@ option ONEWIREVERBOSE owid* at onewire? # ID owsbm* at onewire? # Smart Battery Monitor owtemp* at onewire? # Temperature +owctr* at onewire? # Counter pseudo-device pctr 1 pseudo-device mtrr 1 # Memory range attributes control