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

Annotation of sys/arch/mvme68k/dev/vme.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: vme.c,v 1.24 2005/11/27 14:19:09 miod Exp $ */
        !             2:
        !             3: /*
        !             4:  * Copyright (c) 1995 Theo de Raadt
        !             5:  * Copyright (c) 2000 Steve Murphree, Jr.
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer.
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  *
        !            17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            18:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            19:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            20:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            21:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            22:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            23:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            24:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            25:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            26:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            27:  */
        !            28:
        !            29: #include <sys/param.h>
        !            30: #include <sys/conf.h>
        !            31: #include <sys/ioctl.h>
        !            32: #include <sys/proc.h>
        !            33: #include <sys/user.h>
        !            34: #include <sys/tty.h>
        !            35: #include <sys/uio.h>
        !            36: #include <sys/systm.h>
        !            37: #include <sys/kernel.h>
        !            38: #include <sys/syslog.h>
        !            39: #include <sys/fcntl.h>
        !            40: #include <sys/device.h>
        !            41: #include <machine/autoconf.h>
        !            42: #include <machine/cpu.h>
        !            43: #include <mvme68k/dev/vme.h>
        !            44:
        !            45: #include "pcc.h"
        !            46: #include "mc.h"
        !            47: #include "pcctwo.h"
        !            48:
        !            49: #if NPCC > 0
        !            50: #include <mvme68k/dev/pccreg.h>
        !            51: #endif
        !            52: #if NMC > 0
        !            53: #include <mvme68k/dev/mcreg.h>
        !            54: #endif
        !            55: #if NPCCTWO > 0
        !            56: #include <mvme68k/dev/pcctworeg.h>
        !            57: #endif
        !            58:
        !            59: int  vmematch(struct device *, void *, void *);
        !            60: void vmeattach(struct device *, struct device *, void *);
        !            61:
        !            62: void vme1chip_init(struct vmesoftc *sc);
        !            63: void vme2chip_init(struct vmesoftc *sc);
        !            64: paddr_t vme2chip_map(u_long base, int len, int dwidth);
        !            65: int vme2abort(void *);
        !            66:
        !            67: void vmeunmap(vaddr_t, int);
        !            68: int vmeprint(void *, const char *);
        !            69:
        !            70: static int vmebustype;
        !            71:
        !            72: struct vme2reg *sys_vme2;
        !            73:
        !            74: struct cfattach vme_ca = {
        !            75:        sizeof(struct vmesoftc), vmematch, vmeattach
        !            76: };
        !            77:
        !            78: struct cfdriver vme_cd = {
        !            79:        NULL, "vme", DV_DULL
        !            80: };
        !            81:
        !            82: int
        !            83: vmematch(parent, cf, args)
        !            84:        struct device *parent;
        !            85:        void *cf;
        !            86:        void *args;
        !            87: {
        !            88: #if NMC > 0
        !            89:        struct confargs *ca = args;
        !            90:
        !            91:        if (ca->ca_bustype == BUS_MC) {
        !            92:                if (sys_mc->mc_ver & MC_VER_NOVME)
        !            93:                        return (0);
        !            94:        }
        !            95: #endif
        !            96:        return (1);
        !            97: }
        !            98:
        !            99: #if defined(MVME162) || defined(MVME167) || defined(MVME177)
        !           100: /*
        !           101:  * make local addresses 1G-2G correspond to VME addresses 3G-4G,
        !           102:  * as D32
        !           103:  */
        !           104: #define VME2_D32STARTPHYS      (1*1024*1024*1024UL)
        !           105: #define VME2_D32ENDPHYS                (2*1024*1024*1024UL)
        !           106: #define VME2_D32STARTVME       (3*1024*1024*1024UL)
        !           107: #define VME2_D32BITSVME                (3*1024*1024*1024UL)
        !           108:
        !           109: /*
        !           110:  * make local addresses 3G-3.75G correspond to VME addresses 3G-3.75G,
        !           111:  * as D16
        !           112:  */
        !           113: #define VME2_D16STARTPHYS      (3*1024*1024*1024UL)
        !           114: #define VME2_D16ENDPHYS                (3*1024*1024*1024UL + 768*1024*1024UL)
        !           115: #endif
        !           116:
        !           117: /*
        !           118:  * Returns a physical address mapping for a VME address & length.
        !           119:  * Note: on some hardware it is not possible to create certain
        !           120:  * mappings, ie. the MVME147 cannot do 32 bit accesses to VME bus
        !           121:  * addresses from 0 to physmem.
        !           122:  */
        !           123: paddr_t
        !           124: vmepmap(sc, vmeaddr, len, bustype)
        !           125:        struct vmesoftc *sc;
        !           126:        paddr_t vmeaddr;
        !           127:        int len;
        !           128:        int bustype;
        !           129: {
        !           130:        paddr_t base = vmeaddr;
        !           131:
        !           132:        len = roundup(len, NBPG);
        !           133:        switch (vmebustype) {
        !           134: #if NPCC > 0
        !           135:        case BUS_PCC:
        !           136:                switch (bustype) {
        !           137:                case BUS_VMES:
        !           138: #ifdef DEBUG
        !           139:                        printf("base %8p/0x%8x len 0x%x\n",
        !           140:                                vmeaddr, base, len);
        !           141: #endif
        !           142:                        if (base > VME1_A16BASE &&
        !           143:                            (base+len - VME1_A16BASE) < VME1_A16D16LEN) {
        !           144:                                base = base - VME1_A16BASE + VME1_A16D16BASE;
        !           145: #ifdef DEBUG
        !           146:                                printf("vmes1: base = 0x%8x\n", base); /* 1:1 */
        !           147: #endif
        !           148:                        } else if (base > VME1_A32D16BASE &&
        !           149:                            base+len < VME1_A16BASE) {
        !           150:                                /* 1:1 mapped */
        !           151: #ifdef DEBUG
        !           152:                                printf("vmes2: base = 0x%8x\n", base);
        !           153: #endif
        !           154:                        } else {
        !           155:                                printf("%s: cannot map pa 0x%x len 0x%x\n",
        !           156:                                    sc->sc_dev.dv_xname, base, len);
        !           157:                                return (0);
        !           158:                        }
        !           159:                        break;
        !           160:                case BUS_VMEL:
        !           161:                        if (base >= physmem && (base+len) < VME1_A32D32LEN)
        !           162:                                base = base + VME1_A32D32BASE;
        !           163:                        else if (base+len < VME1_A32D16LEN)             /* HACK! */
        !           164:                                base = base + VME1_A32D16BASE;
        !           165:                        else {
        !           166:                                printf("%s: cannot map pa 0x%x len 0x%x\n",
        !           167:                                    sc->sc_dev.dv_xname, base, len);
        !           168:                                return (0);
        !           169:                        }
        !           170:                        break;
        !           171:                }
        !           172:                break;
        !           173: #endif
        !           174: #if NMC > 0 || NPCCTWO > 0
        !           175:        case BUS_MC:
        !           176:        case BUS_PCCTWO:
        !           177:                switch (bustype) {
        !           178:                case BUS_VMES:
        !           179: #ifdef DEBUG
        !           180:                        printf("base %x len %d\n", base, len);
        !           181: #endif
        !           182:                        if (base > VME2_A16BASE &&
        !           183:                            (base+len-VME2_A16BASE) < VME2_A16D16LEN) {
        !           184:                                /* XXX busted? */
        !           185:                                base = base - VME2_A16BASE + VME2_A16D16BASE;
        !           186:                        } else if (base > VME2_A24BASE &&
        !           187:                            (base+len-VME2_A24BASE) < VME2_A24D16LEN) {
        !           188:                                base = base - VME2_A24BASE + VME2_D16STARTPHYS;
        !           189:                        } else if ((base+len) < VME2_A32D16LEN) {
        !           190:                                /* XXX busted? */
        !           191:                                base = base + VME2_A32D16BASE;
        !           192:                        } else {
        !           193: #ifdef DEBUG
        !           194:                                printf("vme2chip_map\n");
        !           195: #endif
        !           196:                                base = vme2chip_map(base, len, 16);
        !           197:                        }
        !           198:                        break;
        !           199:                case BUS_VMEL:
        !           200: #if 0
        !           201:                        if (base > VME2_A16BASE &&
        !           202:                            (base+len-VME2_A16BASE) < VME2_A16D32LEN)
        !           203:                                base = base - VME2_A16BASE + VME2_A16D32BASE;
        !           204: #endif
        !           205:                        base = vme2chip_map(base, len, 32);
        !           206:                        break;
        !           207:                }
        !           208:                break;
        !           209: #endif
        !           210:        }
        !           211:        return (base);
        !           212: }
        !           213:
        !           214: /* if successful, returns the va of a vme bus mapping */
        !           215: vaddr_t
        !           216: vmemap(sc, vmeaddr, len, bustype)
        !           217:        struct vmesoftc *sc;
        !           218:        paddr_t vmeaddr;
        !           219:        int len;
        !           220:        int bustype;
        !           221: {
        !           222:        paddr_t pa;
        !           223:        vaddr_t va;
        !           224:
        !           225:        pa = vmepmap(sc, vmeaddr, len, bustype);
        !           226:        if (pa == 0)
        !           227:                return (0);
        !           228:        va = mapiodev(pa, len);
        !           229:        return (va);
        !           230: }
        !           231:
        !           232: void
        !           233: vmeunmap(va, len)
        !           234:        vaddr_t va;
        !           235:        int len;
        !           236: {
        !           237:        unmapiodev(va, len);
        !           238: }
        !           239:
        !           240: int
        !           241: vmerw(sc, uio, flags, bus)
        !           242:        struct vmesoftc *sc;
        !           243:        struct uio *uio;
        !           244:        int flags;
        !           245:        int bus;
        !           246: {
        !           247:        vaddr_t v;
        !           248:        int c;
        !           249:        struct iovec *iov;
        !           250:        vaddr_t vme;
        !           251:        int error = 0;
        !           252:
        !           253:        while (uio->uio_resid > 0 && error == 0) {
        !           254:                iov = uio->uio_iov;
        !           255:                if (iov->iov_len == 0) {
        !           256:                        uio->uio_iov++;
        !           257:                        uio->uio_iovcnt--;
        !           258:                        if (uio->uio_iovcnt < 0)
        !           259:                                panic("vmerw");
        !           260:                        continue;
        !           261:                }
        !           262:
        !           263:                v = uio->uio_offset;
        !           264:                c = min(iov->iov_len, MAXPHYS);
        !           265:                if ((v & PGOFSET) + c > NBPG)   /* max NBPG at a time */
        !           266:                        c = NBPG - (v & PGOFSET);
        !           267:                if (c == 0)
        !           268:                        return (0);
        !           269:                vme = vmemap(sc, trunc_page(v), NBPG, BUS_VMES);
        !           270:                if (vme == 0) {
        !           271:                        error = EFAULT; /* XXX? */
        !           272:                        continue;
        !           273:                }
        !           274:                error = uiomove((void *)vme + (v & PGOFSET), c, uio);
        !           275:                vmeunmap(vme, NBPG);
        !           276:        }
        !           277:        return (error);
        !           278: }
        !           279:
        !           280: int
        !           281: vmeprint(args, bus)
        !           282:        void *args;
        !           283:        const char *bus;
        !           284: {
        !           285:        struct confargs *ca = args;
        !           286:
        !           287:        printf(" addr 0x%x", ca->ca_offset);
        !           288:        if (ca->ca_vec > 0)
        !           289:                printf(" vec 0x%x", ca->ca_vec);
        !           290:        if (ca->ca_ipl > 0)
        !           291:                printf(" ipl %d", ca->ca_ipl);
        !           292:        return (UNCONF);
        !           293: }
        !           294:
        !           295: int
        !           296: vmescan(parent, child, args, bustype)
        !           297:        struct device *parent;
        !           298:        void *child, *args;
        !           299:        int bustype;
        !           300: {
        !           301:        struct cfdata *cf = child;
        !           302:        struct vmesoftc *sc = (struct vmesoftc *)parent;
        !           303:        struct confargs oca;
        !           304:
        !           305:        bzero(&oca, sizeof oca);
        !           306:        oca.ca_bustype = bustype;
        !           307:        oca.ca_paddr = cf->cf_loc[0];
        !           308:        oca.ca_vec = cf->cf_loc[1];
        !           309:        oca.ca_ipl = cf->cf_loc[2];
        !           310:        if (oca.ca_ipl > 0 && oca.ca_vec == -1)
        !           311:                oca.ca_vec = intr_findvec(255, 0);
        !           312:
        !           313:        oca.ca_offset = oca.ca_paddr;
        !           314:        oca.ca_vaddr = vmemap(sc, oca.ca_paddr, PAGE_SIZE, oca.ca_bustype);
        !           315:        if (oca.ca_vaddr == 0)
        !           316:                oca.ca_vaddr = (vaddr_t)-1;
        !           317:        oca.ca_name = cf->cf_driver->cd_name;
        !           318:        if ((*cf->cf_attach->ca_match)(parent, cf, &oca) == 0) {
        !           319:                if (oca.ca_vaddr != (vaddr_t)-1)
        !           320:                        vmeunmap(oca.ca_vaddr, PAGE_SIZE);
        !           321:                return (0);
        !           322:        }
        !           323:        /*
        !           324:         * If match works, the driver is responsible for
        !           325:         * vmunmap()ing if it does not need the mapping.
        !           326:         */
        !           327:        config_attach(parent, cf, &oca, vmeprint);
        !           328:        return (1);
        !           329: }
        !           330:
        !           331: void
        !           332: vmeattach(parent, self, args)
        !           333:        struct device *parent, *self;
        !           334:        void *args;
        !           335: {
        !           336:        struct vmesoftc *sc = (struct vmesoftc *)self;
        !           337:        struct confargs *ca = args;
        !           338: #if NPCC > 0
        !           339:        struct vme1reg *vme1;
        !           340: #endif
        !           341: #if NMC > 0 || NPCCTWO > 0
        !           342:        struct vme2reg *vme2;
        !           343: #endif
        !           344:
        !           345:        sc->sc_vaddr = ca->ca_vaddr;
        !           346:
        !           347:        vmebustype = ca->ca_bustype;
        !           348:        switch (ca->ca_bustype) {
        !           349: #if NPCC > 0
        !           350:        case BUS_PCC:
        !           351:                vme1 = (struct vme1reg *)sc->sc_vaddr;
        !           352:                if (vme1->vme1_scon & VME1_SCON_SWITCH)
        !           353:                        printf(": system controller");
        !           354:                printf("\n");
        !           355:                vme1chip_init(sc);
        !           356:                break;
        !           357: #endif
        !           358: #if NMC > 0 || NPCCTWO > 0
        !           359:        case BUS_MC:
        !           360:        case BUS_PCCTWO:
        !           361:                vme2 = (struct vme2reg *)sc->sc_vaddr;
        !           362:                if (vme2->vme2_tctl & VME2_TCTL_SCON)
        !           363:                        printf(": system controller");
        !           364:                printf("\n");
        !           365:                vme2chip_init(sc);
        !           366:                break;
        !           367: #endif
        !           368:        }
        !           369:
        !           370:        while (config_found(self, NULL, NULL))
        !           371:                ;
        !           372: }
        !           373:
        !           374: /*
        !           375:  * On the VMEbus, only one cpu may be configured to respond to any
        !           376:  * particular vme ipl. Therefore, it wouldn't make sense to globally
        !           377:  * enable all the interrupts all the time -- it would not be possible
        !           378:  * to put two cpu's and one vme card into a single cage. Rather, we
        !           379:  * enable each vme interrupt only when we are attaching a device that
        !           380:  * uses it. This makes it easier (though not trivial) to put two cpu
        !           381:  * cards in one VME cage, and both can have some limited access to vme
        !           382:  * interrupts (just can't share the same irq).
        !           383:  * Obviously no check is made to see if another cpu is using that
        !           384:  * interrupt. If you share you will lose.
        !           385:  */
        !           386: int
        !           387: vmeintr_establish(vec, ih, name)
        !           388:        int vec;
        !           389:        struct intrhand *ih;
        !           390:        const char *name;
        !           391: {
        !           392:        struct vmesoftc *sc = (struct vmesoftc *) vme_cd.cd_devs[0];
        !           393: #if NPCC > 0
        !           394:        struct vme1reg *vme1;
        !           395: #endif
        !           396: #if NMC > 0 || NPCCTWO > 0
        !           397:        struct vme2reg *vme2;
        !           398: #endif
        !           399:        int x;
        !           400:
        !           401:        x = intr_establish(vec, ih, name);
        !           402:
        !           403:        switch (vmebustype) {
        !           404: #if NPCC > 0
        !           405:        case BUS_PCC:
        !           406:                vme1 = (struct vme1reg *)sc->sc_vaddr;
        !           407:                vme1->vme1_irqen = vme1->vme1_irqen |
        !           408:                    VME1_IRQ_VME(ih->ih_ipl);
        !           409:                break;
        !           410: #endif
        !           411: #if NMC > 0 || NPCCTWO > 0
        !           412:        case BUS_MC:
        !           413:        case BUS_PCCTWO:
        !           414:                vme2 = (struct vme2reg *)sc->sc_vaddr;
        !           415:                vme2->vme2_irqen = vme2->vme2_irqen |
        !           416:                    VME2_IRQ_VME(ih->ih_ipl);
        !           417:                break;
        !           418: #endif
        !           419:        }
        !           420:        return (x);
        !           421: }
        !           422:
        !           423: #if defined(MVME147)
        !           424: void
        !           425: vme1chip_init(sc)
        !           426:        struct vmesoftc *sc;
        !           427: {
        !           428:        struct vme1reg *vme1 = (struct vme1reg *)sc->sc_vaddr;
        !           429:
        !           430:        vme1->vme1_scon &= ~VME1_SCON_SYSFAIL;  /* XXX doesn't work */
        !           431: }
        !           432: #endif
        !           433:
        !           434:
        !           435: #if defined(MVME162) || defined(MVME167) || defined(MVME177)
        !           436:
        !           437: /*
        !           438:  * XXX what AM bits should be used for the D32/D16 mappings?
        !           439:  */
        !           440: void
        !           441: vme2chip_init(sc)
        !           442:        struct vmesoftc *sc;
        !           443: {
        !           444:        struct vme2reg *vme2 = (struct vme2reg *)sc->sc_vaddr;
        !           445:        u_long ctl;
        !           446:
        !           447:        sys_vme2 = vme2;
        !           448:
        !           449:        /* turn off SYSFAIL LED */
        !           450:        vme2->vme2_tctl &= ~VME2_TCTL_SYSFAIL;
        !           451:
        !           452:        /*
        !           453:         * Display the VMEChip2 decoder status.
        !           454:         */
        !           455:        printf("%s: using BUG parameters\n", sc->sc_dev.dv_xname);
        !           456:        ctl = vme2->vme2_gcsrctl;
        !           457:        if (ctl & VME2_GCSRCTL_MDEN1) {
        !           458:                printf("%s: 1phys 0x%08lx-0x%08lx to VME 0x%08lx-0x%08lx\n",
        !           459:                    sc->sc_dev.dv_xname,
        !           460:                    vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000,
        !           461:                    vme2->vme2_master1 << 16, vme2->vme2_master1 & 0xffff0000);
        !           462:        }
        !           463:        if (ctl & VME2_GCSRCTL_MDEN2) {
        !           464:                printf("%s: 2phys 0x%08lx-0x%08lx to VME 0x%08lx-0x%08lx\n",
        !           465:                    sc->sc_dev.dv_xname,
        !           466:                    vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000,
        !           467:                    vme2->vme2_master2 << 16, vme2->vme2_master2 & 0xffff0000);
        !           468:        }
        !           469:        if (ctl & VME2_GCSRCTL_MDEN3) {
        !           470:                printf("%s: 3phys 0x%08lx-0x%08lx to VME 0x%08lx-0x%08lx\n",
        !           471:                    sc->sc_dev.dv_xname,
        !           472:                    vme2->vme2_master3 << 16, vme2->vme2_master3 & 0xffff0000,
        !           473:                    vme2->vme2_master3 << 16, vme2->vme2_master3 & 0xffff0000);
        !           474:        }
        !           475:        if (ctl & VME2_GCSRCTL_MDEN4) {
        !           476:                printf("%s: 4phys 0x%08lx-0x%08lx to VME 0x%08lx-0x%08lx\n",
        !           477:                    sc->sc_dev.dv_xname,
        !           478:                    vme2->vme2_master4 << 16, vme2->vme2_master4 & 0xffff0000,
        !           479:                    (vme2->vme2_master4 << 16) + (vme2->vme2_master4mod << 16),
        !           480:                    (vme2->vme2_master4 & 0xffff0000) +
        !           481:                      (vme2->vme2_master4mod & 0xffff0000));
        !           482:        }
        !           483:
        !           484:        /*
        !           485:         * Map the VME irq levels to the cpu levels 1:1.
        !           486:         * This is rather inflexible, but much easier.
        !           487:         */
        !           488:        vme2->vme2_irql4 = (7 << VME2_IRQL4_VME7SHIFT) |
        !           489:            (6 << VME2_IRQL4_VME6SHIFT) | (5 << VME2_IRQL4_VME5SHIFT) |
        !           490:            (4 << VME2_IRQL4_VME4SHIFT) | (3 << VME2_IRQL4_VME3SHIFT) |
        !           491:            (2 << VME2_IRQL4_VME2SHIFT) | (1 << VME2_IRQL4_VME1SHIFT);
        !           492:        printf("%s: vme to cpu irq level 1:1\n",sc->sc_dev.dv_xname);
        !           493:
        !           494: #if NPCCTWO > 0
        !           495:        if (vmebustype == BUS_PCCTWO) {
        !           496:                /*
        !           497:                 * pseudo driver, abort interrupt handler
        !           498:                 */
        !           499:                sc->sc_abih.ih_fn = vme2abort;
        !           500:                sc->sc_abih.ih_ipl = 7;
        !           501:                sc->sc_abih.ih_wantframe = 1;
        !           502:
        !           503:                intr_establish(110, &sc->sc_abih, sc->sc_dev.dv_xname); /* XXX 110 */
        !           504:                vme2->vme2_irqen |= VME2_IRQ_AB;
        !           505:        }
        !           506: #endif
        !           507:        /*
        !           508:         * Enable ACFAIL interrupt, but disable Timer 1 interrupt - we
        !           509:         * prefer it without for delay().
        !           510:         */
        !           511:        vme2->vme2_irqen = (vme2->vme2_irqen | VME2_IRQ_ACF) & ~VME2_IRQ_TIC1;
        !           512: }
        !           513:
        !           514: /*
        !           515:  * A32 accesses on the MVME1[67]x require setting up mappings in
        !           516:  * the VME2 chip.
        !           517:  * XXX VME address must be between 2G and 4G
        !           518:  * XXX We only support D32 at the moment..
        !           519:  */
        !           520: u_long
        !           521: vme2chip_map(base, len, dwidth)
        !           522:        u_long base;
        !           523:        int len, dwidth;
        !           524: {
        !           525:        switch (dwidth) {
        !           526:        case 16:
        !           527:                if (base < VME2_D16STARTPHYS ||
        !           528:                    base + (u_long)len > VME2_D16ENDPHYS)
        !           529:                        return (NULL);
        !           530:                return (base);
        !           531:        case 32:
        !           532:                if (base < VME2_D32STARTVME)
        !           533:                        return (NULL);
        !           534:                return (base - VME2_D32STARTVME + VME2_D32STARTPHYS);
        !           535:        default:
        !           536:                return (NULL);
        !           537:        }
        !           538: }
        !           539:
        !           540: #if NPCCTWO > 0
        !           541: int
        !           542: vme2abort(frame)
        !           543:        void *frame;
        !           544: {
        !           545:        struct vmesoftc *sc = (struct vmesoftc *)vme_cd.cd_devs[0];
        !           546:        struct vme2reg *vme2 = (struct vme2reg *)sc->sc_vaddr;
        !           547:
        !           548:        if ((vme2->vme2_irqstat & VME2_IRQ_AB) == 0) {
        !           549:                printf("%s: abort irq not set\n", sc->sc_dev.dv_xname);
        !           550:                return (0);
        !           551:        }
        !           552:        vme2->vme2_irqclr = VME2_IRQ_AB;
        !           553:        nmihand(frame);
        !           554:        return (1);
        !           555: }
        !           556: #endif
        !           557: #endif

CVSweb