[BACK]Return to mba.c CVS log [TXT][DIR] Up to [local] / sys / arch / vax / mba

Annotation of sys/arch/vax/mba/mba.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: mba.c,v 1.10 2006/01/20 23:27:25 miod Exp $ */
                      2: /*     $NetBSD: mba.c,v 1.18 2000/01/24 02:40:36 matt Exp $ */
                      3: /*
                      4:  * Copyright (c) 1994, 1996 Ludd, University of Lule}, Sweden.
                      5:  * All rights reserved.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. All advertising materials mentioning features or use of this software
                     16:  *    must display the following acknowledgement:
                     17:  *      This product includes software developed at Ludd, University of
                     18:  *      Lule}, Sweden and its contributors.
                     19:  * 4. The name of the author may not be used to endorse or promote products
                     20:  *    derived from this software without specific prior written permission
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     31:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     32:  */
                     33:
                     34: /*
                     35:  * Simple massbus drive routine.
                     36:  * TODO:
                     37:  *  Autoconfig new devices 'on the fly'.
                     38:  *  More intelligent way to handle different interrupts.
                     39:  */
                     40:
                     41: #include <sys/param.h>
                     42: #include <sys/systm.h>
                     43: #include <sys/device.h>
                     44: #include <sys/queue.h>
                     45: #include <sys/buf.h>
                     46: #include <sys/proc.h>
                     47:
                     48: #include <uvm/uvm_extern.h>
                     49:
                     50: #include <machine/trap.h>
                     51: #include <machine/scb.h>
                     52: #include <machine/nexus.h>
                     53: #include <machine/pte.h>
                     54: #include <machine/pcb.h>
                     55: #include <machine/sid.h>
                     56: #include <machine/cpu.h>
                     57:
                     58: #include <vax/mba/mbareg.h>
                     59: #include <vax/mba/mbavar.h>
                     60:
                     61: struct mbaunit mbaunit[] = {
                     62:        {MBADT_RP04,    "rp04", MB_RP},
                     63:        {MBADT_RP05,    "rp05", MB_RP},
                     64:        {MBADT_RP06,    "rp06", MB_RP},
                     65:        {MBADT_RP07,    "rp07", MB_RP},
                     66:        {MBADT_RM02,    "rm02", MB_RP},
                     67:        {MBADT_RM03,    "rm03", MB_RP},
                     68:        {MBADT_RM05,    "rm05", MB_RP},
                     69:        {MBADT_RM80,    "rm80", MB_RP},
                     70:        {0,             0,      0}
                     71: };
                     72:
                     73: int    mbamatch(struct device *, struct cfdata *, void *);
                     74: void   mbaattach(struct device *, struct device *, void *);
                     75: void   mbaintr(void *);
                     76: int    mbaprint(void *, const char *);
                     77: void   mbaqueue(struct mba_device *);
                     78: void   mbastart(struct mba_softc *);
                     79: void   mbamapregs(struct mba_softc *);
                     80:
                     81: struct cfattach mba_cmi_ca = {
                     82:        sizeof(struct mba_softc), mbamatch, mbaattach
                     83: };
                     84:
                     85: struct cfattach mba_sbi_ca = {
                     86:        sizeof(struct mba_softc), mbamatch, mbaattach
                     87: };
                     88:
                     89: extern struct cfdriver mba_cd;
                     90:
                     91: /*
                     92:  * Look if this is a massbuss adapter.
                     93:  */
                     94: int
                     95: mbamatch(parent, cf, aux)
                     96:        struct  device *parent;
                     97:        struct  cfdata *cf;
                     98:        void    *aux;
                     99: {
                    100:        struct  sbi_attach_args *sa = (struct sbi_attach_args *)aux;
                    101:
                    102:        if ((cf->cf_loc[0] != sa->nexnum) && (cf->cf_loc[0] > -1 ))
                    103:                return 0;
                    104:
                    105:        if (sa->type == NEX_MBA)
                    106:                return 1;
                    107:
                    108:        return 0;
                    109: }
                    110:
                    111: /*
                    112:  * Attach the found massbuss adapter. Setup its interrupt vectors,
                    113:  * reset it and go searching for drives on it.
                    114:  */
                    115: void
                    116: mbaattach(parent, self, aux)
                    117:        struct  device *parent, *self;
                    118:        void    *aux;
                    119: {
                    120:        struct  mba_softc *sc = (void *)self;
                    121:        struct  sbi_attach_args *sa = (struct sbi_attach_args *)aux;
                    122:        volatile struct mba_regs *mbar = (struct mba_regs *)sa->nexaddr;
                    123:        struct  mba_attach_args ma;
                    124:        int     i, j;
                    125:
                    126:        printf("\n");
                    127:        /*
                    128:         * Set up interrupt vectors for this MBA.
                    129:         */
                    130:        sc->sc_dsp = idsptch;
                    131:        sc->sc_dsp.pushlarg = sc;
                    132:        sc->sc_dsp.hoppaddr = mbaintr;
                    133:        scb->scb_nexvec[0][sa->nexnum] = scb->scb_nexvec[1][sa->nexnum] =
                    134:            scb->scb_nexvec[2][sa->nexnum] = scb->scb_nexvec[3][sa->nexnum] =
                    135:            &sc->sc_dsp;
                    136:
                    137:        sc->sc_physnr = sa->nexnum - 8; /* MBA's have TR between 8 - 11... */
                    138: #if VAX750
                    139:        if (vax_cputype == VAX_750)
                    140:                sc->sc_physnr += 4;     /* ...but not on 11/750 */
                    141: #endif
                    142:        sc->sc_first = 0;
                    143:        sc->sc_last = (void *)&sc->sc_first;
                    144:        sc->sc_mbareg = (struct mba_regs *)mbar;
                    145:        mbar->mba_cr = MBACR_INIT;      /* Reset adapter */
                    146:        mbar->mba_cr = MBACR_IE;        /* Enable interrupts */
                    147:
                    148:        for (i = 0; i < MAXMBADEV; i++) {
                    149:                sc->sc_state = SC_AUTOCONF;
                    150:                if ((mbar->mba_md[i].md_ds & MBADS_DPR) == 0)
                    151:                        continue;
                    152:                /* We have a drive, ok. */
                    153:                ma.unit = i;
                    154:                ma.type = mbar->mba_md[i].md_dt & 0777;
                    155:                j = 0;
                    156:                while (mbaunit[j++].nr)
                    157:                        if (mbaunit[j].nr == ma.type)
                    158:                                break;
                    159:                ma.devtyp = mbaunit[j].devtyp;
                    160:                ma.name = mbaunit[j].name;
                    161:                config_found(&sc->sc_dev, (void *)&ma, mbaprint);
                    162:        }
                    163: }
                    164:
                    165: /*
                    166:  * We got an interrupt. Check type of interrupt and call the specific
                    167:  * device interrupt handling routine.
                    168:  */
                    169: void
                    170: mbaintr(mba)
                    171:        void    *mba;
                    172: {
                    173:        struct  mba_softc *sc = mba;
                    174:        volatile struct mba_regs *mr = sc->sc_mbareg;
                    175:        struct  mba_device *md;
                    176:        struct  buf *bp;
                    177:        int     itype, attn, anr;
                    178:
                    179:        itype = mr->mba_sr;
                    180:        mr->mba_sr = itype;     /* Write back to clear bits */
                    181:
                    182:        attn = mr->mba_md[0].md_as & 0xff;
                    183:        mr->mba_md[0].md_as = attn;
                    184:
                    185:        if (sc->sc_state == SC_AUTOCONF)
                    186:                return; /* During autoconfig */
                    187:
                    188:        md = sc->sc_first;
                    189:        bp = BUFQ_FIRST(&md->md_q);
                    190:        /*
                    191:         * A data-transfer interrupt. Current operation is finished,
                    192:         * call that device's finish routine to see what to do next.
                    193:         */
                    194:        if (sc->sc_state == SC_ACTIVE) {
                    195:
                    196:                sc->sc_state = SC_IDLE;
                    197:                switch ((*md->md_finish)(md, itype, &attn)) {
                    198:
                    199:                case XFER_FINISH:
                    200:                        /*
                    201:                         * Transfer is finished. Take buffer of drive
                    202:                         * queue, and take drive of adapter queue.
                    203:                         * If more to transfer, start the adapter again
                    204:                         * by calling mbastart().
                    205:                         */
                    206:                        BUFQ_REMOVE(&md->md_q, bp);
                    207:                        sc->sc_first = md->md_back;
                    208:                        md->md_back = 0;
                    209:                        if (sc->sc_first == 0)
                    210:                                sc->sc_last = (void *)&sc->sc_first;
                    211:
                    212:                        if (BUFQ_FIRST(&md->md_q) != NULL) {
                    213:                                sc->sc_last->md_back = md;
                    214:                                sc->sc_last = md;
                    215:                        }
                    216:
                    217:                        bp->b_resid = 0;
                    218:                        biodone(bp);
                    219:                        if (sc->sc_first)
                    220:                                mbastart(sc);
                    221:                        break;
                    222:
                    223:                case XFER_RESTART:
                    224:                        /*
                    225:                         * Something went wrong with the transfer. Try again.
                    226:                         */
                    227:                        mbastart(sc);
                    228:                        break;
                    229:                }
                    230:        }
                    231:
                    232:        while (attn) {
                    233:                anr = ffs(attn) - 1;
                    234:                attn &= ~(1 << anr);
                    235:                if (sc->sc_md[anr]->md_attn == 0)
                    236:                        panic("Should check for new MBA device %d", anr);
                    237:                (*sc->sc_md[anr]->md_attn)(sc->sc_md[anr]);
                    238:        }
                    239: }
                    240:
                    241: int
                    242: mbaprint(aux, mbaname)
                    243:        void    *aux;
                    244:        const char      *mbaname;
                    245: {
                    246:        struct  mba_attach_args *ma = aux;
                    247:
                    248:        if (mbaname) {
                    249:                if (ma->name)
                    250:                        printf("%s", ma->name);
                    251:                else
                    252:                        printf("device type %o", ma->type);
                    253:                printf(" at %s", mbaname);
                    254:        }
                    255:        printf(" drive %d", ma->unit);
                    256:        return (ma->name ? UNCONF : UNSUPP);
                    257: }
                    258:
                    259: /*
                    260:  * A device calls mbaqueue() when it wants to get on the adapter queue.
                    261:  * Called at splbio(). If the adapter is inactive, start it.
                    262:  */
                    263: void
                    264: mbaqueue(md)
                    265:        struct  mba_device *md;
                    266: {
                    267:        struct  mba_softc *sc = md->md_mba;
                    268:        int     i = (int)sc->sc_first;
                    269:
                    270:        sc->sc_last->md_back = md;
                    271:        sc->sc_last = md;
                    272:
                    273:        if (i == 0)
                    274:                mbastart(sc);
                    275: }
                    276:
                    277: /*
                    278:  * Start activity on (idling) adapter. Calls mbamapregs() to setup
                    279:  * for dma transfer, then the unit-specific start routine.
                    280:  */
                    281: void
                    282: mbastart(sc)
                    283:        struct  mba_softc *sc;
                    284: {
                    285:        struct  mba_device *md = sc->sc_first;
                    286:        volatile struct mba_regs *mr = sc->sc_mbareg;
                    287:        struct  buf *bp = BUFQ_FIRST(&md->md_q);
                    288:
                    289:        disk_reallymapin(BUFQ_FIRST(&md->md_q), sc->sc_mbareg->mba_map,
                    290:            0, PG_V);
                    291:
                    292:        sc->sc_state = SC_ACTIVE;
                    293:        mr->mba_var = ((u_int)bp->b_data & VAX_PGOFSET);
                    294:        mr->mba_bc = (~bp->b_bcount) + 1;
                    295:        (*md->md_start)(md);            /* machine-dependent start */
                    296: }

CVSweb