LCOV - code coverage report
Current view: top level - dev/onewire - owctr.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 85 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: owctr.c,v 1.8 2015/08/27 05:49:23 deraadt Exp $       */
       2             : /*
       3             :  * Copyright (c) 2010 John L. Scarfone <john@scarfone.net>
       4             :  *
       5             :  * Permission to use, copy, modify, and distribute this software for any
       6             :  * purpose with or without fee is hereby granted, provided that the above
       7             :  * copyright notice and this permission notice appear in all copies.
       8             :  *
       9             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      10             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      11             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      12             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      13             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      14             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      15             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      16             :  */
      17             : 
      18             : /*
      19             :  * DS2423 1-Wire 4kbit SRAM with Counter family type device driver.
      20             :  * Provides 4096 bits of SRAM and four 32-bit, read-only counters.
      21             :  * This driver provides access to the two externally triggered
      22             :  * counters.
      23             :  */
      24             : 
      25             : #include <sys/param.h>
      26             : #include <sys/systm.h>
      27             : #include <sys/device.h>
      28             : #include <sys/malloc.h>
      29             : #include <sys/rwlock.h>
      30             : #include <sys/sensors.h>
      31             : 
      32             : #include <dev/onewire/onewiredevs.h>
      33             : #include <dev/onewire/onewirereg.h>
      34             : #include <dev/onewire/onewirevar.h>
      35             : 
      36             : /* Commands */
      37             : #define DSCTR_CMD_READ_MEMCOUNTER       0xa5
      38             : 
      39             : /* External counter banks */
      40             : #define DS2423_COUNTER_BANK_A           0x1c0
      41             : #define DS2423_COUNTER_BANK_B           0x1e0
      42             : 
      43             : /* Buffer offsets */
      44             : #define DS2423_COUNTER_BUF_COUNTER      35
      45             : #define DS2423_COUNTER_BUF_CRC          43
      46             : 
      47             : #define DS2423_COUNTER_BUFSZ            45
      48             : 
      49             : struct owctr_softc {
      50             :         struct device           sc_dev;
      51             : 
      52             :         void *                  sc_onewire;
      53             :         u_int64_t               sc_rom;
      54             : 
      55             :         struct ksensordev       sc_sensordev;
      56             : 
      57             :         struct ksensor          sc_counterA;
      58             :         struct ksensor          sc_counterB;
      59             : 
      60             :         struct sensor_task      *sc_sensortask;
      61             : 
      62             :         struct rwlock           sc_lock;
      63             : };
      64             : 
      65             : int     owctr_match(struct device *, void *, void *);
      66             : void    owctr_attach(struct device *, struct device *, void *);
      67             : int     owctr_detach(struct device *, int);
      68             : int     owctr_activate(struct device *, int);
      69             : 
      70             : void    owctr_update(void *);
      71             : void    owctr_update_counter(void *, int);
      72             : 
      73             : struct cfattach owctr_ca = {
      74             :         sizeof(struct owctr_softc),
      75             :         owctr_match,
      76             :         owctr_attach,
      77             :         owctr_detach,
      78             :         owctr_activate
      79             : };
      80             : 
      81             : struct cfdriver owctr_cd = {
      82             :         NULL, "owctr", DV_DULL
      83             : };
      84             : 
      85             : static const struct onewire_matchfam owctr_fams[] = {
      86             :         { ONEWIRE_FAMILY_DS2423 }
      87             : };
      88             : 
      89             : int
      90           0 : owctr_match(struct device *parent, void *match, void *aux)
      91             : {
      92           0 :         return (onewire_matchbyfam(aux, owctr_fams, nitems(owctr_fams)));
      93             : }
      94             : 
      95             : void
      96           0 : owctr_attach(struct device *parent, struct device *self, void *aux)
      97             : {
      98           0 :         struct owctr_softc *sc = (struct owctr_softc *)self;
      99           0 :         struct onewire_attach_args *oa = aux;
     100             : 
     101           0 :         sc->sc_onewire = oa->oa_onewire;
     102           0 :         sc->sc_rom = oa->oa_rom;
     103             : 
     104             :         /* Initialize counter sensors */
     105           0 :         strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
     106             :                 sizeof(sc->sc_sensordev.xname));
     107           0 :         sc->sc_counterA.type = SENSOR_INTEGER;
     108           0 :         snprintf(sc->sc_counterA.desc, sizeof(sc->sc_counterA.desc),
     109           0 :                 "Counter A sn %012llx", ONEWIRE_ROM_SN(oa->oa_rom));
     110           0 :         sensor_attach(&sc->sc_sensordev, &sc->sc_counterA);
     111           0 :         sc->sc_counterB.type = SENSOR_INTEGER;
     112           0 :         snprintf(sc->sc_counterB.desc, sizeof(sc->sc_counterB.desc),
     113           0 :                 "Counter B sn %012llx", ONEWIRE_ROM_SN(oa->oa_rom));
     114           0 :         sensor_attach(&sc->sc_sensordev, &sc->sc_counterB);
     115             : 
     116           0 :         sc->sc_sensortask = sensor_task_register(sc, owctr_update, 10);
     117           0 :         if (sc->sc_sensortask == NULL) {
     118           0 :                 printf(": unable to register update task\n");
     119           0 :                 return;
     120             :         }
     121             : 
     122           0 :         sensordev_install(&sc->sc_sensordev);
     123             : 
     124           0 :         rw_init(&sc->sc_lock, sc->sc_dev.dv_xname);
     125           0 :         printf("\n");
     126           0 : }
     127             : 
     128             : int
     129           0 : owctr_detach(struct device *self, int flags)
     130             : {
     131           0 :         struct owctr_softc *sc = (struct owctr_softc *)self;
     132             : 
     133           0 :         rw_enter_write(&sc->sc_lock);
     134           0 :         sensordev_deinstall(&sc->sc_sensordev);
     135           0 :         if (sc->sc_sensortask != NULL)
     136           0 :                 sensor_task_unregister(sc->sc_sensortask);
     137           0 :         rw_exit_write(&sc->sc_lock);
     138             : 
     139           0 :         return (0);
     140             : }
     141             : 
     142             : int
     143           0 : owctr_activate(struct device *self, int act)
     144             : {
     145           0 :         return (0);
     146             : }
     147             : 
     148             : void
     149           0 : owctr_update(void *arg)
     150             : {
     151           0 :         owctr_update_counter(arg, DS2423_COUNTER_BANK_A);
     152           0 :         owctr_update_counter(arg, DS2423_COUNTER_BANK_B);
     153           0 : }
     154             : 
     155             : void
     156           0 : owctr_update_counter(void *arg, int bank)
     157             : {
     158           0 :         struct owctr_softc *sc = arg;
     159             :         u_int32_t counter;
     160             :         u_int16_t crc;
     161             :         u_int8_t *buf;
     162             : 
     163           0 :         rw_enter_write(&sc->sc_lock);
     164           0 :         onewire_lock(sc->sc_onewire, 0);
     165           0 :         if (onewire_reset(sc->sc_onewire) != 0)
     166             :                 goto done;
     167             : 
     168           0 :         buf = malloc(DS2423_COUNTER_BUFSZ, M_DEVBUF, M_NOWAIT);
     169           0 :         if (buf == NULL) {
     170           0 :                 printf("%s: malloc() failed\n", sc->sc_dev.dv_xname);
     171           0 :                 goto done;
     172             :         }
     173             : 
     174           0 :         onewire_matchrom(sc->sc_onewire, sc->sc_rom);
     175           0 :         buf[0] = DSCTR_CMD_READ_MEMCOUNTER;
     176           0 :         buf[1] = bank;
     177           0 :         buf[2] = bank >> 8;
     178           0 :         onewire_write_byte(sc->sc_onewire, buf[0]);
     179           0 :         onewire_write_byte(sc->sc_onewire, buf[1]);
     180           0 :         onewire_write_byte(sc->sc_onewire, buf[2]);
     181           0 :         onewire_read_block(sc->sc_onewire, &buf[3], DS2423_COUNTER_BUFSZ-3);
     182             : 
     183           0 :         crc = onewire_crc16(buf, DS2423_COUNTER_BUFSZ-2);
     184           0 :         crc ^= buf[DS2423_COUNTER_BUF_CRC]
     185           0 :                 | (buf[DS2423_COUNTER_BUF_CRC+1] << 8);
     186           0 :         if ( crc != 0xffff) {
     187           0 :                 printf("%s: invalid CRC\n", sc->sc_dev.dv_xname);
     188           0 :                 if (bank == DS2423_COUNTER_BANK_A) {
     189           0 :                         sc->sc_counterA.value = 0;
     190           0 :                         sc->sc_counterA.status = SENSOR_S_UNKNOWN;
     191           0 :                         sc->sc_counterA.flags |= SENSOR_FUNKNOWN;
     192           0 :                 } else {
     193           0 :                         sc->sc_counterB.value = 0;
     194           0 :                         sc->sc_counterB.status = SENSOR_S_UNKNOWN;
     195           0 :                         sc->sc_counterB.flags |= SENSOR_FUNKNOWN;
     196             :                 }
     197             :         } else {
     198           0 :                 counter = buf[DS2423_COUNTER_BUF_COUNTER]
     199           0 :                         | (buf[DS2423_COUNTER_BUF_COUNTER+1] << 8)
     200           0 :                         | (buf[DS2423_COUNTER_BUF_COUNTER+2] << 16)
     201           0 :                         | (buf[DS2423_COUNTER_BUF_COUNTER+3] << 24);
     202           0 :                 if (bank == DS2423_COUNTER_BANK_A) {
     203           0 :                         sc->sc_counterA.value = counter;
     204           0 :                         sc->sc_counterA.status = SENSOR_S_UNSPEC;
     205           0 :                         sc->sc_counterA.flags &= ~SENSOR_FUNKNOWN;
     206           0 :                 } else {
     207           0 :                         sc->sc_counterB.value = counter;
     208           0 :                         sc->sc_counterB.status = SENSOR_S_UNSPEC;
     209           0 :                         sc->sc_counterB.flags &= ~SENSOR_FUNKNOWN;
     210             :                 }
     211             :         }
     212             : 
     213           0 :         onewire_reset(sc->sc_onewire);
     214           0 :         free(buf, M_DEVBUF, DS2423_COUNTER_BUFSZ);
     215             : 
     216             : done:
     217           0 :         onewire_unlock(sc->sc_onewire);
     218           0 :         rw_exit_write(&sc->sc_lock);
     219           0 : }

Generated by: LCOV version 1.13