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

          Line data    Source code
       1             : /*      $OpenBSD: safte.c,v 1.53 2015/08/23 01:55:39 tedu Exp $ */
       2             : 
       3             : /*
       4             :  * Copyright (c) 2005 David Gwynne <dlg@openbsd.org>
       5             :  *
       6             :  * Permission to use, copy, modify, and distribute this software for any
       7             :  * purpose with or without fee is hereby granted, provided that the above
       8             :  * copyright notice and this permission notice appear in all copies.
       9             :  *
      10             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      11             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      12             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      13             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      14             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      15             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      16             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      17             :  */
      18             : 
      19             : #include "bio.h"
      20             : 
      21             : #include <sys/param.h>
      22             : #include <sys/systm.h>
      23             : #include <sys/device.h>
      24             : #include <sys/scsiio.h>
      25             : #include <sys/malloc.h>
      26             : #include <sys/pool.h>
      27             : #include <sys/rwlock.h>
      28             : #include <sys/queue.h>
      29             : #include <sys/sensors.h>
      30             : 
      31             : #if NBIO > 0
      32             : #include <dev/biovar.h>
      33             : #endif
      34             : 
      35             : #include <scsi/scsi_all.h>
      36             : #include <scsi/scsiconf.h>
      37             : 
      38             : #include <scsi/safte.h>
      39             : 
      40             : #ifdef SAFTE_DEBUG
      41             : #define DPRINTF(x)      do { if (safte_debug) printf x ; } while (0)
      42             : int     safte_debug = 1;
      43             : #else
      44             : #define DPRINTF(x)      /* x */
      45             : #endif
      46             : 
      47             : 
      48             : int     safte_match(struct device *, void *, void *);
      49             : void    safte_attach(struct device *, struct device *, void *);
      50             : int     safte_detach(struct device *, int);
      51             : 
      52             : struct safte_sensor {
      53             :         struct ksensor          se_sensor;
      54             :         enum {
      55             :                 SAFTE_T_FAN,
      56             :                 SAFTE_T_PWRSUP,
      57             :                 SAFTE_T_DOORLOCK,
      58             :                 SAFTE_T_ALARM,
      59             :                 SAFTE_T_TEMP
      60             :         }                       se_type;
      61             :         u_int8_t                *se_field;
      62             : };
      63             : 
      64             : struct safte_softc {
      65             :         struct device           sc_dev;
      66             :         struct scsi_link         *sc_link;
      67             :         struct rwlock           sc_lock;
      68             : 
      69             :         u_int                   sc_encbuflen;
      70             :         u_char                  *sc_encbuf;
      71             : 
      72             :         int                     sc_nsensors;
      73             :         struct safte_sensor     *sc_sensors;
      74             :         struct ksensordev       sc_sensordev;
      75             :         struct sensor_task      *sc_sensortask;
      76             : 
      77             :         int                     sc_celsius;
      78             :         int                     sc_ntemps;
      79             :         struct safte_sensor     *sc_temps;
      80             :         u_int8_t                *sc_temperrs;
      81             : 
      82             : #if NBIO > 0
      83             :         int                     sc_nslots;
      84             :         u_int8_t                *sc_slots;
      85             : #endif
      86             : };
      87             : 
      88             : struct cfattach safte_ca = {
      89             :         sizeof(struct safte_softc), safte_match, safte_attach, safte_detach
      90             : };
      91             : 
      92             : struct cfdriver safte_cd = {
      93             :         NULL, "safte", DV_DULL
      94             : };
      95             : 
      96             : #define DEVNAME(s)      ((s)->sc_dev.dv_xname)
      97             : 
      98             : int     safte_read_config(struct safte_softc *);
      99             : void    safte_read_encstat(void *);
     100             : 
     101             : #if NBIO > 0
     102             : int     safte_ioctl(struct device *, u_long, caddr_t);
     103             : int     safte_bio_blink(struct safte_softc *, struct bioc_blink *);
     104             : #endif
     105             : 
     106             : int64_t safte_temp2uK(u_int8_t, int);
     107             : 
     108             : int
     109           0 : safte_match(struct device *parent, void *match, void *aux)
     110             : {
     111             :         struct scsi_inquiry_data *inqbuf;
     112           0 :         struct scsi_attach_args *sa = aux;
     113           0 :         struct scsi_inquiry_data *inq = sa->sa_inqbuf;
     114             :         struct scsi_xfer *xs;
     115             :         struct safte_inq *si;
     116             :         int error, flags = 0, length;
     117             : 
     118           0 :         if (inq == NULL)
     119           0 :                 return (0);
     120             : 
     121             :         /* match on dell enclosures */
     122           0 :         if ((inq->device & SID_TYPE) == T_PROCESSOR &&
     123           0 :             SCSISPC(inq->version) == 3)
     124           0 :                 return (2);
     125             : 
     126           0 :         if ((inq->device & SID_TYPE) != T_PROCESSOR ||
     127           0 :             SCSISPC(inq->version) != 2 ||
     128           0 :             (inq->response_format & SID_ANSII) != 2)
     129           0 :                 return (0);
     130             : 
     131           0 :         length = inq->additional_length + SAFTE_EXTRA_OFFSET;
     132           0 :         if (length < SAFTE_INQ_LEN)
     133           0 :                 return (0);
     134           0 :         if (length > sizeof(*inqbuf))
     135           0 :                 length = sizeof(*inqbuf);
     136             : 
     137           0 :         inqbuf = dma_alloc(sizeof(*inqbuf), PR_NOWAIT | PR_ZERO);
     138           0 :         if (inqbuf == NULL)
     139           0 :                 return (0);
     140             : 
     141           0 :         memset(inqbuf->extra, ' ', sizeof(inqbuf->extra));
     142             : 
     143           0 :         if (cold)
     144           0 :                 flags |= SCSI_AUTOCONF;
     145           0 :         xs = scsi_xs_get(sa->sa_sc_link, flags | SCSI_DATA_IN);
     146           0 :         if (xs == NULL)
     147             :                 goto fail;
     148             : 
     149           0 :         xs->retries = 2;
     150           0 :         xs->timeout = 10000;
     151             : 
     152           0 :         scsi_init_inquiry(xs, 0, 0, inqbuf, length);
     153             : 
     154           0 :         error = scsi_xs_sync(xs);
     155           0 :         scsi_xs_put(xs);
     156             : 
     157           0 :         if (error)
     158             :                 goto fail;
     159             : 
     160           0 :         si = (struct safte_inq *)&inqbuf->extra;
     161           0 :         if (memcmp(si->ident, SAFTE_IDENT, sizeof(si->ident)) == 0) {
     162           0 :                 dma_free(inqbuf, sizeof(*inqbuf));
     163           0 :                 return (2);
     164             :         }
     165             : 
     166             : fail:
     167           0 :         dma_free(inqbuf, sizeof(*inqbuf));
     168           0 :         return (0);
     169           0 : }
     170             : 
     171             : void
     172           0 : safte_attach(struct device *parent, struct device *self, void *aux)
     173             : {
     174           0 :         struct safte_softc              *sc = (struct safte_softc *)self;
     175           0 :         struct scsi_attach_args         *sa = aux;
     176             :         int                             i = 0;
     177             : 
     178           0 :         sc->sc_link = sa->sa_sc_link;
     179           0 :         sa->sa_sc_link->device_softc = sc;
     180           0 :         rw_init(&sc->sc_lock, DEVNAME(sc));
     181             : 
     182           0 :         printf("\n");
     183             : 
     184           0 :         sc->sc_encbuf = NULL;
     185           0 :         sc->sc_nsensors = 0;
     186             : #if NBIO > 0
     187           0 :         sc->sc_nslots = 0;
     188             : #endif
     189             : 
     190           0 :         if (safte_read_config(sc) != 0) {
     191           0 :                 printf("%s: unable to read enclosure configuration\n",
     192             :                     DEVNAME(sc));
     193           0 :                 return;
     194             :         }
     195             : 
     196           0 :         if (sc->sc_nsensors > 0) {
     197           0 :                 sc->sc_sensortask = sensor_task_register(sc,
     198             :                     safte_read_encstat, 10);
     199           0 :                 if (sc->sc_sensortask == NULL) {
     200           0 :                         printf("%s: unable to register update task\n",
     201             :                             DEVNAME(sc));
     202           0 :                         free(sc->sc_sensors, M_DEVBUF,
     203           0 :                             sc->sc_nsensors * sizeof(struct safte_sensor));
     204           0 :                         sc->sc_nsensors = sc->sc_ntemps = 0;
     205           0 :                 } else {
     206           0 :                         for (i = 0; i < sc->sc_nsensors; i++)
     207           0 :                                 sensor_attach(&sc->sc_sensordev,
     208           0 :                                     &sc->sc_sensors[i].se_sensor);
     209           0 :                         sensordev_install(&sc->sc_sensordev);
     210             :                 }
     211             :         }
     212             : 
     213             : #if NBIO > 0
     214           0 :         if (sc->sc_nslots > 0 &&
     215           0 :             bio_register(self, safte_ioctl) != 0) {
     216           0 :                 printf("%s: unable to register ioctl with bio\n", DEVNAME(sc));
     217           0 :                 sc->sc_nslots = 0;
     218           0 :         } else
     219           0 :                 i++;
     220             : #endif
     221             : 
     222           0 :         if (i) /* if we're doing something, then preinit encbuf and sensors */
     223           0 :                 safte_read_encstat(sc);
     224             :         else {
     225           0 :                 dma_free(sc->sc_encbuf, sc->sc_encbuflen);
     226           0 :                 sc->sc_encbuf = NULL;
     227             :         }
     228           0 : }
     229             : 
     230             : int
     231           0 : safte_detach(struct device *self, int flags)
     232             : {
     233           0 :         struct safte_softc              *sc = (struct safte_softc *)self;
     234             :         int                             i;
     235             : 
     236           0 :         rw_enter_write(&sc->sc_lock);
     237             : 
     238             : #if NBIO > 0
     239           0 :         if (sc->sc_nslots > 0)
     240           0 :                 bio_unregister(self);
     241             : #endif
     242             : 
     243           0 :         if (sc->sc_nsensors > 0) {
     244           0 :                 sensordev_deinstall(&sc->sc_sensordev);
     245           0 :                 sensor_task_unregister(sc->sc_sensortask);
     246             : 
     247           0 :                 for (i = 0; i < sc->sc_nsensors; i++)
     248           0 :                         sensor_detach(&sc->sc_sensordev,
     249           0 :                             &sc->sc_sensors[i].se_sensor);
     250           0 :                 free(sc->sc_sensors, M_DEVBUF,
     251           0 :                     sc->sc_nsensors * sizeof(struct safte_sensor));
     252           0 :         }
     253             : 
     254           0 :         if (sc->sc_encbuf != NULL)
     255           0 :                 dma_free(sc->sc_encbuf, sc->sc_encbuflen);
     256             : 
     257           0 :         rw_exit_write(&sc->sc_lock);
     258             : 
     259           0 :         return (0);
     260             : }
     261             : 
     262             : int
     263           0 : safte_read_config(struct safte_softc *sc)
     264             : {
     265             :         struct safte_config *config = NULL;
     266             :         struct safte_readbuf_cmd *cmd;
     267             :         struct safte_sensor *s;
     268             :         struct scsi_xfer *xs;
     269             :         int error = 0, flags = 0, i, j;
     270             : 
     271           0 :         config = dma_alloc(sizeof(*config), PR_NOWAIT);
     272           0 :         if (config == NULL)
     273           0 :                 return (1);
     274             : 
     275           0 :         if (cold)
     276           0 :                 flags |= SCSI_AUTOCONF;
     277           0 :         xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_IN | SCSI_SILENT);
     278           0 :         if (xs == NULL) {
     279             :                 error = 1;
     280           0 :                 goto done;
     281             :         }
     282           0 :         xs->cmdlen = sizeof(*cmd);
     283           0 :         xs->data = (void *)config;
     284           0 :         xs->datalen = sizeof(*config);
     285           0 :         xs->retries = 2;
     286           0 :         xs->timeout = 30000;
     287             : 
     288           0 :         cmd = (struct safte_readbuf_cmd *)xs->cmd;
     289           0 :         cmd->opcode = READ_BUFFER;
     290           0 :         cmd->flags |= SAFTE_RD_MODE;
     291           0 :         cmd->bufferid = SAFTE_RD_CONFIG;
     292           0 :         cmd->length = htobe16(sizeof(*config));
     293             : 
     294           0 :         error = scsi_xs_sync(xs);
     295           0 :         scsi_xs_put(xs);
     296             : 
     297           0 :         if (error != 0) {
     298             :                 error = 1;
     299           0 :                 goto done;
     300             :         }
     301             : 
     302             :         DPRINTF(("%s: nfans: %d npwrsup: %d nslots: %d doorlock: %d ntemps: %d"
     303             :             " alarm: %d celsius: %d ntherm: %d\n", DEVNAME(sc), config->nfans,
     304             :             config->npwrsup, config->nslots, config->doorlock, config->ntemps,
     305             :             config->alarm, SAFTE_CFG_CELSIUS(config->therm),
     306             :             SAFTE_CFG_NTHERM(config->therm)));
     307             : 
     308           0 :         sc->sc_encbuflen = config->nfans * sizeof(u_int8_t) + /* fan status */
     309           0 :             config->npwrsup * sizeof(u_int8_t) + /* power supply status */
     310           0 :             config->nslots * sizeof(u_int8_t) + /* device scsi id (lun) */
     311           0 :             sizeof(u_int8_t) + /* door lock status */
     312           0 :             sizeof(u_int8_t) + /* speaker status */
     313           0 :             config->ntemps * sizeof(u_int8_t) + /* temp sensors */
     314             :             sizeof(u_int16_t); /* temp out of range sensors */
     315             : 
     316           0 :         sc->sc_encbuf = dma_alloc(sc->sc_encbuflen, PR_NOWAIT);
     317           0 :         if (sc->sc_encbuf == NULL) {
     318             :                 error = 1;
     319           0 :                 goto done;
     320             :         }
     321             : 
     322           0 :         sc->sc_nsensors = config->nfans + config->npwrsup + config->ntemps +
     323           0 :                 (config->doorlock ? 1 : 0) + (config->alarm ? 1 : 0);
     324             : 
     325           0 :         sc->sc_sensors = mallocarray(sc->sc_nsensors, sizeof(struct safte_sensor),
     326             :             M_DEVBUF, M_NOWAIT | M_ZERO);
     327           0 :         if (sc->sc_sensors == NULL) {
     328           0 :                 dma_free(sc->sc_encbuf, sc->sc_encbuflen);
     329           0 :                 sc->sc_encbuf = NULL;
     330           0 :                 sc->sc_nsensors = 0;
     331             :                 error = 1;
     332           0 :                 goto done;
     333             :         }
     334             : 
     335           0 :         strlcpy(sc->sc_sensordev.xname, DEVNAME(sc),
     336             :             sizeof(sc->sc_sensordev.xname));
     337             : 
     338           0 :         s = sc->sc_sensors;
     339             : 
     340           0 :         for (i = 0; i < config->nfans; i++) {
     341           0 :                 s->se_type = SAFTE_T_FAN;
     342           0 :                 s->se_field = (u_int8_t *)(sc->sc_encbuf + i);
     343           0 :                 s->se_sensor.type = SENSOR_INDICATOR;
     344           0 :                 snprintf(s->se_sensor.desc, sizeof(s->se_sensor.desc),
     345             :                     "Fan%d", i);
     346             : 
     347           0 :                 s++;
     348             :         }
     349             :         j = config->nfans;
     350             : 
     351           0 :         for (i = 0; i < config->npwrsup; i++) {
     352           0 :                 s->se_type = SAFTE_T_PWRSUP;
     353           0 :                 s->se_field = (u_int8_t *)(sc->sc_encbuf + j + i);
     354           0 :                 s->se_sensor.type = SENSOR_INDICATOR;
     355           0 :                 snprintf(s->se_sensor.desc, sizeof(s->se_sensor.desc),
     356             :                     "PSU%d", i);
     357             : 
     358           0 :                 s++;
     359             :         }
     360           0 :         j += config->npwrsup;
     361             : 
     362             : #if NBIO > 0
     363           0 :         sc->sc_nslots = config->nslots;
     364           0 :         sc->sc_slots = (u_int8_t *)(sc->sc_encbuf + j);
     365             : #endif
     366           0 :         j += config->nslots;
     367             : 
     368           0 :         if (config->doorlock) {
     369           0 :                 s->se_type = SAFTE_T_DOORLOCK;
     370           0 :                 s->se_field = (u_int8_t *)(sc->sc_encbuf + j);
     371           0 :                 s->se_sensor.type = SENSOR_INDICATOR;
     372           0 :                 strlcpy(s->se_sensor.desc, "doorlock",
     373             :                     sizeof(s->se_sensor.desc));
     374             : 
     375           0 :                 s++;
     376           0 :         }
     377           0 :         j++;
     378             : 
     379           0 :         if (config->alarm) {
     380           0 :                 s->se_type = SAFTE_T_ALARM;
     381           0 :                 s->se_field = (u_int8_t *)(sc->sc_encbuf + j);
     382           0 :                 s->se_sensor.type = SENSOR_INDICATOR;
     383           0 :                 strlcpy(s->se_sensor.desc, "alarm", sizeof(s->se_sensor.desc));
     384             : 
     385           0 :                 s++;
     386           0 :         }
     387           0 :         j++;
     388             : 
     389             :         /*
     390             :          * stash the temp info so we can get out of range status. limit the
     391             :          * number so the out of temp checks cant go into memory it doesnt own
     392             :          */
     393           0 :         sc->sc_ntemps = (config->ntemps > 15) ? 15 : config->ntemps;
     394           0 :         sc->sc_temps = s;
     395           0 :         sc->sc_celsius = SAFTE_CFG_CELSIUS(config->therm);
     396           0 :         for (i = 0; i < config->ntemps; i++) {
     397           0 :                 s->se_type = SAFTE_T_TEMP;
     398           0 :                 s->se_field = (u_int8_t *)(sc->sc_encbuf + j + i);
     399           0 :                 s->se_sensor.type = SENSOR_TEMP;
     400             : 
     401           0 :                 s++;
     402             :         }
     403           0 :         j += config->ntemps;
     404             : 
     405           0 :         sc->sc_temperrs = (u_int8_t *)(sc->sc_encbuf + j);
     406             : done:
     407           0 :         dma_free(config, sizeof(*config));
     408           0 :         return (error);
     409           0 : }
     410             : 
     411             : void
     412           0 : safte_read_encstat(void *arg)
     413             : {
     414             :         struct safte_readbuf_cmd *cmd;
     415             :         struct safte_sensor *s;
     416           0 :         struct safte_softc *sc = (struct safte_softc *)arg;
     417             :         struct scsi_xfer *xs;
     418             :         int error, i, flags = 0;
     419             :         u_int16_t oot;
     420             : 
     421           0 :         rw_enter_write(&sc->sc_lock);
     422             : 
     423           0 :         if (cold)
     424           0 :                 flags |= SCSI_AUTOCONF;
     425           0 :         xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_IN | SCSI_SILENT);
     426           0 :         if (xs == NULL) {
     427           0 :                 rw_exit_write(&sc->sc_lock);
     428           0 :                 return;
     429             :         }
     430           0 :         xs->cmdlen = sizeof(*cmd);
     431           0 :         xs->data = sc->sc_encbuf;
     432           0 :         xs->datalen = sc->sc_encbuflen;
     433           0 :         xs->retries = 2;
     434           0 :         xs->timeout = 30000;
     435             : 
     436           0 :         cmd = (struct safte_readbuf_cmd *)xs->cmd;
     437           0 :         cmd->opcode = READ_BUFFER;
     438           0 :         cmd->flags |= SAFTE_RD_MODE;
     439           0 :         cmd->bufferid = SAFTE_RD_ENCSTAT;
     440           0 :         cmd->length = htobe16(sc->sc_encbuflen);
     441             : 
     442           0 :         error = scsi_xs_sync(xs);
     443           0 :         scsi_xs_put(xs);
     444             : 
     445           0 :         if (error != 0) {
     446           0 :                 rw_exit_write(&sc->sc_lock);
     447           0 :                 return;
     448             :         }
     449             : 
     450           0 :         for (i = 0; i < sc->sc_nsensors; i++) {
     451           0 :                 s = &sc->sc_sensors[i];
     452           0 :                 s->se_sensor.flags &= ~SENSOR_FUNKNOWN;
     453             : 
     454             :                 DPRINTF(("%s: %d type: %d field: 0x%02x\n", DEVNAME(sc), i,
     455             :                     s->se_type, *s->se_field));
     456             : 
     457           0 :                 switch (s->se_type) {
     458             :                 case SAFTE_T_FAN:
     459           0 :                         switch (*s->se_field) {
     460             :                         case SAFTE_FAN_OP:
     461           0 :                                 s->se_sensor.value = 1;
     462           0 :                                 s->se_sensor.status = SENSOR_S_OK;
     463           0 :                                 break;
     464             :                         case SAFTE_FAN_MF:
     465           0 :                                 s->se_sensor.value = 0;
     466           0 :                                 s->se_sensor.status = SENSOR_S_CRIT;
     467           0 :                                 break;
     468             :                         case SAFTE_FAN_NOTINST:
     469             :                         case SAFTE_FAN_UNKNOWN:
     470             :                         default:
     471           0 :                                 s->se_sensor.value = 0;
     472           0 :                                 s->se_sensor.status = SENSOR_S_UNKNOWN;
     473           0 :                                 s->se_sensor.flags |= SENSOR_FUNKNOWN;
     474           0 :                                 break;
     475             :                         }
     476             :                         break;
     477             : 
     478             :                 case SAFTE_T_PWRSUP:
     479           0 :                         switch (*s->se_field) {
     480             :                         case SAFTE_PWR_OP_ON:
     481           0 :                                 s->se_sensor.value = 1;
     482           0 :                                 s->se_sensor.status = SENSOR_S_OK;
     483           0 :                                 break;
     484             :                         case SAFTE_PWR_OP_OFF:
     485           0 :                                 s->se_sensor.value = 0;
     486           0 :                                 s->se_sensor.status = SENSOR_S_OK;
     487           0 :                                 break;
     488             :                         case SAFTE_PWR_MF_ON:
     489           0 :                                 s->se_sensor.value = 1;
     490           0 :                                 s->se_sensor.status = SENSOR_S_CRIT;
     491           0 :                                 break;
     492             :                         case SAFTE_PWR_MF_OFF:
     493           0 :                                 s->se_sensor.value = 0;
     494           0 :                                 s->se_sensor.status = SENSOR_S_CRIT;
     495           0 :                                 break;
     496             :                         case SAFTE_PWR_NOTINST:
     497             :                         case SAFTE_PWR_PRESENT:
     498             :                         case SAFTE_PWR_UNKNOWN:
     499           0 :                                 s->se_sensor.value = 0;
     500           0 :                                 s->se_sensor.status = SENSOR_S_UNKNOWN;
     501           0 :                                 s->se_sensor.flags |= SENSOR_FUNKNOWN;
     502           0 :                                 break;
     503             :                         }
     504             :                         break;
     505             : 
     506             :                 case SAFTE_T_DOORLOCK:
     507           0 :                         switch (*s->se_field) {
     508             :                         case SAFTE_DOOR_LOCKED:
     509           0 :                                 s->se_sensor.value = 1;
     510           0 :                                 s->se_sensor.status = SENSOR_S_OK;
     511           0 :                                 break;
     512             :                         case SAFTE_DOOR_UNLOCKED:
     513           0 :                                 s->se_sensor.value = 0;
     514           0 :                                 s->se_sensor.status = SENSOR_S_CRIT;
     515           0 :                                 break;
     516             :                         case SAFTE_DOOR_UNKNOWN:
     517           0 :                                 s->se_sensor.value = 0;
     518           0 :                                 s->se_sensor.status = SENSOR_S_CRIT;
     519           0 :                                 s->se_sensor.flags |= SENSOR_FUNKNOWN;
     520           0 :                                 break;
     521             :                         }
     522             :                         break;
     523             : 
     524             :                 case SAFTE_T_ALARM:
     525           0 :                         switch (*s->se_field) {
     526             :                         case SAFTE_SPKR_OFF:
     527           0 :                                 s->se_sensor.value = 0;
     528           0 :                                 s->se_sensor.status = SENSOR_S_OK;
     529           0 :                                 break;
     530             :                         case SAFTE_SPKR_ON:
     531           0 :                                 s->se_sensor.value = 1;
     532           0 :                                 s->se_sensor.status = SENSOR_S_CRIT;
     533           0 :                                 break;
     534             :                         }
     535             :                         break;
     536             : 
     537             :                 case SAFTE_T_TEMP:
     538           0 :                         s->se_sensor.value = safte_temp2uK(*s->se_field,
     539           0 :                             sc->sc_celsius);
     540           0 :                         break;
     541             :                 }
     542             :         }
     543             : 
     544           0 :         oot = _2btol(sc->sc_temperrs);
     545           0 :         for (i = 0; i < sc->sc_ntemps; i++)
     546           0 :                 sc->sc_temps[i].se_sensor.status =
     547           0 :                     (oot & (1 << i)) ? SENSOR_S_CRIT : SENSOR_S_OK;
     548             : 
     549           0 :         rw_exit_write(&sc->sc_lock);
     550           0 : }
     551             : 
     552             : #if NBIO > 0
     553             : int
     554           0 : safte_ioctl(struct device *dev, u_long cmd, caddr_t addr)
     555             : {
     556           0 :         struct safte_softc              *sc = (struct safte_softc *)dev;
     557             :         int                             error = 0;
     558             : 
     559           0 :         switch (cmd) {
     560             :         case BIOCBLINK:
     561           0 :                 error = safte_bio_blink(sc, (struct bioc_blink *)addr);
     562           0 :                 break;
     563             : 
     564             :         default:
     565             :                 error = EINVAL;
     566           0 :                 break;
     567             :         }
     568             : 
     569           0 :         return (error);
     570             : }
     571             : 
     572             : int
     573           0 : safte_bio_blink(struct safte_softc *sc, struct bioc_blink *blink)
     574             : {
     575             :         struct safte_writebuf_cmd *cmd;
     576             :         struct safte_slotop *op;
     577             :         struct scsi_xfer *xs;
     578             :         int error, slot, flags = 0, wantblink;
     579             : 
     580           0 :         switch (blink->bb_status) {
     581             :         case BIOC_SBBLINK:
     582             :                 wantblink = 1;
     583           0 :                 break;
     584             :         case BIOC_SBUNBLINK:
     585             :                 wantblink = 0;
     586           0 :                 break;
     587             :         default:
     588           0 :                 return (EINVAL);
     589             :         }
     590             : 
     591           0 :         rw_enter_read(&sc->sc_lock);
     592           0 :         for (slot = 0; slot < sc->sc_nslots; slot++) {
     593           0 :                 if (sc->sc_slots[slot] == blink->bb_target)
     594             :                         break;
     595             :         }
     596           0 :         rw_exit_read(&sc->sc_lock);
     597             : 
     598           0 :         if (slot >= sc->sc_nslots)
     599           0 :                 return (ENODEV);
     600             : 
     601           0 :         op = dma_alloc(sizeof(*op), PR_WAITOK | PR_ZERO);
     602             : 
     603           0 :         op->opcode = SAFTE_WRITE_SLOTOP;
     604           0 :         op->slot = slot;
     605           0 :         op->flags |= wantblink ? SAFTE_SLOTOP_IDENTIFY : 0;
     606             : 
     607           0 :         if (cold)
     608           0 :                 flags |= SCSI_AUTOCONF;
     609           0 :         xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_OUT | SCSI_SILENT);
     610           0 :         if (xs == NULL) {
     611           0 :                 dma_free(op, sizeof(*op));
     612           0 :                 return (ENOMEM);
     613             :         }
     614           0 :         xs->cmdlen = sizeof(*cmd);
     615           0 :         xs->data = (void *)op;
     616           0 :         xs->datalen = sizeof(*op);
     617           0 :         xs->retries = 2;
     618           0 :         xs->timeout = 30000;
     619             : 
     620           0 :         cmd = (struct safte_writebuf_cmd *)xs->cmd;
     621           0 :         cmd->opcode = WRITE_BUFFER;
     622           0 :         cmd->flags |= SAFTE_WR_MODE;
     623           0 :         cmd->length = htobe16(sizeof(struct safte_slotop));
     624             : 
     625           0 :         error = scsi_xs_sync(xs);
     626           0 :         scsi_xs_put(xs);
     627             : 
     628           0 :         if (error != 0) {
     629             :                 error = EIO;
     630           0 :         }
     631           0 :         dma_free(op, sizeof(*op));
     632             : 
     633           0 :         return (error);
     634           0 : }
     635             : #endif /* NBIO > 0 */
     636             : 
     637             : int64_t
     638           0 : safte_temp2uK(u_int8_t measured, int celsius)
     639             : {
     640             :         int64_t                         temp;
     641             : 
     642           0 :         temp = (int64_t)measured;
     643           0 :         temp += SAFTE_TEMP_OFFSET;
     644           0 :         temp *= 1000000; /* convert to micro (mu) degrees */
     645           0 :         if (!celsius)
     646           0 :                 temp = ((temp - 32000000) * 5) / 9; /* convert to Celsius */
     647             : 
     648           0 :         temp += 273150000; /* convert to kelvin */
     649             : 
     650           0 :         return (temp);
     651             : }

Generated by: LCOV version 1.13