[BACK]Return to safte.c CVS log [TXT][DIR] Up to [local] / sys / scsi

Annotation of sys/scsi/safte.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: safte.c,v 1.37 2007/06/24 05:34:35 dlg 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/proc.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_int16_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: safte_match(struct device *parent, void *match, void *aux)
                    110: {
                    111:        struct scsi_attach_args         *sa = aux;
                    112:        struct scsi_inquiry_data        *inq = sa->sa_inqbuf;
                    113:        struct scsi_inquiry_data        inqbuf;
                    114:        struct scsi_inquiry             cmd;
                    115:        struct safte_inq                *si = (struct safte_inq *)&inqbuf.extra;
                    116:        int                             length, flags;
                    117:
                    118:        if (inq == NULL)
                    119:                return (0);
                    120:
                    121:        /* match on dell enclosures */
                    122:        if ((inq->device & SID_TYPE) == T_PROCESSOR &&
                    123:            SCSISPC(inq->version) == 3)
                    124:                return (2);
                    125:
                    126:        if ((inq->device & SID_TYPE) != T_PROCESSOR ||
                    127:            SCSISPC(inq->version) != 2 ||
                    128:            (inq->response_format & SID_ANSII) != 2)
                    129:                return (0);
                    130:
                    131:        length = inq->additional_length + SAFTE_EXTRA_OFFSET;
                    132:        if (length < SAFTE_INQ_LEN)
                    133:                return (0);
                    134:        if (length > sizeof(inqbuf))
                    135:                length = sizeof(inqbuf);
                    136:
                    137:        memset(&cmd, 0, sizeof(cmd));
                    138:        cmd.opcode = INQUIRY;
                    139:        _lto2b(length, cmd.length);
                    140:
                    141:        memset(&inqbuf, 0, sizeof(inqbuf));
                    142:        memset(&inqbuf.extra, ' ', sizeof(inqbuf.extra));
                    143:
                    144:        flags = SCSI_DATA_IN;
                    145:        if (cold)
                    146:                flags |= SCSI_AUTOCONF;
                    147:
                    148:        if (scsi_scsi_cmd(sa->sa_sc_link, (struct scsi_generic *)&cmd,
                    149:            sizeof(cmd), (u_char *)&inqbuf, length, 2, 10000, NULL,
                    150:            flags) != 0)
                    151:                return (0);
                    152:
                    153:        if (memcmp(si->ident, SAFTE_IDENT, sizeof(si->ident)) == 0)
                    154:                return (2);
                    155:
                    156:        return (0);
                    157: }
                    158:
                    159: void
                    160: safte_attach(struct device *parent, struct device *self, void *aux)
                    161: {
                    162:        struct safte_softc              *sc = (struct safte_softc *)self;
                    163:        struct scsi_attach_args         *sa = aux;
                    164:        int                             i = 0;
                    165:
                    166:        sc->sc_link = sa->sa_sc_link;
                    167:        sa->sa_sc_link->device_softc = sc;
                    168:        rw_init(&sc->sc_lock, DEVNAME(sc));
                    169:
                    170:        printf("\n");
                    171:
                    172:        sc->sc_encbuf = NULL;
                    173:        sc->sc_nsensors = 0;
                    174: #if NBIO > 0
                    175:        sc->sc_nslots = 0;
                    176: #endif
                    177:
                    178:        if (safte_read_config(sc) != 0) {
                    179:                printf("%s: unable to read enclosure configuration\n",
                    180:                    DEVNAME(sc));
                    181:                return;
                    182:        }
                    183:
                    184:        if (sc->sc_nsensors > 0) {
                    185:                sc->sc_sensortask = sensor_task_register(sc,
                    186:                    safte_read_encstat, 10);
                    187:                if (sc->sc_sensortask == NULL) {
                    188:                        printf("%s: unable to register update task\n",
                    189:                            DEVNAME(sc));
                    190:                        sc->sc_nsensors = sc->sc_ntemps = 0;
                    191:                        free(sc->sc_sensors, M_DEVBUF);
                    192:                } else {
                    193:                        for (i = 0; i < sc->sc_nsensors; i++)
                    194:                                sensor_attach(&sc->sc_sensordev,
                    195:                                    &sc->sc_sensors[i].se_sensor);
                    196:                        sensordev_install(&sc->sc_sensordev);
                    197:                }
                    198:        }
                    199:
                    200: #if NBIO > 0
                    201:        if (sc->sc_nslots > 0 &&
                    202:            bio_register(self, safte_ioctl) != 0) {
                    203:                printf("%s: unable to register ioctl with bio\n", DEVNAME(sc));
                    204:                sc->sc_nslots = 0;
                    205:        } else
                    206:                i++;
                    207: #endif
                    208:
                    209:        if (i) /* if we're doing something, then preinit encbuf and sensors */
                    210:                safte_read_encstat(sc);
                    211:        else {
                    212:                free(sc->sc_encbuf, M_DEVBUF);
                    213:                sc->sc_encbuf = NULL;
                    214:        }
                    215: }
                    216:
                    217: int
                    218: safte_detach(struct device *self, int flags)
                    219: {
                    220:        struct safte_softc              *sc = (struct safte_softc *)self;
                    221:        int                             i;
                    222:
                    223:        rw_enter_write(&sc->sc_lock);
                    224:
                    225: #if NBIO > 0
                    226:        if (sc->sc_nslots > 0)
                    227:                bio_unregister(self);
                    228: #endif
                    229:
                    230:        if (sc->sc_nsensors > 0) {
                    231:                sensordev_deinstall(&sc->sc_sensordev);
                    232:                sensor_task_unregister(sc->sc_sensortask);
                    233:
                    234:                for (i = 0; i < sc->sc_nsensors; i++)
                    235:                        sensor_detach(&sc->sc_sensordev,
                    236:                            &sc->sc_sensors[i].se_sensor);
                    237:                free(sc->sc_sensors, M_DEVBUF);
                    238:        }
                    239:
                    240:        if (sc->sc_encbuf != NULL)
                    241:                free(sc->sc_encbuf, M_DEVBUF);
                    242:
                    243:        rw_exit_write(&sc->sc_lock);
                    244:
                    245:        return (0);
                    246: }
                    247:
                    248: int
                    249: safte_read_config(struct safte_softc *sc)
                    250: {
                    251:        struct safte_readbuf_cmd        cmd;
                    252:        struct safte_config             config;
                    253:        struct safte_sensor             *s;
                    254:        int                             flags, i, j;
                    255:
                    256:        memset(&cmd, 0, sizeof(cmd));
                    257:        cmd.opcode = READ_BUFFER;
                    258:        cmd.flags |= SAFTE_RD_MODE;
                    259:        cmd.bufferid = SAFTE_RD_CONFIG;
                    260:        cmd.length = htobe16(sizeof(config));
                    261:        flags = SCSI_DATA_IN;
                    262: #ifndef SCSIDEBUG
                    263:        flags |= SCSI_SILENT;
                    264: #endif
                    265:
                    266:        if (cold)
                    267:                flags |= SCSI_AUTOCONF;
                    268:
                    269:        if (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd,
                    270:            sizeof(cmd), (u_char *)&config, sizeof(config), 2, 30000, NULL,
                    271:            flags) != 0)
                    272:                return (1);
                    273:
                    274:        DPRINTF(("%s: nfans: %d npwrsup: %d nslots: %d doorlock: %d ntemps: %d"
                    275:            " alarm: %d celsius: %d ntherm: %d\n", DEVNAME(sc), config.nfans,
                    276:            config.npwrsup, config.nslots, config.doorlock, config.ntemps,
                    277:            config.alarm, SAFTE_CFG_CELSIUS(config.therm),
                    278:            SAFTE_CFG_NTHERM(config.therm)));
                    279:
                    280:        sc->sc_encbuflen = config.nfans * sizeof(u_int8_t) + /* fan status */
                    281:            config.npwrsup * sizeof(u_int8_t) + /* power supply status */
                    282:            config.nslots * sizeof(u_int8_t) + /* device scsi id (lun) */
                    283:            sizeof(u_int8_t) + /* door lock status */
                    284:            sizeof(u_int8_t) + /* speaker status */
                    285:            config.ntemps * sizeof(u_int8_t) + /* temp sensors */
                    286:            sizeof(u_int16_t); /* temp out of range sensors */
                    287:
                    288:        sc->sc_encbuf = malloc(sc->sc_encbuflen, M_DEVBUF, M_NOWAIT);
                    289:        if (sc->sc_encbuf == NULL)
                    290:                return (1);
                    291:
                    292:        sc->sc_nsensors = config.nfans + config.npwrsup + config.ntemps +
                    293:                (config.doorlock ? 1 : 0) + (config.alarm ? 1 : 0);
                    294:
                    295:        sc->sc_sensors = malloc(sc->sc_nsensors * sizeof(struct safte_sensor),
                    296:            M_DEVBUF, M_NOWAIT);
                    297:        if (sc->sc_sensors == NULL) {
                    298:                free(sc->sc_encbuf, M_DEVBUF);
                    299:                sc->sc_encbuf = NULL;
                    300:                sc->sc_nsensors = 0;
                    301:                return (1);
                    302:        }
                    303:
                    304:        strlcpy(sc->sc_sensordev.xname, DEVNAME(sc),
                    305:            sizeof(sc->sc_sensordev.xname));
                    306:
                    307:        memset(sc->sc_sensors, 0,
                    308:            sc->sc_nsensors * sizeof(struct safte_sensor));
                    309:        s = sc->sc_sensors;
                    310:
                    311:        for (i = 0; i < config.nfans; i++) {
                    312:                s->se_type = SAFTE_T_FAN;
                    313:                s->se_field = (u_int8_t *)(sc->sc_encbuf + i);
                    314:                s->se_sensor.type = SENSOR_INDICATOR;
                    315:                snprintf(s->se_sensor.desc, sizeof(s->se_sensor.desc),
                    316:                    "Fan%d", i);
                    317:
                    318:                s++;
                    319:        }
                    320:        j = config.nfans;
                    321:
                    322:        for (i = 0; i < config.npwrsup; i++) {
                    323:                s->se_type = SAFTE_T_PWRSUP;
                    324:                s->se_field = (u_int8_t *)(sc->sc_encbuf + j + i);
                    325:                s->se_sensor.type = SENSOR_INDICATOR;
                    326:                snprintf(s->se_sensor.desc, sizeof(s->se_sensor.desc),
                    327:                    "PSU%d", i);
                    328:
                    329:                s++;
                    330:        }
                    331:        j += config.npwrsup;
                    332:
                    333: #if NBIO > 0
                    334:        sc->sc_nslots = config.nslots;
                    335:        sc->sc_slots = (u_int8_t *)(sc->sc_encbuf + j);
                    336: #endif
                    337:        j += config.nslots;
                    338:
                    339:        if (config.doorlock) {
                    340:                s->se_type = SAFTE_T_DOORLOCK;
                    341:                s->se_field = (u_int8_t *)(sc->sc_encbuf + j);
                    342:                s->se_sensor.type = SENSOR_INDICATOR;
                    343:                strlcpy(s->se_sensor.desc, "doorlock",
                    344:                    sizeof(s->se_sensor.desc));
                    345:
                    346:                s++;
                    347:        }
                    348:        j++;
                    349:
                    350:        if (config.alarm) {
                    351:                s->se_type = SAFTE_T_ALARM;
                    352:                s->se_field = (u_int8_t *)(sc->sc_encbuf + j);
                    353:                s->se_sensor.type = SENSOR_INDICATOR;
                    354:                strlcpy(s->se_sensor.desc, "alarm", sizeof(s->se_sensor.desc));
                    355:
                    356:                s++;
                    357:        }
                    358:        j++;
                    359:
                    360:        /*
                    361:         * stash the temp info so we can get out of range status. limit the
                    362:         * number so the out of temp checks cant go into memory it doesnt own
                    363:         */
                    364:        sc->sc_ntemps = (config.ntemps > 15) ? 15 : config.ntemps;
                    365:        sc->sc_temps = s;
                    366:        sc->sc_celsius = SAFTE_CFG_CELSIUS(config.therm);
                    367:        for (i = 0; i < config.ntemps; i++) {
                    368:                s->se_type = SAFTE_T_TEMP;
                    369:                s->se_field = (u_int8_t *)(sc->sc_encbuf + j + i);
                    370:                s->se_sensor.type = SENSOR_TEMP;
                    371:
                    372:                s++;
                    373:        }
                    374:        j += config.ntemps;
                    375:
                    376:        sc->sc_temperrs = (u_int16_t *)(sc->sc_encbuf + j);
                    377:
                    378:        return (0);
                    379: }
                    380:
                    381: void
                    382: safte_read_encstat(void *arg)
                    383: {
                    384:        struct safte_softc              *sc = (struct safte_softc *)arg;
                    385:        struct safte_readbuf_cmd        cmd;
                    386:        int                             flags, i;
                    387:        struct safte_sensor             *s;
                    388:        u_int16_t                       oot;
                    389:
                    390:        rw_enter_write(&sc->sc_lock);
                    391:
                    392:        memset(&cmd, 0, sizeof(cmd));
                    393:        cmd.opcode = READ_BUFFER;
                    394:        cmd.flags |= SAFTE_RD_MODE;
                    395:        cmd.bufferid = SAFTE_RD_ENCSTAT;
                    396:        cmd.length = htobe16(sc->sc_encbuflen);
                    397:        flags = SCSI_DATA_IN;
                    398: #ifndef SCSIDEBUG
                    399:        flags |= SCSI_SILENT;
                    400: #endif
                    401:
                    402:        if (cold)
                    403:                flags |= SCSI_AUTOCONF;
                    404:
                    405:        if (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd,
                    406:            sizeof(cmd), sc->sc_encbuf, sc->sc_encbuflen, 2, 30000, NULL,
                    407:            flags) != 0) {
                    408:                rw_exit_write(&sc->sc_lock);
                    409:                return;
                    410:        }
                    411:
                    412:        for (i = 0; i < sc->sc_nsensors; i++) {
                    413:                s = &sc->sc_sensors[i];
                    414:                s->se_sensor.flags &= ~SENSOR_FUNKNOWN;
                    415:
                    416:                DPRINTF(("%s: %d type: %d field: 0x%02x\n", DEVNAME(sc), i,
                    417:                    s->se_type, *s->se_field));
                    418:
                    419:                switch (s->se_type) {
                    420:                case SAFTE_T_FAN:
                    421:                        switch (*s->se_field) {
                    422:                        case SAFTE_FAN_OP:
                    423:                                s->se_sensor.value = 1;
                    424:                                s->se_sensor.status = SENSOR_S_OK;
                    425:                                break;
                    426:                        case SAFTE_FAN_MF:
                    427:                                s->se_sensor.value = 0;
                    428:                                s->se_sensor.status = SENSOR_S_CRIT;
                    429:                                break;
                    430:                        case SAFTE_FAN_NOTINST:
                    431:                        case SAFTE_FAN_UNKNOWN:
                    432:                        default:
                    433:                                s->se_sensor.value = 0;
                    434:                                s->se_sensor.status = SENSOR_S_UNKNOWN;
                    435:                                s->se_sensor.flags |= SENSOR_FUNKNOWN;
                    436:                                break;
                    437:                        }
                    438:                        break;
                    439:
                    440:                case SAFTE_T_PWRSUP:
                    441:                        switch (*s->se_field) {
                    442:                        case SAFTE_PWR_OP_ON:
                    443:                                s->se_sensor.value = 1;
                    444:                                s->se_sensor.status = SENSOR_S_OK;
                    445:                                break;
                    446:                        case SAFTE_PWR_OP_OFF:
                    447:                                s->se_sensor.value = 0;
                    448:                                s->se_sensor.status = SENSOR_S_OK;
                    449:                                break;
                    450:                        case SAFTE_PWR_MF_ON:
                    451:                                s->se_sensor.value = 1;
                    452:                                s->se_sensor.status = SENSOR_S_CRIT;
                    453:                                break;
                    454:                        case SAFTE_PWR_MF_OFF:
                    455:                                s->se_sensor.value = 0;
                    456:                                s->se_sensor.status = SENSOR_S_CRIT;
                    457:                                break;
                    458:                        case SAFTE_PWR_NOTINST:
                    459:                        case SAFTE_PWR_PRESENT:
                    460:                        case SAFTE_PWR_UNKNOWN:
                    461:                                s->se_sensor.value = 0;
                    462:                                s->se_sensor.status = SENSOR_S_UNKNOWN;
                    463:                                s->se_sensor.flags |= SENSOR_FUNKNOWN;
                    464:                                break;
                    465:                        }
                    466:                        break;
                    467:
                    468:                case SAFTE_T_DOORLOCK:
                    469:                        switch (*s->se_field) {
                    470:                        case SAFTE_DOOR_LOCKED:
                    471:                                s->se_sensor.value = 1;
                    472:                                s->se_sensor.status = SENSOR_S_OK;
                    473:                                break;
                    474:                        case SAFTE_DOOR_UNLOCKED:
                    475:                                s->se_sensor.value = 0;
                    476:                                s->se_sensor.status = SENSOR_S_CRIT;
                    477:                                break;
                    478:                        case SAFTE_DOOR_UNKNOWN:
                    479:                                s->se_sensor.value = 0;
                    480:                                s->se_sensor.status = SENSOR_S_CRIT;
                    481:                                s->se_sensor.flags |= SENSOR_FUNKNOWN;
                    482:                                break;
                    483:                        }
                    484:                        break;
                    485:
                    486:                case SAFTE_T_ALARM:
                    487:                        switch (*s->se_field) {
                    488:                        case SAFTE_SPKR_OFF:
                    489:                                s->se_sensor.value = 0;
                    490:                                s->se_sensor.status = SENSOR_S_OK;
                    491:                                break;
                    492:                        case SAFTE_SPKR_ON:
                    493:                                s->se_sensor.value = 1;
                    494:                                s->se_sensor.status = SENSOR_S_CRIT;
                    495:                                break;
                    496:                        }
                    497:                        break;
                    498:
                    499:                case SAFTE_T_TEMP:
                    500:                        s->se_sensor.value = safte_temp2uK(*s->se_field,
                    501:                            sc->sc_celsius);
                    502:                        break;
                    503:                }
                    504:        }
                    505:
                    506:        oot = betoh16(*sc->sc_temperrs);
                    507:        for (i = 0; i < sc->sc_ntemps; i++)
                    508:                sc->sc_temps[i].se_sensor.status =
                    509:                    (oot & (1 << i)) ? SENSOR_S_CRIT : SENSOR_S_OK;
                    510:
                    511:        rw_exit_write(&sc->sc_lock);
                    512: }
                    513:
                    514: #if NBIO > 0
                    515: int
                    516: safte_ioctl(struct device *dev, u_long cmd, caddr_t addr)
                    517: {
                    518:        struct safte_softc              *sc = (struct safte_softc *)dev;
                    519:        int                             error = 0;
                    520:
                    521:        switch (cmd) {
                    522:        case BIOCBLINK:
                    523:                error = safte_bio_blink(sc, (struct bioc_blink *)addr);
                    524:                break;
                    525:
                    526:        default:
                    527:                error = EINVAL;
                    528:                break;
                    529:        }
                    530:
                    531:        return (error);
                    532: }
                    533:
                    534: int
                    535: safte_bio_blink(struct safte_softc *sc, struct bioc_blink *blink)
                    536: {
                    537:        struct safte_writebuf_cmd       cmd;
                    538:        struct safte_slotop             *op;
                    539:        int                             slot;
                    540:        int                             flags;
                    541:        int                             wantblink;
                    542:
                    543:        switch (blink->bb_status) {
                    544:        case BIOC_SBBLINK:
                    545:                wantblink = 1;
                    546:                break;
                    547:        case BIOC_SBUNBLINK:
                    548:                wantblink = 0;
                    549:                break;
                    550:        default:
                    551:                return (EINVAL);
                    552:        }
                    553:
                    554:        rw_enter_read(&sc->sc_lock);
                    555:        for (slot = 0; slot < sc->sc_nslots; slot++) {
                    556:                if (sc->sc_slots[slot] == blink->bb_target)
                    557:                        break;
                    558:        }
                    559:        rw_exit_read(&sc->sc_lock);
                    560:
                    561:        if (slot >= sc->sc_nslots)
                    562:                return (ENODEV);
                    563:
                    564:        op = malloc(sizeof(struct safte_slotop), M_TEMP, 0);
                    565:
                    566:        memset(op, 0, sizeof(struct safte_slotop));
                    567:        op->opcode = SAFTE_WRITE_SLOTOP;
                    568:        op->slot = slot;
                    569:        op->flags |= wantblink ? SAFTE_SLOTOP_IDENTIFY : 0;
                    570:
                    571:        memset(&cmd, 0, sizeof(cmd));
                    572:        cmd.opcode = WRITE_BUFFER;
                    573:        cmd.flags |= SAFTE_WR_MODE;
                    574:        cmd.length = htobe16(sizeof(struct safte_slotop));
                    575:        flags = SCSI_DATA_OUT;
                    576: #ifndef SCSIDEBUG
                    577:        flags |= SCSI_SILENT;
                    578: #endif
                    579:        if (cold)
                    580:                flags |= SCSI_AUTOCONF;
                    581:
                    582:        if (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd,
                    583:            sizeof(cmd), (u_char *)op, sizeof(struct safte_slotop),
                    584:            2, 30000, NULL, flags) != 0) {
                    585:                free(op, M_TEMP);
                    586:                return (EIO);
                    587:        }
                    588:
                    589:        free(op, M_TEMP);
                    590:
                    591:        return (0);
                    592: }
                    593: #endif /* NBIO > 0 */
                    594:
                    595: int64_t
                    596: safte_temp2uK(u_int8_t measured, int celsius)
                    597: {
                    598:        int64_t                         temp;
                    599:
                    600:        temp = (int64_t)measured;
                    601:        temp += SAFTE_TEMP_OFFSET;
                    602:        temp *= 1000000; /* convert to micro (mu) degrees */
                    603:        if (!celsius)
                    604:                temp = ((temp - 32000000) * 5) / 9; /* convert to Celsius */
                    605:
                    606:        temp += 273150000; /* convert to kelvin */
                    607:
                    608:        return (temp);
                    609: }

CVSweb