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

Annotation of sys/arch/mvme88k/dev/osiop_pcctwo.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: osiop_pcctwo.c,v 1.5 2006/05/08 14:36:10 miod Exp $   */
                      2: /*
                      3:  * Copyright (c) 2004, Miodrag Vallat.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  *
                     14:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     15:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     16:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     17:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     18:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     19:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     20:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     21:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     22:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     23:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     24:  * POSSIBILITY OF SUCH DAMAGE.
                     25:  */
                     26:
                     27: #include <sys/param.h>
                     28: #include <sys/systm.h>
                     29: #include <sys/device.h>
                     30: #include <sys/disklabel.h>
                     31: #include <sys/dkstat.h>
                     32:
                     33: #include <scsi/scsi_all.h>
                     34: #include <scsi/scsiconf.h>
                     35:
                     36: #include <machine/bus.h>
                     37: #include <machine/autoconf.h>
                     38: #include <machine/cpu.h>
                     39:
                     40: #include <machine/bugio.h>
                     41: #include <machine/prom.h>
                     42:
                     43: #include <dev/ic/osiopreg.h>
                     44: #include <dev/ic/osiopvar.h>
                     45:
                     46: #include <mvme88k/dev/pcctworeg.h>
                     47: #include <mvme88k/dev/pcctwovar.h>
                     48:
                     49: void   osiop_pcctwo_attach(struct device *, struct device *, void *);
                     50: int    osiop_pcctwo_intr(void *);
                     51: int    osiop_pcctwo_match(struct device *, void *, void *);
                     52:
                     53: struct osiop_pcctwo_softc {
                     54:        struct osiop_softc sc_osiop;
                     55:        struct intrhand sc_ih;
                     56: };
                     57:
                     58: struct cfattach osiop_pcctwo_ca = {
                     59:        sizeof(struct osiop_pcctwo_softc),
                     60:            osiop_pcctwo_match, osiop_pcctwo_attach
                     61: };
                     62:
                     63: int
                     64: osiop_pcctwo_match(struct device *parent, void *cf, void *aux)
                     65: {
                     66:        struct confargs *ca = aux;
                     67:        bus_space_handle_t ioh;
                     68:        int rc;
                     69:
                     70:        if (bus_space_map(ca->ca_iot, ca->ca_paddr, OSIOP_NREGS, 0, &ioh) != 0)
                     71:                return (0);
                     72:        rc = badaddr((vaddr_t)bus_space_vaddr(ca->ca_iot, ioh), 4);
                     73:        if (rc == 0) {
                     74:                bus_space_unmap(ca->ca_iot, ioh, OSIOP_NREGS);
                     75:                return (1);
                     76:        }
                     77:
                     78:        /*
                     79:         * For some reason, if the SCSI hardware is not ``warmed'' by the
                     80:         * BUG (netboot or boot from external SCSI controller), badaddr()
                     81:         * will always fail, although the hardware is there.
                     82:         * Since the BUG will do the right thing, we'll defer a dummy read
                     83:         * from the controller and retry.
                     84:         */
                     85:        if (brdtyp == BRD_187 || brdtyp == BRD_8120 || brdtyp == BRD_197) {
                     86:                struct mvmeprom_dskio dio;
                     87:                char buf[MVMEPROM_BLOCK_SIZE];
                     88:
                     89: #ifdef DEBUG
                     90:                printf("osiop_pcctwo_match: trying to warm up controller\n");
                     91: #endif
                     92:                bzero(&dio, sizeof dio);
                     93:                dio.pbuffer = buf;
                     94:                dio.blk_cnt = 1;
                     95:                bugdiskrd(&dio);
                     96:
                     97:                rc = badaddr((vaddr_t)bus_space_vaddr(ca->ca_iot, ioh), 4);
                     98:        }
                     99:
                    100:        bus_space_unmap(ca->ca_iot, ioh, OSIOP_NREGS);
                    101:        return (rc == 0);
                    102: }
                    103:
                    104: void
                    105: osiop_pcctwo_attach(struct device *parent, struct device *self, void *aux)
                    106: {
                    107:        struct pcctwosoftc *pcctwo = (struct pcctwosoftc *)parent;
                    108:        struct osiop_softc *sc = (struct osiop_softc *)self;
                    109:        struct osiop_pcctwo_softc *psc = (struct osiop_pcctwo_softc *)self;
                    110:        struct confargs *ca = aux;
                    111:        int tmp;
                    112:        extern int cpuspeed;
                    113:
                    114:        sc->sc_bst = ca->ca_iot;
                    115:        sc->sc_dmat = ca->ca_dmat;
                    116:
                    117:        if (bus_space_map(sc->sc_bst, ca->ca_paddr, OSIOP_NREGS, 0,
                    118:            &sc->sc_reg) != 0) {
                    119:                printf(": couldn't map I/O ports\n");
                    120:                return;
                    121:        }
                    122:
                    123:        switch (brdtyp) {
                    124: #ifdef MVME197
                    125:        case BRD_197:
                    126:                sc->sc_clock_freq = cpuspeed;
                    127:                break;
                    128: #endif
                    129: #ifdef MVME187
                    130:        case BRD_187:
                    131:        case BRD_8120:
                    132:                sc->sc_clock_freq = cpuspeed * 2;
                    133:                break;
                    134: #endif
                    135:        default:
                    136:                sc->sc_clock_freq = 50; /* wild guess */
                    137:                break;
                    138:        }
                    139:
                    140:        sc->sc_dcntl = OSIOP_DCNTL_EA;
                    141:        sc->sc_ctest7 = OSIOP_CTEST7_TT1;       /* no snooping */
                    142:        sc->sc_dmode = OSIOP_DMODE_BL4; /* burst length = 4 */
                    143:        sc->sc_flags = 0;
                    144:        sc->sc_id = 7;  /* XXX should read from CNFG block in nvram */
                    145:
                    146:        tmp = bootpart;
                    147:        if (ca->ca_paddr != bootaddr)
                    148:                bootpart = -1;  /* never match */
                    149:
                    150:        osiop_attach(sc);
                    151:
                    152:        bootpart = tmp;
                    153:
                    154:        psc->sc_ih.ih_fn = osiop_pcctwo_intr;
                    155:        psc->sc_ih.ih_arg = sc;
                    156:        psc->sc_ih.ih_wantframe = 0;
                    157:        psc->sc_ih.ih_ipl = ca->ca_ipl;
                    158:
                    159:        /* enable device interrupts */
                    160:        pcctwointr_establish(PCC2V_SCSI, &psc->sc_ih, self->dv_xname);
                    161:        bus_space_write_1(pcctwo->sc_iot, pcctwo->sc_ioh,
                    162:            PCCTWO_SCSIICR, PCC2_IRQ_IEN | (ca->ca_ipl & PCC2_IRQ_IPL));
                    163: }
                    164:
                    165: int
                    166: osiop_pcctwo_intr(void *arg)
                    167: {
                    168:        struct osiop_softc *sc = arg;
                    169:        u_int8_t istat;
                    170:
                    171:        if (sc->sc_flags & OSIOP_INTSOFF)
                    172:                return 0;
                    173:
                    174:        istat = osiop_read_1(sc, OSIOP_ISTAT);
                    175:        if ((istat & (OSIOP_ISTAT_SIP | OSIOP_ISTAT_DIP)) == 0)
                    176:                return 0;
                    177:
                    178:        /*
                    179:         * 53c710 manual recommends reading dstat and sstat0 at least
                    180:         * 12 clk cycles apart if reading as bytes (which is what
                    181:         * pcc2 permits). Stick in a 1us delay between accessing dstat and
                    182:         * sstat0 below.
                    183:         *
                    184:         * save interrupt status, DMA status, and SCSI status 0
                    185:         * (may need to deal with stacked interrupts?)
                    186:         */
                    187:        sc->sc_istat = istat;
                    188:        sc->sc_sstat0 = osiop_read_1(sc, OSIOP_SSTAT0);
                    189:        DELAY(25);
                    190:        sc->sc_dstat = osiop_read_1(sc, OSIOP_DSTAT);
                    191:
                    192:        osiop_intr(sc);
                    193:
                    194:        return 1;
                    195: }

CVSweb