126199Ssklower /* 226266Ssklower * Copyright (c) 1986 MICOM-Interlan, Inc., Boxborough Mass 326266Ssklower * All rights reserved. The Berkeley software License Agreement 426266Ssklower * specifies the terms and conditions for redistribution. 526199Ssklower * 6*30865Skarels * @(#)np.c 7.2 (Berkeley) 04/08/87 7*30865Skarels * 8*30865Skarels * From: 9*30865Skarels * np.c version 1.5 10*30865Skarels * 11*30865Skarels * This version retrieved: 8/18/86 @ 18:58:54 12*30865Skarels * This delta created: 8/18/86 @ 18:19:24 13*30865Skarels * 14*30865Skarels * static char *SCCSID = "@(#)np.c 1.5"; 15*30865Skarels * 1626199Ssklower */ 1726199Ssklower 1826199Ssklower /****************************************** 1926199Ssklower * * 2026199Ssklower * NPDRIVER * 2126199Ssklower * * 2226199Ssklower ******************************************/ 2326199Ssklower 2426199Ssklower /* 2526199Ssklower * The NP Driver is used to route requests, independent of protocol type, 2626199Ssklower * to the NP series Intelligent Board. The facilities it provides are 2726199Ssklower * used for board maintainance by the superuser and by protocol pseudo-drivers, 2826199Ssklower * such as WN, for sending requests to a board. The board maintainance and 2926199Ssklower * control functions are accessed via npioctl() by the NP support utilities. 3026199Ssklower */ 3126199Ssklower 32*30865Skarels /* 33*30865Skarels * Modification History: 34*30865Skarels * 4/9/86 DDW Removed pseudo-driver initialization flag resets from NpReset 35*30865Skarels * 5/28/86 CJM Changed iodone() to wakeup() in NpProcQueue(). 36*30865Skarels * 37*30865Skarels */ 3826199Ssklower 3926199Ssklower /* 4026199Ssklower * Include Files 4126199Ssklower */ 4226199Ssklower 4326199Ssklower #include "np.h" 4426199Ssklower #if NNP > 0 45*30865Skarels #include "../h/param.h" 46*30865Skarels #include "../h/buf.h" 47*30865Skarels #include "../vaxuba/ubavar.h" 48*30865Skarels #include "../h/signal.h" 49*30865Skarels #include "../h/systm.h" 50*30865Skarels #include "../h/dir.h" 51*30865Skarels #include "../h/user.h" 52*30865Skarels #include "../h/proc.h" 53*30865Skarels #include "../h/uio.h" 54*30865Skarels #include "../h/errno.h" 5526199Ssklower 5626199Ssklower #include "../vaxuba/npreg.h" 5726199Ssklower 58*30865Skarels #define b_uio b_forw 59*30865Skarels #define b_rp av_back 6026199Ssklower /* 6126199Ssklower * Global variables for pseudo-drivers. 6226199Ssklower */ 6326199Ssklower 64*30865Skarels int WnInitFlag = 0; 65*30865Skarels int IsInitFlag = 0; 66*30865Skarels int (*IxAttach)(); 67*30865Skarels int (*IxReset)(); 6826199Ssklower 6926199Ssklower /* 7026199Ssklower * Debugging level. 7126199Ssklower */ 7226199Ssklower 7326199Ssklower int NpDebug = 0; 7426199Ssklower 7526199Ssklower /* Driver Wide State used by the ICP */ 7626199Ssklower 7726199Ssklower int NpState = NPCLEAR; 7826199Ssklower 7926199Ssklower 8026199Ssklower /* 8126199Ssklower * Master structure, one per board, contains request queue header, 8226199Ssklower * shared memory address, and memory mapping information. 8326199Ssklower */ 8426199Ssklower 8526199Ssklower struct npmaster npmasters[NNP]; 8626199Ssklower 8726199Ssklower /* Structure of the shared memory area */ 8826199Ssklower 8926199Ssklower static struct npspace npspaces[NNP]; 9026199Ssklower 9126199Ssklower /* Panic Message data structures */ 9226199Ssklower 9326199Ssklower static int panicmap; /* Mapping information */ 9426199Ssklower static char NpPbuf[PANLEN] = 0; /* Panic message buffer */ 9526199Ssklower static caddr_t pstring; /* Panic string address on board, absolute */ 9626199Ssklower static unsign16 panaddr[2]; /* Panic string address on board (seg/offset) */ 9726199Ssklower 9826199Ssklower /* Driver Wide Connection Table */ 9926199Ssklower 10026199Ssklower static struct npconn npcnxtab[NNP][NNPCNN]; 10126199Ssklower 10226199Ssklower /* Head of the request queue, one per board */ 10326199Ssklower 10426199Ssklower static struct npreq reqhdr[NNP]; 10526199Ssklower 106*30865Skarels /* Require for diagnostic packages */ 107*30865Skarels 108*30865Skarels typedef struct npreq *reqptr; 109*30865Skarels reqptr np_mapreq[NNP]; 110*30865Skarels 11126199Ssklower /* The request structures, one pool per board */ 11226199Ssklower 11326199Ssklower static struct npreq npreqs[NNP][NUMCQE]; 11426199Ssklower 11526199Ssklower 11626199Ssklower /* 11726199Ssklower * Data structures needed for BSD 4.2 Device Drivers 11826199Ssklower */ 11926199Ssklower 12026199Ssklower int npprobe(), npattach(), npintr(); 12126199Ssklower struct uba_device *npdinfo[NNP]; 12226199Ssklower 12326199Ssklower /* UNIBUS address of Network Processors */ 12426199Ssklower 12526199Ssklower u_short npstd[] = { 0166000, 0166020, 0 }; 12626199Ssklower 12726199Ssklower /* Interrupt vectors used by the Network Processors */ 12826199Ssklower 12926199Ssklower static unsign16 npvectors[NNP]; 13026199Ssklower 13126199Ssklower struct uba_driver npdriver = 13226199Ssklower { npprobe, 0, npattach, 0, npstd, "np", npdinfo }; 13326199Ssklower struct buf np_tab[NNP]; 134*30865Skarels static unsigned long np_icount[NNP]; 13526199Ssklower 13626199Ssklower 13726199Ssklower /* 13826199Ssklower * External function and data structure declarations. 13926199Ssklower */ 14026199Ssklower 14126199Ssklower struct npreq * NpGetReq(); 14226199Ssklower struct npmaster *NpBoardChange(); 14326199Ssklower int NpTimer(); 14426199Ssklower struct CQE * NpRemCQE(); 14526199Ssklower 14626199Ssklower extern struct user u; 14726199Ssklower 14826199Ssklower /* 14926199Ssklower * Np_init() is responsible for hardware initializiation and the software 15026199Ssklower * initialization of the connection table and driver software data structures. 15126199Ssklower */ 15226199Ssklower 15326199Ssklower npinit(unit) 15426199Ssklower int unit; 15526199Ssklower { 15626199Ssklower register int j; 15726199Ssklower 15826199Ssklower 15926199Ssklower /* Software Initialization */ 16026199Ssklower 16126199Ssklower npmasters[unit].flags = NPCLEAR; 16226199Ssklower 16326199Ssklower NpSWinit(unit); 16426199Ssklower 16526199Ssklower /* Hardware Initialization */ 16626199Ssklower 16726199Ssklower NpHWinit(unit); 16826199Ssklower 16926199Ssklower /* Connection Table Initialization */ 17026199Ssklower 17126199Ssklower for(j=0;j<NNPCNN;j++) { 17226199Ssklower npcnxtab[unit][j].protocol = NPCLCONN; 17326199Ssklower npcnxtab[unit][j].unit = &npmasters[unit]; 17426199Ssklower } 17526199Ssklower } 17626199Ssklower 17726199Ssklower /* 17826199Ssklower * Np_open establishes a connection to the NP Driver using the minor 17926199Ssklower * device number as an identifier. A default protocol, NPMAINT, is assigned 18026199Ssklower * with the specified unit. Protocol and unit may be changed using the 18126199Ssklower * NpProtChange and NpBoardChange functions. 18226199Ssklower * Since the maintainance protocol does not need a working I-Board, entries 18326199Ssklower * are always made in the Connection Table, npcnxtab, if the board exists. 18426199Ssklower */ 18526199Ssklower 18626199Ssklower /*ARGSUSED*/ 18726199Ssklower npopen(dev,flag) 18826199Ssklower dev_t dev; 18926199Ssklower int flag; 19026199Ssklower { 19126199Ssklower int unit; 19226199Ssklower unsign16 conn; 19326199Ssklower struct npmaster *mp; 19426199Ssklower int error; 19526199Ssklower 19626199Ssklower if(NpDebug & DEBENTRY) 19726199Ssklower printf("npopen\n"); 19826199Ssklower 19926199Ssklower /* Clear error */ 20026199Ssklower 20126199Ssklower error = 0; 20226199Ssklower 20326199Ssklower /* Make sure it's the superuser */ 20426199Ssklower 20526199Ssklower if(u.u_uid) 20626199Ssklower return(EPERM); 20726199Ssklower 20826199Ssklower /* Get the connection identifier */ 20926199Ssklower 21026199Ssklower if(((conn = NPCONN(dev)) >= NNPCNN) || 21126199Ssklower ((unit = NPUNIT(dev)) >= NNP)) 21226199Ssklower return(ENODEV); 21326199Ssklower 21426199Ssklower 21526199Ssklower if(NpDebug & DEBOPEN) 21626199Ssklower printf("conn = %x unit = %d\n",conn,unit); 21726199Ssklower 21826199Ssklower /* Get the board for the specified unit */ 21926199Ssklower 22026199Ssklower mp = NpBoardChange(NPMAINT,unit); 22126199Ssklower 22226199Ssklower if(mp != (struct npmaster *) 0) { 22326199Ssklower npcnxtab[unit][conn].unit = mp; 22426199Ssklower npcnxtab[unit][conn].protocol = NPMAINT; 22526199Ssklower } 22626199Ssklower else error = ENXIO; 22726199Ssklower 22826199Ssklower if(NpDebug & DEBENTRY) 22926199Ssklower printf("npopen...\n"); 23026199Ssklower 23126199Ssklower return(error); 23226199Ssklower } 23326199Ssklower 23426199Ssklower /* 23526199Ssklower * Np_close is responsible updating the connection table for 23626199Ssklower * that connection by marking it closed. 23726199Ssklower */ 23826199Ssklower 23926199Ssklower npclose(dev) 24026199Ssklower dev_t dev; 24126199Ssklower { 24226199Ssklower 24326199Ssklower if(NpDebug & DEBENTRY) 24426199Ssklower printf("npclose\n"); 24526199Ssklower 24626199Ssklower /* Get the connection identifier */ 24726199Ssklower 24826199Ssklower npcnxtab[NPUNIT(dev)][NPCONN(dev)].protocol = NPCLCONN; 24926199Ssklower 25026199Ssklower if(NpDebug & DEBENTRY) 25126199Ssklower printf("npclose...\n"); 25226199Ssklower 25326199Ssklower return(0); 25426199Ssklower 25526199Ssklower } 25626199Ssklower 25726199Ssklower /* 25826199Ssklower * Npioctl is the main conduit of commands between the I-Board and the 25926199Ssklower * NP support utilities. Relevant information for the request is found in the 26026199Ssklower * cmd and addr parameters. Cmd specifies the function to perform, addr is 26126199Ssklower * command specific. Npioctl returns 0 if successful, or an error number 26226199Ssklower * (which winds up in errno). 26326199Ssklower */ 26426199Ssklower 26526199Ssklower /*ARGSUSED*/ 26626199Ssklower npioctl(dev,cmd,addr,flag) 26726199Ssklower dev_t dev; 26826199Ssklower int cmd; 26926199Ssklower caddr_t *addr; 27026199Ssklower int flag; 27126199Ssklower { 27226199Ssklower unsign16 protocol; 27326199Ssklower unsign16 conn; 27426199Ssklower unsign16 unit; 27526199Ssklower int error; 27626199Ssklower 27726199Ssklower register struct npmaster *mp; 27826199Ssklower register struct npreq *rp; 27926199Ssklower unsigned usrarg; 28026199Ssklower 28126199Ssklower if(NpDebug & DEBENTRY) 28226199Ssklower printf("npioctl\n"); 28326199Ssklower 28426199Ssklower /* Clear error */ 28526199Ssklower 28626199Ssklower error = 0; 28726199Ssklower 28826199Ssklower /* Strip off IOC_VOID bit */ 28926199Ssklower 29026199Ssklower cmd &= CMDMASK; 29126199Ssklower 29226199Ssklower /* Get connection identifier */ 29326199Ssklower 29426199Ssklower conn = NPCONN(dev); 29526199Ssklower unit = NPUNIT(dev); 29626199Ssklower 29726199Ssklower /* Master pointer for this unit */ 29826199Ssklower 29926199Ssklower mp = npcnxtab[unit][conn].unit; 30026199Ssklower 30126199Ssklower protocol = npcnxtab[unit][conn].protocol; 30226199Ssklower 30326199Ssklower /* Get a request structure from the pool and initialize it */ 30426199Ssklower 30526199Ssklower while((rp = NpGetReq(mp->reqtab)) == NULL) { 30626199Ssklower mp->reqtab->flags |= WANTREQ; 30726199Ssklower sleep((caddr_t)(mp->reqtab),PZERO -1); 30826199Ssklower } 30926199Ssklower 31026199Ssklower if(NpDebug & DEBREQ) 31126199Ssklower printf("NP Reqp is %x\n",rp); 31226199Ssklower 31326199Ssklower /* Initializations of request structure */ 31426199Ssklower 31526199Ssklower rp->intr = (int (*)())0; /* Do not call interrupt routine */ 31626199Ssklower rp->bufoffset = 0; /* Offset into data buffer */ 31726199Ssklower rp->procp = u.u_procp; /* Process structure for this user */ 31826199Ssklower 31926199Ssklower /* Copy in user's argument to ioctl() call */ 32026199Ssklower 32126199Ssklower if(error = copyin(*addr,&usrarg,sizeof(usrarg))) 32226199Ssklower return(error); 32326199Ssklower 32426199Ssklower 32526199Ssklower if(NpDebug & DEBIOCTL) 32626199Ssklower printf("arg = %x\n",usrarg); 32726199Ssklower 32826199Ssklower /* Execute the specified command */ 32926199Ssklower 33026199Ssklower switch(cmd) { 33126199Ssklower 33226199Ssklower case NPSETPROT: 33326199Ssklower if((error = NpProtChange(usrarg,mp->unit)) == 0) 33426199Ssklower npcnxtab[unit][conn].protocol = usrarg; 33526199Ssklower break; 33626199Ssklower case NPSETBOARD: 33726199Ssklower if(mp = NpBoardChange(protocol,usrarg)) 33826199Ssklower npcnxtab[unit][conn].unit = mp; 33926199Ssklower else { 34026199Ssklower mp = npcnxtab[unit][conn].unit; 34126199Ssklower error = ENXIO; 34226199Ssklower } 34326199Ssklower break; 34426199Ssklower case NPRESET: 34526199Ssklower error = NpReset(mp,rp); 34626199Ssklower break; 34726199Ssklower case NPSETNPDEB: 34826199Ssklower NpDebug = usrarg; 34926199Ssklower break; 35026199Ssklower case NPINIT: 35126199Ssklower error = NpSWinit(mp->unit); 35226199Ssklower break; 35326199Ssklower case NPSTART: 35426199Ssklower 35526199Ssklower #ifdef OLDROM 35626199Ssklower /* 35726199Ssklower * Kludge to work around I-Board boot from Host. Read two bytes 35826199Ssklower * from the board into the Device Configuration Word 35926199Ssklower * in Shared Memory. 36026199Ssklower */ 36126199Ssklower 36226199Ssklower NPIO(mp,(paddr_t)0x500,(paddr_t)(&mp->shmemp->statblock.sb_dcw),2,B_READ); 36326199Ssklower 36426199Ssklower mp->shmemp->statblock.sb_drw = 0; 36526199Ssklower #endif 36626199Ssklower 36726199Ssklower /* Set the Address at which to begin On-Board execution */ 36826199Ssklower 36926199Ssklower error = NpSetXeqAddr(mp,(caddr_t)usrarg); 37026199Ssklower break; 37126199Ssklower case NPSTATS: 37226199Ssklower error = NpStats(); 37326199Ssklower break; 37426199Ssklower case NPGPANIC: 37526199Ssklower error = copyout((caddr_t)NpPbuf,*addr,PANLEN); 37626199Ssklower 37726199Ssklower /* Clear panic request flag and leave */ 37826199Ssklower 37926199Ssklower mp->flags &= ~PANICREQ; 38026199Ssklower break; 38126199Ssklower case NPPOLL: 38226199Ssklower error = NpPoll(mp,*addr); 38326199Ssklower break; 38426199Ssklower case NPKILL: 38526199Ssklower error = NpKill(mp,rp); 38626199Ssklower break; 38726199Ssklower case NPSETADDR: 38826199Ssklower error = NpSetMemAddr(mp,*addr); 38926199Ssklower break; 39026199Ssklower case NPRCSR0: 39126199Ssklower usrarg = RCSR0(mp->iobase); 39226199Ssklower error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); 39326199Ssklower break; 39426199Ssklower case NPRCSR1: 39526199Ssklower usrarg = RCSR1(mp->iobase); 39626199Ssklower error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); 39726199Ssklower break; 39826199Ssklower case NPRCSR2: 39926199Ssklower usrarg = RCSR2(mp->iobase); 40026199Ssklower error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); 40126199Ssklower break; 40226199Ssklower case NPRCSR3: 40326199Ssklower usrarg = RCSR3(mp->iobase); 40426199Ssklower error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); 40526199Ssklower break; 40626199Ssklower case NPWCSR0: 40726199Ssklower WCSR0(mp->iobase,usrarg); 40826199Ssklower break; 40926199Ssklower case NPWCSR1: 41026199Ssklower WCSR1(mp->iobase,usrarg); 41126199Ssklower break; 41226199Ssklower case NPWCSR2: 41326199Ssklower WCSR2(mp->iobase,usrarg); 41426199Ssklower break; 41526199Ssklower case NPWCSR3: 41626199Ssklower WCSR3(mp->iobase,usrarg); 41726199Ssklower break; 41826199Ssklower case NPNETBOOT: 41926199Ssklower error = NpSetIntLevel(mp,mp->vector); 42026199Ssklower if(error) break; 42126199Ssklower error = NpSetXeqAddr(mp,(caddr_t)INETBOOT); 42226199Ssklower break; 423*30865Skarels case NPSETLAST: 424*30865Skarels if (usrarg) 425*30865Skarels mp->flags &= ~LSTCMD; 426*30865Skarels else 427*30865Skarels mp->flags |= LSTCMD; 428*30865Skarels break; 429*30865Skarels case NPCLRICNT: 430*30865Skarels np_icount[unit] = NPCLEAR; 431*30865Skarels break; 432*30865Skarels case NPGETICNT: 433*30865Skarels usrarg = np_icount[unit]; 434*30865Skarels error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); 435*30865Skarels break; 436*30865Skarels case NPGETIVEC: 437*30865Skarels usrarg = mp->vector; 438*30865Skarels error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); 439*30865Skarels break; 440*30865Skarels case NPMAPMEM: 441*30865Skarels error = NpMem(mp, rp, *addr); 442*30865Skarels break; 44326199Ssklower default: 44426199Ssklower printf("Bad Maintenance command: %d!\n",cmd); 44526199Ssklower error = EIO; 44626199Ssklower break; 44726199Ssklower } 448*30865Skarels if((cmd != NPRESET) && (cmd != NPINIT) && (cmd != NPMAPMEM)) 44926199Ssklower NpFreeReq(mp->reqtab,rp); 45026199Ssklower 45126199Ssklower if(NpDebug & DEBENTRY) 45226199Ssklower printf("npioctl...\n"); 45326199Ssklower 45426199Ssklower return(error); 45526199Ssklower } 45626199Ssklower 45726199Ssklower /* 45826199Ssklower * np_start - start io activity 45926199Ssklower */ 46026199Ssklower npstart(mp) 46126199Ssklower register struct npmaster *mp; 46226199Ssklower { 46326199Ssklower 464*30865Skarels register struct uio *uio; 46526199Ssklower register struct buf *bp; 46626199Ssklower register struct npreq *rp; 46726199Ssklower 46826199Ssklower int error; /* Return from NPIO call */ 46926199Ssklower 47026199Ssklower if(NpDebug & DEBENTRY) 47126199Ssklower printf("npstart\n"); 47226199Ssklower 47326199Ssklower if((bp = np_tab[mp->unit].b_actf) == (struct buf *)0) { 47426199Ssklower np_tab[mp->unit].b_active = 0; 47526199Ssklower return; 47626199Ssklower } 477*30865Skarels if((rp = (struct npreq *)(bp->b_rp)) == (struct npreq *)0) { 47826199Ssklower bp->b_flags = B_ERROR; 47926199Ssklower iodone(bp); 48026199Ssklower return; 48126199Ssklower } 482*30865Skarels if ((uio = (struct uio *)bp->b_uio) == (struct uio *)0) { 483*30865Skarels bp->b_flags = B_ERROR; 484*30865Skarels iodone(bp); 485*30865Skarels return; 486*30865Skarels } 48726199Ssklower np_tab[mp->unit].b_active = 1; 48826199Ssklower 48926199Ssklower if(NpDebug & DEBIO) 490*30865Skarels printf("NP IO src %x dst = %x cnt = %x\n", bp->b_un.b_addr, 491*30865Skarels uio->uio_offset, bp->b_bcount); 49226199Ssklower 49326199Ssklower /* Send the request to the board via the CSR0 command interface */ 49426199Ssklower 49526199Ssklower if(bp->b_flags & B_READ) 496*30865Skarels error = NPIO(mp, (paddr_t)uio->uio_offset, (paddr_t)rp->bufaddr, 497*30865Skarels bp->b_bcount, (bp->b_flags & B_READ)); 49826199Ssklower else 499*30865Skarels error = NPIO(mp, (paddr_t)rp->bufaddr, (paddr_t)uio->uio_offset, 500*30865Skarels bp->b_bcount, (bp->b_flags & B_READ)); 50126199Ssklower 50226199Ssklower 50326199Ssklower /* Check return from I/O */ 50426199Ssklower 50526199Ssklower if(error) { 50626199Ssklower bp->b_flags |= B_ERROR; 50726199Ssklower np_tab[mp->unit].b_actf = bp->av_forw; 50826199Ssklower if(NpDebug & DEBIO) 50926199Ssklower printf("NPIO return error: b_flags is %x \n",bp->b_flags); 51026199Ssklower iodone(bp); 51126199Ssklower } 51226199Ssklower 51326199Ssklower if(NpDebug & DEBENTRY) 51426199Ssklower printf("npstart...\n"); 51526199Ssklower 51626199Ssklower } 51726199Ssklower /* 518*30865Skarels * npstrategy - the strategy routine 51926199Ssklower */ 52026199Ssklower 52126199Ssklower npstrategy(bp) 52226199Ssklower register struct buf *bp; 52326199Ssklower { 52426199Ssklower 52526199Ssklower register struct buf *ip; /* quick pointer */ 52626199Ssklower register struct npmaster *mp; /* master structure for this device */ 52726199Ssklower register struct npreq *rp; /* reqest struct pointer */ 52826199Ssklower int s; /* priority to return to */ 52926199Ssklower 53026199Ssklower if(NpDebug & DEBENTRY) 53126199Ssklower printf("npstrategy\n"); 53226199Ssklower if(NpDebug & DEBIO) 53326199Ssklower printf("flag = %x count = %x paddr = %x %x blkno = %x %x\n", 534*30865Skarels bp->b_flags, bp->b_bcount, bp->b_un.b_addr, bp->b_un.b_addr, 535*30865Skarels bp->b_blkno,bp->b_blkno); 53626199Ssklower 53726199Ssklower /* get master structure */ 53826199Ssklower 53926199Ssklower mp = npcnxtab[NPUNIT(bp->b_dev)][NPCONN(bp->b_dev)].unit; 54026199Ssklower 54126199Ssklower /* make sure the boards ok */ 54226199Ssklower 54326199Ssklower if (mp->flags & BADBOARD) { 54426199Ssklower bp->b_flags |= B_ERROR; 54526199Ssklower 54626199Ssklower if(NpDebug & DEBMEM) 54726199Ssklower printf("Bad Board %x bp %x\n",mp->flags,bp->b_flags); 54826199Ssklower 54926199Ssklower np_tab[mp->unit].b_actf = bp->av_forw; 55026199Ssklower iodone(bp); 55126199Ssklower return; 55226199Ssklower } 55326199Ssklower 55426199Ssklower /* Initializations of request structure */ 55526199Ssklower 55626199Ssklower while((rp = NpGetReq(mp->reqtab)) == NULL) { 55726199Ssklower mp->reqtab->flags |= WANTREQ; 55826199Ssklower sleep((caddr_t)(mp->reqtab),PZERO -1); 55926199Ssklower } 56026199Ssklower 56126199Ssklower rp->bufoffset = 0; /* This is the start of the buffer */ 56226199Ssklower ip = &np_tab[mp->unit]; 563*30865Skarels bp->b_rp = (struct buf *)rp; 56426199Ssklower 56526199Ssklower rp->flags |= KERNREQ; /* Mark it as kernel so not to map */ 56626199Ssklower 56726199Ssklower rp->mapbase = ubasetup(mp->devp->ui_ubanum,bp,0); 56826199Ssklower rp->bufaddr = (caddr_t)((int)(rp->mapbase) & UBADDRMASK); 56926199Ssklower 57026199Ssklower s = spl5(); 57126199Ssklower if(ip->b_actf ==(struct buf *)0) 57226199Ssklower ip->b_actf = bp; 57326199Ssklower else { 57426199Ssklower if(ip->b_actf->av_forw) 57526199Ssklower printf("Panic NP100 bad buffer chain\n"); 57626199Ssklower ip->b_actf->av_forw = bp; 57726199Ssklower } 57826199Ssklower ip->b_actl = bp; 57926199Ssklower 58026199Ssklower NpAddReq(mp->reqtab,rp); /* Queue onto active list */ 58126199Ssklower 58226199Ssklower if(ip->b_active == 0) { 58326199Ssklower 58426199Ssklower if(NpDebug & DEBIO) 58526199Ssklower printf("calling npstart %x\n",mp); 58626199Ssklower 58726199Ssklower npstart(mp); 58826199Ssklower } 58926199Ssklower splx(s); 59026199Ssklower 59126199Ssklower if(NpDebug & DEBIO) 59226199Ssklower printf("back from npstart\n"); 59326199Ssklower 59426199Ssklower /* Await completion of I/O */ 59526199Ssklower 59626199Ssklower iowait(bp); 59726199Ssklower 59826199Ssklower if(NpDebug & DEBIO) 59926199Ssklower printf("after iowait in npstrategy\n"); 60026199Ssklower 60126199Ssklower /* Remove request from queue */ 60226199Ssklower 60326199Ssklower NpRemReq(rp); 60426199Ssklower 60526199Ssklower /* Release mapping registers */ 60626199Ssklower 60726199Ssklower ubarelse(mp->devp->ui_ubanum,&rp->mapbase); 60826199Ssklower 60926199Ssklower /* Free up request structure */ 61026199Ssklower 61126199Ssklower NpFreeReq(mp->reqtab,rp); 61226199Ssklower 61326199Ssklower if(NpDebug & DEBENTRY) 61426199Ssklower printf("Leaving npstrategy flags is %x\n",bp->b_flags); 61526199Ssklower } 61626199Ssklower 61726199Ssklower unsigned 61826199Ssklower nptrim(bp) 61926199Ssklower register struct buf *bp; 62026199Ssklower { 62126199Ssklower 62226199Ssklower if(bp->b_bcount > NPMAXXFR) 62326199Ssklower bp->b_bcount = NPMAXXFR; 62426199Ssklower } 62526199Ssklower 62626199Ssklower /* 62726199Ssklower * Npread dumps data from the board to the user's buffer 62826199Ssklower */ 62926199Ssklower npread(dev,uio) 63026199Ssklower dev_t dev; 63126199Ssklower struct uio *uio; 63226199Ssklower { 633*30865Skarels struct buf *bp; 634*30865Skarels bp = &npcnxtab[NPUNIT(dev)][NPCONN(dev)].np_rbuf; 63526199Ssklower 63626199Ssklower if(NpDebug & DEBENTRY) 63726199Ssklower printf("in npread\n"); 63826199Ssklower 639*30865Skarels bp->b_uio = (struct buf *)uio; 640*30865Skarels return(physio(npstrategy,bp,dev,B_READ ,nptrim,uio)); 64126199Ssklower } 64226199Ssklower 64326199Ssklower /* 64426199Ssklower * Npwrite loads the np100 board from the user's buffer 64526199Ssklower */ 64626199Ssklower 64726199Ssklower npwrite(dev,uio) 64826199Ssklower dev_t dev; 64926199Ssklower struct uio *uio; 65026199Ssklower { 65126199Ssklower struct buf *bp; 65226199Ssklower bp = &npcnxtab[NPUNIT(dev)][NPCONN(dev)].np_wbuf; 65326199Ssklower 65426199Ssklower if(NpDebug & DEBENTRY) 65526199Ssklower printf("in npwrite \n"); 65626199Ssklower 657*30865Skarels bp->b_uio = (struct buf *)uio; 65826199Ssklower return(physio(npstrategy,bp,dev,B_WRITE ,nptrim,uio)); 65926199Ssklower } 660*30865Skarels 66126199Ssklower /* 66226199Ssklower * npreset - called as result of a UNIBUS reset. 66326199Ssklower */ 66426199Ssklower 66526199Ssklower npreset(uban) 66626199Ssklower int uban; 66726199Ssklower { 66826199Ssklower 66926199Ssklower register struct npmaster *mp; 67026199Ssklower register struct npreq *rp; 67126199Ssklower register struct uba_device *ui; 67226199Ssklower int i; 67326199Ssklower 674*30865Skarels if(NpDebug & DEBENTRY) 675*30865Skarels printf("npreset(ubareset)\n"); 67626199Ssklower for(i = 0; i < NNP; i++) { 67726199Ssklower 67826199Ssklower if(((ui = npdinfo[i]) == (struct uba_device *)NULL) || 67926199Ssklower (ui->ui_ubanum != uban)) 68026199Ssklower continue; 68126199Ssklower 68226199Ssklower mp = &npmasters[i]; 683*30865Skarels 684*30865Skarels /* Get a Request structure */ 685*30865Skarels 686*30865Skarels while((rp = NpGetReq(mp->reqtab)) == NULL) { 687*30865Skarels mp->reqtab->flags |= WANTREQ; 688*30865Skarels sleep((caddr_t)(mp->reqtab),PZERO -1); 689*30865Skarels } 690*30865Skarels 691*30865Skarels NpReset(mp,rp); 69226199Ssklower } 693*30865Skarels if(NpDebug & DEBENTRY) 694*30865Skarels printf("npreset(ubareset)...\n"); 69526199Ssklower } 69626199Ssklower 697*30865Skarels 69826199Ssklower /* 69926199Ssklower * Nppoll looks for work by polling each board. He goes to sleep if there are 70026199Ssklower * no outstanding requests for him but reminds the board that he's there when 70126199Ssklower * needed. 70226199Ssklower */ 70326199Ssklower 70426199Ssklower NpPoll(mp,addr) 70526199Ssklower struct npmaster *mp; 70626199Ssklower caddr_t addr; 70726199Ssklower { 70826199Ssklower int error; 70926199Ssklower 71026199Ssklower struct { 71126199Ssklower unsign16 request; 71226199Ssklower unsign16 unit; 71326199Ssklower }icpreq; 71426199Ssklower 71526199Ssklower if(NpDebug & DEBMAINT) 71626199Ssklower printf("NpPoll: flags is %x.\n",mp->flags); 71726199Ssklower 71826199Ssklower while(TRUE) { 71926199Ssklower 72026199Ssklower for(mp = npmasters; mp; mp = mp->next) { 72126199Ssklower 72226199Ssklower if(mp->flags & BOARDREQ) { 72326199Ssklower 72426199Ssklower /* Get request type from master structure */ 72526199Ssklower 72626199Ssklower if(mp->flags & BRDRESET) { 72726199Ssklower icpreq.request = ICPPOLL; 72826199Ssklower mp->reqtab->reqcnt--; 72926199Ssklower 73026199Ssklower if(NpDebug & DEBMAINT) 73126199Ssklower printf("Waking NpResetter!\n"); 73226199Ssklower 73326199Ssklower wakeup((caddr_t)(&mp->reqtab)); 73426199Ssklower } 73526199Ssklower else if(mp->flags & PANICREQ) 73626199Ssklower icpreq.request = ICPPANIC; 73726199Ssklower else if(mp->flags & DUMPREQ) 73826199Ssklower icpreq.request = ICPDUMP; 73926199Ssklower else if(mp->flags & LOADREQ) 74026199Ssklower icpreq.request = ICPLOAD; 74126199Ssklower else { 74226199Ssklower mp->flags &= ~BOARDREQ; 74326199Ssklower continue; 74426199Ssklower } 74526199Ssklower 74626199Ssklower if(NpDebug & DEBMAINT) 74726199Ssklower printf("ProcICP servicing %d \n",icpreq.request ); 74826199Ssklower 74926199Ssklower /* Request and unit number to be sent */ 75026199Ssklower 75126199Ssklower icpreq.unit = mp->unit; 75226199Ssklower 75326199Ssklower /* Copy service request to calling process */ 75426199Ssklower 75526199Ssklower error = copyout(&icpreq,addr,sizeof(icpreq)); 75626199Ssklower 75726199Ssklower /* Mark Poller as being unavailable */ 75826199Ssklower 75926199Ssklower NpState &= ~ICPAVAIL; 76026199Ssklower 76126199Ssklower return(error); 76226199Ssklower } 76326199Ssklower } 76426199Ssklower 76526199Ssklower /* Mark Poller as being available */ 76626199Ssklower 76726199Ssklower NpState |= ICPAVAIL; 76826199Ssklower 76926199Ssklower sleep((caddr_t)&NpState, PZERO + 1); 77026199Ssklower 77126199Ssklower if(NpDebug & DEBMAINT) 77226199Ssklower printf("wakeup in NpPoll\n"); 77326199Ssklower 77426199Ssklower } 77526199Ssklower } 77626199Ssklower 77726199Ssklower /* 77826199Ssklower * Software initialization of Driver data structures for the specified unit. 77926199Ssklower */ 78026199Ssklower 78126199Ssklower NpSWinit(unit) 78226199Ssklower int unit; 78326199Ssklower { 78426199Ssklower 78526199Ssklower register int j; 78626199Ssklower register struct npmaster *mp; 78726199Ssklower register struct npspace *npsp; 78826199Ssklower register struct CmdQue *cqp; 78926199Ssklower int offset; 79026199Ssklower 79126199Ssklower if(NpDebug & DEBINIT) 79226199Ssklower printf("SW reset on unit %d.\n",unit); 79326199Ssklower 794*30865Skarels np_icount[unit] = NPCLEAR; 795*30865Skarels np_mapreq[unit] = (struct npreq *) NPCLEAR; 796*30865Skarels 79726199Ssklower /* Initialize master structure pointer for this unit */ 79826199Ssklower 79926199Ssklower mp = &npmasters[unit]; 80026199Ssklower 80126199Ssklower /* Initialize unit buffer headers */ 80226199Ssklower 80326199Ssklower np_tab[unit].b_active = 0; 80426199Ssklower np_tab[unit].b_actf = 0; 80526199Ssklower 80626199Ssklower /* UBA device structure for this unit */ 80726199Ssklower 80826199Ssklower mp->devp = npdinfo[unit]; 80926199Ssklower 81026199Ssklower /* Interrupt vector for this unit */ 81126199Ssklower 81226199Ssklower mp->vector = npvectors[unit]; 81326199Ssklower 81426199Ssklower if(unit == (NNP -1)) 81526199Ssklower mp->next = (struct npmaster *)NULL; 81626199Ssklower else mp->next = &npmasters[unit + 1]; 81726199Ssklower 81826199Ssklower /* 81926199Ssklower * Guarantee alignment of shared memory area on a 82026199Ssklower * 16 byte boundary as required by I-Board 82126199Ssklower */ 82226199Ssklower 82326199Ssklower mp->shmemp = &npspaces[unit]; 82426199Ssklower mp->shmemp = (struct npspace *)ROUND16((int)(mp->shmemp)); 82526199Ssklower 82626199Ssklower /* Base address of this controller */ 82726199Ssklower 82826199Ssklower mp->iobase = (struct NPREG *)(mp->devp->ui_addr); 82926199Ssklower 83026199Ssklower if(NpDebug & DEBMEM) { 83126199Ssklower printf("Npspaces starts at %x.\n",npspaces); 83226199Ssklower printf("Shared memory starts at %x.\n",mp->shmemp); 83326199Ssklower printf("End of shared memory is %x.\n",&npspaces[unit + 1]); 83426199Ssklower printf("Iobase is %x.\n",mp->iobase); 83526199Ssklower printf("Npmasters start at %x\n",npmasters); 83626199Ssklower printf("Reqhdr start at %x\n",reqhdr); 83726199Ssklower printf("Npreqs start at %x\n",npreqs); 83826199Ssklower } 83926199Ssklower 84026199Ssklower /* Initialize the request header */ 84126199Ssklower 84226199Ssklower mp->reqtab = &reqhdr[unit]; 84326199Ssklower 84426199Ssklower /* Unit initialization */ 84526199Ssklower 84626199Ssklower mp->unit = unit; 84726199Ssklower 84826199Ssklower /* Initialize Status Block */ 84926199Ssklower 85026199Ssklower npsp = mp->shmemp; 85126199Ssklower offset = (int) (mp->shmemp); 85226199Ssklower 85326199Ssklower npsp->statblock.sb_drw = 0; 85426199Ssklower npsp->statblock.sb_hcw = HOSTCONF; 85526199Ssklower npsp->statblock.sb_dcw = 0; 85626199Ssklower npsp->statblock.sb_dpm = 0; 85726199Ssklower 85826199Ssklower npsp->statblock.sb_dcq = (unsign16)((int)(&npsp->devcq))-offset; 85926199Ssklower 86026199Ssklower npsp->statblock.sb_hcq = (unsign16)((int)(&npsp->hostcq))-offset; 86126199Ssklower 86226199Ssklower /* Initialize Device Command Queue */ 86326199Ssklower 86426199Ssklower cqp = (struct CmdQue *) &npsp->devcq; 86526199Ssklower 86626199Ssklower if(NpDebug & DEBCQ) 86726199Ssklower printf("Device CQ at %x\n",cqp); 86826199Ssklower 86926199Ssklower cqp->scanflag = NPCLEAR; 87026199Ssklower cqp->chngflag = NPCLEAR; 87126199Ssklower 87226199Ssklower cqp->cq_add = (unsign16)(int)(&cqp->cq_cqe[0]) - offset; 87326199Ssklower cqp->cq_rem = cqp->cq_add; 87426199Ssklower 87526199Ssklower cqp->cq_wrap = (unsign16)(int)(&cqp->cq_cqe[NUMCQE]) - offset; 87626199Ssklower 87726199Ssklower for(j = 0; j < NUMCQE; j++) 87826199Ssklower cqp->cq_cqe[j] = (unsign16)NULL; 87926199Ssklower 88026199Ssklower /* Initialize Host Command Queue */ 88126199Ssklower 88226199Ssklower cqp = (struct CmdQue *) &npsp->hostcq; 88326199Ssklower 88426199Ssklower if(NpDebug & DEBCQ) 88526199Ssklower printf("HOST CQ at %x\n",cqp); 88626199Ssklower 88726199Ssklower cqp->scanflag = NPCLEAR; 88826199Ssklower cqp->chngflag = NPCLEAR; 88926199Ssklower 89026199Ssklower cqp->cq_add = (unsign16)(int)(&cqp->cq_cqe[0]) - offset; 89126199Ssklower cqp->cq_rem = cqp->cq_add; 89226199Ssklower 89326199Ssklower cqp->cq_wrap = (unsign16)(int)(&cqp->cq_cqe[NUMCQE]) - offset; 89426199Ssklower 89526199Ssklower for(j = 0; j < NUMCQE; j++) 89626199Ssklower cqp->cq_cqe[j] = (unsign16)NULL; 89726199Ssklower 89826199Ssklower /* 89926199Ssklower * Initialize the reqid of the elements to the address 90026199Ssklower * of the corresponding Npreq structure. These don't change. 90126199Ssklower */ 90226199Ssklower 90326199Ssklower for(j = 0; j < NUMCQE; j++) 90426199Ssklower npsp->elements[j].cqe_reqid = &npreqs[unit][j]; 90526199Ssklower 90626199Ssklower /* 90726199Ssklower * Initialize the Request Header (reqhdr), free list of 90826199Ssklower * npreqs, and pointers to CQEs. 90926199Ssklower */ 91026199Ssklower 91126199Ssklower reqhdr[unit].forw = reqhdr[unit].back = &reqhdr[unit]; 91226199Ssklower reqhdr[unit].free = &npreqs[unit][0]; 91326199Ssklower 91426199Ssklower for(j = 0; j < NUMCQE; j++) { 91526199Ssklower npreqs[unit][j].free = &npreqs[unit][j + 1]; 91626199Ssklower npreqs[unit][j].element = &npsp->elements[j]; 91726199Ssklower npreqs[unit][j].forw = npreqs[unit][j].back = (struct npreq *)NULL; 918*30865Skarels npreqs[unit][j].flags = NPCLEAR; 91926199Ssklower } 92026199Ssklower npreqs[unit][--j].free = &reqhdr[unit]; 92126199Ssklower 92226199Ssklower /* 92326199Ssklower * Set up the UNIBUS I/O Map Registers for the 92426199Ssklower * Shared memory area. 92526199Ssklower */ 92626199Ssklower 92726199Ssklower mp->iomapbase = uballoc(mp->devp->ui_ubanum,(caddr_t)(mp->shmemp),sizeof(struct npspace),0); 92826199Ssklower 92926199Ssklower 93026199Ssklower if(NpDebug & DEBENTRY) 93126199Ssklower printf("SW_Init...\n"); 932*30865Skarels return(0); 93326199Ssklower } 93426199Ssklower 93526199Ssklower /* 93626199Ssklower * NpHWinit() issues a hardware reset to the specified board and waits 93726199Ssklower * for on-board diagnostics to complete. It returns 0 if the board is 93826199Ssklower * present and passed diagnostics, an error value otherwise. 93926199Ssklower */ 94026199Ssklower 94126199Ssklower NpHWinit(unit) 94226199Ssklower int unit; 94326199Ssklower { 94426199Ssklower register struct npmaster *mp; 94526199Ssklower struct NPREG *REG; 94626199Ssklower unsign16 status; 94726199Ssklower int dflag; 94826199Ssklower 94926199Ssklower if(unit >= NNP) 95026199Ssklower return(ENXIO); 95126199Ssklower 95226199Ssklower mp = &npmasters[unit]; 95326199Ssklower 95426199Ssklower if(NpDebug & DEBENTRY) 95526199Ssklower printf("NpHWinit\n"); 95626199Ssklower 95726199Ssklower /* See if the board is out there */ 95826199Ssklower 95926199Ssklower REG = (struct NPREG *)mp->iobase; 96026199Ssklower 96126199Ssklower if(NpDebug & DEBINIT) 96226199Ssklower printf("REG in HWinit is %x.\n",mp->iobase); 96326199Ssklower 96426199Ssklower if(!(mp->flags & BRDRESET)) 96526199Ssklower 96626199Ssklower if(badaddr(REG,2)) { 96726199Ssklower mp->flags |= BADBOARD; 96826199Ssklower printf("\nNP100 unit %d not found!\n",unit); 96926199Ssklower return(ENXIO); 97026199Ssklower } 97126199Ssklower 97226199Ssklower 97326199Ssklower #ifdef mc500 97426199Ssklower if(setjmp(u.u_tsav) == 0) { 97526199Ssklower u.u_nofault = TRUE; 97626199Ssklower status = RCSR1(mp->iobase); 97726199Ssklower u.u_nofault = FALSE; 97826199Ssklower } 97926199Ssklower else { 98026199Ssklower np__addr[unit] = 0; 98126199Ssklower mp->flags |= BADBOARD; 98226199Ssklower u.u_error = ENXIO; 98326199Ssklower printf("\nNP100 Unit %x not here!\n",unit); 98426199Ssklower return(0); 98526199Ssklower } 98626199Ssklower #endif 98726199Ssklower 98826199Ssklower if(NpDebug & DEBENTRY) 98926199Ssklower printf("Resetting the NP100 Board at %x\n",mp->iobase); 99026199Ssklower 99126199Ssklower /* Reset the Board */ 99226199Ssklower 99326199Ssklower RESET(mp); 99426199Ssklower 99526199Ssklower dflag = NPCLEAR; 99626199Ssklower 99726199Ssklower timeout(NpTimer,&dflag,DIAGTIME); 99826199Ssklower 99926199Ssklower /* Wait for Enable and Read Data Ready to go high */ 100026199Ssklower 100126199Ssklower while(! ((RCSR1(mp->iobase) & NPENB) && (RCSR1(mp->iobase) & NPRDR))) { 100226199Ssklower if(dflag) 100326199Ssklower break; 100426199Ssklower 100526199Ssklower } 100626199Ssklower 100726199Ssklower untimeout(NpTimer,&dflag); 100826199Ssklower 100926199Ssklower if(NpDebug & DEBINIT) 101026199Ssklower printf("np reset %d \n",dflag); 101126199Ssklower 101226199Ssklower if(dflag) { 101326199Ssklower mp->flags |= BADBOARD; 101426199Ssklower printf("NP100 Unit %d timed out!\n",unit); 101526199Ssklower return(EIO); 101626199Ssklower } 101726199Ssklower 101826199Ssklower status = RCSR0(mp->iobase); 101926199Ssklower 102026199Ssklower /* Check for Hardware OK */ 102126199Ssklower 102226199Ssklower if(!(RCSR1(mp->iobase) & NPHOK)) { 102326199Ssklower mp->flags |= BADBOARD; 102426199Ssklower u.u_error = EIO; 102526199Ssklower printf("NP100 Unit %d Failed diagnostics!\n",unit); 102626199Ssklower printf("Status from CSR0: %x.\n",status); 102726199Ssklower return(EIO); 102826199Ssklower } 102926199Ssklower 103026199Ssklower if(NpDebug & DEBENTRY) 103126199Ssklower printf("HWinit...\n"); 103226199Ssklower 103326199Ssklower return(0); 103426199Ssklower } 103526199Ssklower 103626199Ssklower /* 103726199Ssklower * NP Driver Interrupt Handler 103826199Ssklower */ 103926199Ssklower 104026199Ssklower npintr(unit) 104126199Ssklower int unit; 104226199Ssklower { 104326199Ssklower register struct npmaster *mp; 104426199Ssklower register struct buf *bp; 104526199Ssklower 104626199Ssklower if(NpDebug & DEBENTRY) 104726199Ssklower printf("npintr on unit %d!\n",unit); 104826199Ssklower 104926199Ssklower mp = &npmasters[unit]; 1050*30865Skarels np_icount[unit]++; 105126199Ssklower 105226199Ssklower if(NpDebug & DEBINTR) 1053*30865Skarels printf("npintr mp->flags = %x interupt count = %x\n", 1054*30865Skarels mp->flags, np_icount[unit]); 105526199Ssklower 105626199Ssklower /* Wake up anyone sleeping on a CSR0 Command */ 105726199Ssklower 105826199Ssklower if(mp->flags & CSRPEND) { 105926199Ssklower 106026199Ssklower mp->flags &= ~CSRPEND; 106126199Ssklower if(np_tab[mp->unit].b_active) { 106226199Ssklower np_tab[mp->unit].b_active = 0; 106326199Ssklower bp = np_tab[mp->unit].b_actf; 106426199Ssklower np_tab[mp->unit].b_actf = bp->av_forw; 106526199Ssklower 106626199Ssklower if(NpDebug & DEBINTR) 106726199Ssklower printf("bp = %x resid = %d forw = %x\n",bp, 106826199Ssklower bp->b_resid,bp->av_forw); 106926199Ssklower 107026199Ssklower bp->b_resid = 0; 107126199Ssklower iodone(bp); 107226199Ssklower } 107326199Ssklower if(mp->flags & PANIC3) { 107426199Ssklower mp->flags &= ~PANIC3; 107526199Ssklower mp->flags = AVAILABLE; 107626199Ssklower ubarelse(mp->devp->ui_ubanum,&panicmap); 107726199Ssklower } 107826199Ssklower if(mp->flags & PANIC2) { 107926199Ssklower mp->flags &= ~PANIC2; 108026199Ssklower printf("Panic Message: %s",NpPbuf); 108126199Ssklower mp->flags |= PANIC3; 108226199Ssklower NpPbuf[0] = 0; 108326199Ssklower NPIO(mp,(paddr_t)((int) panicmap & UBADDRMASK),(paddr_t)pstring,sizeof(NpPbuf),B_WRITE); 108426199Ssklower } 108526199Ssklower if(mp->flags & PANIC1) { 108626199Ssklower mp->flags &= ~PANIC1; 108726199Ssklower mp->flags |= PANIC2; 108826199Ssklower ubarelse(mp->devp->ui_ubanum,&panicmap); 108926199Ssklower panicmap = uballoc(mp->devp->ui_ubanum,(caddr_t)NpPbuf,sizeof(NpPbuf),0); 109026199Ssklower pstring = (caddr_t)((panaddr[1] << 4) + panaddr[0]); 109126199Ssklower NPIO(mp,(paddr_t)pstring,(paddr_t)((int) panicmap & UBADDRMASK),sizeof(NpPbuf),B_READ); 109226199Ssklower } 109326199Ssklower 109426199Ssklower wakeup((caddr_t)mp); 109526199Ssklower goto out; 109626199Ssklower } 109726199Ssklower 109826199Ssklower /* Mark unit as being available if Device Protocol Mask set */ 109926199Ssklower 110026199Ssklower if(!(mp->flags & AVAILABLE)) { 110126199Ssklower 110226199Ssklower if((mp->shmemp->statblock.sb_dpm) && (!(mp->flags & BRDRESET))){ 110326199Ssklower 110426199Ssklower mp->flags = AVAILABLE; 110526199Ssklower printf("\nNP100 unit #%d available!\n",mp->unit); 110626199Ssklower } 110726199Ssklower } 110826199Ssklower 110926199Ssklower /* Honor service requests from the device */ 111026199Ssklower 111126199Ssklower switch(mp->shmemp->statblock.sb_drw) { 111226199Ssklower 111326199Ssklower case NOREQ: 111426199Ssklower break; 111526199Ssklower 111626199Ssklower case NPPANIC: 111726199Ssklower 111826199Ssklower printf("\nPanic from NP100 unit %d!\n",mp->unit); 111926199Ssklower mp->flags &= ~AVAILABLE; 112026199Ssklower mp->flags |= PANIC1; 112126199Ssklower 112226199Ssklower /* Clear device request word */ 112326199Ssklower 112426199Ssklower mp->shmemp->statblock.sb_drw = 0; 112526199Ssklower 112626199Ssklower panicmap = uballoc(mp->devp->ui_ubanum,(caddr_t)panaddr,sizeof(panaddr),0); 112726199Ssklower NPIO(mp,(paddr_t)NPPSADDR,(paddr_t)((int)panicmap & UBADDRMASK),sizeof(panaddr),B_READ); 112826199Ssklower goto out; 112926199Ssklower break; 113026199Ssklower 113126199Ssklower case NPDUMP: 113226199Ssklower mp->flags |= (DUMPREQ | BOARDREQ); 113326199Ssklower 113426199Ssklower /* Clear device request word */ 113526199Ssklower 113626199Ssklower mp->shmemp->statblock.sb_drw = 0; 113726199Ssklower 113826199Ssklower if(NpState & ICPAVAIL) 113926199Ssklower wakeup((caddr_t)&NpState); 114026199Ssklower break; 114126199Ssklower 114226199Ssklower case NPLOAD: 114326199Ssklower mp->flags |= (LOADREQ | BOARDREQ); 114426199Ssklower 114526199Ssklower /* Clear device request word */ 114626199Ssklower 114726199Ssklower mp->shmemp->statblock.sb_drw = 0; 114826199Ssklower 114926199Ssklower if(NpState & ICPAVAIL) 115026199Ssklower wakeup((caddr_t)&NpState); 115126199Ssklower break; 115226199Ssklower 115326199Ssklower default: 115426199Ssklower printf("Bad Req: %x.\n",mp->shmemp->statblock.sb_drw); 115526199Ssklower goto out; 115626199Ssklower 115726199Ssklower } 115826199Ssklower 115926199Ssklower /* Process the Host Command Queue for this device */ 116026199Ssklower 116126199Ssklower NpProcQueue(mp); 116226199Ssklower 116326199Ssklower out: 116426199Ssklower CLEARINT(mp); /* Clear the interrupt */ 116526199Ssklower 116626199Ssklower if(NpDebug & DEBENTRY) 116726199Ssklower printf("npintr...\n"); 116826199Ssklower 116926199Ssklower return(1); /* Interrupt serviced */ 117026199Ssklower 117126199Ssklower } 117226199Ssklower 117326199Ssklower /* 117426199Ssklower * This routine, called from the interrupt handler, is used to process the 117526199Ssklower * Host Command Queue for the specified device. 117626199Ssklower */ 117726199Ssklower 117826199Ssklower NpProcQueue(mp) 117926199Ssklower struct npmaster *mp; 118026199Ssklower { 118126199Ssklower register struct CmdQue *cqp; 118226199Ssklower register struct CQE *ep; 118326199Ssklower register struct npreq *rp; 118426199Ssklower register int base; 118526199Ssklower 118626199Ssklower if(NpDebug & DEBENTRY) 118726199Ssklower printf("NpProcQueue\n"); 118826199Ssklower 118926199Ssklower cqp = &mp->shmemp->hostcq; /* Command Queue pointer */ 119026199Ssklower 119126199Ssklower if(cqp->scanflag & ON) 119226199Ssklower return; 119326199Ssklower 119426199Ssklower else cqp->scanflag | = ON; 119526199Ssklower 119626199Ssklower base = (int)mp->shmemp; /* Shared memory base address */ 119726199Ssklower 119826199Ssklower while(cqp->scanflag & ON) { 119926199Ssklower 120026199Ssklower while(ep = NpRemCQE(cqp,base)) { 120126199Ssklower 120226199Ssklower rp = ep->cqe_reqid; 120326199Ssklower 120426199Ssklower if(NpDebug & DEBCQE) 120526199Ssklower printf("cqe_sts is %x ep = %x\n",ep->cqe_sts,ep); 120626199Ssklower 120726199Ssklower switch (ep->cqe_sts) { 120826199Ssklower 120926199Ssklower case NPDONE: 121026199Ssklower rp->flags |= REQDONE; /* Normal completion */ 121126199Ssklower break; 121226199Ssklower case NPIFC: /* IFC Request */ 121326199Ssklower rp->flags |= IOIFC; 121426199Ssklower break; 121526199Ssklower case NPPERR: /* Protocol Error */ 121626199Ssklower rp->flags |= (NPPERR | REQDONE); 121726199Ssklower break; 121826199Ssklower case NPMERR: /* Memory allocation */ 121926199Ssklower rp->flags |= (NPMERR | REQDONE); 122026199Ssklower break; 122126199Ssklower default: /* Error on Board */ 122226199Ssklower rp->flags |= (IOERR | REQDONE); 122326199Ssklower break; 122426199Ssklower 122526199Ssklower } 122626199Ssklower 122726199Ssklower if(NpDebug & DEBCQE) { 122826199Ssklower printf("flag is %x reqid = %x\n",rp->flags,ep->cqe_reqid); 122926199Ssklower printf("wakeup in procqueue\n"); 123026199Ssklower } 123126199Ssklower 123226199Ssklower if(rp->intr) { 123326199Ssklower 123426199Ssklower if(NpDebug & DEBINTR) 123526199Ssklower printf("calling usr intr at %x\n", 123626199Ssklower rp->intr); 123726199Ssklower 123826199Ssklower /* Call interrupt routine */ 123926199Ssklower 124026199Ssklower (*rp->intr)(mp,rp); 124126199Ssklower } 124226199Ssklower else { 124326199Ssklower 124426199Ssklower if(NpDebug & DEBINTR) 124526199Ssklower printf("waking up %x\n",rp); 124626199Ssklower 1247*30865Skarels /* if(rp->flags & NPUIO) 124826199Ssklower iodone(&rp->buf); 124926199Ssklower else wakeup((caddr_t) (rp)); /* Awaken */ 125026199Ssklower 1251*30865Skarels wakeup((caddr_t)(rp)); /* Awaken */ 125226199Ssklower if(NpDebug & DEBINTR) 125326199Ssklower printf("AWAKE\n"); 125426199Ssklower } 125526199Ssklower } 125626199Ssklower 125726199Ssklower if(!(cqp->chngflag & ON)) 125826199Ssklower cqp->scanflag &= ~ON; 125926199Ssklower 126026199Ssklower } 126126199Ssklower 126226199Ssklower if(NpDebug & DEBENTRY) 126326199Ssklower printf("NpProcQueue...\n"); 126426199Ssklower } 126526199Ssklower 126626199Ssklower /* 126726199Ssklower * NpIFC - processes an IFC (Internal Fuction Call) request 126826199Ssklower * NOTE: this function must be called from the user context 126926199Ssklower * on all virtual pageing systems 127026199Ssklower * 127126199Ssklower */ 127226199Ssklower NpIFC(mp,rp) 127326199Ssklower register struct npmaster *mp; 127426199Ssklower register struct npreq *rp; 127526199Ssklower { 127626199Ssklower register struct CQE *ep; 127726199Ssklower 127826199Ssklower if(NpDebug & DEBENTRY) 127926199Ssklower printf("NpIFC\n"); 128026199Ssklower 128126199Ssklower ep = rp->element; 128226199Ssklower rp->flags &= ~IOIFC; 128326199Ssklower switch(ep->cqe_func) { 128426199Ssklower 128526199Ssklower case NPUNLOCK: /* Unlock process, free up mapping registers */ 128626199Ssklower 128726199Ssklower if(NpDebug & DEBIFC) 128826199Ssklower printf("NPUNLOCK\n"); 128926199Ssklower 129026199Ssklower if(rp->mapbase) 129126199Ssklower NpUnMapMem(mp,rp); 129226199Ssklower break; 129326199Ssklower 129426199Ssklower case NPLOCK: /* Lock process, get mapping registers */ 129526199Ssklower 129626199Ssklower if(NpDebug & DEBIFC) 129726199Ssklower printf("NPLOCK\n"); 129826199Ssklower NpMapMem(mp,rp,rp->virtmem,rp->bytecnt); 129926199Ssklower ep->cqe_dma[0] = LOWORD(rp->bufaddr); 130026199Ssklower ep->cqe_dma[1] = HIWORD(rp->bufaddr); 130126199Ssklower break; 130226199Ssklower 130326199Ssklower case NPREMAP: 130426199Ssklower 130526199Ssklower if(NpDebug & DEBIFC) 130626199Ssklower printf("NPREMAP\n"); 130726199Ssklower 130826199Ssklower /* Remap user buffer and update buffer offset */ 130926199Ssklower #ifdef USG 131026199Ssklower np_remapmem(rp,rp->virtmem); 131126199Ssklower ep->cqe_dma[0] = LOWORD(rp->bufaddr); 131226199Ssklower ep->cqe_dma[1] = HIWORD(rp->bufaddr); 131326199Ssklower break; 131426199Ssklower #endif 131526199Ssklower 131626199Ssklower default: 131726199Ssklower if(NpDebug & DEBIFC) 131826199Ssklower printf("Bad case %x in IFC\n", ep->cqe_func); 131926199Ssklower 132026199Ssklower rp->flags |= (REQDONE | IOERR); 132126199Ssklower break; 132226199Ssklower } 132326199Ssklower } 132426199Ssklower 132526199Ssklower /* 132626199Ssklower * The following contains various routines for allocating and deallocating 132726199Ssklower * structures used by the NP Driver. Routines are also here for addding 132826199Ssklower * and removing Command Queue Elements from a Command Queue. 132926199Ssklower */ 133026199Ssklower 133126199Ssklower /* 133226199Ssklower * Get a free NP Request structure from the list pointed to by head. Returns 133326199Ssklower * a pointer to a npreq or NULL if none left. 133426199Ssklower */ 133526199Ssklower 133626199Ssklower struct npreq * 133726199Ssklower NpGetReq(head) 133826199Ssklower struct npreq *head; 133926199Ssklower { 134026199Ssklower 134126199Ssklower register struct npreq *p; 134226199Ssklower 134326199Ssklower p = head->free; 134426199Ssklower head->free = p->free; 1345*30865Skarels if (p->flags & REQALOC) 1346*30865Skarels printf("GetReq: Req %x already allocated\n", p); 1347*30865Skarels p->flags &= WANTREQ; 1348*30865Skarels if (p != head) 1349*30865Skarels p->flags |= REQALOC; 135026199Ssklower return(p==head ? (struct npreq *)NULL : p); 135126199Ssklower } 135226199Ssklower 135326199Ssklower /* 135426199Ssklower * Return a NP Request structure to the free list pointed to by head. 135526199Ssklower */ 135626199Ssklower 135726199Ssklower NpFreeReq(head,nprp) 135826199Ssklower register struct npreq *head, *nprp; 135926199Ssklower { 1360*30865Skarels int s; 136126199Ssklower 136226199Ssklower if(NpDebug & DEBREQ) 136326199Ssklower printf("NpFreeReq, head is %x rp is %x\n",head,nprp); 136426199Ssklower 1365*30865Skarels if (nprp == NULL) { 1366*30865Skarels printf("FREEREQ: attempt to free null pointer\n"); 1367*30865Skarels return; 1368*30865Skarels } 1369*30865Skarels if (!(nprp->flags & REQALOC)) { 1370*30865Skarels printf("FREEREQ: attempt to free unallocated request %x\n", 1371*30865Skarels nprp); 1372*30865Skarels return; 1373*30865Skarels } 1374*30865Skarels if (nprp->flags & REQUSE) 1375*30865Skarels printf("FREEREQ: freeing unremoved request %x\n", nprp); 1376*30865Skarels 1377*30865Skarels s = spl5(); 137826199Ssklower nprp->forw = nprp->back = (struct npreq *)NULL; 137926199Ssklower nprp->free = head->free; 138026199Ssklower head->free = nprp; 1381*30865Skarels nprp->flags &= ~REQALOC; 1382*30865Skarels splx(s); 138326199Ssklower 138426199Ssklower /* Wake up any processes waiting for a request structure */ 138526199Ssklower 138626199Ssklower if(head->flags & WANTREQ) { 138726199Ssklower head->flags &= ~WANTREQ; 138826199Ssklower wakeup((caddr_t)head); 138926199Ssklower } 139026199Ssklower 139126199Ssklower if(NpDebug & DEBENTRY) 139226199Ssklower printf("NpFreeReq...\n"); 139326199Ssklower } 139426199Ssklower 139526199Ssklower /* 139626199Ssklower * Add a Command Queue Element onto the specified Command Queue and 139726199Ssklower * update its Add offset. 139826199Ssklower */ 139926199Ssklower 140026199Ssklower NpAddCQE(ep,cqp,mp) 140126199Ssklower struct CQE *ep; 140226199Ssklower struct CmdQue *cqp; 140326199Ssklower struct npmaster *mp; 140426199Ssklower { 140526199Ssklower 140626199Ssklower register unsign16 *temp; 140726199Ssklower register unsign16 cqe_offset; 140826199Ssklower register int base; 140926199Ssklower 141026199Ssklower base = (int)mp->shmemp; /* Shared memory base address */ 141126199Ssklower 141226199Ssklower temp = (unsign16 *)(base + cqp->cq_add); /* Offset to add element */ 141326199Ssklower 141426199Ssklower cqe_offset = (unsign16)((int)ep - base); 141526199Ssklower 141626199Ssklower if(*temp) { /* Should never happen */ 141726199Ssklower 141826199Ssklower printf("No more room on Command Queue!\n"); 141926199Ssklower u.u_error = EIO; 142026199Ssklower return; 142126199Ssklower } 142226199Ssklower else *temp = cqe_offset; /* Enter this request's offset */ 142326199Ssklower 142426199Ssklower cqp->chngflag |= ON; /* Set change flag unconditionally */ 142526199Ssklower 142626199Ssklower /* Update cqe_add where next request is to be added */ 142726199Ssklower 142826199Ssklower cqp->cq_add += sizeof(unsign16); 142926199Ssklower 143026199Ssklower if(cqp->cq_add == cqp->cq_wrap) /* Wrap if necessary */ 143126199Ssklower cqp->cq_add = (unsign16)((int)cqp->cq_cqe - base); 143226199Ssklower 143326199Ssklower /* Interrupt the Board if his scan flag isn't on */ 143426199Ssklower 143526199Ssklower if(!(cqp->scanflag & ON)) 143626199Ssklower 143726199Ssklower INTNI(mp); /* Interrupt the Board */ 143826199Ssklower 143926199Ssklower } 144026199Ssklower 144126199Ssklower /* 144226199Ssklower * The NpRemCQE routine is used to remove the next CQE from the Command Queue 144326199Ssklower * specified by cqp. The common offset of shared memory used by the device 144426199Ssklower * is specified by base. NpRemCQE returns a pointer to the next CQE or 144526199Ssklower * NULL if there are none left. This routine will also update the cqe_rem 144626199Ssklower * offset which specifies where the next element to be removed from the 144726199Ssklower * queue is located. 144826199Ssklower */ 144926199Ssklower 145026199Ssklower struct CQE * 145126199Ssklower NpRemCQE(cqp,base) 145226199Ssklower struct CmdQue *cqp; 145326199Ssklower int base; 145426199Ssklower { 145526199Ssklower 145626199Ssklower register unsign16 *temp; 145726199Ssklower register unsign16 cqe_offset; 145826199Ssklower 145926199Ssklower cqp->chngflag &= ~ON; /* Turn off unconditionally */ 146026199Ssklower 146126199Ssklower /* Get address of element to remove */ 146226199Ssklower 146326199Ssklower temp = (unsign16 *)(base +cqp->cq_rem); 146426199Ssklower 146526199Ssklower if(*temp == NULL) /* If none left, go home */ 146626199Ssklower return((struct CQE *) NULL); 146726199Ssklower 146826199Ssklower else cqe_offset = *temp; /* Offset of CQE to remove */ 146926199Ssklower 147026199Ssklower /* Update the Command Queue's cqe_rem offset */ 147126199Ssklower 147226199Ssklower *temp = NULL; /* Clear out this entry */ 147326199Ssklower 147426199Ssklower cqp->cq_rem += sizeof(unsign16); /* Bump offset */ 147526199Ssklower 147626199Ssklower if(cqp->cq_rem == cqp->cq_wrap) /* Wrap if necessary */ 147726199Ssklower cqp->cq_rem = (unsign16)((int)cqp->cq_cqe - base); 147826199Ssklower 147926199Ssklower temp = (unsign16 *)(base + cqe_offset); /* CQE address */ 148026199Ssklower return((struct CQE *)temp); /* is returned */ 148126199Ssklower } 148226199Ssklower 148326199Ssklower /* 148426199Ssklower * NpAddReq will add the specified npreq structure to the queue controlled 148526199Ssklower * by head. 148626199Ssklower */ 148726199Ssklower 148826199Ssklower NpAddReq(head,rp) 148926199Ssklower register struct npreq *head, *rp; 149026199Ssklower { 1491*30865Skarels int s; 149226199Ssklower 1493*30865Skarels if (NpDebug & (DEBENTRY|DEBREQ)) 149426199Ssklower printf("NpAddReq: %x\n",rp); 149526199Ssklower 1496*30865Skarels if (rp->flags & REQUSE) 1497*30865Skarels printf("ADDREQ: Request %x allready in use\n", rp); 1498*30865Skarels 1499*30865Skarels s = spl7(); 150026199Ssklower rp->forw = head->forw; 150126199Ssklower rp->forw->back = rp; 150226199Ssklower rp->back = head; 150326199Ssklower head->forw = rp; 1504*30865Skarels rp->flags |= REQUSE; 1505*30865Skarels splx(s); 150626199Ssklower 150726199Ssklower if(NpDebug & DEBENTRY) 150826199Ssklower printf("NpAddReq...\n"); 150926199Ssklower } 151026199Ssklower 151126199Ssklower /* 151226199Ssklower * NpRemReq is used to remove a npreq structure from the queue specified by 151326199Ssklower * head. 151426199Ssklower */ 151526199Ssklower 151626199Ssklower NpRemReq(rp) 151726199Ssklower register struct npreq *rp; 151826199Ssklower { 1519*30865Skarels int s; 152026199Ssklower 1521*30865Skarels if (NpDebug & (DEBENTRY|DEBREQ)) 152226199Ssklower printf("NpRemReq: %x\n",rp); 152326199Ssklower 1524*30865Skarels if (rp == NULL) { 1525*30865Skarels printf("REMREQ: null pointer removal requested\n"); 1526*30865Skarels return; 1527*30865Skarels } 1528*30865Skarels if (!(rp->flags & REQUSE)) { 1529*30865Skarels printf("REMREQ: trying to rem unused req %x\n", rp); 1530*30865Skarels return; 1531*30865Skarels } 1532*30865Skarels if (!(rp->flags & REQALOC)) { 1533*30865Skarels printf("REMREQ: trying to rem unallocated req %x\n", rp); 1534*30865Skarels return; 1535*30865Skarels } 1536*30865Skarels 1537*30865Skarels s = spl7(); 153826199Ssklower rp->back->forw = rp->forw; 153926199Ssklower rp->forw->back = rp->back; 1540*30865Skarels rp->flags &= ~REQUSE; 1541*30865Skarels splx(s); 154226199Ssklower 154326199Ssklower if(NpDebug & DEBENTRY) 154426199Ssklower printf("NpRemReq...\n"); 154526199Ssklower } 154626199Ssklower 154726199Ssklower 154826199Ssklower /* 154926199Ssklower * The following routines are used to communicate with the 155026199Ssklower * NI Hardware via the CSR0 commands. These commands are issued during 155126199Ssklower * the hardware initializtion process and may also be used subsequently 155226199Ssklower * by privileged processes who wish to communicate in this way. The 155326199Ssklower * convention for passing data as a Command Block is discussed in detail 155426199Ssklower * in the NI1510 UNIBUS Compatible Ethernet Communications Processor 155526199Ssklower * Hardware Specification. 155626199Ssklower */ 155726199Ssklower 155826199Ssklower NpSendCSR0(iobase,src,bcount) 155926199Ssklower struct NPREG *iobase; 156026199Ssklower register unsign16 *src; 156126199Ssklower int bcount; 156226199Ssklower { 156326199Ssklower register int wcount; 156426199Ssklower int i; 156526199Ssklower int csrflag; 156626199Ssklower unsign16 tmp; 156726199Ssklower 156826199Ssklower if(NpDebug & DEBENTRY) 156926199Ssklower printf("NpSendCSR0\n"); 157026199Ssklower 157126199Ssklower /* Jolt the board into CSR0 command mode if necessary */ 157226199Ssklower 157326199Ssklower if(!(RCSR1(iobase) & NPENB)){ 157426199Ssklower tmp = NPCLEAR; /* MC68000 clr reads before writing */ 157526199Ssklower WCSR0(iobase,tmp); 157626199Ssklower } 157726199Ssklower 157826199Ssklower wcount = (bcount +1) >> 1; /* Convert byte count to word count */ 157926199Ssklower 158026199Ssklower /* Clear timer flag before beginning the timer */ 158126199Ssklower 158226199Ssklower csrflag = NPCLEAR; 158326199Ssklower timeout(NpTimer,&csrflag,DIAGTIME); 158426199Ssklower 158526199Ssklower for(i = 0; (i < wcount) & (csrflag == NPCLEAR); i++) { 158626199Ssklower while(! ((RCSR1(iobase) & NPENB) && (RCSR1(iobase) & NPRDY))) 158726199Ssklower if(csrflag) break; 158826199Ssklower WCSR0(iobase,*src); 158926199Ssklower src++; /* Better do this WCSR is a macro */ 159026199Ssklower } 159126199Ssklower 159226199Ssklower /* Clear the timer entry */ 159326199Ssklower 159426199Ssklower untimeout(NpTimer,&csrflag); 159526199Ssklower 159626199Ssklower /* Error if timer went off */ 159726199Ssklower 159826199Ssklower if(csrflag) 159926199Ssklower return(EIO); 160026199Ssklower 160126199Ssklower if(NpDebug & DEBENTRY) 160226199Ssklower printf("NpSendCSR0...\n"); 160326199Ssklower return(0); 160426199Ssklower } 160526199Ssklower 160626199Ssklower /* 160726199Ssklower * NpSetIntLev sets the UNIBUS interrupt vector to be used by the NP board when 160826199Ssklower * interupting the host. The board is specified by mp. 160926199Ssklower */ 161026199Ssklower 161126199Ssklower NpSetIntLevel(mp,level) 161226199Ssklower struct npmaster *mp; 161326199Ssklower int level; 161426199Ssklower { 161526199Ssklower 161626199Ssklower struct { 161726199Ssklower unsign16 cmd_word; 161826199Ssklower unsign16 int_level; 161926199Ssklower }cmd_block; 162026199Ssklower 162126199Ssklower cmd_block.cmd_word = NPCBI | CBICNT; 162226199Ssklower cmd_block.int_level = level; 162326199Ssklower 162426199Ssklower return(NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block))); 162526199Ssklower } 162626199Ssklower 162726199Ssklower /* 162826199Ssklower * NpSetMemAddr is used to declare the shared memory area address to be used 162926199Ssklower * for communication between the driver and the device. This address is used 163026199Ssklower * to access data structures by acting as a base from which defined offsets 163126199Ssklower * locate data. The board is specified by mp. 163226199Ssklower */ 163326199Ssklower 163426199Ssklower NpSetMemAddr(mp,addr) 163526199Ssklower struct npmaster *mp; 163626199Ssklower caddr_t addr; 163726199Ssklower { 163826199Ssklower 163926199Ssklower caddr_t shmaddr; 164026199Ssklower int error; 164126199Ssklower 164226199Ssklower struct { 164326199Ssklower unsign16 cmd_word; 164426199Ssklower unsign16 hi_addr; 164526199Ssklower unsign16 lo_addr; 164626199Ssklower } cmd_block; 164726199Ssklower 164826199Ssklower if(NpDebug & DEBENTRY) 164926199Ssklower printf("NpSetMemAddr\n"); 165026199Ssklower 165126199Ssklower shmaddr = addr; 165226199Ssklower 165326199Ssklower if(NpDebug & DEBMEM) 165426199Ssklower printf("NpSetMemAddr, addr is %x shmaddr is %x.\n",addr,shmaddr); 165526199Ssklower 165626199Ssklower cmd_block.cmd_word = NPCMD | CMDCNT; 165726199Ssklower cmd_block.hi_addr = HIWORD(shmaddr); 165826199Ssklower cmd_block.lo_addr = LOWORD(shmaddr); 165926199Ssklower 166026199Ssklower error = NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block)); 166126199Ssklower 166226199Ssklower if(NpDebug & DEBENTRY) 166326199Ssklower printf("NpSetMemAddr...\n"); 166426199Ssklower 166526199Ssklower return(error); 166626199Ssklower } 166726199Ssklower 166826199Ssklower 166926199Ssklower /* 167026199Ssklower * NpSetXeqAddr specifies the address at which the board should begin 167126199Ssklower * execution of its on-board software. It also indicates the shared memory 167226199Ssklower * address to be used. The board is specified by mp. 167326199Ssklower */ 167426199Ssklower 167526199Ssklower NpSetXeqAddr(mp,addr) 167626199Ssklower struct npmaster *mp; 167726199Ssklower caddr_t addr; 167826199Ssklower { 167926199Ssklower caddr_t shmaddr; 168026199Ssklower int error; 168126199Ssklower 168226199Ssklower struct { 168326199Ssklower unsign16 cmd_word; 168426199Ssklower unsign16 hi_addr; 168526199Ssklower unsign16 lo_addr; 168626199Ssklower unsign16 mhi_addr; 168726199Ssklower unsign16 mlo_addr; 168826199Ssklower } cmd_block; 168926199Ssklower 169026199Ssklower if(NpDebug & DEBENTRY) 169126199Ssklower printf("NpSetXeqAddr\n"); 169226199Ssklower 169326199Ssklower shmaddr = (caddr_t)((int)mp->iomapbase & UBADDRMASK); 169426199Ssklower 169526199Ssklower cmd_block.cmd_word = NPBGN | NPCMD | NPLST | (BGNCNT + CMDCNT); 169626199Ssklower cmd_block.hi_addr = HIWORD(addr); 169726199Ssklower cmd_block.lo_addr = LOWORD(addr); 169826199Ssklower cmd_block.mhi_addr = HIWORD(shmaddr); 169926199Ssklower cmd_block.mlo_addr = LOWORD(shmaddr); 170026199Ssklower 170126199Ssklower if(NpDebug & DEBINIT) { 170226199Ssklower printf("NpSetXeqAdddr: hi: %x lo: %x\n",HIWORD(addr), LOWORD(addr)); 170326199Ssklower printf("NpSetXeqAdddr: mhi: %x mlo: %x\n",HIWORD(shmaddr),LOWORD(shmaddr)); 170426199Ssklower } 170526199Ssklower 170626199Ssklower error = NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block)); 170726199Ssklower 170826199Ssklower if(NpDebug & DEBENTRY) 170926199Ssklower printf("NpSetXeqAddr...\n"); 171026199Ssklower 171126199Ssklower return(error); 171226199Ssklower } 171326199Ssklower 171426199Ssklower /* 171526199Ssklower * NPIO issues a CSR0 load or dump request to the I-Board after packaging a 171626199Ssklower * CSR0 Command Block. 171726199Ssklower */ 171826199Ssklower 171926199Ssklower NPIO(mp,src,dest,count,dir) 172026199Ssklower struct npmaster *mp; 172126199Ssklower paddr_t dest; 172226199Ssklower paddr_t src; 172326199Ssklower unsign16 count; 172426199Ssklower int dir; /* Direction READ/WRITE */ 172526199Ssklower { 172626199Ssklower 172726199Ssklower int error; 172826199Ssklower 172926199Ssklower struct { 173026199Ssklower unsign16 cmd_word; /* Command Word */ 173126199Ssklower unsign16 shi_addr; /* High word of Source Address */ 173226199Ssklower unsign16 slo_addr; /* Low word of Source Address */ 173326199Ssklower unsign16 dhi_addr; /* High word of Destination Address */ 173426199Ssklower unsign16 dlo_addr; /* Low word of Destination Address */ 173526199Ssklower unsign16 count; /* Byte count */ 173626199Ssklower unsign16 intlevel; /* Interrupt level to host */ 173726199Ssklower } cmd_block; 173826199Ssklower 173926199Ssklower if(NpDebug & DEBENTRY) 174026199Ssklower printf("NPIO\n"); 174126199Ssklower if(NpDebug & DEBMAINT) { 174226199Ssklower printf("I/O src addr = %x, dest addr = %x \n",src,dest); 174326199Ssklower printf("I/O count = %d \n",count); 174426199Ssklower } 174526199Ssklower 1746*30865Skarels cmd_block.cmd_word = NPCBI | (CBICNT + IOCNT); 174726199Ssklower cmd_block.intlevel = mp->vector; 174826199Ssklower cmd_block.shi_addr = HIWORD(src); 174926199Ssklower cmd_block.slo_addr = LOWORD(src); 175026199Ssklower cmd_block.dhi_addr = HIWORD(dest); 175126199Ssklower cmd_block.dlo_addr = LOWORD(dest); 175226199Ssklower cmd_block.count = count; 1753*30865Skarels if ((mp->flags & LSTCMD) == 0) 1754*30865Skarels cmd_block.cmd_word |= NPLST; 175526199Ssklower if(dir == B_READ) 175626199Ssklower cmd_block.cmd_word |= NPDMP; 175726199Ssklower else 175826199Ssklower cmd_block.cmd_word |= NPLD; 175926199Ssklower 176026199Ssklower 176126199Ssklower if(NpDebug & DEBIO) { 176226199Ssklower printf("cmd: %x int: %o shi: %x slo: %x dhi: %x dlo: %x cnt: %x\n", 176326199Ssklower cmd_block.cmd_word,cmd_block.intlevel,cmd_block.shi_addr,cmd_block.slo_addr, 176426199Ssklower cmd_block.dhi_addr,cmd_block.dlo_addr,cmd_block.count); 176526199Ssklower } 176626199Ssklower 176726199Ssklower mp->flags |= CSRPEND; /* CSR0 command pending */ 176826199Ssklower 176926199Ssklower error = NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block)); 177026199Ssklower if(NpDebug & DEBENTRY) 177126199Ssklower printf("NPIO...\n"); 177226199Ssklower 177326199Ssklower return(error); 177426199Ssklower } 177526199Ssklower 177626199Ssklower 177726199Ssklower /* 177826199Ssklower * NpKill will terminate all outstanding requests for the specified board. 177926199Ssklower */ 178026199Ssklower 178126199Ssklower NpKill(mp,curr_rp) 178226199Ssklower struct npmaster *mp; 178326199Ssklower struct npreq *curr_rp; 178426199Ssklower { 178526199Ssklower struct npreq *rp; 178626199Ssklower int s; 178726199Ssklower 178826199Ssklower if(NpDebug & DEBENTRY) 178926199Ssklower printf("NpKill\n"); 179026199Ssklower 179126199Ssklower mp->reqtab->reqcnt = 0; /* Init request count */ 179226199Ssklower 179326199Ssklower s = spl4(); /* Disable interrupts */ 179426199Ssklower 179526199Ssklower /* Mark each active request as having an error and wake him up */ 179626199Ssklower 179726199Ssklower for(rp = mp->reqtab->forw;rp != mp->reqtab;rp = rp->forw) { 179826199Ssklower 179926199Ssklower if(rp == curr_rp) continue; 180026199Ssklower 180126199Ssklower rp->flags |= (IOABORT | REQDONE); 180226199Ssklower mp->reqtab->reqcnt++; 1803*30865Skarels /* if(rp->flags & NPUIO) 180426199Ssklower iodone(&rp->buf); 1805*30865Skarels else */ 1806*30865Skarels wakeup((caddr_t)rp); 180726199Ssklower } 180826199Ssklower 180926199Ssklower if(NpDebug & DEBMAINT) 181026199Ssklower printf("NpKill, req count is %d\n",mp->reqtab->reqcnt); 181126199Ssklower 181226199Ssklower splx(s); 181326199Ssklower 181426199Ssklower if(NpDebug & DEBENTRY) 181526199Ssklower printf("NpKill...\n"); 181626199Ssklower 181726199Ssklower return(0); 181826199Ssklower 181926199Ssklower } 182026199Ssklower 182126199Ssklower /* Hardware and Software Initializations for the specified unit */ 182226199Ssklower 182326199Ssklower NpReset(mp,rp) 182426199Ssklower register struct npmaster *mp; 182526199Ssklower struct npreq *rp; 182626199Ssklower { 182726199Ssklower int error; 182826199Ssklower 182926199Ssklower if(NpDebug & DEBENTRY) 183026199Ssklower printf("NpReset!\n"); 183126199Ssklower 183226199Ssklower /* Mark board as being reset and make unavailable */ 183326199Ssklower 183426199Ssklower mp->flags = BRDRESET; 183526199Ssklower 183626199Ssklower /* Abort outstanding requests for this board */ 183726199Ssklower 183826199Ssklower mp->reqtab->reqcnt = 0; /* Init request count */ 183926199Ssklower 184026199Ssklower /* Wakeup Poller if available and wait until he's gone */ 184126199Ssklower 184226199Ssklower if(NpState & ICPAVAIL) { 184326199Ssklower 184426199Ssklower mp->flags |= BOARDREQ; 184526199Ssklower mp->reqtab->reqcnt++; 184626199Ssklower 184726199Ssklower if(NpDebug & DEBMAINT) 184826199Ssklower printf("Waking ICP in reset!\n"); 184926199Ssklower 185026199Ssklower wakeup((caddr_t)&NpState); 185126199Ssklower 185226199Ssklower while(mp->reqtab->reqcnt) 185326199Ssklower sleep((caddr_t)(&mp->reqtab),PZERO +1); 185426199Ssklower 185526199Ssklower if(NpDebug & DEBMAINT) 185626199Ssklower printf("Reset:awoken by ICP senior!\n"); 185726199Ssklower 185826199Ssklower } 185926199Ssklower 186026199Ssklower /* Abort outstanding requests and wait till they're gone */ 186126199Ssklower 186226199Ssklower NpKill(mp,rp); 186326199Ssklower 186426199Ssklower while(mp->reqtab->reqcnt) { 186526199Ssklower 186626199Ssklower if(NpDebug & DEBMAINT) { 186726199Ssklower printf("Sleeping in NpReset on reqtab!\n"); 186826199Ssklower printf("Reqcnt is %d.\n",mp->reqtab->reqcnt); 186926199Ssklower } 187026199Ssklower 187126199Ssklower sleep((caddr_t)(&mp->reqtab),PZERO +1); 187226199Ssklower 187326199Ssklower } 187426199Ssklower 187526199Ssklower /* Free up I/O Map registers if any allocated */ 187626199Ssklower 187726199Ssklower if(mp->iomapbase) { 187826199Ssklower 187926199Ssklower if(NpDebug & DEBMEM) 188026199Ssklower printf("freeing shared memory map.\n"); 188126199Ssklower 188226199Ssklower ubarelse(mp->devp->ui_ubanum,&mp->iomapbase); 188326199Ssklower mp->iomapbase = 0; 188426199Ssklower } 188526199Ssklower 188626199Ssklower /* Initialize S/W data structures in NP Driver */ 188726199Ssklower 188826199Ssklower NpSWinit(mp->unit); /* Software initialization */ 188926199Ssklower 189026199Ssklower /* Hardware initialization of the board */ 189126199Ssklower 189226199Ssklower error = NpHWinit(mp->unit); /* Hardware initialization */ 189326199Ssklower 189426199Ssklower mp->flags &= ~BRDRESET; /* Initialization complete */ 189526199Ssklower 189626199Ssklower /* Initialize Pseudo-Drivers */ 189726199Ssklower 189826199Ssklower if (IxReset) 189926199Ssklower (*IxReset)(mp->unit, mp->devp->ui_ubanum, rp); 190026199Ssklower 190126199Ssklower /* Clear Poller's State Flag */ 190226199Ssklower 190326199Ssklower NpState = NPCLEAR; 190426199Ssklower 190526199Ssklower if(NpDebug & DEBENTRY) 190626199Ssklower printf("NpReset...\n"); 190726199Ssklower 190826199Ssklower return(error); 190926199Ssklower } 191026199Ssklower 191126199Ssklower /* 191226199Ssklower * General purpose timeout function which sets the flag passed to it 191326199Ssklower * as argument. 191426199Ssklower */ 191526199Ssklower 191626199Ssklower NpTimer(flagp) 191726199Ssklower int *flagp; 191826199Ssklower { 191926199Ssklower *flagp = NPSET; 192026199Ssklower } 192126199Ssklower 192226199Ssklower NpStats() 192326199Ssklower { 192426199Ssklower if(NpDebug & DEBENTRY) 192526199Ssklower printf("npstats\n"); 192626199Ssklower return(0); 192726199Ssklower } 192826199Ssklower 192926199Ssklower /* 193026199Ssklower * NpCloseConn is called to issue a close connection command to the I-Board. 193126199Ssklower */ 193226199Ssklower 193326199Ssklower NpCloseConn(mp,protocol) 193426199Ssklower struct npmaster *mp; 193526199Ssklower unsign16 protocol; 193626199Ssklower { 193726199Ssklower 193826199Ssklower register struct npreq *rp; 193926199Ssklower register struct CQE *ep; 194026199Ssklower int pri; 194126199Ssklower 194226199Ssklower if(NpDebug & DEBENTRY) 194326199Ssklower printf("NpCloseConn\n"); 194426199Ssklower 194526199Ssklower /* 194626199Ssklower * Don't issue the Close Connection command if the Board 194726199Ssklower * isn't up. 194826199Ssklower */ 194926199Ssklower 195026199Ssklower if(!((mp->shmemp->statblock.sb_dpm) & PROTOMASK(protocol))) { 195126199Ssklower return; 195226199Ssklower } 195326199Ssklower 195426199Ssklower /* Get a Request structure */ 195526199Ssklower 195626199Ssklower while((rp = NpGetReq(mp->reqtab)) == NULL) { 195726199Ssklower mp->reqtab->flags |= WANTREQ; 195826199Ssklower sleep((caddr_t)(mp->reqtab),PZERO -1); 195926199Ssklower } 196026199Ssklower 196126199Ssklower rp->intr = (int (*)())0; /* Do not call interrupt routine */ 196226199Ssklower rp->mapbase = 0; /* Clear mapping information */ 196326199Ssklower 196426199Ssklower ep = rp->element; /* Handy pointer */ 196526199Ssklower 196626199Ssklower /* Fill in CQE */ 196726199Ssklower 196826199Ssklower ep->cqe_wind = 0; /* Entire buffer mapped */ 196926199Ssklower ep->cqe_nbuf = 1; /* Must be 1, no buffer chaining */ 197026199Ssklower ep->cqe_char = 0; /* Set to 0 for now */ 197126199Ssklower 197226199Ssklower ep->cqe_func = NPSTOP; /* OS_STP to I-Board */ 197326199Ssklower 197426199Ssklower ep->cqe_prot = protocol; /* Protocol of this connection */ 197526199Ssklower ep->cqe_lenrpb = 0; /* Parameter block length */ 197626199Ssklower 197726199Ssklower ep->cqe_ust0 = ep->cqe_ust1 = NPCLEAR; /* Clear status flags */ 197826199Ssklower 197926199Ssklower ep->cqe_famid = (unsign32)u.u_procp->p_pid; /* Process ID */ 198026199Ssklower 198126199Ssklower NpAddReq(mp->reqtab,rp); /* Queue onto active list */ 198226199Ssklower 198326199Ssklower pri = spl4(); /* Mask our interrupts */ 198426199Ssklower 198526199Ssklower NpAddCQE(ep,&mp->shmemp->devcq,mp); /* Add CQE to device's queue */ 198626199Ssklower 198726199Ssklower /* Wait for command to complete */ 198826199Ssklower 198926199Ssklower while(!(rp->flags & REQDONE)) 199026199Ssklower sleep((caddr_t)rp,PZERO - 1); 199126199Ssklower 199226199Ssklower splx(pri); 199326199Ssklower 199426199Ssklower NpRemReq(rp); /* Remove request from active list */ 199526199Ssklower 199626199Ssklower NpFreeReq(mp->reqtab,rp); /* Deallocate request structure */ 199726199Ssklower 199826199Ssklower if(NpDebug & DEBENTRY) 199926199Ssklower printf("NpCloseConn...\n"); 200026199Ssklower 200126199Ssklower } 200226199Ssklower 200326199Ssklower /* 200426199Ssklower * This function allows the protocol to be changed for a given connection. 200526199Ssklower * It returns 0 for success, error code otherwise. 200626199Ssklower */ 200726199Ssklower 200826199Ssklower NpProtChange(protocol,unit) 200926199Ssklower register unsign16 protocol; 201026199Ssklower register int unit; 201126199Ssklower { 201226199Ssklower 201326199Ssklower register struct npmaster *mp; 201426199Ssklower 201526199Ssklower /* Privileged users only for Maintenance Protocol */ 201626199Ssklower 201726199Ssklower if((protocol == NPMAINT) && (u.u_uid != 0)) 201826199Ssklower return(EPERM); 201926199Ssklower 202026199Ssklower if(NpDebug & DEBMAINT) 202126199Ssklower printf("NpProtChange = %x\n",protocol); 202226199Ssklower 202326199Ssklower if(protocol != NPMAINT) { 202426199Ssklower 202526199Ssklower /* Make sure the I-Board supports the protocol */ 202626199Ssklower 202726199Ssklower mp = &npmasters[unit]; 202826199Ssklower 202926199Ssklower if(!((mp->shmemp->statblock.sb_dpm) & PROTOMASK(protocol))) 203026199Ssklower return(ENXIO); 203126199Ssklower } 203226199Ssklower 203326199Ssklower return(0); 203426199Ssklower } 203526199Ssklower 203626199Ssklower /* 203726199Ssklower * This function allows for the changing of the unit for a given connection. 203826199Ssklower */ 203926199Ssklower 204026199Ssklower struct npmaster * 204126199Ssklower NpBoardChange(protocol,unit) 204226199Ssklower register unsign16 protocol; 204326199Ssklower register int unit; /* Unit number */ 204426199Ssklower { 204526199Ssklower register struct npmaster *mp; 204626199Ssklower 204726199Ssklower 204826199Ssklower if(unit > NNP) 204926199Ssklower return((struct npmaster *)0); 205026199Ssklower 205126199Ssklower if(protocol != NPMAINT) { 205226199Ssklower 205326199Ssklower /* 205426199Ssklower * Loop through the master structures finding a board which 205526199Ssklower * supports the requested protocol. 205626199Ssklower */ 205726199Ssklower 205826199Ssklower for(mp = npmasters; mp ; mp = mp->next) { 205926199Ssklower 206026199Ssklower if(mp->flags & BADBOARD) 206126199Ssklower continue; 206226199Ssklower 206326199Ssklower if(((mp->shmemp->statblock.sb_dpm) & PROTOMASK(protocol))) 206426199Ssklower return(mp); 206526199Ssklower } 206626199Ssklower return((struct npmaster *)0); 206726199Ssklower } 206826199Ssklower return(&npmasters[unit]); 206926199Ssklower } 207026199Ssklower 207126199Ssklower /* 207226199Ssklower * NpMapMem - maps the user's memory updating the fields in the npreq 207326199Ssklower * structure and returning the mapped address in rp->buffaddr. 207426199Ssklower */ 207526199Ssklower NpMapMem(mp,rp,addr,count) 207626199Ssklower register struct npmaster *mp; 207726199Ssklower register struct npreq *rp; 207826199Ssklower caddr_t addr; 207926199Ssklower int count; 208026199Ssklower { 208126199Ssklower 208226199Ssklower if(NpDebug & DEBENTRY) 208326199Ssklower printf("NpMapMem\n"); 208426199Ssklower if(NpDebug & DEBIO) 208526199Ssklower printf("mp %x rp %x addr %x count %x\n",mp,rp,addr,count); 208626199Ssklower 208726199Ssklower rp->virtmem = addr; 208826199Ssklower rp->bytecnt = count; 208926199Ssklower 209026199Ssklower rp->buf.b_un.b_addr = addr; 209126199Ssklower rp->buf.b_flags = B_PHYS | B_BUSY; 209226199Ssklower rp->buf.b_bcount = count; 209326199Ssklower rp->buf.b_proc = rp->procp; 209426199Ssklower 209526199Ssklower rp->procp->p_flag |= SPHYSIO; 2096*30865Skarels if(NpDebug & DEBENTRY) 2097*30865Skarels printf("vslock\n"); 209826199Ssklower vslock(addr,count); 2099*30865Skarels if(NpDebug & DEBENTRY) 2100*30865Skarels printf("vslock...\n"); 210126199Ssklower 210226199Ssklower rp->mapbase = ubasetup(mp->devp->ui_ubanum,&rp->buf,0); 210326199Ssklower 210426199Ssklower rp->bufaddr = (caddr_t)(rp->mapbase & UBADDRMASK); 210526199Ssklower 210626199Ssklower if(NpDebug & DEBENTRY) 210726199Ssklower printf("NpMapMem...\n"); 210826199Ssklower } 210926199Ssklower 211026199Ssklower /* 211126199Ssklower * Unmap the user's memory and free up mapping registers 211226199Ssklower */ 211326199Ssklower 211426199Ssklower NpUnMapMem(mp,rp) 211526199Ssklower struct npmaster *mp; 211626199Ssklower struct npreq *rp; 211726199Ssklower { 211826199Ssklower if(NpDebug & DEBENTRY) 211926199Ssklower printf("NpUnMapMem\n"); 212026199Ssklower 212126199Ssklower ubarelse(mp->devp->ui_ubanum,&rp->mapbase); 212226199Ssklower rp->mapbase = 0; 212326199Ssklower vsunlock(rp->virtmem,rp->bytecnt,B_READ); 212426199Ssklower rp->procp->p_flag &= ~SPHYSIO; 212526199Ssklower 212626199Ssklower if(NpDebug & DEBENTRY) 212726199Ssklower printf("NpUnMapMem...\n"); 212826199Ssklower } 212926199Ssklower 213026199Ssklower npprobe(reg, ui) 213126199Ssklower caddr_t reg; 213226199Ssklower struct uba_device *ui; 213326199Ssklower { 213426199Ssklower register int br,cvec; 213526199Ssklower u_short csraddr; 213626199Ssklower int i; 213726199Ssklower 213826199Ssklower #ifdef lint 213926199Ssklower br = 0; cvec = br; br = cvec; 214026199Ssklower #endif 214126199Ssklower 214226199Ssklower if(NpDebug & DEBINIT) 214326199Ssklower printf("In npprobe, regaddr is %x!\n",reg); 214426199Ssklower 214526199Ssklower cvec = (uba_hd[numuba].uh_lastiv -= 4); 214626199Ssklower 2147*30865Skarels #ifdef OLDBSD 214826199Ssklower /* Find unit number from npstd[] by matching the csr address */ 214926199Ssklower 215026199Ssklower csraddr = (u_short)((int)reg & 0x0FFFF); 215126199Ssklower 215226199Ssklower for(i = 0; i < NNP; i++) { 215326199Ssklower 215426199Ssklower if(csraddr == npstd[i]) { 215526199Ssklower npvectors[i] = cvec; 215626199Ssklower break; 215726199Ssklower } 215826199Ssklower } 215926199Ssklower if(i == NNP) 216026199Ssklower printf("Couldn't find device in npstd[]!\n"); 2161*30865Skarels 216226199Ssklower #else 216326199Ssklower npvectors[ui->ui_unit] = cvec; 216426199Ssklower #endif 216526199Ssklower br = 0x15; 216626199Ssklower 216726199Ssklower if(NpDebug & DEBINIT) 216826199Ssklower printf("npprobe...\n"); 216926199Ssklower 217026199Ssklower return(sizeof(struct NPREG)); /* CSR Registers */ 217126199Ssklower 217226199Ssklower } 217326199Ssklower 217426199Ssklower npattach(ui) 217526199Ssklower register struct uba_device *ui; 217626199Ssklower { 217726199Ssklower 217826199Ssklower if(NpDebug & DEBINIT) 217926199Ssklower printf("In npattach, ui is %x.\n",ui); 218026199Ssklower 218126199Ssklower npinit(ui->ui_unit); 218226199Ssklower if (IxAttach) 218326199Ssklower (*IxAttach)(ui); 218426199Ssklower 218526199Ssklower if(NpDebug & DEBINIT) 218626199Ssklower printf("npattach...\n"); 218726199Ssklower } 218826199Ssklower 2189*30865Skarels 2190*30865Skarels NpMem(mp, rp, uaddr) 2191*30865Skarels struct npmaster *mp; 2192*30865Skarels struct npreq *rp; 2193*30865Skarels unsigned long uaddr; 2194*30865Skarels { 2195*30865Skarels struct np_mem mem; 2196*30865Skarels register int error = 0; 2197*30865Skarels 2198*30865Skarels if(NpDebug & DEBENTRY) 2199*30865Skarels printf("npmem\n"); 2200*30865Skarels 2201*30865Skarels if (error = copyin(uaddr, &mem, sizeof(mem))) 2202*30865Skarels return (error); 2203*30865Skarels 2204*30865Skarels if (mem.mem_type == NP_SET) { 2205*30865Skarels if (np_mapreq[mp->unit] != (struct npreq *)NPCLEAR) 2206*30865Skarels error = EBUSY; 2207*30865Skarels else { 2208*30865Skarels error = NpMapMem(mp, rp, mem.mem_addr, mem.mem_count); 2209*30865Skarels if (error != 0) { 2210*30865Skarels np_mapreq[mp->unit] = rp; 2211*30865Skarels mem.mem_addr = rp->bufaddr; 2212*30865Skarels } 2213*30865Skarels } 2214*30865Skarels } else if (mem.mem_type == NP_USET) { 2215*30865Skarels error = NpUnMapMem(mp, np_mapreq[mp->unit]); 2216*30865Skarels NpFreeReq(mp->reqtab, rp); 2217*30865Skarels NpFreeReq(mp->reqtab, np_mapreq[mp->unit]); 2218*30865Skarels np_mapreq[mp->unit] = (struct npreq *)NPCLEAR; 2219*30865Skarels } else 2220*30865Skarels error = EIO; 2221*30865Skarels 2222*30865Skarels if (error != 0) 2223*30865Skarels error = copyout(&mem, uaddr, sizeof(mem)); 2224*30865Skarels 2225*30865Skarels if(NpDebug & DEBENTRY) 2226*30865Skarels printf("npmem...\n"); 2227*30865Skarels return (error); 2228*30865Skarels } 222926199Ssklower #endif 2230