[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     ! 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