[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

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