Annotation of 43BSDTahoe/sys/vaxuba/np.c, revision 1.1

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

unix.superglobalmegacorp.com

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