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

Annotation of sys/arch/vax/qbus/uba.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: uba.c,v 1.11 2005/11/24 04:52:26 brad Exp $   */
        !             2: /*     $NetBSD: uba.c,v 1.57 2001/04/26 19:16:07 ragge Exp $   */
        !             3: /*
        !             4:  * Copyright (c) 1996 Jonathan Stone.
        !             5:  * Copyright (c) 1994, 1996 Ludd, University of Lule}, Sweden.
        !             6:  * Copyright (c) 1982, 1986 The Regents of the University of California.
        !             7:  * All rights reserved.
        !             8:  *
        !             9:  * Redistribution and use in source and binary forms, with or without
        !            10:  * modification, are permitted provided that the following conditions
        !            11:  * are met:
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer in the
        !            16:  *    documentation and/or other materials provided with the distribution.
        !            17:  * 3. Neither the name of the University nor the names of its contributors
        !            18:  *    may be used to endorse or promote products derived from this software
        !            19:  *    without specific prior written permission.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  *
        !            33:  *     @(#)uba.c       7.10 (Berkeley) 12/16/90
        !            34:  *     @(#)autoconf.c  7.20 (Berkeley) 5/9/91
        !            35:  */
        !            36:
        !            37: #include <sys/param.h>
        !            38: #include <sys/types.h>
        !            39: #include <sys/time.h>
        !            40: #include <sys/systm.h>
        !            41: #include <sys/buf.h>
        !            42: #include <sys/proc.h>
        !            43: #include <sys/user.h>
        !            44: #include <sys/conf.h>
        !            45: #include <sys/dkstat.h>
        !            46: #include <sys/kernel.h>
        !            47: #include <sys/malloc.h>
        !            48: #include <sys/device.h>
        !            49:
        !            50: #include <uvm/uvm_extern.h>
        !            51:
        !            52: #include <machine/bus.h>
        !            53: #include <machine/scb.h>
        !            54: #include <machine/cpu.h>
        !            55:
        !            56: #include <arch/vax/qbus/ubavar.h>
        !            57:
        !            58: static int ubasearch (struct device *, struct cfdata *, void *);
        !            59: static int ubaprint (void *, const char *);
        !            60:
        !            61: struct         cfdriver uba_cd = {
        !            62:        NULL, "uba", DV_DULL
        !            63: };
        !            64:
        !            65: /*
        !            66:  * If we failed to allocate uba resources, put us on a queue to wait
        !            67:  * until there is available resources. Resources to compete about
        !            68:  * are map registers and BDPs. This is normally only a problem on
        !            69:  * Unibus systems, Qbus systems have more map registers than usable.
        !            70:  */
        !            71: void
        !            72: uba_enqueue(struct uba_unit *uu)
        !            73: {
        !            74:        struct uba_softc *uh;
        !            75:        int s;
        !            76:
        !            77:        uh = (void *)((struct device *)(uu->uu_softc))->dv_parent;
        !            78:
        !            79:        s = splvm();
        !            80:        SIMPLEQ_INSERT_TAIL(&uh->uh_resq, uu, uu_resq);
        !            81:        splx(s);
        !            82: }
        !            83:
        !            84: /*
        !            85:  * When a routine that uses resources is finished, the next device
        !            86:  * in queue for map registers etc is called. If it succeeds to get
        !            87:  * resources, call next, and next, and next...
        !            88:  * This routine must be called at splvm.
        !            89:  */
        !            90: void
        !            91: uba_done(struct uba_softc *uh)
        !            92: {
        !            93:        struct uba_unit *uu;
        !            94:
        !            95:        while ((uu = SIMPLEQ_FIRST(&uh->uh_resq))) {
        !            96:                SIMPLEQ_REMOVE_HEAD(&uh->uh_resq, uu_resq);
        !            97:                if ((*uu->uu_ready)(uu) == 0) {
        !            98:                        SIMPLEQ_INSERT_HEAD(&uh->uh_resq, uu, uu_resq);
        !            99:                        break;
        !           100:                }
        !           101:        }
        !           102: }
        !           103:
        !           104: /*
        !           105:  * Each device that needs some handling if an ubareset occurs must
        !           106:  * register for reset first through this routine.
        !           107:  */
        !           108: void
        !           109: uba_reset_establish(void (*reset)(struct device *), struct device *dev)
        !           110: {
        !           111:        struct uba_softc *uh = (void *)dev->dv_parent;
        !           112:        struct uba_reset *ur;
        !           113:
        !           114:        ur = malloc(sizeof(struct uba_reset), M_DEVBUF, M_NOWAIT);
        !           115:        if (ur == NULL)
        !           116:                panic("uba_reset_establish");
        !           117:        ur->ur_dev = dev;
        !           118:        ur->ur_reset = reset;
        !           119:
        !           120:        SIMPLEQ_INSERT_TAIL(&uh->uh_resetq, ur, ur_resetq);
        !           121: }
        !           122:
        !           123: /*
        !           124:  * Allocate a bunch of map registers and map them to the given address.
        !           125:  */
        !           126: int
        !           127: uballoc(struct uba_softc *uh, struct ubinfo *ui, int flags)
        !           128: {
        !           129:        int waitok = (flags & UBA_CANTWAIT) == 0;
        !           130:        int error;
        !           131:
        !           132:        if ((error = bus_dmamap_create(uh->uh_dmat, ui->ui_size, 1,
        !           133:            ui->ui_size, 0, (waitok ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT),
        !           134:            &ui->ui_dmam)))
        !           135:                return error;
        !           136:
        !           137:        if ((error = bus_dmamap_load(uh->uh_dmat, ui->ui_dmam, ui->ui_vaddr,
        !           138:            ui->ui_size, NULL, (waitok ? BUS_DMA_WAITOK : BUS_DMA_NOWAIT)))) {
        !           139:                bus_dmamap_destroy(uh->uh_dmat, ui->ui_dmam);
        !           140:                return error;
        !           141:        }
        !           142:        ui->ui_baddr = ui->ui_dmam->dm_segs[0].ds_addr;
        !           143:        return 0;
        !           144: }
        !           145:
        !           146: /*
        !           147:  * Allocate DMA-able memory and map it on the unibus.
        !           148:  */
        !           149: int
        !           150: ubmemalloc(struct uba_softc *uh, struct ubinfo *ui, int flags)
        !           151: {
        !           152:        int waitok = (flags & UBA_CANTWAIT ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
        !           153:        int error;
        !           154:
        !           155:        if ((error = bus_dmamem_alloc(uh->uh_dmat, ui->ui_size, NBPG, 0,
        !           156:            &ui->ui_seg, 1, &ui->ui_rseg, waitok)))
        !           157:                return error;
        !           158:        if ((error = bus_dmamem_map(uh->uh_dmat, &ui->ui_seg, ui->ui_rseg,
        !           159:            ui->ui_size, &ui->ui_vaddr, waitok|BUS_DMA_COHERENT))) {
        !           160:                bus_dmamem_free(uh->uh_dmat, &ui->ui_seg, ui->ui_rseg);
        !           161:                return error;
        !           162:        }
        !           163:        if ((error = uballoc(uh, ui, flags))) {
        !           164:                bus_dmamem_unmap(uh->uh_dmat, ui->ui_vaddr, ui->ui_size);
        !           165:                bus_dmamem_free(uh->uh_dmat, &ui->ui_seg, ui->ui_rseg);
        !           166:        }
        !           167:        return error;
        !           168: }
        !           169:
        !           170: void
        !           171: ubfree(struct uba_softc *uh, struct ubinfo *ui)
        !           172: {
        !           173:        bus_dmamap_unload(uh->uh_dmat, ui->ui_dmam);
        !           174:        bus_dmamap_destroy(uh->uh_dmat, ui->ui_dmam);
        !           175: }
        !           176:
        !           177: void
        !           178: ubmemfree(struct uba_softc *uh, struct ubinfo *ui)
        !           179: {
        !           180:        bus_dmamem_unmap(uh->uh_dmat, ui->ui_vaddr, ui->ui_size);
        !           181:        bus_dmamem_free(uh->uh_dmat, &ui->ui_seg, ui->ui_rseg);
        !           182:        ubfree(uh, ui);
        !           183: }
        !           184:
        !           185: /*
        !           186:  * Generate a reset on uba number uban.         Then
        !           187:  * call each device that asked to be called during attach,
        !           188:  * giving it a chance to clean up so as to be able to continue.
        !           189:  */
        !           190: void
        !           191: ubareset(struct uba_softc *uh)
        !           192: {
        !           193:        struct uba_reset *ur;
        !           194:        int s;
        !           195:
        !           196:        s = splvm();
        !           197:        SIMPLEQ_INIT(&uh->uh_resq);
        !           198:        printf("%s: reset", uh->uh_dev.dv_xname);
        !           199:        (*uh->uh_ubainit)(uh);
        !           200:
        !           201:        ur = SIMPLEQ_FIRST(&uh->uh_resetq);
        !           202:        if (ur) do {
        !           203:                printf(" %s", ur->ur_dev->dv_xname);
        !           204:                (*ur->ur_reset)(ur->ur_dev);
        !           205:        } while ((ur = SIMPLEQ_NEXT(ur, ur_resetq)));
        !           206:
        !           207:        printf("\n");
        !           208:        splx(s);
        !           209: }
        !           210:
        !           211: /*
        !           212:  * The common attach routine:
        !           213:  *   Calls the scan routine to search for uba devices.
        !           214:  */
        !           215: void
        !           216: uba_attach(struct uba_softc *sc, paddr_t iopagephys)
        !           217: {
        !           218:
        !           219:        /*
        !           220:         * Set last free interrupt vector for devices with
        !           221:         * programmable interrupt vectors.  Use is to decrement
        !           222:         * this number and use result as interrupt vector.
        !           223:         */
        !           224:        sc->uh_lastiv = 0x200;
        !           225:        SIMPLEQ_INIT(&sc->uh_resq);
        !           226:        SIMPLEQ_INIT(&sc->uh_resetq);
        !           227:
        !           228:        /*
        !           229:         * Allocate place for unibus I/O space in virtual space.
        !           230:         */
        !           231:        if (bus_space_map(sc->uh_iot, iopagephys, UBAIOSIZE, 0, &sc->uh_ioh))
        !           232:                return;
        !           233:
        !           234:        if (sc->uh_beforescan)
        !           235:                (*sc->uh_beforescan)(sc);
        !           236:        /*
        !           237:         * Now start searching for devices.
        !           238:         */
        !           239:        config_search((cfmatch_t)ubasearch,(struct device *)sc, NULL);
        !           240:
        !           241:        if (sc->uh_afterscan)
        !           242:                (*sc->uh_afterscan)(sc);
        !           243: }
        !           244:
        !           245: int
        !           246: ubasearch(struct device *parent, struct cfdata *cf, void *aux)
        !           247: {
        !           248:        struct  uba_softc *sc = (struct uba_softc *)parent;
        !           249:        struct  uba_attach_args ua;
        !           250:        int     i, vec, br;
        !           251:
        !           252:        ua.ua_ioh = ubdevreg(cf->cf_loc[0]) + sc->uh_ioh;
        !           253:        ua.ua_iot = sc->uh_iot;
        !           254:        ua.ua_dmat = sc->uh_dmat;
        !           255:
        !           256:        if (badaddr((caddr_t)ua.ua_ioh, 2) ||
        !           257:            (sc->uh_errchk ? (*sc->uh_errchk)(sc):0))
        !           258:                goto forgetit;
        !           259:
        !           260:        scb_vecref(0, 0); /* Clear vector ref */
        !           261:        i = (*cf->cf_attach->ca_match) (parent, cf, &ua);
        !           262:
        !           263:        if (sc->uh_errchk)
        !           264:                if ((*sc->uh_errchk)(sc))
        !           265:                        goto forgetit;
        !           266:        if (i == 0)
        !           267:                goto forgetit;
        !           268:
        !           269:        i = scb_vecref(&vec, &br);
        !           270:        if (i == 0)
        !           271:                goto fail;
        !           272:        if (vec == 0)
        !           273:                goto fail;
        !           274:
        !           275:        ua.ua_br = br;
        !           276:        ua.ua_cvec = vec;
        !           277:        ua.ua_iaddr = cf->cf_loc[0];
        !           278:
        !           279:        config_attach(parent, cf, &ua, ubaprint);
        !           280:        return 0;
        !           281:
        !           282: fail:
        !           283:        printf("%s%d at %s csr %o %s\n",
        !           284:            cf->cf_driver->cd_name, cf->cf_unit, parent->dv_xname,
        !           285:            cf->cf_loc[0], (i ? "zero vector" : "didn't interrupt"));
        !           286:
        !           287: forgetit:
        !           288:        return 0;
        !           289: }
        !           290:
        !           291: /*
        !           292:  * Print out some interesting info common to all unibus devices.
        !           293:  */
        !           294: int
        !           295: ubaprint(void *aux, const char *uba)
        !           296: {
        !           297:        struct uba_attach_args *ua = aux;
        !           298:
        !           299:        printf(" csr %o vec %d ipl %x", ua->ua_iaddr,
        !           300:            ua->ua_cvec & 511, ua->ua_br);
        !           301:        return UNCONF;
        !           302: }
        !           303:
        !           304: /*
        !           305:  * Move to machdep eventually
        !           306:  */
        !           307: void
        !           308: uba_intr_establish(icookie, vec, ifunc, iarg, ev)
        !           309:        void *icookie;
        !           310:        int vec;
        !           311:        void (*ifunc)(void *iarg);
        !           312:        void *iarg;
        !           313:        struct evcount *ev;
        !           314: {
        !           315:        scb_vecalloc(vec, ifunc, iarg, SCB_ISTACK, ev);
        !           316: }

CVSweb