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

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

unix.superglobalmegacorp.com

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