[BACK]Return to scf.c CVS log [TXT][DIR] Up to [local] / sys / arch / sparc / dev

Annotation of sys/arch/sparc/dev/scf.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: scf.c,v 1.10 2006/03/15 20:03:06 miod Exp $   */
                      2:
                      3: /*
                      4:  * Copyright (c) 1999 Jason L. Wright (jason@thought.net)
                      5:  * All rights reserved.
                      6:  *
                      7:  * This software was developed by Jason L. Wright under contract with
                      8:  * RTMX Incorporated (http://www.rtmx.com).
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     20:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     21:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     22:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     23:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     24:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     25:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     27:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     28:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     29:  * POSSIBILITY OF SUCH DAMAGE.
                     30:  */
                     31:
                     32: /*
                     33:  * Driver for the flash memory and sysconfig registers found on Force CPU-5V
                     34:  * boards.
                     35:  */
                     36:
                     37: #include <sys/param.h>
                     38: #include <sys/systm.h>
                     39: #include <sys/kernel.h>
                     40: #include <sys/errno.h>
                     41: #include <sys/ioctl.h>
                     42: #include <sys/mbuf.h>
                     43: #include <sys/socket.h>
                     44: #include <sys/syslog.h>
                     45: #include <sys/device.h>
                     46: #include <sys/malloc.h>
                     47: #include <sys/timeout.h>
                     48:
                     49: #include <machine/autoconf.h>
                     50: #include <sparc/cpu.h>
                     51: #include <sparc/sparc/cpuvar.h>
                     52: #include <machine/scfio.h>
                     53: #include <sparc/dev/scfreg.h>
                     54:
                     55: int    scfmatch(struct device *, void *, void *);
                     56: void   scfattach(struct device *, struct device *, void *);
                     57:
                     58: int    scfopen(dev_t, int, int, struct proc *);
                     59: int    scfclose(dev_t, int, int, struct proc *);
                     60: int    scfioctl(dev_t, u_long, caddr_t, int, struct proc *);
                     61:
                     62: struct scf_softc {
                     63:        struct  device sc_dv;                   /* base device */
                     64:        struct  scf_regs *sc_regs;      /* our registers */
                     65:        int     sc_open;
                     66:        int     sc_tick;
                     67:        struct  timeout sc_blink_tmo;   /* for scfblink() */
                     68: };
                     69:
                     70: struct cfattach scf_ca = {
                     71:        sizeof (struct scf_softc), scfmatch, scfattach
                     72: };
                     73:
                     74: struct cfdriver scf_cd = {
                     75:        NULL, "scf", DV_DULL
                     76: };
                     77:
                     78: extern int sparc_led_blink;
                     79:
                     80: static const u_int8_t scf_pattern[] = {
                     81:        SSLDCR_A|SSLDCR_B|SSLDCR_C|SSLDCR_D|SSLDCR_E|SSLDCR_F,
                     82:        SSLDCR_B|SSLDCR_C,
                     83:        SSLDCR_A|SSLDCR_B|SSLDCR_D|SSLDCR_E|SSLDCR_G,
                     84:        SSLDCR_A|SSLDCR_B|SSLDCR_C|SSLDCR_D|SSLDCR_G,
                     85:        SSLDCR_B|SSLDCR_C|SSLDCR_F|SSLDCR_G,
                     86:        SSLDCR_A|SSLDCR_C|SSLDCR_D|SSLDCR_F|SSLDCR_G,
                     87:        SSLDCR_A|SSLDCR_C|SSLDCR_D|SSLDCR_E|SSLDCR_F|SSLDCR_G,
                     88:        SSLDCR_A|SSLDCR_B|SSLDCR_C,
                     89:        SSLDCR_A|SSLDCR_B|SSLDCR_C|SSLDCR_D|SSLDCR_E|SSLDCR_F|SSLDCR_G,
                     90:        SSLDCR_A|SSLDCR_B|SSLDCR_C|SSLDCR_D|SSLDCR_F|SSLDCR_G,
                     91:        SSLDCR_A|SSLDCR_B|SSLDCR_C|SSLDCR_E|SSLDCR_F|SSLDCR_G,
                     92:        SSLDCR_C|SSLDCR_D|SSLDCR_E|SSLDCR_F|SSLDCR_G,
                     93:        SSLDCR_A|SSLDCR_D|SSLDCR_E|SSLDCR_F,
                     94:        SSLDCR_B|SSLDCR_C|SSLDCR_D|SSLDCR_E|SSLDCR_G,
                     95:        SSLDCR_A|SSLDCR_D|SSLDCR_E|SSLDCR_F|SSLDCR_G,
                     96:        SSLDCR_A|SSLDCR_E|SSLDCR_F|SSLDCR_G,
                     97: };
                     98:
                     99: int
                    100: scfmatch(parent, vcf, aux)
                    101:        struct device *parent;
                    102:        void *vcf, *aux;
                    103: {
                    104:        struct confargs *ca = aux;
                    105:        register struct romaux *ra = &ca->ca_ra;
                    106:
                    107:        if (strcmp("sysconfig", ra->ra_name))
                    108:                return (0);
                    109:
                    110:        return (1);
                    111: }
                    112:
                    113: void
                    114: scfattach(parent, self, aux)
                    115:        struct device *parent, *self;
                    116:        void *aux;
                    117: {
                    118:        struct confargs *ca = aux;
                    119:        struct scf_softc *sc = (struct scf_softc *)self;
                    120:        char *s;
                    121:
                    122:        /* map registers */
                    123:        if (ca->ca_ra.ra_nreg != 1) {
                    124:                printf(": expected 1 register, got %d\n", ca->ca_ra.ra_nreg);
                    125:                return;
                    126:        }
                    127:
                    128:        sc->sc_regs = mapiodev(&(ca->ca_ra.ra_reg[0]), 0,
                    129:                        ca->ca_ra.ra_reg[0].rr_len);
                    130:
                    131:        s = getpropstring(ca->ca_ra.ra_node, "model");
                    132:        printf(": model %s\n", s);
                    133:
                    134:        sc->sc_regs->led1 &= ~LED_MASK;
                    135:        sc->sc_regs->led2 &= ~LED_MASK;
                    136:        sc->sc_regs->ssldcr = 0;
                    137:
                    138:        timeout_set(&sc->sc_blink_tmo, scfblink, 0);
                    139:
                    140:        if (sparc_led_blink)
                    141:                scfblink(0);
                    142: }
                    143:
                    144: int
                    145: scfopen(dev, flags, mode, p)
                    146:        dev_t dev;
                    147:        int flags;
                    148:        int mode;
                    149:        struct proc *p;
                    150: {
                    151:        struct scf_softc *sc;
                    152:        int card = 0;
                    153:
                    154:        if (card >= scf_cd.cd_ndevs)
                    155:                return (ENXIO);
                    156:        sc = scf_cd.cd_devs[card];
                    157:        if (sc == NULL)
                    158:                return (ENXIO);
                    159:        if (sc->sc_open)
                    160:                return (EBUSY);
                    161:
                    162:        sc->sc_open = 1;
                    163:        return (0);
                    164: }
                    165:
                    166: int
                    167: scfclose(dev, flags, mode, p)
                    168:        dev_t dev;
                    169:        int flags;
                    170:        int mode;
                    171:        struct proc *p;
                    172: {
                    173:        struct scf_softc *sc;
                    174:        int card = 0;
                    175:
                    176:        sc = scf_cd.cd_devs[card];
                    177:        sc->sc_open = 0;
                    178:        return (0);
                    179: }
                    180:
                    181: int
                    182: scfioctl(dev, cmd, data, flags, p)
                    183:        dev_t dev;
                    184:        u_long cmd;
                    185:        caddr_t data;
                    186:        int flags;
                    187:        struct proc *p;
                    188: {
                    189:        struct scf_softc *sc = scf_cd.cd_devs[0];
                    190:        u_int8_t *ptr = (u_int8_t *)data, c;
                    191:        int error = 0;
                    192:
                    193:        switch (cmd) {
                    194:        case SCFIOCSLED1:
                    195:                sc->sc_regs->led1 = LED_MASK | (*ptr);
                    196:                break;
                    197:        case SCFIOCGLED1:
                    198:                *ptr = sc->sc_regs->led1 & (LED_COLOR_MASK | LED_BLINK_MASK);
                    199:                break;
                    200:        case SCFIOCSLED2:
                    201:                sc->sc_regs->led2 = LED_MASK | (*ptr);
                    202:                break;
                    203:        case SCFIOCGLED2:
                    204:                *ptr = sc->sc_regs->led2 & (LED_COLOR_MASK | LED_BLINK_MASK);
                    205:                break;
                    206:        case SCFIOCSLED7:
                    207:                sc->sc_regs->ssldcr = *ptr;
                    208:                break;
                    209:        case SCFIOCGLED7:
                    210:                *ptr = sc->sc_regs->ssldcr;
                    211:                break;
                    212:        case SCFIOCGROT:
                    213:                *ptr = sc->sc_regs->rssr;
                    214:                break;
                    215:        case SCFIOCSFMCTRL:
                    216:                if ((*ptr) & SCF_FMCTRL_SELROM)
                    217:                        sc->sc_regs->fmpcr1 |= FMPCR1_SELROM;
                    218:                else
                    219:                        sc->sc_regs->fmpcr1 &= ~FMPCR1_SELROM;
                    220:
                    221:                if ((*ptr) & SCF_FMCTRL_SELBOOT)
                    222:                        sc->sc_regs->fmpcr2 |= FMPCR2_SELBOOT;
                    223:                else
                    224:                        sc->sc_regs->fmpcr2 &= ~FMPCR2_SELBOOT;
                    225:
                    226:                if ((*ptr) & SCF_FMCTRL_WRITEV)
                    227:                        sc->sc_regs->fmpvcr |= FMPVCR_VPP;
                    228:                else
                    229:                        sc->sc_regs->fmpvcr &= ~FMPVCR_VPP;
                    230:
                    231:                c = ((*ptr) & SCF_FMCTRL_SELADDR) >> 3;
                    232:                sc->sc_regs->fmpcr1 =
                    233:                    (sc->sc_regs->fmpcr1 & ~FMPCR1_SELADDR) | (c << 1);
                    234:
                    235:                break;
                    236:        case SCFIOCGFMCTRL:
                    237:                c = (sc->sc_regs->fmpcr1 & FMPCR1_SELADDR) << 2;
                    238:                if (sc->sc_regs->fmpcr1 & FMPCR1_SELROM)
                    239:                        c |= SCF_FMCTRL_SELROM;
                    240:                if (sc->sc_regs->fmpcr2 & FMPCR2_SELBOOT)
                    241:                        c |= SCF_FMCTRL_SELBOOT;
                    242:                if (sc->sc_regs->fmpvcr & FMPVCR_VPP)
                    243:                        c |= SCF_FMCTRL_WRITEV;
                    244:                *ptr = c;
                    245:                break;
                    246:        default:
                    247:                error = ENOTTY;
                    248:        }
                    249:
                    250:        return (error);
                    251: }
                    252:
                    253: void
                    254: scfblink(v)
                    255:         void *v;
                    256: {
                    257:        struct scf_softc *sc;
                    258:        int s, avg, hi = 0;
                    259:
                    260:        if (scf_cd.cd_ndevs == 0)
                    261:                return;
                    262:
                    263:        sc = scf_cd.cd_devs[0];
                    264:        if (sc == NULL)
                    265:                return;
                    266:
                    267:        if (sparc_led_blink == 0) {
                    268:                sc->sc_regs->led1 &= ~LED_MASK;
                    269:                sc->sc_regs->led2 &= ~LED_MASK;
                    270:                sc->sc_regs->ssldcr = 0;
                    271:                return;
                    272:        }
                    273:
                    274:        avg = averunnable.ldavg[0] >> FSHIFT;
                    275:        while (avg > 15) {
                    276:                hi = 1;
                    277:                avg >>= 4;
                    278:        }
                    279:
                    280:        s = splhigh();
                    281:        if (sc->sc_tick & 1) {
                    282:                sc->sc_regs->led1 &= ~LED_MASK;
                    283:                sc->sc_regs->led2 |= LED_COLOR_GREEN;
                    284:        }
                    285:        else {
                    286:                sc->sc_regs->led1 |= LED_COLOR_YELLOW;
                    287:                sc->sc_regs->led2 &= ~LED_MASK;
                    288:        }
                    289:        sc->sc_regs->ssldcr = scf_pattern[avg] | (hi ? SSLDCR_P : 0);
                    290:        splx(s);
                    291:
                    292:        sc->sc_tick++;
                    293:
                    294:        s = ((averunnable.ldavg[0] + FSCALE) * hz) >> (FSHIFT + 1);
                    295:        timeout_add(&sc->sc_blink_tmo, s);
                    296: }

CVSweb