Annotation of Net2/arch/vax/uba/np.c, revision 1.1

1.1     ! root        1: /*-
        !             2:  * Copyright (c) 1986 MICOM-Interlan, Inc., Boxborough Mass
        !             3:  * Copyright (c) 1991 The Regents of the University of California.
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  * 1. Redistributions of source code must retain the above copyright
        !            10:  *    notice, this list of conditions and the following disclaimer.
        !            11:  * 2. Redistributions in binary form must reproduce the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer in the
        !            13:  *    documentation and/or other materials provided with the distribution.
        !            14:  * 3. All advertising materials mentioning features or use of this software
        !            15:  *    must display the following acknowledgement:
        !            16:  *     This product includes software developed by the University of
        !            17:  *     California, Berkeley and its contributors.
        !            18:  * 4. Neither the name of the University nor the names of its contributors
        !            19:  *    may be used to endorse or promote products derived from this software
        !            20:  *    without specific prior written permission.
        !            21:  *
        !            22:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            32:  * SUCH DAMAGE.
        !            33:  *
        !            34:  *     @(#)np.c        7.10 (Berkeley) 5/9/91
        !            35:  */
        !            36: 
        !            37: /*
        !            38:  * From:
        !            39:  *     np.c version 1.5
        !            40:  *
        !            41:  *     This version retrieved: 8/18/86 @ 18:58:54
        !            42:  *         This delta created: 8/18/86 @ 18:19:24
        !            43:  *
        !            44:  *     static          char    *SCCSID = "@(#)np.c     1.5";
        !            45:  *
        !            46:  */
        !            47: 
        !            48:                /******************************************
        !            49:                *                                         *
        !            50:                *               NPDRIVER                  *
        !            51:                *                                         *
        !            52:                ******************************************/
        !            53: 
        !            54: /*
        !            55:  * The NP Driver is used to route requests, independent of protocol type,
        !            56:  * to the NP series Intelligent Board. The facilities it provides are
        !            57:  * used for board maintainance by the superuser and by protocol pseudo-drivers, 
        !            58:  * such as WN, for sending requests to a board. The board maintainance and
        !            59:  * control functions are accessed via npioctl() by the NP support utilities.
        !            60:  */
        !            61: 
        !            62: /*
        !            63:  * Modification History:
        !            64:  * 4/9/86 DDW Removed pseudo-driver initialization flag resets from NpReset
        !            65:  * 5/28/86 CJM Changed iodone() to wakeup() in NpProcQueue().
        !            66:  *
        !            67:  */
        !            68: 
        !            69: /*
        !            70:  * Include Files
        !            71:  */
        !            72: 
        !            73: #include "np.h"
        !            74: #if NNP > 0
        !            75: #include "sys/param.h"
        !            76: #include "sys/buf.h"
        !            77: #include "sys/conf.h"
        !            78: #include "sys/ubavar.h"
        !            79: #include "sys/signal.h"
        !            80: #include "sys/systm.h"
        !            81: #include "sys/user.h"
        !            82: #include "sys/proc.h"
        !            83: #include "sys/uio.h"
        !            84: #include "sys/errno.h"
        !            85: #include "sys/ioctl.h"
        !            86: 
        !            87: #include "../uba/npreg.h"
        !            88: 
        !            89: #define b_uio b_forw
        !            90: #define b_rp  av_back
        !            91: /*
        !            92:  * Global variables for pseudo-drivers.
        !            93:  */
        !            94: 
        !            95: int WnInitFlag = 0;
        !            96: int IsInitFlag = 0;
        !            97: int (*IxAttach)();
        !            98: int (*IxReset)();
        !            99: 
        !           100: /*
        !           101:  * Debugging level.
        !           102:  */
        !           103: 
        !           104: int    NpDebug = 0;            
        !           105: 
        !           106: /* Driver Wide State used by the ICP */
        !           107: 
        !           108: int NpState = NPCLEAR;
        !           109: 
        !           110: 
        !           111: /*
        !           112:  * Master structure, one per board, contains request queue header,
        !           113:  * shared memory address, and memory mapping information.
        !           114:  */
        !           115: 
        !           116: struct npmaster npmasters[NNP];
        !           117: 
        !           118: /* Structure of the shared memory area */
        !           119: 
        !           120: static struct npspace npspaces[NNP];
        !           121: 
        !           122: /* Panic Message data structures */
        !           123: 
        !           124: static int panicmap;                   /* Mapping information */
        !           125: static char    NpPbuf[PANLEN] = 0;     /* Panic message buffer */
        !           126: static caddr_t pstring;                        /* Panic string address on board, absolute */
        !           127: static unsign16 panaddr[2];            /* Panic string address on board (seg/offset) */
        !           128: 
        !           129: /* Driver Wide Connection Table */
        !           130: 
        !           131: static struct npconn npcnxtab[NNP][NNPCNN];
        !           132: 
        !           133: /* Head of the request queue, one per board */
        !           134: 
        !           135: static struct npreq reqhdr[NNP];
        !           136: 
        !           137: /* Require for diagnostic packages */
        !           138: 
        !           139: typedef struct npreq *reqptr;
        !           140: reqptr np_mapreq[NNP];
        !           141: 
        !           142: /* The request structures, one pool per board */
        !           143: 
        !           144: static struct npreq npreqs[NNP][NUMCQE];
        !           145: 
        !           146: 
        !           147: /*
        !           148:  * Data structures needed for BSD 4.2 Device Drivers
        !           149:  */
        !           150: 
        !           151: int    npprobe(), npattach(), npintr();
        !           152: struct uba_device *npdinfo[NNP];
        !           153: 
        !           154: /* UNIBUS address of Network Processors */
        !           155: 
        !           156: u_short        npstd[] = { 0166000, 0166020, 0 };
        !           157: 
        !           158: /* Interrupt vectors used by the Network Processors */
        !           159: 
        !           160: static unsign16 npvectors[NNP];
        !           161: 
        !           162: struct uba_driver npdriver =
        !           163:     { npprobe, 0, npattach, 0, npstd, "np", npdinfo };
        !           164: struct buf     np_tab[NNP];
        !           165: static unsigned long np_icount[NNP];
        !           166: 
        !           167: 
        !           168: /*
        !           169:  * External function and data structure declarations.
        !           170:  */
        !           171: 
        !           172: struct npreq * NpGetReq();
        !           173: struct npmaster        *NpBoardChange();
        !           174: int NpTimer();
        !           175: struct CQE * NpRemCQE();
        !           176: 
        !           177: extern struct user u;
        !           178: 
        !           179: /*
        !           180:  * Np_init() is responsible for hardware initializiation and the software 
        !           181:  * initialization of the connection table and driver software data structures.
        !           182:  */
        !           183: 
        !           184: npinit(unit)
        !           185: int unit;
        !           186: {
        !           187:        register int j;
        !           188: 
        !           189: 
        !           190:                /* Software Initialization */
        !           191: 
        !           192:        npmasters[unit].flags = NPCLEAR;
        !           193: 
        !           194:        NpSWinit(unit);
        !           195: 
        !           196:                /* Hardware Initialization */
        !           197: 
        !           198:        NpHWinit(unit);         
        !           199: 
        !           200:                /* Connection Table Initialization */
        !           201: 
        !           202:        for(j=0;j<NNPCNN;j++) {
        !           203:                npcnxtab[unit][j].protocol = NPCLCONN;
        !           204:                npcnxtab[unit][j].unit = &npmasters[unit];
        !           205:        }
        !           206: }
        !           207: 
        !           208: /*
        !           209:  * Np_open establishes a connection to the NP Driver using the minor
        !           210:  * device number as an identifier. A default protocol, NPMAINT, is assigned
        !           211:  * with the specified unit. Protocol and unit may be changed using the 
        !           212:  * NpProtChange and NpBoardChange functions.
        !           213:  * Since the maintainance protocol does not need a working I-Board, entries
        !           214:  * are always made in the Connection Table, npcnxtab, if the board exists.
        !           215:  */
        !           216: 
        !           217: /*ARGSUSED*/
        !           218: npopen(dev,flag)
        !           219: dev_t dev;
        !           220: int flag;
        !           221: {
        !           222:        int unit;
        !           223:        unsign16 conn;
        !           224:        struct npmaster *mp;
        !           225:        int error;
        !           226: 
        !           227:        if(NpDebug & DEBENTRY)
        !           228:                printf("npopen\n");
        !           229: 
        !           230:        /* Clear error */
        !           231: 
        !           232:        error = 0;
        !           233: 
        !           234:        /* Make sure it's the superuser */
        !           235: 
        !           236:        if(u.u_uid) 
        !           237:                return(EPERM);
        !           238:        
        !           239:        /* Get the connection identifier */
        !           240: 
        !           241:        if(((conn = NPCONN(dev)) >= NNPCNN) ||
        !           242:            ((unit = NPUNIT(dev)) >= NNP)) 
        !           243:                return(ENODEV);
        !           244:        
        !           245: 
        !           246:        if(NpDebug  & DEBOPEN)
        !           247:                printf("conn = %x unit = %d\n",conn,unit);
        !           248: 
        !           249:        /* Get the board for the specified unit */
        !           250: 
        !           251:        mp = NpBoardChange(NPMAINT,unit);
        !           252: 
        !           253:        if(mp != (struct npmaster *) 0) {
        !           254:                npcnxtab[unit][conn].unit = mp;
        !           255:                npcnxtab[unit][conn].protocol = NPMAINT;
        !           256:        }
        !           257:        else error = ENXIO;
        !           258: 
        !           259:        if(NpDebug & DEBENTRY)
        !           260:                printf("npopen...\n");
        !           261: 
        !           262:        return(error);
        !           263: }
        !           264: 
        !           265: /*
        !           266:  * Np_close is responsible updating the connection table for
        !           267:  * that connection by marking it closed.
        !           268:  */
        !           269: 
        !           270: npclose(dev)
        !           271: dev_t dev;
        !           272: {
        !           273: 
        !           274:        if(NpDebug & DEBENTRY)
        !           275:                printf("npclose\n");
        !           276: 
        !           277:        /* Get the connection identifier */
        !           278: 
        !           279:        npcnxtab[NPUNIT(dev)][NPCONN(dev)].protocol = NPCLCONN;
        !           280: 
        !           281:        if(NpDebug & DEBENTRY)
        !           282:                printf("npclose...\n");
        !           283: 
        !           284:        return(0);
        !           285: 
        !           286: }
        !           287: 
        !           288: /*
        !           289:  * Npioctl is the main conduit of commands between the I-Board and the
        !           290:  * NP support utilities. Relevant information for the request is found in the
        !           291:  * cmd and addr parameters. Cmd specifies the function to perform, addr is 
        !           292:  * command specific. Npioctl returns 0 if successful, or an error number
        !           293:  * (which winds up in errno).
        !           294:  */
        !           295: 
        !           296: /*ARGSUSED*/
        !           297: npioctl(dev,cmd,addr,flag)
        !           298: dev_t dev;
        !           299: int cmd;
        !           300: caddr_t *addr;
        !           301: int flag;
        !           302: {
        !           303:        unsign16 protocol;
        !           304:        unsign16 conn;
        !           305:        unsign16 unit;
        !           306:        int error;
        !           307: 
        !           308:        register struct npmaster *mp;
        !           309:        register struct npreq *rp;
        !           310:        unsigned usrarg;
        !           311: 
        !           312:        if(NpDebug & DEBENTRY)
        !           313:                printf("npioctl\n");
        !           314: 
        !           315:        /* Clear error */
        !           316: 
        !           317:        error = 0;
        !           318: 
        !           319:        /* Strip off IOC_VOID bit */
        !           320: 
        !           321:        cmd &= CMDMASK;
        !           322: 
        !           323:        /* Get connection identifier */
        !           324: 
        !           325:        conn = NPCONN(dev);
        !           326:        unit = NPUNIT(dev);
        !           327: 
        !           328:        /* Master pointer for this unit */
        !           329: 
        !           330:        mp = npcnxtab[unit][conn].unit;
        !           331: 
        !           332:        protocol = npcnxtab[unit][conn].protocol;
        !           333: 
        !           334:        /* Get a request structure from the pool and initialize it */
        !           335: 
        !           336:        while((rp = NpGetReq(mp->reqtab)) == NULL) {
        !           337:                mp->reqtab->flags |= WANTREQ;
        !           338:                sleep((caddr_t)(mp->reqtab),PZERO -1);
        !           339:        }
        !           340: 
        !           341:        if(NpDebug & DEBREQ)
        !           342:                printf("NP Reqp is %x\n",rp);
        !           343: 
        !           344:        /* Initializations of request structure */
        !           345: 
        !           346:        rp->intr = (int (*)())0;        /* Do not call interrupt routine */
        !           347:        rp->bufoffset = 0;              /* Offset into data buffer */
        !           348:        rp->procp = u.u_procp;  /* Process structure for this user */
        !           349: 
        !           350:        /* Copy in user's argument to ioctl() call */
        !           351: 
        !           352:        if(error = copyin(*addr,&usrarg,sizeof(usrarg)))
        !           353:                return(error);
        !           354:        
        !           355: 
        !           356:        if(NpDebug & DEBIOCTL)
        !           357:                printf("arg = %x\n",usrarg);
        !           358: 
        !           359:        /* Execute the specified command */
        !           360: 
        !           361:        switch(cmd) {
        !           362: 
        !           363:            case NPSETPROT:
        !           364:                if((error = NpProtChange(usrarg,mp->unit)) == 0)
        !           365:                        npcnxtab[unit][conn].protocol = usrarg;
        !           366:                break;
        !           367:            case NPSETBOARD:
        !           368:                if(mp = NpBoardChange(protocol,usrarg))
        !           369:                        npcnxtab[unit][conn].unit = mp;
        !           370:                else {
        !           371:                        mp = npcnxtab[unit][conn].unit;
        !           372:                        error = ENXIO;
        !           373:                }
        !           374:                break;
        !           375:            case NPRESET:
        !           376:                error = NpReset(mp,rp);
        !           377:                break;
        !           378:            case NPSETNPDEB:
        !           379:                NpDebug = usrarg;
        !           380:                break;
        !           381:            case NPINIT:
        !           382:                error = NpSWinit(mp->unit);
        !           383:                break;
        !           384:            case NPSTART:
        !           385: 
        !           386: #ifdef OLDROM
        !           387:                /*
        !           388:                 * Kludge to work around I-Board boot from Host. Read two bytes
        !           389:                 * from the board into the Device Configuration Word
        !           390:                 * in Shared Memory.
        !           391:                 */
        !           392: 
        !           393:                NPIO(mp,(paddr_t)0x500,(paddr_t)(&mp->shmemp->statblock.sb_dcw),2,B_READ);
        !           394: 
        !           395:                mp->shmemp->statblock.sb_drw = 0;
        !           396: #endif
        !           397: 
        !           398:                /* Set the Address at which to begin On-Board execution */
        !           399: 
        !           400:                error = NpSetXeqAddr(mp,(caddr_t)usrarg);
        !           401:                break;
        !           402:            case NPSTATS:
        !           403:                error = NpStats();
        !           404:                break;
        !           405:            case NPGPANIC:
        !           406:                error = copyout((caddr_t)NpPbuf,*addr,PANLEN);
        !           407: 
        !           408:                /* Clear panic request flag and leave */
        !           409: 
        !           410:                mp->flags &= ~PANICREQ;
        !           411:                break;
        !           412:            case NPPOLL:
        !           413:                error = NpPoll(mp,*addr);
        !           414:                break;
        !           415:            case NPKILL:
        !           416:                error = NpKill(mp,rp);
        !           417:                break;
        !           418:            case NPSETADDR:
        !           419:                error = NpSetMemAddr(mp,*addr);
        !           420:                break;
        !           421:            case NPRCSR0:
        !           422:                usrarg = RCSR0(mp->iobase);
        !           423:                error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg));
        !           424:                break;
        !           425:            case NPRCSR1:
        !           426:                usrarg = RCSR1(mp->iobase);
        !           427:                error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg));
        !           428:                break;
        !           429:            case NPRCSR2:
        !           430:                usrarg = RCSR2(mp->iobase);
        !           431:                error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg));
        !           432:                break;
        !           433:            case NPRCSR3:
        !           434:                usrarg = RCSR3(mp->iobase);
        !           435:                error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg));
        !           436:                break;
        !           437:            case NPWCSR0:
        !           438:                WCSR0(mp->iobase,usrarg);
        !           439:                break;
        !           440:            case NPWCSR1:
        !           441:                WCSR1(mp->iobase,usrarg);
        !           442:                break;
        !           443:            case NPWCSR2:
        !           444:                WCSR2(mp->iobase,usrarg);
        !           445:                break;
        !           446:            case NPWCSR3:
        !           447:                WCSR3(mp->iobase,usrarg);
        !           448:                break;
        !           449:            case NPNETBOOT:
        !           450:                error = NpSetIntLevel(mp,mp->vector);
        !           451:                if(error) break;
        !           452:                error = NpSetXeqAddr(mp,(caddr_t)INETBOOT);
        !           453:                break;
        !           454:            case NPSETLAST:
        !           455:                if (usrarg)
        !           456:                        mp->flags &= ~LSTCMD;
        !           457:                else
        !           458:                        mp->flags |= LSTCMD;
        !           459:                break;
        !           460:            case NPCLRICNT:
        !           461:                np_icount[unit] = NPCLEAR;
        !           462:                break;
        !           463:            case NPGETICNT:
        !           464:                usrarg = np_icount[unit];
        !           465:                error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg));
        !           466:                break;
        !           467:            case NPGETIVEC:
        !           468:                usrarg = mp->vector;
        !           469:                error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg));
        !           470:                break;
        !           471:            case NPMAPMEM:
        !           472:                error = NpMem(mp, rp, *addr);
        !           473:                break;
        !           474:            default:
        !           475:                printf("Bad Maintenance command: %d!\n",cmd);
        !           476:                error = EIO;
        !           477:                break;
        !           478:        }
        !           479:        if((cmd != NPRESET) && (cmd != NPINIT) && (cmd != NPMAPMEM))
        !           480:                NpFreeReq(mp->reqtab,rp);
        !           481: 
        !           482:        if(NpDebug & DEBENTRY)
        !           483:                printf("npioctl...\n");
        !           484: 
        !           485:        return(error);
        !           486: }
        !           487: 
        !           488: /*
        !           489:  * np_start - start io activity
        !           490:  */
        !           491: npstart(mp)
        !           492: register struct npmaster *mp;
        !           493: {
        !           494: 
        !           495:        register struct uio     *uio;
        !           496:        register struct buf     *bp;
        !           497:        register struct npreq   *rp;
        !           498: 
        !           499:        int error;                      /* Return from NPIO call */
        !           500: 
        !           501:        if(NpDebug & DEBENTRY)
        !           502:                printf("npstart\n");
        !           503: 
        !           504:        if((bp = np_tab[mp->unit].b_actf) == (struct buf *)0) {
        !           505:                np_tab[mp->unit].b_active = 0;
        !           506:                return;
        !           507:        }
        !           508:        if((rp = (struct npreq *)(bp->b_rp)) == (struct npreq *)0) {
        !           509:                bp->b_flags = B_ERROR;
        !           510:                iodone(bp);
        !           511:                return;
        !           512:        }
        !           513:        if ((uio = (struct uio *)bp->b_uio) == (struct uio *)0) {
        !           514:                bp->b_flags = B_ERROR;
        !           515:                iodone(bp);
        !           516:                return;
        !           517:        }
        !           518:        np_tab[mp->unit].b_active = 1;
        !           519: 
        !           520:        if(NpDebug & DEBIO)
        !           521:                printf("NP IO src %x dst = %x cnt = %x\n", bp->b_un.b_addr,
        !           522:                        uio->uio_offset, bp->b_bcount);
        !           523: 
        !           524:        /* Send the request to the board via the CSR0 command interface */
        !           525: 
        !           526:        if(bp->b_flags & B_READ) 
        !           527:                error = NPIO(mp, (paddr_t)uio->uio_offset, (paddr_t)rp->bufaddr,
        !           528:                        bp->b_bcount, (bp->b_flags & B_READ)); 
        !           529:        else
        !           530:                error = NPIO(mp, (paddr_t)rp->bufaddr, (paddr_t)uio->uio_offset,
        !           531:                        bp->b_bcount, (bp->b_flags & B_READ)); 
        !           532:        
        !           533: 
        !           534:        /* Check return from I/O */
        !           535: 
        !           536:        if(error) {
        !           537:                bp->b_flags |= B_ERROR;
        !           538:                np_tab[mp->unit].b_actf = bp->av_forw;
        !           539:                if(NpDebug & DEBIO)
        !           540:                        printf("NPIO return error: b_flags is %x \n",bp->b_flags);
        !           541:                iodone(bp);
        !           542:        }
        !           543: 
        !           544:        if(NpDebug & DEBENTRY)
        !           545:                printf("npstart...\n");
        !           546: 
        !           547: }
        !           548: /*
        !           549:  * npstrategy - the strategy routine
        !           550:  */
        !           551: 
        !           552: npstrategy(bp)
        !           553: register struct buf *bp;
        !           554: {
        !           555: 
        !           556:        register struct buf *ip;        /* quick pointer */
        !           557:        register struct npmaster *mp;   /* master structure for this device */
        !           558:        register struct npreq *rp;      /* reqest struct pointer */
        !           559:        int s;                          /* priority to return to */
        !           560: 
        !           561:        if(NpDebug & DEBENTRY)
        !           562:                printf("npstrategy\n");
        !           563:        if(NpDebug & DEBIO)
        !           564:                printf("flag = %x count = %x paddr = %x %x blkno = %x %x\n",
        !           565:                    bp->b_flags, bp->b_bcount, bp->b_un.b_addr, bp->b_un.b_addr,
        !           566:                    bp->b_blkno,bp->b_blkno);
        !           567: 
        !           568:        /* get master structure */
        !           569: 
        !           570:        mp = npcnxtab[NPUNIT(bp->b_dev)][NPCONN(bp->b_dev)].unit;
        !           571: 
        !           572:        /* make sure the boards ok */
        !           573: 
        !           574:        if (mp->flags & BADBOARD) {
        !           575:                bp->b_flags |= B_ERROR;
        !           576: 
        !           577:                if(NpDebug & DEBMEM)
        !           578:                        printf("Bad Board %x bp %x\n",mp->flags,bp->b_flags);
        !           579: 
        !           580:                np_tab[mp->unit].b_actf = bp->av_forw;
        !           581:                iodone(bp);
        !           582:                return;
        !           583:        }
        !           584: 
        !           585:        /* Initializations of request structure */
        !           586: 
        !           587:        while((rp = NpGetReq(mp->reqtab)) == NULL) {
        !           588:                mp->reqtab->flags |= WANTREQ;
        !           589:                sleep((caddr_t)(mp->reqtab),PZERO -1);
        !           590:        }
        !           591: 
        !           592:        rp->bufoffset = 0;              /* This is the start of the buffer */
        !           593:        ip = &np_tab[mp->unit];
        !           594:        bp->b_rp = (struct buf *)rp;
        !           595: 
        !           596:        rp->flags |= KERNREQ;           /* Mark it as kernel so not to map */
        !           597: 
        !           598:        rp->mapbase = ubasetup(mp->devp->ui_ubanum,bp,0);
        !           599:        rp->bufaddr = (caddr_t)((int)(rp->mapbase) & UBADDRMASK);
        !           600: 
        !           601:        s = spl5();
        !           602:        if(ip->b_actf ==(struct buf *)0)
        !           603:                ip->b_actf = bp;
        !           604:        else {
        !           605:                if(ip->b_actf->av_forw)
        !           606:                        printf("Panic NP100 bad buffer chain\n");
        !           607:                ip->b_actf->av_forw = bp;
        !           608:        }
        !           609:        ip->b_actl = bp;
        !           610: 
        !           611:        NpAddReq(mp->reqtab,rp);                /* Queue onto active list */
        !           612: 
        !           613:        if(ip->b_active == 0) {
        !           614: 
        !           615:                if(NpDebug & DEBIO)
        !           616:                        printf("calling npstart %x\n",mp);
        !           617: 
        !           618:                npstart(mp);
        !           619:        }
        !           620:        splx(s);
        !           621: 
        !           622:        if(NpDebug & DEBIO)
        !           623:                printf("back from npstart\n");
        !           624: 
        !           625:        /* Await completion of I/O */
        !           626: 
        !           627:        iowait(bp);
        !           628: 
        !           629:        if(NpDebug & DEBIO)
        !           630:                printf("after iowait in npstrategy\n");
        !           631: 
        !           632:        /* Remove request from queue */
        !           633: 
        !           634:        NpRemReq(rp);
        !           635: 
        !           636:        /* Release mapping registers */
        !           637: 
        !           638:        ubarelse(mp->devp->ui_ubanum,&rp->mapbase);
        !           639: 
        !           640:        /* Free up request structure */
        !           641: 
        !           642:        NpFreeReq(mp->reqtab,rp);
        !           643: 
        !           644:        if(NpDebug & DEBENTRY)
        !           645:                printf("Leaving npstrategy flags is %x\n",bp->b_flags);
        !           646: }
        !           647: 
        !           648: unsigned
        !           649: nptrim(bp)
        !           650: register struct buf *bp;
        !           651: {
        !           652: 
        !           653:        if(bp->b_bcount > NPMAXXFR)
        !           654:                bp->b_bcount = NPMAXXFR;
        !           655: }
        !           656: 
        !           657: /*
        !           658:  * Npread dumps data from the board to the user's buffer
        !           659:  */
        !           660: npread(dev,uio)
        !           661: dev_t dev;
        !           662: struct uio *uio;
        !           663: {
        !           664:        struct buf *bp;
        !           665:        bp = &npcnxtab[NPUNIT(dev)][NPCONN(dev)].np_rbuf;
        !           666: 
        !           667:        if(NpDebug & DEBENTRY)
        !           668:                printf("in npread\n");
        !           669: 
        !           670:        bp->b_uio = (struct buf *)uio;
        !           671:        return(physio(npstrategy,bp,dev,B_READ ,nptrim,uio));
        !           672: }
        !           673: 
        !           674: /*
        !           675:  * Npwrite loads the np100 board from the user's buffer
        !           676:  */
        !           677: 
        !           678: npwrite(dev,uio)
        !           679: dev_t dev;
        !           680: struct uio *uio;
        !           681: {
        !           682:        struct buf *bp;
        !           683:        bp = &npcnxtab[NPUNIT(dev)][NPCONN(dev)].np_wbuf;
        !           684: 
        !           685:        if(NpDebug & DEBENTRY)
        !           686:                printf("in npwrite \n");
        !           687: 
        !           688:        bp->b_uio = (struct buf *)uio;
        !           689:        return(physio(npstrategy,bp,dev,B_WRITE ,nptrim,uio));
        !           690: }
        !           691: 
        !           692: /*
        !           693:  * npreset - called as result of a UNIBUS reset.
        !           694:  */
        !           695: 
        !           696: npreset(uban)
        !           697: int uban;
        !           698: {
        !           699: 
        !           700:        register struct npmaster *mp;
        !           701:        register struct npreq *rp;
        !           702:        register struct uba_device *ui;
        !           703:        int i;
        !           704: 
        !           705:        if(NpDebug & DEBENTRY)
        !           706:                printf("npreset(ubareset)\n");
        !           707:        for(i = 0; i < NNP; i++) {
        !           708: 
        !           709:                if(((ui = npdinfo[i]) == (struct uba_device *)NULL) ||
        !           710:                        (ui->ui_ubanum != uban))
        !           711:                        continue;
        !           712: 
        !           713:                mp = &npmasters[i];
        !           714: 
        !           715:                /* Get a Request structure */
        !           716: 
        !           717:                while((rp = NpGetReq(mp->reqtab)) == NULL) {
        !           718:                        mp->reqtab->flags |= WANTREQ;
        !           719:                        sleep((caddr_t)(mp->reqtab),PZERO -1);
        !           720:                }
        !           721: 
        !           722:                NpReset(mp,rp);
        !           723:        }
        !           724:        if(NpDebug & DEBENTRY)
        !           725:                printf("npreset(ubareset)...\n");
        !           726: }
        !           727: 
        !           728: 
        !           729: /*
        !           730:  * Nppoll looks for work by polling each board. He goes to sleep if there are
        !           731:  * no outstanding requests for him but reminds the board that he's there when
        !           732:  * needed.
        !           733:  */
        !           734: 
        !           735: NpPoll(mp,addr)
        !           736: struct npmaster *mp;
        !           737: caddr_t        addr;
        !           738: {
        !           739:        int error;
        !           740: 
        !           741:        struct {
        !           742:                unsign16 request;
        !           743:                unsign16 unit;
        !           744:        }icpreq;
        !           745: 
        !           746:        if(NpDebug & DEBMAINT)
        !           747:                printf("NpPoll: flags is %x.\n",mp->flags);
        !           748: 
        !           749:        while(TRUE) {
        !           750: 
        !           751:                for(mp = npmasters; mp; mp = mp->next) {
        !           752: 
        !           753:                        if(mp->flags & BOARDREQ) {
        !           754: 
        !           755:                                /* Get request type from master structure */
        !           756: 
        !           757:                                if(mp->flags & BRDRESET) {
        !           758:                                        icpreq.request = ICPPOLL;
        !           759:                                        mp->reqtab->reqcnt--;
        !           760: 
        !           761:                                        if(NpDebug & DEBMAINT)
        !           762:                                                printf("Waking NpResetter!\n");
        !           763: 
        !           764:                                        wakeup((caddr_t)(&mp->reqtab));
        !           765:                                }
        !           766:                                else if(mp->flags & PANICREQ)
        !           767:                                        icpreq.request = ICPPANIC;
        !           768:                                else if(mp->flags & DUMPREQ)
        !           769:                                        icpreq.request = ICPDUMP;
        !           770:                                else if(mp->flags & LOADREQ)
        !           771:                                        icpreq.request = ICPLOAD;
        !           772:                                else {
        !           773:                                        mp->flags &= ~BOARDREQ;
        !           774:                                        continue;
        !           775:                                }
        !           776: 
        !           777:                                if(NpDebug & DEBMAINT)
        !           778:                                        printf("ProcICP servicing %d \n",icpreq.request );
        !           779: 
        !           780:                                /* Request and unit number to be sent */
        !           781: 
        !           782:                                icpreq.unit = mp->unit;
        !           783: 
        !           784:                                /* Copy service request to calling process */
        !           785: 
        !           786:                                error = copyout(&icpreq,addr,sizeof(icpreq));
        !           787: 
        !           788:                                /* Mark Poller as being unavailable */
        !           789: 
        !           790:                                NpState &= ~ICPAVAIL;
        !           791: 
        !           792:                                return(error);
        !           793:                        }
        !           794:                }
        !           795: 
        !           796:                /* Mark Poller as being available */
        !           797: 
        !           798:                NpState |= ICPAVAIL;
        !           799: 
        !           800:                if (error = tsleep((caddr_t)&NpState, (PZERO + 1) | PCATCH,
        !           801:                    devio, 0))
        !           802:                        return (error);
        !           803: 
        !           804:                if(NpDebug & DEBMAINT)
        !           805:                        printf("wakeup in NpPoll\n");
        !           806: 
        !           807:        }
        !           808: }
        !           809: 
        !           810: /*
        !           811:  * Software initialization of Driver data structures for the specified unit.
        !           812:  */
        !           813: 
        !           814: NpSWinit(unit)
        !           815: int unit;
        !           816: {
        !           817: 
        !           818:        register int j;
        !           819:        register struct npmaster *mp;
        !           820:        register struct npspace *npsp;
        !           821:        register struct CmdQue *cqp;
        !           822:        int offset;
        !           823: 
        !           824:        if(NpDebug & DEBINIT)
        !           825:                printf("SW reset on unit %d.\n",unit);
        !           826: 
        !           827:        np_icount[unit] = NPCLEAR;
        !           828:        np_mapreq[unit] = (struct npreq *) NPCLEAR;
        !           829: 
        !           830:        /* Initialize master structure pointer for this unit */
        !           831: 
        !           832:        mp = &npmasters[unit];
        !           833: 
        !           834:        /* Initialize unit buffer headers */
        !           835: 
        !           836:        np_tab[unit].b_active = 0;
        !           837:        np_tab[unit].b_actf = 0;
        !           838: 
        !           839:        /* UBA device structure for this unit */
        !           840: 
        !           841:        mp->devp = npdinfo[unit];
        !           842: 
        !           843:        /* Interrupt vector for this unit */
        !           844: 
        !           845:        mp->vector = npvectors[unit];
        !           846: 
        !           847:        if(unit == (NNP -1))
        !           848:                mp->next = (struct npmaster *)NULL;
        !           849:        else mp->next = &npmasters[unit + 1];
        !           850: 
        !           851:        /*
        !           852:         * Guarantee alignment of shared memory area on a
        !           853:          * 16 byte boundary as required by I-Board
        !           854:         */
        !           855: 
        !           856:        mp->shmemp = &npspaces[unit];
        !           857:        mp->shmemp = (struct npspace *)ROUND16((int)(mp->shmemp));
        !           858: 
        !           859:        /* Base address of this controller */
        !           860: 
        !           861:        mp->iobase = (struct NPREG *)(mp->devp->ui_addr);
        !           862: 
        !           863:        if(NpDebug & DEBMEM) { 
        !           864:                printf("Npspaces starts at %x.\n",npspaces);
        !           865:                printf("Shared memory starts at %x.\n",mp->shmemp);
        !           866:                printf("End of shared memory is %x.\n",&npspaces[unit + 1]);
        !           867:                printf("Iobase is %x.\n",mp->iobase);
        !           868:                printf("Npmasters start at %x\n",npmasters);
        !           869:                printf("Reqhdr start at %x\n",reqhdr);
        !           870:                printf("Npreqs start at %x\n",npreqs);
        !           871:        }
        !           872: 
        !           873:        /* Initialize the request header */
        !           874: 
        !           875:        mp->reqtab = &reqhdr[unit];
        !           876: 
        !           877:        /* Unit initialization */
        !           878: 
        !           879:        mp->unit = unit;
        !           880: 
        !           881:        /* Initialize Status Block */
        !           882: 
        !           883:        npsp = mp->shmemp;
        !           884:        offset = (int) (mp->shmemp);
        !           885: 
        !           886:        npsp->statblock.sb_drw = 0;
        !           887:        npsp->statblock.sb_hcw = HOSTCONF;
        !           888:        npsp->statblock.sb_dcw = 0;
        !           889:        npsp->statblock.sb_dpm = 0;
        !           890: 
        !           891:        npsp->statblock.sb_dcq = (unsign16)((int)(&npsp->devcq))-offset;
        !           892: 
        !           893:        npsp->statblock.sb_hcq = (unsign16)((int)(&npsp->hostcq))-offset;
        !           894: 
        !           895:        /* Initialize Device Command Queue */
        !           896: 
        !           897:        cqp = (struct CmdQue *) &npsp->devcq;
        !           898: 
        !           899:        if(NpDebug & DEBCQ) 
        !           900:                printf("Device CQ at %x\n",cqp);
        !           901: 
        !           902:        cqp->scanflag = NPCLEAR;
        !           903:        cqp->chngflag = NPCLEAR;
        !           904: 
        !           905:        cqp->cq_add = (unsign16)(int)(&cqp->cq_cqe[0]) - offset;
        !           906:        cqp->cq_rem = cqp->cq_add;
        !           907: 
        !           908:        cqp->cq_wrap = (unsign16)(int)(&cqp->cq_cqe[NUMCQE]) - offset;
        !           909: 
        !           910:        for(j = 0; j < NUMCQE; j++)
        !           911:                cqp->cq_cqe[j] = (unsign16)NULL;
        !           912: 
        !           913:        /* Initialize Host Command Queue */
        !           914: 
        !           915:        cqp = (struct CmdQue *) &npsp->hostcq;
        !           916: 
        !           917:        if(NpDebug & DEBCQ) 
        !           918:                printf("HOST CQ at %x\n",cqp);
        !           919: 
        !           920:        cqp->scanflag = NPCLEAR;
        !           921:        cqp->chngflag = NPCLEAR;
        !           922: 
        !           923:        cqp->cq_add = (unsign16)(int)(&cqp->cq_cqe[0]) - offset;
        !           924:        cqp->cq_rem = cqp->cq_add;
        !           925: 
        !           926:        cqp->cq_wrap = (unsign16)(int)(&cqp->cq_cqe[NUMCQE]) - offset;
        !           927: 
        !           928:        for(j = 0; j < NUMCQE; j++)
        !           929:                cqp->cq_cqe[j] = (unsign16)NULL;
        !           930: 
        !           931:        /*
        !           932:         * Initialize the reqid of the elements to the address
        !           933:         * of the corresponding Npreq structure. These don't change.
        !           934:         */
        !           935: 
        !           936:        for(j = 0; j < NUMCQE; j++)
        !           937:                npsp->elements[j].cqe_reqid = &npreqs[unit][j];
        !           938: 
        !           939:        /*
        !           940:         * Initialize the Request Header (reqhdr), free list of
        !           941:         * npreqs, and pointers to CQEs.
        !           942:         */
        !           943: 
        !           944:        reqhdr[unit].forw = reqhdr[unit].back = &reqhdr[unit];
        !           945:        reqhdr[unit].free = &npreqs[unit][0];
        !           946: 
        !           947:        for(j = 0; j < NUMCQE; j++) {
        !           948:                npreqs[unit][j].free = &npreqs[unit][j + 1];
        !           949:                npreqs[unit][j].element = &npsp->elements[j];
        !           950:                npreqs[unit][j].forw = npreqs[unit][j].back = (struct npreq *)NULL;
        !           951:                npreqs[unit][j].flags = NPCLEAR;
        !           952:        }
        !           953:        npreqs[unit][--j].free = &reqhdr[unit];
        !           954: 
        !           955:        /*
        !           956:         * Set up the UNIBUS I/O Map Registers for the
        !           957:         * Shared memory area.
        !           958:         */
        !           959: 
        !           960:        mp->iomapbase = uballoc(mp->devp->ui_ubanum,(caddr_t)(mp->shmemp),sizeof(struct npspace),0);
        !           961: 
        !           962: 
        !           963:        if(NpDebug & DEBENTRY)
        !           964:                printf("SW_Init...\n");
        !           965:        return(0);
        !           966: }
        !           967: 
        !           968: /*
        !           969:  * NpHWinit() issues a hardware reset to the specified board and waits
        !           970:  * for on-board diagnostics to complete. It returns 0 if the board is
        !           971:  * present and passed diagnostics, an error value otherwise.
        !           972:  */
        !           973: 
        !           974: NpHWinit(unit)
        !           975: int unit;
        !           976: {
        !           977:        register struct npmaster *mp;
        !           978:        struct NPREG *REG;
        !           979:        unsign16 status;
        !           980:        int dflag;
        !           981: 
        !           982:        if(unit >= NNP)
        !           983:                return(ENXIO);
        !           984: 
        !           985:        mp = &npmasters[unit];
        !           986: 
        !           987:        if(NpDebug & DEBENTRY)
        !           988:                printf("NpHWinit\n");
        !           989: 
        !           990:        /* See if the board is out there */
        !           991: 
        !           992:        REG = (struct NPREG *)mp->iobase;
        !           993: 
        !           994:        if(NpDebug & DEBINIT)
        !           995:                printf("REG in HWinit is %x.\n",mp->iobase);
        !           996: 
        !           997:        if(!(mp->flags & BRDRESET))
        !           998: 
        !           999:                if(badaddr(REG,2)) {
        !          1000:                        mp->flags |= BADBOARD;
        !          1001:                        printf("\nNP100 unit %d not found!\n",unit);
        !          1002:                        return(ENXIO);
        !          1003:                }
        !          1004: 
        !          1005: 
        !          1006:        if(NpDebug & DEBENTRY)
        !          1007:                printf("Resetting the NP100 Board at %x\n",mp->iobase);
        !          1008: 
        !          1009:        /* Reset the Board */
        !          1010: 
        !          1011:        RESET(mp);
        !          1012: 
        !          1013:        dflag = NPCLEAR;
        !          1014: 
        !          1015:        timeout(NpTimer,&dflag,DIAGTIME);
        !          1016: 
        !          1017:        /* Wait for Enable and Read Data Ready to go high */
        !          1018: 
        !          1019:        while(! ((RCSR1(mp->iobase) & NPENB) && (RCSR1(mp->iobase) & NPRDR))) {
        !          1020:                if(dflag)
        !          1021:                        break;
        !          1022: 
        !          1023:        }
        !          1024: 
        !          1025:        untimeout(NpTimer,&dflag);
        !          1026: 
        !          1027:        if(NpDebug & DEBINIT)
        !          1028:                printf("np reset %d \n",dflag);
        !          1029: 
        !          1030:        if(dflag) {
        !          1031:                mp->flags |= BADBOARD;
        !          1032:                printf("NP100 Unit %d timed out!\n",unit);
        !          1033:                return(EIO);
        !          1034:        }
        !          1035: 
        !          1036:        status = RCSR0(mp->iobase);
        !          1037: 
        !          1038:        /* Check for Hardware OK */
        !          1039: 
        !          1040:        if(!(RCSR1(mp->iobase) & NPHOK)) {
        !          1041:                mp->flags |= BADBOARD;
        !          1042:                printf("NP100 Unit %d Failed diagnostics!\n",unit);
        !          1043:                printf("Status from CSR0: %x.\n",status);
        !          1044:                return(EIO);
        !          1045:        }
        !          1046: 
        !          1047:        if(NpDebug & DEBENTRY)
        !          1048:                printf("HWinit...\n");
        !          1049: 
        !          1050:        return(0);
        !          1051: }
        !          1052: 
        !          1053: /*
        !          1054:  * NP Driver Interrupt Handler
        !          1055:  */
        !          1056: 
        !          1057: npintr(unit)
        !          1058: int unit;
        !          1059: {
        !          1060:        register struct npmaster *mp;
        !          1061:        register struct buf     *bp;
        !          1062: 
        !          1063:        if(NpDebug & DEBENTRY)
        !          1064:                printf("npintr on unit %d!\n",unit);
        !          1065: 
        !          1066:        mp = &npmasters[unit];
        !          1067:        np_icount[unit]++;
        !          1068: 
        !          1069:        if(NpDebug & DEBINTR)
        !          1070:                printf("npintr mp->flags = %x  interupt count = %x\n",
        !          1071:                        mp->flags, np_icount[unit]);
        !          1072: 
        !          1073:        /* Wake up anyone sleeping on a CSR0 Command */
        !          1074: 
        !          1075:        if(mp->flags & CSRPEND) {
        !          1076: 
        !          1077:                mp->flags &= ~CSRPEND;
        !          1078:                if(np_tab[mp->unit].b_active) {
        !          1079:                        np_tab[mp->unit].b_active = 0;
        !          1080:                        bp = np_tab[mp->unit].b_actf;
        !          1081:                        np_tab[mp->unit].b_actf = bp->av_forw;
        !          1082: 
        !          1083:                        if(NpDebug & DEBINTR)
        !          1084:                                printf("bp = %x resid = %d forw = %x\n",bp,
        !          1085:                                    bp->b_resid,bp->av_forw);
        !          1086: 
        !          1087:                        bp->b_resid = 0;
        !          1088:                        iodone(bp);
        !          1089:                }
        !          1090:                if(mp->flags & PANIC3) {
        !          1091:                        mp->flags &= ~PANIC3;
        !          1092:                        mp->flags = AVAILABLE;
        !          1093:                        ubarelse(mp->devp->ui_ubanum,&panicmap);
        !          1094:                }
        !          1095:                if(mp->flags & PANIC2) {
        !          1096:                        mp->flags &= ~PANIC2;
        !          1097:                        printf("Panic Message: %s",NpPbuf);
        !          1098:                        mp->flags |= PANIC3;
        !          1099:                        NpPbuf[0] = 0;
        !          1100:                        NPIO(mp,(paddr_t)((int) panicmap & UBADDRMASK),(paddr_t)pstring,sizeof(NpPbuf),B_WRITE);
        !          1101:                }
        !          1102:                if(mp->flags & PANIC1) {
        !          1103:                        mp->flags &= ~PANIC1;
        !          1104:                        mp->flags |= PANIC2;
        !          1105:                        ubarelse(mp->devp->ui_ubanum,&panicmap);
        !          1106:                        panicmap = uballoc(mp->devp->ui_ubanum,(caddr_t)NpPbuf,sizeof(NpPbuf),0);
        !          1107:                        pstring = (caddr_t)((panaddr[1] << 4) + panaddr[0]);
        !          1108:                        NPIO(mp,(paddr_t)pstring,(paddr_t)((int) panicmap & UBADDRMASK),sizeof(NpPbuf),B_READ);
        !          1109:                }
        !          1110: 
        !          1111:                wakeup((caddr_t)mp);
        !          1112:                goto out;
        !          1113:        }
        !          1114: 
        !          1115:        /* Mark unit as being available if Device Protocol Mask set */
        !          1116: 
        !          1117:        if(!(mp->flags & AVAILABLE)) {
        !          1118: 
        !          1119:                if((mp->shmemp->statblock.sb_dpm) && (!(mp->flags & BRDRESET)))
        !          1120: 
        !          1121:                        mp->flags = AVAILABLE;
        !          1122:        }
        !          1123: 
        !          1124:        /* Honor service requests from the device */
        !          1125: 
        !          1126:        switch(mp->shmemp->statblock.sb_drw) {
        !          1127: 
        !          1128:            case NOREQ:
        !          1129:                break;
        !          1130: 
        !          1131:            case NPPANIC:
        !          1132: 
        !          1133:                printf("\nPanic from NP100 unit %d!\n",mp->unit);
        !          1134:                mp->flags &= ~AVAILABLE;
        !          1135:                mp->flags |= PANIC1;
        !          1136: 
        !          1137:                /* Clear device request word */
        !          1138: 
        !          1139:                mp->shmemp->statblock.sb_drw = 0;
        !          1140: 
        !          1141:                panicmap = uballoc(mp->devp->ui_ubanum,(caddr_t)panaddr,sizeof(panaddr),0);
        !          1142:                NPIO(mp,(paddr_t)NPPSADDR,(paddr_t)((int)panicmap & UBADDRMASK),sizeof(panaddr),B_READ);
        !          1143:                goto out;
        !          1144:                break;
        !          1145: 
        !          1146:            case NPDUMP:
        !          1147:                mp->flags |= (DUMPREQ | BOARDREQ);
        !          1148: 
        !          1149:                /* Clear device request word */
        !          1150: 
        !          1151:                mp->shmemp->statblock.sb_drw = 0;
        !          1152: 
        !          1153:                if(NpState & ICPAVAIL)
        !          1154:                        wakeup((caddr_t)&NpState);
        !          1155:                break;
        !          1156: 
        !          1157:            case NPLOAD:
        !          1158:                mp->flags |= (LOADREQ | BOARDREQ);
        !          1159: 
        !          1160:                /* Clear device request word */
        !          1161: 
        !          1162:                mp->shmemp->statblock.sb_drw = 0;
        !          1163: 
        !          1164:                if(NpState & ICPAVAIL)
        !          1165:                        wakeup((caddr_t)&NpState);
        !          1166:                break;
        !          1167: 
        !          1168:            default:
        !          1169:                printf("Bad Req: %x.\n",mp->shmemp->statblock.sb_drw);
        !          1170:                goto out;
        !          1171: 
        !          1172:        }
        !          1173: 
        !          1174:        /* Process the Host Command Queue for this device */
        !          1175: 
        !          1176:        NpProcQueue(mp);
        !          1177: 
        !          1178: out:
        !          1179:        CLEARINT(mp);   /* Clear the interrupt */
        !          1180: 
        !          1181:        if(NpDebug & DEBENTRY)
        !          1182:                printf("npintr...\n");
        !          1183: 
        !          1184:        return(1);      /* Interrupt serviced */
        !          1185: 
        !          1186: }
        !          1187: 
        !          1188: /*
        !          1189:  * This routine, called from the interrupt handler, is used to process the
        !          1190:  * Host Command Queue for the specified device.
        !          1191:  */
        !          1192: 
        !          1193: NpProcQueue(mp)
        !          1194: struct npmaster *mp;
        !          1195: {
        !          1196:        register struct CmdQue *cqp;
        !          1197:        register struct CQE *ep;
        !          1198:        register struct npreq *rp;
        !          1199:        register int base;
        !          1200:        int s;
        !          1201: 
        !          1202:        if(NpDebug & DEBENTRY)
        !          1203:                printf("NpProcQueue\n");
        !          1204: 
        !          1205:        cqp = &mp->shmemp->hostcq;      /* Command Queue pointer */
        !          1206: 
        !          1207:        s = spl5();
        !          1208:        if(mp->flags & SCANNING) {
        !          1209:                splx(s);
        !          1210:                return;
        !          1211:        }
        !          1212:        mp->flags |= SCANNING;
        !          1213:        splx(s);
        !          1214: 
        !          1215:        cqp->scanflag | = ON;
        !          1216: 
        !          1217:        base = (int)mp->shmemp;         /* Shared memory base address */
        !          1218: 
        !          1219:        while(1) {
        !          1220: 
        !          1221:                cqp->scanflag |= ON;
        !          1222:                cqp->chngflag &= ~ON;
        !          1223:                while(ep = NpRemCQE(cqp,base)) {
        !          1224: 
        !          1225:                        rp = ep->cqe_reqid;
        !          1226: 
        !          1227:                        if(NpDebug & DEBCQE)
        !          1228:                                printf("cqe_sts is %x ep = %x\n",ep->cqe_sts,ep);
        !          1229: 
        !          1230:                        switch (ep->cqe_sts)  {
        !          1231: 
        !          1232:                            case NPDONE:
        !          1233:                                rp->flags |= REQDONE;   /* Normal completion */
        !          1234:                                break;
        !          1235:                            case NPIFC:                 /* IFC Request */
        !          1236:                                rp->flags |= IOIFC;
        !          1237:                                break;
        !          1238:                            case NPPERR:                /* Protocol Error */
        !          1239:                                rp->flags |= (NPPERR | REQDONE);
        !          1240:                                break;
        !          1241:                            case NPMERR:                /* Memory allocation */
        !          1242:                                rp->flags |= (NPMERR | REQDONE);
        !          1243:                                break;
        !          1244:                            default:                    /* Error on Board */
        !          1245:                                rp->flags |= (IOERR | REQDONE);
        !          1246:                                break;
        !          1247: 
        !          1248:                        }
        !          1249: 
        !          1250:                        if(NpDebug & DEBCQE) {
        !          1251:                                printf("flag is %x reqid = %x\n",rp->flags,ep->cqe_reqid);
        !          1252:                                printf("wakeup in procqueue\n");
        !          1253:                        }
        !          1254: 
        !          1255:                        if(rp->intr) {
        !          1256: 
        !          1257:                                if(NpDebug & DEBINTR)
        !          1258:                                        printf("calling usr intr at %x\n",
        !          1259:                                                rp->intr);
        !          1260: 
        !          1261:                                /* Call interrupt routine */
        !          1262: 
        !          1263:                                (*rp->intr)(mp,rp);
        !          1264:                        }
        !          1265:                        else {
        !          1266: 
        !          1267:                        if(NpDebug & DEBINTR)
        !          1268:                                printf("waking up %x\n",rp);
        !          1269: 
        !          1270:                                /* if(rp->flags & NPUIO)
        !          1271:                                        iodone(&rp->buf);
        !          1272:                                else    wakeup((caddr_t) (rp)); /* Awaken */
        !          1273: 
        !          1274:                                wakeup((caddr_t)(rp));  /* Awaken */
        !          1275:                        if(NpDebug & DEBINTR)
        !          1276:                                printf("AWAKE\n");
        !          1277:                        }
        !          1278:                }
        !          1279: 
        !          1280:                cqp->scanflag &= ~ON;
        !          1281:                if(!(cqp->chngflag & ON))
        !          1282:                        break;
        !          1283: 
        !          1284:        }
        !          1285: 
        !          1286:        mp->flags &= ~SCANNING;
        !          1287:        if(NpDebug & DEBENTRY)
        !          1288:                printf("NpProcQueue...\n");
        !          1289: }
        !          1290: 
        !          1291: /*
        !          1292:  * NpIFC - processes an IFC (Internal Fuction Call) request 
        !          1293:  *             NOTE: this function must be called from the user context
        !          1294:  *                     on all virtual pageing systems
        !          1295:  *
        !          1296:  */
        !          1297: NpIFC(mp,rp)
        !          1298: register struct npmaster *mp;
        !          1299: register struct npreq *rp;
        !          1300: {
        !          1301:        register struct CQE     *ep;
        !          1302: 
        !          1303:        if(NpDebug & DEBENTRY)
        !          1304:                printf("NpIFC\n");
        !          1305: 
        !          1306:        ep = rp->element;
        !          1307:        rp->flags &= ~IOIFC;
        !          1308:        switch(ep->cqe_func) {
        !          1309: 
        !          1310:            case NPUNLOCK:      /* Unlock process, free up mapping registers  */
        !          1311: 
        !          1312:                if(NpDebug & DEBIFC)
        !          1313:                        printf("NPUNLOCK\n");
        !          1314: 
        !          1315:                if(rp->mapbase)
        !          1316:                        NpUnMapMem(mp,rp);
        !          1317:                break;
        !          1318: 
        !          1319:            case NPLOCK:        /* Lock process, get mapping registers */
        !          1320: 
        !          1321:                if(NpDebug & DEBIFC)
        !          1322:                        printf("NPLOCK\n");
        !          1323:                NpMapMem(mp,rp,rp->virtmem,rp->bytecnt);
        !          1324:                ep->cqe_dma[0] = LOWORD(rp->bufaddr);
        !          1325:                ep->cqe_dma[1] = HIWORD(rp->bufaddr);
        !          1326:                break;
        !          1327: 
        !          1328:            case NPREMAP:
        !          1329: 
        !          1330:                if(NpDebug & DEBIFC)
        !          1331:                        printf("NPREMAP\n");
        !          1332: 
        !          1333:                /* Remap user buffer and update buffer offset */
        !          1334: #ifdef USG
        !          1335:                np_remapmem(rp,rp->virtmem); 
        !          1336:                ep->cqe_dma[0] = LOWORD(rp->bufaddr);
        !          1337:                ep->cqe_dma[1] = HIWORD(rp->bufaddr);
        !          1338:                break;
        !          1339: #endif
        !          1340: 
        !          1341:            default:
        !          1342:                if(NpDebug & DEBIFC)
        !          1343:                        printf("Bad case %x in IFC\n", ep->cqe_func);
        !          1344: 
        !          1345:                rp->flags |= (REQDONE | IOERR);
        !          1346:                break;
        !          1347:        }
        !          1348: }
        !          1349: 
        !          1350: /*
        !          1351:  * The following contains various routines for allocating and deallocating
        !          1352:  * structures used by the NP Driver. Routines are also here for addding
        !          1353:  * and removing Command Queue Elements from a Command Queue.
        !          1354:  */
        !          1355: 
        !          1356: /*
        !          1357:  * Get a free NP Request structure from the list pointed to by head. Returns
        !          1358:  * a pointer to a npreq or NULL if none left.
        !          1359:  */
        !          1360: 
        !          1361: struct npreq *
        !          1362: NpGetReq(head)
        !          1363: struct npreq *head;
        !          1364: {
        !          1365: 
        !          1366:        register struct npreq *p;
        !          1367: 
        !          1368:        p = head->free;
        !          1369:        head->free = p->free;
        !          1370:        if (p->flags & REQALOC)
        !          1371:                printf("GetReq: Req %x already allocated\n", p);
        !          1372:        p->flags &= WANTREQ;
        !          1373:        if (p != head)
        !          1374:                p->flags |= REQALOC;
        !          1375:        return(p==head ? (struct npreq *)NULL : p);
        !          1376: }
        !          1377: 
        !          1378: /*
        !          1379:  * Return a NP Request structure to the free list pointed to by head.
        !          1380:  */
        !          1381: 
        !          1382: NpFreeReq(head,nprp)
        !          1383: register struct npreq *head, *nprp;
        !          1384: {
        !          1385:        int s;
        !          1386: 
        !          1387:        if(NpDebug & DEBREQ)
        !          1388:                printf("NpFreeReq, head is %x rp is %x\n",head,nprp);
        !          1389: 
        !          1390:        if (nprp == NULL) {
        !          1391:                printf("FREEREQ: attempt to free null pointer\n");
        !          1392:                return;
        !          1393:        }
        !          1394:        if (!(nprp->flags & REQALOC)) {
        !          1395:                printf("FREEREQ: attempt to free unallocated request %x\n",
        !          1396:                        nprp);
        !          1397:                return;
        !          1398:        }
        !          1399:        if (nprp->flags & REQUSE)
        !          1400:                printf("FREEREQ: freeing unremoved request %x\n", nprp);
        !          1401: 
        !          1402:        s = spl5();
        !          1403:        nprp->forw = nprp->back = (struct npreq *)NULL;
        !          1404:        nprp->free = head->free;
        !          1405:        head->free = nprp;
        !          1406:        nprp->flags &= ~REQALOC;
        !          1407:        splx(s);
        !          1408: 
        !          1409:        /* Wake up any processes waiting for a request structure */
        !          1410: 
        !          1411:        if(head->flags & WANTREQ) {
        !          1412:                head->flags &= ~WANTREQ;
        !          1413:                wakeup((caddr_t)head);
        !          1414:        }
        !          1415: 
        !          1416:        if(NpDebug & DEBENTRY)
        !          1417:                printf("NpFreeReq...\n");
        !          1418: }
        !          1419: 
        !          1420: /*
        !          1421:  * Add a Command Queue Element onto the specified Command Queue and
        !          1422:  * update its Add offset.
        !          1423:  */
        !          1424: 
        !          1425: NpAddCQE(ep,cqp,mp)
        !          1426: struct CQE *ep;
        !          1427: struct CmdQue *cqp;
        !          1428: struct npmaster *mp;
        !          1429: {
        !          1430: 
        !          1431:        register unsign16 *temp;
        !          1432:        register unsign16 cqe_offset;
        !          1433:        register int base;
        !          1434: 
        !          1435:        base = (int)mp->shmemp;         /* Shared memory base address */
        !          1436: 
        !          1437:        temp = (unsign16 *)(base + cqp->cq_add); /* Offset to add element */
        !          1438: 
        !          1439:        cqe_offset = (unsign16)((int)ep - base);
        !          1440: 
        !          1441:        if(*temp) {                     /* Should never happen */
        !          1442: 
        !          1443:                printf("No more room on Command Queue!\n");
        !          1444:                return;
        !          1445:        }
        !          1446:        else *temp = cqe_offset;        /* Enter this request's offset */
        !          1447: 
        !          1448:        /* Update cqe_add where next request is to be added */
        !          1449: 
        !          1450:        cqp->cq_add += sizeof(unsign16);
        !          1451: 
        !          1452:        if(cqp->cq_add == cqp->cq_wrap) /* Wrap if necessary */
        !          1453:                cqp->cq_add = (unsign16)((int)cqp->cq_cqe - base);
        !          1454: 
        !          1455:        cqp->chngflag |= ON;            /* Set change flag unconditionally */
        !          1456: 
        !          1457:        /* Interrupt the Board if his scan flag isn't on */
        !          1458: 
        !          1459:        if(!(cqp->scanflag & ON))
        !          1460: 
        !          1461:                INTNI(mp);              /* Interrupt the Board */
        !          1462: 
        !          1463: }
        !          1464: 
        !          1465: /*
        !          1466:  * The NpRemCQE routine is used to remove the next CQE from the Command Queue
        !          1467:  * specified by cqp. The common offset of shared memory used by the device
        !          1468:  * is specified by base. NpRemCQE returns a pointer to the next CQE or
        !          1469:  * NULL if there are none left. This routine will also update the cqe_rem
        !          1470:  * offset which specifies where the next element to be removed from the
        !          1471:  * queue is located.
        !          1472:  */
        !          1473: 
        !          1474: struct CQE *
        !          1475: NpRemCQE(cqp,base)
        !          1476: struct CmdQue *cqp;
        !          1477: int base;
        !          1478: {
        !          1479: 
        !          1480:        register unsign16 *temp;
        !          1481:        register unsign16 cqe_offset;
        !          1482: 
        !          1483:        cqp->chngflag &= ~ON;                   /* Turn off unconditionally */
        !          1484: 
        !          1485:        /* Get address of element to remove */
        !          1486: 
        !          1487:        temp = (unsign16 *)(base +cqp->cq_rem);
        !          1488: 
        !          1489:        if(*temp == NULL)                       /* If none left, go home */
        !          1490:                return((struct CQE *) NULL);
        !          1491: 
        !          1492:        else cqe_offset = *temp;                /* Offset of CQE to remove */
        !          1493: 
        !          1494:        /* Update the Command Queue's cqe_rem offset */
        !          1495: 
        !          1496:        *temp = NULL;                           /* Clear out this entry */
        !          1497: 
        !          1498:        cqp->cq_rem += sizeof(unsign16);        /* Bump offset */
        !          1499: 
        !          1500:        if(cqp->cq_rem == cqp->cq_wrap)         /* Wrap if necessary */
        !          1501:                cqp->cq_rem = (unsign16)((int)cqp->cq_cqe - base);
        !          1502: 
        !          1503:        temp = (unsign16 *)(base + cqe_offset); /* CQE address */
        !          1504:        return((struct CQE *)temp);             /* is returned */
        !          1505: }
        !          1506: 
        !          1507: /*
        !          1508:  * NpAddReq will add the specified npreq structure to the queue controlled
        !          1509:  * by head.
        !          1510:  */
        !          1511: 
        !          1512: NpAddReq(head,rp)
        !          1513: register struct npreq *head, *rp;
        !          1514: {
        !          1515:        int s;
        !          1516: 
        !          1517:        if (NpDebug & (DEBENTRY|DEBREQ))
        !          1518:                printf("NpAddReq: %x\n",rp);
        !          1519: 
        !          1520:        if (rp->flags & REQUSE)
        !          1521:                printf("ADDREQ: Request %x allready in use\n", rp);
        !          1522: 
        !          1523:        s = spl7();
        !          1524:        rp->forw = head->forw;
        !          1525:        rp->forw->back = rp;
        !          1526:        rp->back = head;
        !          1527:        head->forw = rp;
        !          1528:        rp->flags |= REQUSE;
        !          1529:        splx(s);
        !          1530: 
        !          1531:        if(NpDebug & DEBENTRY)
        !          1532:                printf("NpAddReq...\n");
        !          1533: }
        !          1534: 
        !          1535: /*
        !          1536:  * NpRemReq is used to remove a npreq structure from the queue specified by
        !          1537:  * head.
        !          1538:  */
        !          1539: 
        !          1540: NpRemReq(rp)
        !          1541: register struct npreq *rp;
        !          1542: {
        !          1543:        int s;
        !          1544: 
        !          1545:        if (NpDebug & (DEBENTRY|DEBREQ))
        !          1546:                printf("NpRemReq: %x\n",rp);
        !          1547: 
        !          1548:        if (rp == NULL) {
        !          1549:                printf("REMREQ: null pointer removal requested\n");
        !          1550:                return;
        !          1551:        }
        !          1552:        if (!(rp->flags & REQUSE)) {
        !          1553:                printf("REMREQ: trying to rem unused req %x\n", rp);
        !          1554:                return;
        !          1555:        }
        !          1556:        if (!(rp->flags & REQALOC)) {
        !          1557:                printf("REMREQ: trying to rem unallocated req %x\n", rp);
        !          1558:                return;
        !          1559:        }
        !          1560:                
        !          1561:        s = spl7();
        !          1562:        rp->back->forw = rp->forw;
        !          1563:        rp->forw->back = rp->back;
        !          1564:        rp->flags &= ~REQUSE;
        !          1565:        splx(s);
        !          1566: 
        !          1567:        if(NpDebug & DEBENTRY)
        !          1568:                printf("NpRemReq...\n");
        !          1569: }
        !          1570: 
        !          1571: 
        !          1572: /*
        !          1573:  * The following routines are used to communicate with the
        !          1574:  * NI Hardware via the CSR0 commands. These commands are issued during
        !          1575:  * the hardware initializtion process and may also be used subsequently
        !          1576:  * by privileged processes who wish to communicate in this way. The
        !          1577:  * convention for passing data as a Command Block is discussed in detail
        !          1578:  * in the NI1510 UNIBUS Compatible Ethernet Communications Processor
        !          1579:  * Hardware Specification.
        !          1580:  */
        !          1581: 
        !          1582: NpSendCSR0(iobase,src,bcount)
        !          1583: struct NPREG *iobase;
        !          1584: register unsign16 *src;
        !          1585: int bcount;
        !          1586: {
        !          1587:        register int wcount;
        !          1588:        int i;
        !          1589:        int csrflag;
        !          1590:        unsign16 tmp;
        !          1591: 
        !          1592:        if(NpDebug & DEBENTRY)
        !          1593:                printf("NpSendCSR0\n");
        !          1594: 
        !          1595:        /* Jolt the board into CSR0 command mode if necessary */
        !          1596: 
        !          1597:        if(!(RCSR1(iobase) & NPENB)){   
        !          1598:                tmp = NPCLEAR;          /* MC68000 clr reads before writing */
        !          1599:                WCSR0(iobase,tmp);      
        !          1600:        }
        !          1601: 
        !          1602:        wcount = (bcount +1) >> 1;      /* Convert byte count to word count */
        !          1603: 
        !          1604:        /* Clear timer flag before beginning the timer */
        !          1605: 
        !          1606:        csrflag = NPCLEAR;
        !          1607:        timeout(NpTimer,&csrflag,DIAGTIME);
        !          1608: 
        !          1609:        for(i = 0; (i < wcount) & (csrflag == NPCLEAR); i++) {
        !          1610:                while(! ((RCSR1(iobase) & NPENB) && (RCSR1(iobase) & NPRDY)))
        !          1611:                        if(csrflag) break;
        !          1612:                WCSR0(iobase,*src);
        !          1613:                src++;                  /* Better do this WCSR is a macro */
        !          1614:        }
        !          1615: 
        !          1616:        /* Clear the timer entry */
        !          1617: 
        !          1618:        untimeout(NpTimer,&csrflag);
        !          1619: 
        !          1620:        /* Error if timer went off */
        !          1621: 
        !          1622:        if(csrflag)
        !          1623:                return(EIO);    
        !          1624: 
        !          1625:        if(NpDebug & DEBENTRY)
        !          1626:                printf("NpSendCSR0...\n");
        !          1627:        return(0);
        !          1628: }
        !          1629: 
        !          1630: /*
        !          1631:  * NpSetIntLev sets the UNIBUS interrupt vector to be used by the NP board when
        !          1632:  * interupting the host. The board is specified by mp.
        !          1633:  */
        !          1634: 
        !          1635: NpSetIntLevel(mp,level)
        !          1636: struct npmaster *mp;
        !          1637: int level;
        !          1638: {
        !          1639: 
        !          1640:        struct {
        !          1641:                unsign16 cmd_word;
        !          1642:                unsign16 int_level;
        !          1643:        }cmd_block;
        !          1644: 
        !          1645:        cmd_block.cmd_word = NPCBI | CBICNT;
        !          1646:        cmd_block.int_level = level;
        !          1647: 
        !          1648:        return(NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block)));
        !          1649: }
        !          1650: 
        !          1651: /*
        !          1652:  * NpSetMemAddr is used to declare the shared memory area address to be used
        !          1653:  * for communication between the driver and the device. This address is used
        !          1654:  * to access data structures by acting as a base from which defined offsets
        !          1655:  * locate data. The board is specified by mp.
        !          1656:  */
        !          1657: 
        !          1658: NpSetMemAddr(mp,addr)
        !          1659: struct npmaster *mp;
        !          1660: caddr_t addr;
        !          1661: {
        !          1662: 
        !          1663:        caddr_t shmaddr;
        !          1664:        int error;
        !          1665: 
        !          1666:        struct {
        !          1667:                unsign16 cmd_word;
        !          1668:                unsign16 hi_addr;
        !          1669:                unsign16 lo_addr;
        !          1670:        } cmd_block;
        !          1671: 
        !          1672:        if(NpDebug & DEBENTRY)
        !          1673:                printf("NpSetMemAddr\n");
        !          1674: 
        !          1675:        shmaddr = addr;
        !          1676: 
        !          1677:        if(NpDebug & DEBMEM)
        !          1678:                printf("NpSetMemAddr, addr is %x shmaddr is %x.\n",addr,shmaddr);
        !          1679: 
        !          1680:        cmd_block.cmd_word = NPCMD | CMDCNT;
        !          1681:        cmd_block.hi_addr = HIWORD(shmaddr);
        !          1682:        cmd_block.lo_addr = LOWORD(shmaddr);
        !          1683: 
        !          1684:        error = NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block));
        !          1685: 
        !          1686:        if(NpDebug & DEBENTRY)
        !          1687:                printf("NpSetMemAddr...\n");
        !          1688: 
        !          1689:        return(error);
        !          1690: }
        !          1691: 
        !          1692: 
        !          1693: /*
        !          1694:  * NpSetXeqAddr specifies the address at which the board should begin
        !          1695:  * execution of its on-board software. It also indicates the shared memory
        !          1696:  * address to be used. The board is specified by mp.
        !          1697:  */
        !          1698: 
        !          1699: NpSetXeqAddr(mp,addr)
        !          1700: struct npmaster *mp;
        !          1701: caddr_t addr;
        !          1702: {
        !          1703:        caddr_t shmaddr;
        !          1704:        int error;
        !          1705: 
        !          1706:        struct {
        !          1707:                unsign16 cmd_word;
        !          1708:                unsign16 hi_addr;
        !          1709:                unsign16 lo_addr;
        !          1710:                unsign16 mhi_addr;
        !          1711:                unsign16 mlo_addr;
        !          1712:        } cmd_block;
        !          1713: 
        !          1714:        if(NpDebug & DEBENTRY)
        !          1715:                printf("NpSetXeqAddr\n");
        !          1716: 
        !          1717:        shmaddr = (caddr_t)((int)mp->iomapbase & UBADDRMASK);
        !          1718: 
        !          1719:        cmd_block.cmd_word = NPBGN | NPCMD | NPLST | (BGNCNT + CMDCNT);
        !          1720:        cmd_block.hi_addr = HIWORD(addr);
        !          1721:        cmd_block.lo_addr = LOWORD(addr);
        !          1722:        cmd_block.mhi_addr = HIWORD(shmaddr);
        !          1723:        cmd_block.mlo_addr = LOWORD(shmaddr);
        !          1724: 
        !          1725:        if(NpDebug & DEBINIT) {
        !          1726:                printf("NpSetXeqAdddr: hi: %x lo: %x\n",HIWORD(addr), LOWORD(addr));
        !          1727:                printf("NpSetXeqAdddr: mhi: %x mlo: %x\n",HIWORD(shmaddr),LOWORD(shmaddr));
        !          1728:        }
        !          1729: 
        !          1730:        error = NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block));
        !          1731: 
        !          1732:        if(NpDebug & DEBENTRY)
        !          1733:                printf("NpSetXeqAddr...\n");
        !          1734: 
        !          1735:        return(error);
        !          1736: }
        !          1737: 
        !          1738: /*
        !          1739:  * NPIO issues a CSR0 load or dump request to the I-Board after packaging a
        !          1740:  * CSR0 Command Block.
        !          1741:  */
        !          1742: 
        !          1743: NPIO(mp,src,dest,count,dir)
        !          1744: struct npmaster *mp;
        !          1745: paddr_t dest;
        !          1746: paddr_t src;
        !          1747: unsign16 count;
        !          1748: int dir;               /* Direction  READ/WRITE */
        !          1749: {
        !          1750: 
        !          1751:        int error;
        !          1752: 
        !          1753:        struct {
        !          1754:                unsign16 cmd_word;      /* Command Word */
        !          1755:                unsign16 shi_addr;      /* High word of Source Address */
        !          1756:                unsign16 slo_addr;      /* Low word of Source Address */
        !          1757:                unsign16 dhi_addr;      /* High word of Destination Address */
        !          1758:                unsign16 dlo_addr;      /* Low word of Destination Address */
        !          1759:                unsign16 count;         /* Byte count */
        !          1760:                unsign16 intlevel;      /* Interrupt level to host */
        !          1761:        } cmd_block;
        !          1762: 
        !          1763:        if(NpDebug & DEBENTRY)
        !          1764:                printf("NPIO\n");
        !          1765:        if(NpDebug & DEBMAINT) {
        !          1766:                printf("I/O src addr = %x, dest addr = %x \n",src,dest);
        !          1767:                printf("I/O count = %d \n",count);
        !          1768:        }
        !          1769: 
        !          1770:        cmd_block.cmd_word = NPCBI | (CBICNT + IOCNT);
        !          1771:        cmd_block.intlevel = mp->vector;
        !          1772:        cmd_block.shi_addr = HIWORD(src);
        !          1773:        cmd_block.slo_addr = LOWORD(src);
        !          1774:        cmd_block.dhi_addr = HIWORD(dest);
        !          1775:        cmd_block.dlo_addr = LOWORD(dest);
        !          1776:        cmd_block.count = count;
        !          1777:        if ((mp->flags & LSTCMD) == 0)
        !          1778:                cmd_block.cmd_word |= NPLST;
        !          1779:        if(dir == B_READ)
        !          1780:                cmd_block.cmd_word |= NPDMP;
        !          1781:        else
        !          1782:                cmd_block.cmd_word |= NPLD;
        !          1783: 
        !          1784: 
        !          1785:        if(NpDebug & DEBIO) {
        !          1786:                printf("cmd: %x int: %o shi: %x slo: %x dhi: %x dlo: %x cnt: %x\n",
        !          1787:        cmd_block.cmd_word,cmd_block.intlevel,cmd_block.shi_addr,cmd_block.slo_addr,
        !          1788:        cmd_block.dhi_addr,cmd_block.dlo_addr,cmd_block.count);
        !          1789:        }
        !          1790:        
        !          1791:        mp->flags |= CSRPEND;           /* CSR0 command pending */
        !          1792: 
        !          1793:        error = NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block));
        !          1794:        if(NpDebug & DEBENTRY)
        !          1795:                printf("NPIO...\n");
        !          1796: 
        !          1797:        return(error);
        !          1798: }
        !          1799: 
        !          1800: 
        !          1801: /*
        !          1802:  * NpKill will terminate all outstanding requests for the specified board.
        !          1803:  */
        !          1804: 
        !          1805: NpKill(mp,curr_rp)
        !          1806: struct npmaster *mp;
        !          1807: struct npreq *curr_rp;
        !          1808: {
        !          1809:        struct npreq *rp;
        !          1810:        int s;
        !          1811: 
        !          1812:        if(NpDebug & DEBENTRY)
        !          1813:                printf("NpKill\n");
        !          1814: 
        !          1815:        mp->reqtab->reqcnt = 0;         /* Init request count */
        !          1816: 
        !          1817:        s = spl5();                     /* Disable interrupts */
        !          1818: 
        !          1819:        /* Mark each active request as having an error and wake him up */
        !          1820: 
        !          1821:        for(rp = mp->reqtab->forw;rp != mp->reqtab;rp = rp->forw) {
        !          1822: 
        !          1823:                if(rp == curr_rp) continue;
        !          1824: 
        !          1825:                rp->flags |= (IOABORT | REQDONE);
        !          1826:                mp->reqtab->reqcnt++;
        !          1827:                /* if(rp->flags & NPUIO)
        !          1828:                        iodone(&rp->buf);
        !          1829:                else */
        !          1830:                wakeup((caddr_t)rp);
        !          1831:        }
        !          1832: 
        !          1833:        if(NpDebug & DEBMAINT)
        !          1834:                printf("NpKill, req count is %d\n",mp->reqtab->reqcnt);
        !          1835: 
        !          1836:        splx(s);
        !          1837: 
        !          1838:        if(NpDebug & DEBENTRY)
        !          1839:                printf("NpKill...\n");
        !          1840: 
        !          1841:        return(0);
        !          1842: 
        !          1843: }
        !          1844: 
        !          1845: /* Hardware and Software Initializations for the specified unit */
        !          1846: 
        !          1847: NpReset(mp,rp)
        !          1848: register struct npmaster *mp;
        !          1849: struct npreq *rp;
        !          1850: {
        !          1851:        int error;
        !          1852: 
        !          1853:        if(NpDebug & DEBENTRY)
        !          1854:                printf("NpReset!\n");
        !          1855: 
        !          1856:        /* Mark board as being reset and make unavailable */
        !          1857: 
        !          1858:        mp->flags = BRDRESET;
        !          1859: 
        !          1860:        /* Abort outstanding requests for this board */
        !          1861: 
        !          1862:        mp->reqtab->reqcnt = 0;         /* Init request count */
        !          1863: 
        !          1864:        /* Wakeup Poller if available and wait until he's gone */
        !          1865: 
        !          1866:        if(NpState & ICPAVAIL) {
        !          1867: 
        !          1868:                mp->flags |= BOARDREQ;
        !          1869:                mp->reqtab->reqcnt++;
        !          1870: 
        !          1871:                if(NpDebug & DEBMAINT)
        !          1872:                        printf("Waking ICP in reset!\n");
        !          1873: 
        !          1874:                wakeup((caddr_t)&NpState);
        !          1875: 
        !          1876:                while(mp->reqtab->reqcnt)
        !          1877:                        if (error = tsleep((caddr_t)(&mp->reqtab),
        !          1878:                            (PZERO + 1) | PCATCH, devio, 0))
        !          1879:                                return (error);
        !          1880: 
        !          1881:                if(NpDebug & DEBMAINT)
        !          1882:                        printf("Reset:awoken by ICP senior!\n");
        !          1883: 
        !          1884:        }
        !          1885: 
        !          1886:        /* Abort outstanding requests and wait till they're gone */
        !          1887: 
        !          1888:        NpKill(mp,rp);
        !          1889: 
        !          1890:        while(mp->reqtab->reqcnt) {
        !          1891: 
        !          1892:                if(NpDebug & DEBMAINT) {
        !          1893:                        printf("Sleeping in NpReset on reqtab!\n");
        !          1894:                        printf("Reqcnt is %d.\n",mp->reqtab->reqcnt);
        !          1895:                }
        !          1896: 
        !          1897:                if (error = tsleep((caddr_t)(&mp->reqtab),
        !          1898:                    (PZERO + 1) | PCATCH, devio, 0))
        !          1899:                        return (error);
        !          1900:        }
        !          1901: 
        !          1902:        /* Free up I/O Map registers if any allocated */
        !          1903: 
        !          1904:        if(mp->iomapbase) {
        !          1905: 
        !          1906:                if(NpDebug & DEBMEM)
        !          1907:                        printf("freeing shared memory map.\n");
        !          1908: 
        !          1909:                ubarelse(mp->devp->ui_ubanum,&mp->iomapbase);
        !          1910:                mp->iomapbase = 0;
        !          1911:        }
        !          1912: 
        !          1913:        /* Initialize S/W data structures in NP Driver */
        !          1914: 
        !          1915:        NpSWinit(mp->unit);             /* Software initialization */
        !          1916: 
        !          1917:        /* Hardware initialization of the board */
        !          1918: 
        !          1919:        error = NpHWinit(mp->unit);     /* Hardware initialization */
        !          1920: 
        !          1921:        mp->flags &= ~BRDRESET;         /* Initialization complete */
        !          1922: 
        !          1923:        /* Initialize Pseudo-Drivers */
        !          1924: 
        !          1925:        if (IxReset)
        !          1926:                (*IxReset)(mp->unit, mp->devp->ui_ubanum, rp);
        !          1927: 
        !          1928:        /* Clear Poller's State Flag */
        !          1929: 
        !          1930:        NpState = NPCLEAR;
        !          1931: 
        !          1932:        if(NpDebug & DEBENTRY)
        !          1933:                printf("NpReset...\n");
        !          1934:        
        !          1935:        return(error);
        !          1936: }
        !          1937: 
        !          1938: /*
        !          1939:  * General purpose timeout function which sets the flag passed to it
        !          1940:  * as argument.
        !          1941:  */
        !          1942: 
        !          1943: NpTimer(flagp)
        !          1944: int *flagp;
        !          1945: {
        !          1946:        *flagp = NPSET;
        !          1947: }
        !          1948: 
        !          1949: NpStats()
        !          1950: {
        !          1951:        if(NpDebug & DEBENTRY)
        !          1952:                printf("npstats\n");
        !          1953:        return(0);
        !          1954: }
        !          1955: 
        !          1956: /*
        !          1957:  * NpCloseConn is called to issue a close connection command to the I-Board.
        !          1958:  */
        !          1959: 
        !          1960: NpCloseConn(mp,protocol)
        !          1961: struct npmaster *mp;
        !          1962: unsign16 protocol;
        !          1963: {
        !          1964: 
        !          1965:        register struct npreq *rp;
        !          1966:        register struct CQE *ep;
        !          1967:        int pri;
        !          1968: 
        !          1969:        if(NpDebug & DEBENTRY)
        !          1970:                printf("NpCloseConn\n");
        !          1971: 
        !          1972:        /*
        !          1973:         * Don't issue the Close Connection command if the Board
        !          1974:          * isn't up.
        !          1975:          */
        !          1976: 
        !          1977:        if(!((mp->shmemp->statblock.sb_dpm) & PROTOMASK(protocol))) {
        !          1978:                return;
        !          1979:        }
        !          1980: 
        !          1981:        /* Get a Request structure */
        !          1982: 
        !          1983:        while((rp = NpGetReq(mp->reqtab)) == NULL) {
        !          1984:                mp->reqtab->flags |= WANTREQ;
        !          1985:                sleep((caddr_t)(mp->reqtab),PZERO -1);
        !          1986:        }
        !          1987: 
        !          1988:        rp->intr = (int (*)())0;        /* Do not call interrupt routine */
        !          1989:        rp->mapbase = 0;                /* Clear mapping information */
        !          1990: 
        !          1991:        ep = rp->element;               /* Handy pointer */
        !          1992: 
        !          1993:        /* Fill in CQE */
        !          1994: 
        !          1995:        ep->cqe_wind = 0;               /* Entire buffer mapped */
        !          1996:        ep->cqe_nbuf = 1;               /* Must be 1, no buffer chaining */
        !          1997:        ep->cqe_char = 0;               /* Set to 0 for now */
        !          1998: 
        !          1999:        ep->cqe_func = NPSTOP;          /* OS_STP to I-Board */
        !          2000: 
        !          2001:        ep->cqe_prot = protocol;        /* Protocol of this connection */
        !          2002:        ep->cqe_lenrpb = 0;             /* Parameter block length */
        !          2003: 
        !          2004:        ep->cqe_ust0 = ep->cqe_ust1 = NPCLEAR;  /* Clear status flags */
        !          2005: 
        !          2006:        ep->cqe_famid = (unsign32)u.u_procp->p_pid;  /* Process ID */
        !          2007: 
        !          2008:        NpAddReq(mp->reqtab,rp);        /* Queue onto active list */
        !          2009: 
        !          2010:        pri = spl5();                   /* Mask our interrupts */
        !          2011: 
        !          2012:        NpAddCQE(ep,&mp->shmemp->devcq,mp); /* Add CQE to device's queue */
        !          2013: 
        !          2014:        /* Wait for command to complete */
        !          2015: 
        !          2016:        while(!(rp->flags & REQDONE)) 
        !          2017:                sleep((caddr_t)rp,PZERO - 1);
        !          2018: 
        !          2019:        splx(pri);
        !          2020: 
        !          2021:        NpRemReq(rp);                   /* Remove request from active list */
        !          2022: 
        !          2023:        NpFreeReq(mp->reqtab,rp);       /* Deallocate request structure */
        !          2024: 
        !          2025:        if(NpDebug & DEBENTRY)
        !          2026:                printf("NpCloseConn...\n");
        !          2027: 
        !          2028: }
        !          2029: 
        !          2030: /*
        !          2031:  * This function allows the protocol to be changed for a given connection.
        !          2032:  * It returns 0 for success, error code otherwise.
        !          2033:  */
        !          2034: 
        !          2035: NpProtChange(protocol,unit)
        !          2036: register unsign16 protocol;
        !          2037: register int unit;
        !          2038: {
        !          2039: 
        !          2040:        register struct npmaster *mp;
        !          2041: 
        !          2042:        /* Privileged users only for Maintenance Protocol */
        !          2043: 
        !          2044:        if((protocol == NPMAINT) && (u.u_uid != 0)) 
        !          2045:                return(EPERM);
        !          2046: 
        !          2047:        if(NpDebug & DEBMAINT)
        !          2048:                printf("NpProtChange = %x\n",protocol);
        !          2049: 
        !          2050:        if(protocol != NPMAINT) {
        !          2051: 
        !          2052:                /* Make sure the I-Board supports the protocol */
        !          2053: 
        !          2054:                mp = &npmasters[unit];
        !          2055: 
        !          2056:                if(!((mp->shmemp->statblock.sb_dpm) & PROTOMASK(protocol)))
        !          2057:                        return(ENXIO);
        !          2058:        }
        !          2059: 
        !          2060:        return(0);
        !          2061: }
        !          2062: 
        !          2063: /*
        !          2064:  * This function allows for the changing of the unit for a given connection.
        !          2065:  */
        !          2066: 
        !          2067: struct npmaster *
        !          2068: NpBoardChange(protocol,unit)
        !          2069: register unsign16 protocol;
        !          2070: register int unit;                     /* Unit number */
        !          2071: {
        !          2072:        register struct npmaster *mp;
        !          2073: 
        !          2074: 
        !          2075:        if(unit > NNP)
        !          2076:                return((struct npmaster *)0);
        !          2077: 
        !          2078:        if(protocol != NPMAINT) {
        !          2079: 
        !          2080:                /*
        !          2081:                 * Loop through the master structures finding a board which 
        !          2082:                 * supports the requested protocol.
        !          2083:                 */
        !          2084: 
        !          2085:                for(mp = npmasters; mp ; mp = mp->next) {
        !          2086: 
        !          2087:                        if(mp->flags & BADBOARD)
        !          2088:                                continue;
        !          2089: 
        !          2090:                        if(((mp->shmemp->statblock.sb_dpm) & PROTOMASK(protocol)))
        !          2091:                                return(mp);
        !          2092:                }
        !          2093:                return((struct npmaster *)0);
        !          2094:        }
        !          2095:        return(&npmasters[unit]);
        !          2096: }
        !          2097: 
        !          2098: /*
        !          2099:  * NpMapMem - maps the user's memory updating the fields in the npreq
        !          2100:  * structure and returning the mapped address in rp->buffaddr.
        !          2101:  */
        !          2102: NpMapMem(mp,rp,addr,count)
        !          2103: register struct npmaster *mp;
        !          2104: register struct npreq *rp;
        !          2105: caddr_t        addr;
        !          2106: int    count;
        !          2107: {
        !          2108: 
        !          2109:        if(NpDebug & DEBENTRY)
        !          2110:                printf("NpMapMem\n");
        !          2111:        if(NpDebug & DEBIO)
        !          2112:                printf("mp %x rp %x addr %x count %x\n",mp,rp,addr,count);
        !          2113: 
        !          2114:        rp->virtmem = addr;
        !          2115:        rp->bytecnt = count;
        !          2116: 
        !          2117:        rp->buf.b_un.b_addr = addr;
        !          2118:        rp->buf.b_flags = B_PHYS | B_BUSY;
        !          2119:        rp->buf.b_bcount = count;
        !          2120:        rp->buf.b_proc = rp->procp;
        !          2121:                
        !          2122:        rp->procp->p_flag |= SPHYSIO;
        !          2123:        if(NpDebug & DEBENTRY)
        !          2124:                printf("vslock\n");
        !          2125:        vslock(addr,count);
        !          2126:        if(NpDebug & DEBENTRY)
        !          2127:                printf("vslock...\n");
        !          2128: 
        !          2129:        rp->mapbase = ubasetup(mp->devp->ui_ubanum,&rp->buf,0);
        !          2130: 
        !          2131:        rp->bufaddr = (caddr_t)(rp->mapbase & UBADDRMASK);
        !          2132: 
        !          2133:        if(NpDebug & DEBENTRY)
        !          2134:                printf("NpMapMem...\n");
        !          2135: }
        !          2136: 
        !          2137: /*
        !          2138:  * Unmap the user's memory and free up mapping registers 
        !          2139:  */
        !          2140: 
        !          2141: NpUnMapMem(mp,rp)
        !          2142: struct npmaster *mp;
        !          2143: struct npreq *rp;
        !          2144: {
        !          2145:        if(NpDebug & DEBENTRY)
        !          2146:                printf("NpUnMapMem\n");
        !          2147: 
        !          2148:        ubarelse(mp->devp->ui_ubanum,&rp->mapbase);
        !          2149:        rp->mapbase = 0;
        !          2150:        vsunlock(rp->virtmem,rp->bytecnt,B_READ);
        !          2151:        rp->procp->p_flag &= ~SPHYSIO;
        !          2152: 
        !          2153:        if(NpDebug & DEBENTRY)
        !          2154:                printf("NpUnMapMem...\n");
        !          2155: }
        !          2156: 
        !          2157: npprobe(reg, ui)
        !          2158: caddr_t reg;
        !          2159: struct uba_device *ui;
        !          2160: {
        !          2161: register int br,cvec;
        !          2162: u_short csraddr;
        !          2163: int i;
        !          2164: 
        !          2165: #ifdef lint
        !          2166:        br = 0; cvec = br; br = cvec;
        !          2167: #endif
        !          2168: 
        !          2169:        if(NpDebug & DEBINIT)
        !          2170:                printf("In npprobe, regaddr is %x!\n",reg);
        !          2171: 
        !          2172:        cvec = (uba_hd[numuba].uh_lastiv -= 4); 
        !          2173: 
        !          2174: #ifdef OLDBSD
        !          2175:        /* Find unit number from npstd[] by matching the csr address */
        !          2176: 
        !          2177:        csraddr = (u_short)((int)reg & 0x0FFFF);
        !          2178: 
        !          2179:        for(i = 0; i < NNP; i++) {
        !          2180: 
        !          2181:                if(csraddr == npstd[i]) {
        !          2182:                        npvectors[i] = cvec;
        !          2183:                        break;
        !          2184:                }
        !          2185:        }
        !          2186:        if(i == NNP)
        !          2187:                printf("Couldn't find device in npstd[]!\n");
        !          2188: 
        !          2189: #else
        !          2190:        npvectors[ui->ui_unit] = cvec;
        !          2191: #endif
        !          2192:        br = 0x15;
        !          2193: 
        !          2194:        if(NpDebug & DEBINIT)
        !          2195:                printf("npprobe...\n");
        !          2196: 
        !          2197:        return(sizeof(struct NPREG));           /* CSR Registers */
        !          2198: 
        !          2199: }
        !          2200: 
        !          2201: npattach(ui)
        !          2202: register struct uba_device *ui;
        !          2203: {
        !          2204: 
        !          2205:        if(NpDebug & DEBINIT)
        !          2206:                printf("In npattach, ui is %x.\n",ui);
        !          2207: 
        !          2208:        npinit(ui->ui_unit);
        !          2209:        if (IxAttach)
        !          2210:                (*IxAttach)(ui);
        !          2211: 
        !          2212:        if(NpDebug & DEBINIT)
        !          2213:                printf("npattach...\n");
        !          2214: }
        !          2215: 
        !          2216: 
        !          2217: NpMem(mp, rp, uaddr)
        !          2218: struct npmaster *mp;
        !          2219: struct npreq *rp;
        !          2220: unsigned long uaddr;
        !          2221: {
        !          2222:        struct np_mem mem;
        !          2223:        register int error = 0;
        !          2224: 
        !          2225:        if(NpDebug & DEBENTRY)
        !          2226:                printf("npmem\n");
        !          2227: 
        !          2228:        if (error = copyin(uaddr, &mem, sizeof(mem)))
        !          2229:                return (error);
        !          2230: 
        !          2231:        if (mem.mem_type == NP_SET) {
        !          2232:                if (np_mapreq[mp->unit] != (struct npreq *)NPCLEAR)
        !          2233:                        error = EBUSY;
        !          2234:                else {
        !          2235:                        error = NpMapMem(mp, rp, mem.mem_addr, mem.mem_count);
        !          2236:                        if (error != 0) {
        !          2237:                                np_mapreq[mp->unit] = rp;
        !          2238:                                mem.mem_addr = rp->bufaddr;
        !          2239:                        }
        !          2240:                }
        !          2241:        } else if (mem.mem_type == NP_USET) {
        !          2242:                error = NpUnMapMem(mp, np_mapreq[mp->unit]);
        !          2243:                NpFreeReq(mp->reqtab, rp);
        !          2244:                NpFreeReq(mp->reqtab, np_mapreq[mp->unit]);
        !          2245:                np_mapreq[mp->unit] = (struct npreq *)NPCLEAR;
        !          2246:        } else 
        !          2247:                error = EIO;
        !          2248: 
        !          2249:        if (error != 0)
        !          2250:                error = copyout(&mem, uaddr, sizeof(mem));
        !          2251: 
        !          2252:        if(NpDebug & DEBENTRY)
        !          2253:                printf("npmem...\n");
        !          2254:        return (error);
        !          2255: }
        !          2256: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.