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*30913Skarels * @(#)np.c 7.3 (Berkeley) 04/16/87 730865Skarels * 830865Skarels * From: 930865Skarels * np.c version 1.5 1030865Skarels * 1130865Skarels * This version retrieved: 8/18/86 @ 18:58:54 1230865Skarels * This delta created: 8/18/86 @ 18:19:24 1330865Skarels * 1430865Skarels * static char *SCCSID = "@(#)np.c 1.5"; 1530865Skarels * 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 3230865Skarels /* 3330865Skarels * Modification History: 3430865Skarels * 4/9/86 DDW Removed pseudo-driver initialization flag resets from NpReset 3530865Skarels * 5/28/86 CJM Changed iodone() to wakeup() in NpProcQueue(). 3630865Skarels * 3730865Skarels */ 3826199Ssklower 3926199Ssklower /* 4026199Ssklower * Include Files 4126199Ssklower */ 4226199Ssklower 4326199Ssklower #include "np.h" 4426199Ssklower #if NNP > 0 4530865Skarels #include "../h/param.h" 4630865Skarels #include "../h/buf.h" 4730865Skarels #include "../vaxuba/ubavar.h" 4830865Skarels #include "../h/signal.h" 4930865Skarels #include "../h/systm.h" 5030865Skarels #include "../h/dir.h" 5130865Skarels #include "../h/user.h" 5230865Skarels #include "../h/proc.h" 5330865Skarels #include "../h/uio.h" 5430865Skarels #include "../h/errno.h" 5526199Ssklower 5626199Ssklower #include "../vaxuba/npreg.h" 5726199Ssklower 5830865Skarels #define b_uio b_forw 5930865Skarels #define b_rp av_back 6026199Ssklower /* 6126199Ssklower * Global variables for pseudo-drivers. 6226199Ssklower */ 6326199Ssklower 6430865Skarels int WnInitFlag = 0; 6530865Skarels int IsInitFlag = 0; 6630865Skarels int (*IxAttach)(); 6730865Skarels 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 10630865Skarels /* Require for diagnostic packages */ 10730865Skarels 10830865Skarels typedef struct npreq *reqptr; 10930865Skarels reqptr np_mapreq[NNP]; 11030865Skarels 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]; 13430865Skarels 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; 42330865Skarels case NPSETLAST: 42430865Skarels if (usrarg) 42530865Skarels mp->flags &= ~LSTCMD; 42630865Skarels else 42730865Skarels mp->flags |= LSTCMD; 42830865Skarels break; 42930865Skarels case NPCLRICNT: 43030865Skarels np_icount[unit] = NPCLEAR; 43130865Skarels break; 43230865Skarels case NPGETICNT: 43330865Skarels usrarg = np_icount[unit]; 43430865Skarels error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); 43530865Skarels break; 43630865Skarels case NPGETIVEC: 43730865Skarels usrarg = mp->vector; 43830865Skarels error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); 43930865Skarels break; 44030865Skarels case NPMAPMEM: 44130865Skarels error = NpMem(mp, rp, *addr); 44230865Skarels break; 44326199Ssklower default: 44426199Ssklower printf("Bad Maintenance command: %d!\n",cmd); 44526199Ssklower error = EIO; 44626199Ssklower break; 44726199Ssklower } 44830865Skarels 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 46430865Skarels 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 } 47730865Skarels if((rp = (struct npreq *)(bp->b_rp)) == (struct npreq *)0) { 47826199Ssklower bp->b_flags = B_ERROR; 47926199Ssklower iodone(bp); 48026199Ssklower return; 48126199Ssklower } 48230865Skarels if ((uio = (struct uio *)bp->b_uio) == (struct uio *)0) { 48330865Skarels bp->b_flags = B_ERROR; 48430865Skarels iodone(bp); 48530865Skarels return; 48630865Skarels } 48726199Ssklower np_tab[mp->unit].b_active = 1; 48826199Ssklower 48926199Ssklower if(NpDebug & DEBIO) 49030865Skarels printf("NP IO src %x dst = %x cnt = %x\n", bp->b_un.b_addr, 49130865Skarels 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) 49630865Skarels error = NPIO(mp, (paddr_t)uio->uio_offset, (paddr_t)rp->bufaddr, 49730865Skarels bp->b_bcount, (bp->b_flags & B_READ)); 49826199Ssklower else 49930865Skarels error = NPIO(mp, (paddr_t)rp->bufaddr, (paddr_t)uio->uio_offset, 50030865Skarels 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 /* 51830865Skarels * 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", 53430865Skarels bp->b_flags, bp->b_bcount, bp->b_un.b_addr, bp->b_un.b_addr, 53530865Skarels 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]; 56330865Skarels 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 { 63330865Skarels struct buf *bp; 63430865Skarels bp = &npcnxtab[NPUNIT(dev)][NPCONN(dev)].np_rbuf; 63526199Ssklower 63626199Ssklower if(NpDebug & DEBENTRY) 63726199Ssklower printf("in npread\n"); 63826199Ssklower 63930865Skarels bp->b_uio = (struct buf *)uio; 64030865Skarels 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 65730865Skarels bp->b_uio = (struct buf *)uio; 65826199Ssklower return(physio(npstrategy,bp,dev,B_WRITE ,nptrim,uio)); 65926199Ssklower } 66030865Skarels 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 67430865Skarels if(NpDebug & DEBENTRY) 67530865Skarels 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]; 68330865Skarels 68430865Skarels /* Get a Request structure */ 68530865Skarels 68630865Skarels while((rp = NpGetReq(mp->reqtab)) == NULL) { 68730865Skarels mp->reqtab->flags |= WANTREQ; 68830865Skarels sleep((caddr_t)(mp->reqtab),PZERO -1); 68930865Skarels } 69030865Skarels 69130865Skarels NpReset(mp,rp); 69226199Ssklower } 69330865Skarels if(NpDebug & DEBENTRY) 69430865Skarels printf("npreset(ubareset)...\n"); 69526199Ssklower } 69626199Ssklower 69730865Skarels 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 79430865Skarels np_icount[unit] = NPCLEAR; 79530865Skarels np_mapreq[unit] = (struct npreq *) NPCLEAR; 79630865Skarels 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; 91830865Skarels 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"); 93230865Skarels 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]; 105030865Skarels np_icount[unit]++; 105126199Ssklower 105226199Ssklower if(NpDebug & DEBINTR) 105330865Skarels printf("npintr mp->flags = %x interupt count = %x\n", 105430865Skarels 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; 1185*30913Skarels int s; 118626199Ssklower 118726199Ssklower if(NpDebug & DEBENTRY) 118826199Ssklower printf("NpProcQueue\n"); 118926199Ssklower 119026199Ssklower cqp = &mp->shmemp->hostcq; /* Command Queue pointer */ 119126199Ssklower 1192*30913Skarels s = spl5(); 1193*30913Skarels if(mp->flags & SCANNING) { 1194*30913Skarels splx(s); 119526199Ssklower return; 1196*30913Skarels } 1197*30913Skarels mp->flags |= SCANNING; 1198*30913Skarels splx(s); 119926199Ssklower 1200*30913Skarels cqp->scanflag | = ON; 120126199Ssklower 120226199Ssklower base = (int)mp->shmemp; /* Shared memory base address */ 120326199Ssklower 1204*30913Skarels while(1) { 120526199Ssklower 1206*30913Skarels cqp->scanflag |= ON; 1207*30913Skarels cqp->chngflag &= ~ON; 120826199Ssklower while(ep = NpRemCQE(cqp,base)) { 120926199Ssklower 121026199Ssklower rp = ep->cqe_reqid; 121126199Ssklower 121226199Ssklower if(NpDebug & DEBCQE) 121326199Ssklower printf("cqe_sts is %x ep = %x\n",ep->cqe_sts,ep); 121426199Ssklower 121526199Ssklower switch (ep->cqe_sts) { 121626199Ssklower 121726199Ssklower case NPDONE: 121826199Ssklower rp->flags |= REQDONE; /* Normal completion */ 121926199Ssklower break; 122026199Ssklower case NPIFC: /* IFC Request */ 122126199Ssklower rp->flags |= IOIFC; 122226199Ssklower break; 122326199Ssklower case NPPERR: /* Protocol Error */ 122426199Ssklower rp->flags |= (NPPERR | REQDONE); 122526199Ssklower break; 122626199Ssklower case NPMERR: /* Memory allocation */ 122726199Ssklower rp->flags |= (NPMERR | REQDONE); 122826199Ssklower break; 122926199Ssklower default: /* Error on Board */ 123026199Ssklower rp->flags |= (IOERR | REQDONE); 123126199Ssklower break; 123226199Ssklower 123326199Ssklower } 123426199Ssklower 123526199Ssklower if(NpDebug & DEBCQE) { 123626199Ssklower printf("flag is %x reqid = %x\n",rp->flags,ep->cqe_reqid); 123726199Ssklower printf("wakeup in procqueue\n"); 123826199Ssklower } 123926199Ssklower 124026199Ssklower if(rp->intr) { 124126199Ssklower 124226199Ssklower if(NpDebug & DEBINTR) 124326199Ssklower printf("calling usr intr at %x\n", 124426199Ssklower rp->intr); 124526199Ssklower 124626199Ssklower /* Call interrupt routine */ 124726199Ssklower 124826199Ssklower (*rp->intr)(mp,rp); 124926199Ssklower } 125026199Ssklower else { 125126199Ssklower 125226199Ssklower if(NpDebug & DEBINTR) 125326199Ssklower printf("waking up %x\n",rp); 125426199Ssklower 125530865Skarels /* if(rp->flags & NPUIO) 125626199Ssklower iodone(&rp->buf); 125726199Ssklower else wakeup((caddr_t) (rp)); /* Awaken */ 125826199Ssklower 125930865Skarels wakeup((caddr_t)(rp)); /* Awaken */ 126026199Ssklower if(NpDebug & DEBINTR) 126126199Ssklower printf("AWAKE\n"); 126226199Ssklower } 126326199Ssklower } 126426199Ssklower 1265*30913Skarels cqp->scanflag &= ~ON; 126626199Ssklower if(!(cqp->chngflag & ON)) 1267*30913Skarels break; 126826199Ssklower 126926199Ssklower } 127026199Ssklower 1271*30913Skarels mp->flags &= ~SCANNING; 127226199Ssklower if(NpDebug & DEBENTRY) 127326199Ssklower printf("NpProcQueue...\n"); 127426199Ssklower } 127526199Ssklower 127626199Ssklower /* 127726199Ssklower * NpIFC - processes an IFC (Internal Fuction Call) request 127826199Ssklower * NOTE: this function must be called from the user context 127926199Ssklower * on all virtual pageing systems 128026199Ssklower * 128126199Ssklower */ 128226199Ssklower NpIFC(mp,rp) 128326199Ssklower register struct npmaster *mp; 128426199Ssklower register struct npreq *rp; 128526199Ssklower { 128626199Ssklower register struct CQE *ep; 128726199Ssklower 128826199Ssklower if(NpDebug & DEBENTRY) 128926199Ssklower printf("NpIFC\n"); 129026199Ssklower 129126199Ssklower ep = rp->element; 129226199Ssklower rp->flags &= ~IOIFC; 129326199Ssklower switch(ep->cqe_func) { 129426199Ssklower 129526199Ssklower case NPUNLOCK: /* Unlock process, free up mapping registers */ 129626199Ssklower 129726199Ssklower if(NpDebug & DEBIFC) 129826199Ssklower printf("NPUNLOCK\n"); 129926199Ssklower 130026199Ssklower if(rp->mapbase) 130126199Ssklower NpUnMapMem(mp,rp); 130226199Ssklower break; 130326199Ssklower 130426199Ssklower case NPLOCK: /* Lock process, get mapping registers */ 130526199Ssklower 130626199Ssklower if(NpDebug & DEBIFC) 130726199Ssklower printf("NPLOCK\n"); 130826199Ssklower NpMapMem(mp,rp,rp->virtmem,rp->bytecnt); 130926199Ssklower ep->cqe_dma[0] = LOWORD(rp->bufaddr); 131026199Ssklower ep->cqe_dma[1] = HIWORD(rp->bufaddr); 131126199Ssklower break; 131226199Ssklower 131326199Ssklower case NPREMAP: 131426199Ssklower 131526199Ssklower if(NpDebug & DEBIFC) 131626199Ssklower printf("NPREMAP\n"); 131726199Ssklower 131826199Ssklower /* Remap user buffer and update buffer offset */ 131926199Ssklower #ifdef USG 132026199Ssklower np_remapmem(rp,rp->virtmem); 132126199Ssklower ep->cqe_dma[0] = LOWORD(rp->bufaddr); 132226199Ssklower ep->cqe_dma[1] = HIWORD(rp->bufaddr); 132326199Ssklower break; 132426199Ssklower #endif 132526199Ssklower 132626199Ssklower default: 132726199Ssklower if(NpDebug & DEBIFC) 132826199Ssklower printf("Bad case %x in IFC\n", ep->cqe_func); 132926199Ssklower 133026199Ssklower rp->flags |= (REQDONE | IOERR); 133126199Ssklower break; 133226199Ssklower } 133326199Ssklower } 133426199Ssklower 133526199Ssklower /* 133626199Ssklower * The following contains various routines for allocating and deallocating 133726199Ssklower * structures used by the NP Driver. Routines are also here for addding 133826199Ssklower * and removing Command Queue Elements from a Command Queue. 133926199Ssklower */ 134026199Ssklower 134126199Ssklower /* 134226199Ssklower * Get a free NP Request structure from the list pointed to by head. Returns 134326199Ssklower * a pointer to a npreq or NULL if none left. 134426199Ssklower */ 134526199Ssklower 134626199Ssklower struct npreq * 134726199Ssklower NpGetReq(head) 134826199Ssklower struct npreq *head; 134926199Ssklower { 135026199Ssklower 135126199Ssklower register struct npreq *p; 135226199Ssklower 135326199Ssklower p = head->free; 135426199Ssklower head->free = p->free; 135530865Skarels if (p->flags & REQALOC) 135630865Skarels printf("GetReq: Req %x already allocated\n", p); 135730865Skarels p->flags &= WANTREQ; 135830865Skarels if (p != head) 135930865Skarels p->flags |= REQALOC; 136026199Ssklower return(p==head ? (struct npreq *)NULL : p); 136126199Ssklower } 136226199Ssklower 136326199Ssklower /* 136426199Ssklower * Return a NP Request structure to the free list pointed to by head. 136526199Ssklower */ 136626199Ssklower 136726199Ssklower NpFreeReq(head,nprp) 136826199Ssklower register struct npreq *head, *nprp; 136926199Ssklower { 137030865Skarels int s; 137126199Ssklower 137226199Ssklower if(NpDebug & DEBREQ) 137326199Ssklower printf("NpFreeReq, head is %x rp is %x\n",head,nprp); 137426199Ssklower 137530865Skarels if (nprp == NULL) { 137630865Skarels printf("FREEREQ: attempt to free null pointer\n"); 137730865Skarels return; 137830865Skarels } 137930865Skarels if (!(nprp->flags & REQALOC)) { 138030865Skarels printf("FREEREQ: attempt to free unallocated request %x\n", 138130865Skarels nprp); 138230865Skarels return; 138330865Skarels } 138430865Skarels if (nprp->flags & REQUSE) 138530865Skarels printf("FREEREQ: freeing unremoved request %x\n", nprp); 138630865Skarels 138730865Skarels s = spl5(); 138826199Ssklower nprp->forw = nprp->back = (struct npreq *)NULL; 138926199Ssklower nprp->free = head->free; 139026199Ssklower head->free = nprp; 139130865Skarels nprp->flags &= ~REQALOC; 139230865Skarels splx(s); 139326199Ssklower 139426199Ssklower /* Wake up any processes waiting for a request structure */ 139526199Ssklower 139626199Ssklower if(head->flags & WANTREQ) { 139726199Ssklower head->flags &= ~WANTREQ; 139826199Ssklower wakeup((caddr_t)head); 139926199Ssklower } 140026199Ssklower 140126199Ssklower if(NpDebug & DEBENTRY) 140226199Ssklower printf("NpFreeReq...\n"); 140326199Ssklower } 140426199Ssklower 140526199Ssklower /* 140626199Ssklower * Add a Command Queue Element onto the specified Command Queue and 140726199Ssklower * update its Add offset. 140826199Ssklower */ 140926199Ssklower 141026199Ssklower NpAddCQE(ep,cqp,mp) 141126199Ssklower struct CQE *ep; 141226199Ssklower struct CmdQue *cqp; 141326199Ssklower struct npmaster *mp; 141426199Ssklower { 141526199Ssklower 141626199Ssklower register unsign16 *temp; 141726199Ssklower register unsign16 cqe_offset; 141826199Ssklower register int base; 141926199Ssklower 142026199Ssklower base = (int)mp->shmemp; /* Shared memory base address */ 142126199Ssklower 142226199Ssklower temp = (unsign16 *)(base + cqp->cq_add); /* Offset to add element */ 142326199Ssklower 142426199Ssklower cqe_offset = (unsign16)((int)ep - base); 142526199Ssklower 142626199Ssklower if(*temp) { /* Should never happen */ 142726199Ssklower 142826199Ssklower printf("No more room on Command Queue!\n"); 142926199Ssklower u.u_error = EIO; 143026199Ssklower return; 143126199Ssklower } 143226199Ssklower else *temp = cqe_offset; /* Enter this request's offset */ 143326199Ssklower 143426199Ssklower /* Update cqe_add where next request is to be added */ 143526199Ssklower 143626199Ssklower cqp->cq_add += sizeof(unsign16); 143726199Ssklower 143826199Ssklower if(cqp->cq_add == cqp->cq_wrap) /* Wrap if necessary */ 143926199Ssklower cqp->cq_add = (unsign16)((int)cqp->cq_cqe - base); 144026199Ssklower 1441*30913Skarels cqp->chngflag |= ON; /* Set change flag unconditionally */ 1442*30913Skarels 144326199Ssklower /* Interrupt the Board if his scan flag isn't on */ 144426199Ssklower 144526199Ssklower if(!(cqp->scanflag & ON)) 144626199Ssklower 144726199Ssklower INTNI(mp); /* Interrupt the Board */ 144826199Ssklower 144926199Ssklower } 145026199Ssklower 145126199Ssklower /* 145226199Ssklower * The NpRemCQE routine is used to remove the next CQE from the Command Queue 145326199Ssklower * specified by cqp. The common offset of shared memory used by the device 145426199Ssklower * is specified by base. NpRemCQE returns a pointer to the next CQE or 145526199Ssklower * NULL if there are none left. This routine will also update the cqe_rem 145626199Ssklower * offset which specifies where the next element to be removed from the 145726199Ssklower * queue is located. 145826199Ssklower */ 145926199Ssklower 146026199Ssklower struct CQE * 146126199Ssklower NpRemCQE(cqp,base) 146226199Ssklower struct CmdQue *cqp; 146326199Ssklower int base; 146426199Ssklower { 146526199Ssklower 146626199Ssklower register unsign16 *temp; 146726199Ssklower register unsign16 cqe_offset; 146826199Ssklower 146926199Ssklower cqp->chngflag &= ~ON; /* Turn off unconditionally */ 147026199Ssklower 147126199Ssklower /* Get address of element to remove */ 147226199Ssklower 147326199Ssklower temp = (unsign16 *)(base +cqp->cq_rem); 147426199Ssklower 147526199Ssklower if(*temp == NULL) /* If none left, go home */ 147626199Ssklower return((struct CQE *) NULL); 147726199Ssklower 147826199Ssklower else cqe_offset = *temp; /* Offset of CQE to remove */ 147926199Ssklower 148026199Ssklower /* Update the Command Queue's cqe_rem offset */ 148126199Ssklower 148226199Ssklower *temp = NULL; /* Clear out this entry */ 148326199Ssklower 148426199Ssklower cqp->cq_rem += sizeof(unsign16); /* Bump offset */ 148526199Ssklower 148626199Ssklower if(cqp->cq_rem == cqp->cq_wrap) /* Wrap if necessary */ 148726199Ssklower cqp->cq_rem = (unsign16)((int)cqp->cq_cqe - base); 148826199Ssklower 148926199Ssklower temp = (unsign16 *)(base + cqe_offset); /* CQE address */ 149026199Ssklower return((struct CQE *)temp); /* is returned */ 149126199Ssklower } 149226199Ssklower 149326199Ssklower /* 149426199Ssklower * NpAddReq will add the specified npreq structure to the queue controlled 149526199Ssklower * by head. 149626199Ssklower */ 149726199Ssklower 149826199Ssklower NpAddReq(head,rp) 149926199Ssklower register struct npreq *head, *rp; 150026199Ssklower { 150130865Skarels int s; 150226199Ssklower 150330865Skarels if (NpDebug & (DEBENTRY|DEBREQ)) 150426199Ssklower printf("NpAddReq: %x\n",rp); 150526199Ssklower 150630865Skarels if (rp->flags & REQUSE) 150730865Skarels printf("ADDREQ: Request %x allready in use\n", rp); 150830865Skarels 150930865Skarels s = spl7(); 151026199Ssklower rp->forw = head->forw; 151126199Ssklower rp->forw->back = rp; 151226199Ssklower rp->back = head; 151326199Ssklower head->forw = rp; 151430865Skarels rp->flags |= REQUSE; 151530865Skarels splx(s); 151626199Ssklower 151726199Ssklower if(NpDebug & DEBENTRY) 151826199Ssklower printf("NpAddReq...\n"); 151926199Ssklower } 152026199Ssklower 152126199Ssklower /* 152226199Ssklower * NpRemReq is used to remove a npreq structure from the queue specified by 152326199Ssklower * head. 152426199Ssklower */ 152526199Ssklower 152626199Ssklower NpRemReq(rp) 152726199Ssklower register struct npreq *rp; 152826199Ssklower { 152930865Skarels int s; 153026199Ssklower 153130865Skarels if (NpDebug & (DEBENTRY|DEBREQ)) 153226199Ssklower printf("NpRemReq: %x\n",rp); 153326199Ssklower 153430865Skarels if (rp == NULL) { 153530865Skarels printf("REMREQ: null pointer removal requested\n"); 153630865Skarels return; 153730865Skarels } 153830865Skarels if (!(rp->flags & REQUSE)) { 153930865Skarels printf("REMREQ: trying to rem unused req %x\n", rp); 154030865Skarels return; 154130865Skarels } 154230865Skarels if (!(rp->flags & REQALOC)) { 154330865Skarels printf("REMREQ: trying to rem unallocated req %x\n", rp); 154430865Skarels return; 154530865Skarels } 154630865Skarels 154730865Skarels s = spl7(); 154826199Ssklower rp->back->forw = rp->forw; 154926199Ssklower rp->forw->back = rp->back; 155030865Skarels rp->flags &= ~REQUSE; 155130865Skarels splx(s); 155226199Ssklower 155326199Ssklower if(NpDebug & DEBENTRY) 155426199Ssklower printf("NpRemReq...\n"); 155526199Ssklower } 155626199Ssklower 155726199Ssklower 155826199Ssklower /* 155926199Ssklower * The following routines are used to communicate with the 156026199Ssklower * NI Hardware via the CSR0 commands. These commands are issued during 156126199Ssklower * the hardware initializtion process and may also be used subsequently 156226199Ssklower * by privileged processes who wish to communicate in this way. The 156326199Ssklower * convention for passing data as a Command Block is discussed in detail 156426199Ssklower * in the NI1510 UNIBUS Compatible Ethernet Communications Processor 156526199Ssklower * Hardware Specification. 156626199Ssklower */ 156726199Ssklower 156826199Ssklower NpSendCSR0(iobase,src,bcount) 156926199Ssklower struct NPREG *iobase; 157026199Ssklower register unsign16 *src; 157126199Ssklower int bcount; 157226199Ssklower { 157326199Ssklower register int wcount; 157426199Ssklower int i; 157526199Ssklower int csrflag; 157626199Ssklower unsign16 tmp; 157726199Ssklower 157826199Ssklower if(NpDebug & DEBENTRY) 157926199Ssklower printf("NpSendCSR0\n"); 158026199Ssklower 158126199Ssklower /* Jolt the board into CSR0 command mode if necessary */ 158226199Ssklower 158326199Ssklower if(!(RCSR1(iobase) & NPENB)){ 158426199Ssklower tmp = NPCLEAR; /* MC68000 clr reads before writing */ 158526199Ssklower WCSR0(iobase,tmp); 158626199Ssklower } 158726199Ssklower 158826199Ssklower wcount = (bcount +1) >> 1; /* Convert byte count to word count */ 158926199Ssklower 159026199Ssklower /* Clear timer flag before beginning the timer */ 159126199Ssklower 159226199Ssklower csrflag = NPCLEAR; 159326199Ssklower timeout(NpTimer,&csrflag,DIAGTIME); 159426199Ssklower 159526199Ssklower for(i = 0; (i < wcount) & (csrflag == NPCLEAR); i++) { 159626199Ssklower while(! ((RCSR1(iobase) & NPENB) && (RCSR1(iobase) & NPRDY))) 159726199Ssklower if(csrflag) break; 159826199Ssklower WCSR0(iobase,*src); 159926199Ssklower src++; /* Better do this WCSR is a macro */ 160026199Ssklower } 160126199Ssklower 160226199Ssklower /* Clear the timer entry */ 160326199Ssklower 160426199Ssklower untimeout(NpTimer,&csrflag); 160526199Ssklower 160626199Ssklower /* Error if timer went off */ 160726199Ssklower 160826199Ssklower if(csrflag) 160926199Ssklower return(EIO); 161026199Ssklower 161126199Ssklower if(NpDebug & DEBENTRY) 161226199Ssklower printf("NpSendCSR0...\n"); 161326199Ssklower return(0); 161426199Ssklower } 161526199Ssklower 161626199Ssklower /* 161726199Ssklower * NpSetIntLev sets the UNIBUS interrupt vector to be used by the NP board when 161826199Ssklower * interupting the host. The board is specified by mp. 161926199Ssklower */ 162026199Ssklower 162126199Ssklower NpSetIntLevel(mp,level) 162226199Ssklower struct npmaster *mp; 162326199Ssklower int level; 162426199Ssklower { 162526199Ssklower 162626199Ssklower struct { 162726199Ssklower unsign16 cmd_word; 162826199Ssklower unsign16 int_level; 162926199Ssklower }cmd_block; 163026199Ssklower 163126199Ssklower cmd_block.cmd_word = NPCBI | CBICNT; 163226199Ssklower cmd_block.int_level = level; 163326199Ssklower 163426199Ssklower return(NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block))); 163526199Ssklower } 163626199Ssklower 163726199Ssklower /* 163826199Ssklower * NpSetMemAddr is used to declare the shared memory area address to be used 163926199Ssklower * for communication between the driver and the device. This address is used 164026199Ssklower * to access data structures by acting as a base from which defined offsets 164126199Ssklower * locate data. The board is specified by mp. 164226199Ssklower */ 164326199Ssklower 164426199Ssklower NpSetMemAddr(mp,addr) 164526199Ssklower struct npmaster *mp; 164626199Ssklower caddr_t addr; 164726199Ssklower { 164826199Ssklower 164926199Ssklower caddr_t shmaddr; 165026199Ssklower int error; 165126199Ssklower 165226199Ssklower struct { 165326199Ssklower unsign16 cmd_word; 165426199Ssklower unsign16 hi_addr; 165526199Ssklower unsign16 lo_addr; 165626199Ssklower } cmd_block; 165726199Ssklower 165826199Ssklower if(NpDebug & DEBENTRY) 165926199Ssklower printf("NpSetMemAddr\n"); 166026199Ssklower 166126199Ssklower shmaddr = addr; 166226199Ssklower 166326199Ssklower if(NpDebug & DEBMEM) 166426199Ssklower printf("NpSetMemAddr, addr is %x shmaddr is %x.\n",addr,shmaddr); 166526199Ssklower 166626199Ssklower cmd_block.cmd_word = NPCMD | CMDCNT; 166726199Ssklower cmd_block.hi_addr = HIWORD(shmaddr); 166826199Ssklower cmd_block.lo_addr = LOWORD(shmaddr); 166926199Ssklower 167026199Ssklower error = NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block)); 167126199Ssklower 167226199Ssklower if(NpDebug & DEBENTRY) 167326199Ssklower printf("NpSetMemAddr...\n"); 167426199Ssklower 167526199Ssklower return(error); 167626199Ssklower } 167726199Ssklower 167826199Ssklower 167926199Ssklower /* 168026199Ssklower * NpSetXeqAddr specifies the address at which the board should begin 168126199Ssklower * execution of its on-board software. It also indicates the shared memory 168226199Ssklower * address to be used. The board is specified by mp. 168326199Ssklower */ 168426199Ssklower 168526199Ssklower NpSetXeqAddr(mp,addr) 168626199Ssklower struct npmaster *mp; 168726199Ssklower caddr_t addr; 168826199Ssklower { 168926199Ssklower caddr_t shmaddr; 169026199Ssklower int error; 169126199Ssklower 169226199Ssklower struct { 169326199Ssklower unsign16 cmd_word; 169426199Ssklower unsign16 hi_addr; 169526199Ssklower unsign16 lo_addr; 169626199Ssklower unsign16 mhi_addr; 169726199Ssklower unsign16 mlo_addr; 169826199Ssklower } cmd_block; 169926199Ssklower 170026199Ssklower if(NpDebug & DEBENTRY) 170126199Ssklower printf("NpSetXeqAddr\n"); 170226199Ssklower 170326199Ssklower shmaddr = (caddr_t)((int)mp->iomapbase & UBADDRMASK); 170426199Ssklower 170526199Ssklower cmd_block.cmd_word = NPBGN | NPCMD | NPLST | (BGNCNT + CMDCNT); 170626199Ssklower cmd_block.hi_addr = HIWORD(addr); 170726199Ssklower cmd_block.lo_addr = LOWORD(addr); 170826199Ssklower cmd_block.mhi_addr = HIWORD(shmaddr); 170926199Ssklower cmd_block.mlo_addr = LOWORD(shmaddr); 171026199Ssklower 171126199Ssklower if(NpDebug & DEBINIT) { 171226199Ssklower printf("NpSetXeqAdddr: hi: %x lo: %x\n",HIWORD(addr), LOWORD(addr)); 171326199Ssklower printf("NpSetXeqAdddr: mhi: %x mlo: %x\n",HIWORD(shmaddr),LOWORD(shmaddr)); 171426199Ssklower } 171526199Ssklower 171626199Ssklower error = NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block)); 171726199Ssklower 171826199Ssklower if(NpDebug & DEBENTRY) 171926199Ssklower printf("NpSetXeqAddr...\n"); 172026199Ssklower 172126199Ssklower return(error); 172226199Ssklower } 172326199Ssklower 172426199Ssklower /* 172526199Ssklower * NPIO issues a CSR0 load or dump request to the I-Board after packaging a 172626199Ssklower * CSR0 Command Block. 172726199Ssklower */ 172826199Ssklower 172926199Ssklower NPIO(mp,src,dest,count,dir) 173026199Ssklower struct npmaster *mp; 173126199Ssklower paddr_t dest; 173226199Ssklower paddr_t src; 173326199Ssklower unsign16 count; 173426199Ssklower int dir; /* Direction READ/WRITE */ 173526199Ssklower { 173626199Ssklower 173726199Ssklower int error; 173826199Ssklower 173926199Ssklower struct { 174026199Ssklower unsign16 cmd_word; /* Command Word */ 174126199Ssklower unsign16 shi_addr; /* High word of Source Address */ 174226199Ssklower unsign16 slo_addr; /* Low word of Source Address */ 174326199Ssklower unsign16 dhi_addr; /* High word of Destination Address */ 174426199Ssklower unsign16 dlo_addr; /* Low word of Destination Address */ 174526199Ssklower unsign16 count; /* Byte count */ 174626199Ssklower unsign16 intlevel; /* Interrupt level to host */ 174726199Ssklower } cmd_block; 174826199Ssklower 174926199Ssklower if(NpDebug & DEBENTRY) 175026199Ssklower printf("NPIO\n"); 175126199Ssklower if(NpDebug & DEBMAINT) { 175226199Ssklower printf("I/O src addr = %x, dest addr = %x \n",src,dest); 175326199Ssklower printf("I/O count = %d \n",count); 175426199Ssklower } 175526199Ssklower 175630865Skarels cmd_block.cmd_word = NPCBI | (CBICNT + IOCNT); 175726199Ssklower cmd_block.intlevel = mp->vector; 175826199Ssklower cmd_block.shi_addr = HIWORD(src); 175926199Ssklower cmd_block.slo_addr = LOWORD(src); 176026199Ssklower cmd_block.dhi_addr = HIWORD(dest); 176126199Ssklower cmd_block.dlo_addr = LOWORD(dest); 176226199Ssklower cmd_block.count = count; 176330865Skarels if ((mp->flags & LSTCMD) == 0) 176430865Skarels cmd_block.cmd_word |= NPLST; 176526199Ssklower if(dir == B_READ) 176626199Ssklower cmd_block.cmd_word |= NPDMP; 176726199Ssklower else 176826199Ssklower cmd_block.cmd_word |= NPLD; 176926199Ssklower 177026199Ssklower 177126199Ssklower if(NpDebug & DEBIO) { 177226199Ssklower printf("cmd: %x int: %o shi: %x slo: %x dhi: %x dlo: %x cnt: %x\n", 177326199Ssklower cmd_block.cmd_word,cmd_block.intlevel,cmd_block.shi_addr,cmd_block.slo_addr, 177426199Ssklower cmd_block.dhi_addr,cmd_block.dlo_addr,cmd_block.count); 177526199Ssklower } 177626199Ssklower 177726199Ssklower mp->flags |= CSRPEND; /* CSR0 command pending */ 177826199Ssklower 177926199Ssklower error = NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block)); 178026199Ssklower if(NpDebug & DEBENTRY) 178126199Ssklower printf("NPIO...\n"); 178226199Ssklower 178326199Ssklower return(error); 178426199Ssklower } 178526199Ssklower 178626199Ssklower 178726199Ssklower /* 178826199Ssklower * NpKill will terminate all outstanding requests for the specified board. 178926199Ssklower */ 179026199Ssklower 179126199Ssklower NpKill(mp,curr_rp) 179226199Ssklower struct npmaster *mp; 179326199Ssklower struct npreq *curr_rp; 179426199Ssklower { 179526199Ssklower struct npreq *rp; 179626199Ssklower int s; 179726199Ssklower 179826199Ssklower if(NpDebug & DEBENTRY) 179926199Ssklower printf("NpKill\n"); 180026199Ssklower 180126199Ssklower mp->reqtab->reqcnt = 0; /* Init request count */ 180226199Ssklower 1803*30913Skarels s = spl5(); /* Disable interrupts */ 180426199Ssklower 180526199Ssklower /* Mark each active request as having an error and wake him up */ 180626199Ssklower 180726199Ssklower for(rp = mp->reqtab->forw;rp != mp->reqtab;rp = rp->forw) { 180826199Ssklower 180926199Ssklower if(rp == curr_rp) continue; 181026199Ssklower 181126199Ssklower rp->flags |= (IOABORT | REQDONE); 181226199Ssklower mp->reqtab->reqcnt++; 181330865Skarels /* if(rp->flags & NPUIO) 181426199Ssklower iodone(&rp->buf); 181530865Skarels else */ 181630865Skarels wakeup((caddr_t)rp); 181726199Ssklower } 181826199Ssklower 181926199Ssklower if(NpDebug & DEBMAINT) 182026199Ssklower printf("NpKill, req count is %d\n",mp->reqtab->reqcnt); 182126199Ssklower 182226199Ssklower splx(s); 182326199Ssklower 182426199Ssklower if(NpDebug & DEBENTRY) 182526199Ssklower printf("NpKill...\n"); 182626199Ssklower 182726199Ssklower return(0); 182826199Ssklower 182926199Ssklower } 183026199Ssklower 183126199Ssklower /* Hardware and Software Initializations for the specified unit */ 183226199Ssklower 183326199Ssklower NpReset(mp,rp) 183426199Ssklower register struct npmaster *mp; 183526199Ssklower struct npreq *rp; 183626199Ssklower { 183726199Ssklower int error; 183826199Ssklower 183926199Ssklower if(NpDebug & DEBENTRY) 184026199Ssklower printf("NpReset!\n"); 184126199Ssklower 184226199Ssklower /* Mark board as being reset and make unavailable */ 184326199Ssklower 184426199Ssklower mp->flags = BRDRESET; 184526199Ssklower 184626199Ssklower /* Abort outstanding requests for this board */ 184726199Ssklower 184826199Ssklower mp->reqtab->reqcnt = 0; /* Init request count */ 184926199Ssklower 185026199Ssklower /* Wakeup Poller if available and wait until he's gone */ 185126199Ssklower 185226199Ssklower if(NpState & ICPAVAIL) { 185326199Ssklower 185426199Ssklower mp->flags |= BOARDREQ; 185526199Ssklower mp->reqtab->reqcnt++; 185626199Ssklower 185726199Ssklower if(NpDebug & DEBMAINT) 185826199Ssklower printf("Waking ICP in reset!\n"); 185926199Ssklower 186026199Ssklower wakeup((caddr_t)&NpState); 186126199Ssklower 186226199Ssklower while(mp->reqtab->reqcnt) 186326199Ssklower sleep((caddr_t)(&mp->reqtab),PZERO +1); 186426199Ssklower 186526199Ssklower if(NpDebug & DEBMAINT) 186626199Ssklower printf("Reset:awoken by ICP senior!\n"); 186726199Ssklower 186826199Ssklower } 186926199Ssklower 187026199Ssklower /* Abort outstanding requests and wait till they're gone */ 187126199Ssklower 187226199Ssklower NpKill(mp,rp); 187326199Ssklower 187426199Ssklower while(mp->reqtab->reqcnt) { 187526199Ssklower 187626199Ssklower if(NpDebug & DEBMAINT) { 187726199Ssklower printf("Sleeping in NpReset on reqtab!\n"); 187826199Ssklower printf("Reqcnt is %d.\n",mp->reqtab->reqcnt); 187926199Ssklower } 188026199Ssklower 188126199Ssklower sleep((caddr_t)(&mp->reqtab),PZERO +1); 188226199Ssklower 188326199Ssklower } 188426199Ssklower 188526199Ssklower /* Free up I/O Map registers if any allocated */ 188626199Ssklower 188726199Ssklower if(mp->iomapbase) { 188826199Ssklower 188926199Ssklower if(NpDebug & DEBMEM) 189026199Ssklower printf("freeing shared memory map.\n"); 189126199Ssklower 189226199Ssklower ubarelse(mp->devp->ui_ubanum,&mp->iomapbase); 189326199Ssklower mp->iomapbase = 0; 189426199Ssklower } 189526199Ssklower 189626199Ssklower /* Initialize S/W data structures in NP Driver */ 189726199Ssklower 189826199Ssklower NpSWinit(mp->unit); /* Software initialization */ 189926199Ssklower 190026199Ssklower /* Hardware initialization of the board */ 190126199Ssklower 190226199Ssklower error = NpHWinit(mp->unit); /* Hardware initialization */ 190326199Ssklower 190426199Ssklower mp->flags &= ~BRDRESET; /* Initialization complete */ 190526199Ssklower 190626199Ssklower /* Initialize Pseudo-Drivers */ 190726199Ssklower 190826199Ssklower if (IxReset) 190926199Ssklower (*IxReset)(mp->unit, mp->devp->ui_ubanum, rp); 191026199Ssklower 191126199Ssklower /* Clear Poller's State Flag */ 191226199Ssklower 191326199Ssklower NpState = NPCLEAR; 191426199Ssklower 191526199Ssklower if(NpDebug & DEBENTRY) 191626199Ssklower printf("NpReset...\n"); 191726199Ssklower 191826199Ssklower return(error); 191926199Ssklower } 192026199Ssklower 192126199Ssklower /* 192226199Ssklower * General purpose timeout function which sets the flag passed to it 192326199Ssklower * as argument. 192426199Ssklower */ 192526199Ssklower 192626199Ssklower NpTimer(flagp) 192726199Ssklower int *flagp; 192826199Ssklower { 192926199Ssklower *flagp = NPSET; 193026199Ssklower } 193126199Ssklower 193226199Ssklower NpStats() 193326199Ssklower { 193426199Ssklower if(NpDebug & DEBENTRY) 193526199Ssklower printf("npstats\n"); 193626199Ssklower return(0); 193726199Ssklower } 193826199Ssklower 193926199Ssklower /* 194026199Ssklower * NpCloseConn is called to issue a close connection command to the I-Board. 194126199Ssklower */ 194226199Ssklower 194326199Ssklower NpCloseConn(mp,protocol) 194426199Ssklower struct npmaster *mp; 194526199Ssklower unsign16 protocol; 194626199Ssklower { 194726199Ssklower 194826199Ssklower register struct npreq *rp; 194926199Ssklower register struct CQE *ep; 195026199Ssklower int pri; 195126199Ssklower 195226199Ssklower if(NpDebug & DEBENTRY) 195326199Ssklower printf("NpCloseConn\n"); 195426199Ssklower 195526199Ssklower /* 195626199Ssklower * Don't issue the Close Connection command if the Board 195726199Ssklower * isn't up. 195826199Ssklower */ 195926199Ssklower 196026199Ssklower if(!((mp->shmemp->statblock.sb_dpm) & PROTOMASK(protocol))) { 196126199Ssklower return; 196226199Ssklower } 196326199Ssklower 196426199Ssklower /* Get a Request structure */ 196526199Ssklower 196626199Ssklower while((rp = NpGetReq(mp->reqtab)) == NULL) { 196726199Ssklower mp->reqtab->flags |= WANTREQ; 196826199Ssklower sleep((caddr_t)(mp->reqtab),PZERO -1); 196926199Ssklower } 197026199Ssklower 197126199Ssklower rp->intr = (int (*)())0; /* Do not call interrupt routine */ 197226199Ssklower rp->mapbase = 0; /* Clear mapping information */ 197326199Ssklower 197426199Ssklower ep = rp->element; /* Handy pointer */ 197526199Ssklower 197626199Ssklower /* Fill in CQE */ 197726199Ssklower 197826199Ssklower ep->cqe_wind = 0; /* Entire buffer mapped */ 197926199Ssklower ep->cqe_nbuf = 1; /* Must be 1, no buffer chaining */ 198026199Ssklower ep->cqe_char = 0; /* Set to 0 for now */ 198126199Ssklower 198226199Ssklower ep->cqe_func = NPSTOP; /* OS_STP to I-Board */ 198326199Ssklower 198426199Ssklower ep->cqe_prot = protocol; /* Protocol of this connection */ 198526199Ssklower ep->cqe_lenrpb = 0; /* Parameter block length */ 198626199Ssklower 198726199Ssklower ep->cqe_ust0 = ep->cqe_ust1 = NPCLEAR; /* Clear status flags */ 198826199Ssklower 198926199Ssklower ep->cqe_famid = (unsign32)u.u_procp->p_pid; /* Process ID */ 199026199Ssklower 199126199Ssklower NpAddReq(mp->reqtab,rp); /* Queue onto active list */ 199226199Ssklower 1993*30913Skarels pri = spl5(); /* Mask our interrupts */ 199426199Ssklower 199526199Ssklower NpAddCQE(ep,&mp->shmemp->devcq,mp); /* Add CQE to device's queue */ 199626199Ssklower 199726199Ssklower /* Wait for command to complete */ 199826199Ssklower 199926199Ssklower while(!(rp->flags & REQDONE)) 200026199Ssklower sleep((caddr_t)rp,PZERO - 1); 200126199Ssklower 200226199Ssklower splx(pri); 200326199Ssklower 200426199Ssklower NpRemReq(rp); /* Remove request from active list */ 200526199Ssklower 200626199Ssklower NpFreeReq(mp->reqtab,rp); /* Deallocate request structure */ 200726199Ssklower 200826199Ssklower if(NpDebug & DEBENTRY) 200926199Ssklower printf("NpCloseConn...\n"); 201026199Ssklower 201126199Ssklower } 201226199Ssklower 201326199Ssklower /* 201426199Ssklower * This function allows the protocol to be changed for a given connection. 201526199Ssklower * It returns 0 for success, error code otherwise. 201626199Ssklower */ 201726199Ssklower 201826199Ssklower NpProtChange(protocol,unit) 201926199Ssklower register unsign16 protocol; 202026199Ssklower register int unit; 202126199Ssklower { 202226199Ssklower 202326199Ssklower register struct npmaster *mp; 202426199Ssklower 202526199Ssklower /* Privileged users only for Maintenance Protocol */ 202626199Ssklower 202726199Ssklower if((protocol == NPMAINT) && (u.u_uid != 0)) 202826199Ssklower return(EPERM); 202926199Ssklower 203026199Ssklower if(NpDebug & DEBMAINT) 203126199Ssklower printf("NpProtChange = %x\n",protocol); 203226199Ssklower 203326199Ssklower if(protocol != NPMAINT) { 203426199Ssklower 203526199Ssklower /* Make sure the I-Board supports the protocol */ 203626199Ssklower 203726199Ssklower mp = &npmasters[unit]; 203826199Ssklower 203926199Ssklower if(!((mp->shmemp->statblock.sb_dpm) & PROTOMASK(protocol))) 204026199Ssklower return(ENXIO); 204126199Ssklower } 204226199Ssklower 204326199Ssklower return(0); 204426199Ssklower } 204526199Ssklower 204626199Ssklower /* 204726199Ssklower * This function allows for the changing of the unit for a given connection. 204826199Ssklower */ 204926199Ssklower 205026199Ssklower struct npmaster * 205126199Ssklower NpBoardChange(protocol,unit) 205226199Ssklower register unsign16 protocol; 205326199Ssklower register int unit; /* Unit number */ 205426199Ssklower { 205526199Ssklower register struct npmaster *mp; 205626199Ssklower 205726199Ssklower 205826199Ssklower if(unit > NNP) 205926199Ssklower return((struct npmaster *)0); 206026199Ssklower 206126199Ssklower if(protocol != NPMAINT) { 206226199Ssklower 206326199Ssklower /* 206426199Ssklower * Loop through the master structures finding a board which 206526199Ssklower * supports the requested protocol. 206626199Ssklower */ 206726199Ssklower 206826199Ssklower for(mp = npmasters; mp ; mp = mp->next) { 206926199Ssklower 207026199Ssklower if(mp->flags & BADBOARD) 207126199Ssklower continue; 207226199Ssklower 207326199Ssklower if(((mp->shmemp->statblock.sb_dpm) & PROTOMASK(protocol))) 207426199Ssklower return(mp); 207526199Ssklower } 207626199Ssklower return((struct npmaster *)0); 207726199Ssklower } 207826199Ssklower return(&npmasters[unit]); 207926199Ssklower } 208026199Ssklower 208126199Ssklower /* 208226199Ssklower * NpMapMem - maps the user's memory updating the fields in the npreq 208326199Ssklower * structure and returning the mapped address in rp->buffaddr. 208426199Ssklower */ 208526199Ssklower NpMapMem(mp,rp,addr,count) 208626199Ssklower register struct npmaster *mp; 208726199Ssklower register struct npreq *rp; 208826199Ssklower caddr_t addr; 208926199Ssklower int count; 209026199Ssklower { 209126199Ssklower 209226199Ssklower if(NpDebug & DEBENTRY) 209326199Ssklower printf("NpMapMem\n"); 209426199Ssklower if(NpDebug & DEBIO) 209526199Ssklower printf("mp %x rp %x addr %x count %x\n",mp,rp,addr,count); 209626199Ssklower 209726199Ssklower rp->virtmem = addr; 209826199Ssklower rp->bytecnt = count; 209926199Ssklower 210026199Ssklower rp->buf.b_un.b_addr = addr; 210126199Ssklower rp->buf.b_flags = B_PHYS | B_BUSY; 210226199Ssklower rp->buf.b_bcount = count; 210326199Ssklower rp->buf.b_proc = rp->procp; 210426199Ssklower 210526199Ssklower rp->procp->p_flag |= SPHYSIO; 210630865Skarels if(NpDebug & DEBENTRY) 210730865Skarels printf("vslock\n"); 210826199Ssklower vslock(addr,count); 210930865Skarels if(NpDebug & DEBENTRY) 211030865Skarels printf("vslock...\n"); 211126199Ssklower 211226199Ssklower rp->mapbase = ubasetup(mp->devp->ui_ubanum,&rp->buf,0); 211326199Ssklower 211426199Ssklower rp->bufaddr = (caddr_t)(rp->mapbase & UBADDRMASK); 211526199Ssklower 211626199Ssklower if(NpDebug & DEBENTRY) 211726199Ssklower printf("NpMapMem...\n"); 211826199Ssklower } 211926199Ssklower 212026199Ssklower /* 212126199Ssklower * Unmap the user's memory and free up mapping registers 212226199Ssklower */ 212326199Ssklower 212426199Ssklower NpUnMapMem(mp,rp) 212526199Ssklower struct npmaster *mp; 212626199Ssklower struct npreq *rp; 212726199Ssklower { 212826199Ssklower if(NpDebug & DEBENTRY) 212926199Ssklower printf("NpUnMapMem\n"); 213026199Ssklower 213126199Ssklower ubarelse(mp->devp->ui_ubanum,&rp->mapbase); 213226199Ssklower rp->mapbase = 0; 213326199Ssklower vsunlock(rp->virtmem,rp->bytecnt,B_READ); 213426199Ssklower rp->procp->p_flag &= ~SPHYSIO; 213526199Ssklower 213626199Ssklower if(NpDebug & DEBENTRY) 213726199Ssklower printf("NpUnMapMem...\n"); 213826199Ssklower } 213926199Ssklower 214026199Ssklower npprobe(reg, ui) 214126199Ssklower caddr_t reg; 214226199Ssklower struct uba_device *ui; 214326199Ssklower { 214426199Ssklower register int br,cvec; 214526199Ssklower u_short csraddr; 214626199Ssklower int i; 214726199Ssklower 214826199Ssklower #ifdef lint 214926199Ssklower br = 0; cvec = br; br = cvec; 215026199Ssklower #endif 215126199Ssklower 215226199Ssklower if(NpDebug & DEBINIT) 215326199Ssklower printf("In npprobe, regaddr is %x!\n",reg); 215426199Ssklower 215526199Ssklower cvec = (uba_hd[numuba].uh_lastiv -= 4); 215626199Ssklower 215730865Skarels #ifdef OLDBSD 215826199Ssklower /* Find unit number from npstd[] by matching the csr address */ 215926199Ssklower 216026199Ssklower csraddr = (u_short)((int)reg & 0x0FFFF); 216126199Ssklower 216226199Ssklower for(i = 0; i < NNP; i++) { 216326199Ssklower 216426199Ssklower if(csraddr == npstd[i]) { 216526199Ssklower npvectors[i] = cvec; 216626199Ssklower break; 216726199Ssklower } 216826199Ssklower } 216926199Ssklower if(i == NNP) 217026199Ssklower printf("Couldn't find device in npstd[]!\n"); 217130865Skarels 217226199Ssklower #else 217326199Ssklower npvectors[ui->ui_unit] = cvec; 217426199Ssklower #endif 217526199Ssklower br = 0x15; 217626199Ssklower 217726199Ssklower if(NpDebug & DEBINIT) 217826199Ssklower printf("npprobe...\n"); 217926199Ssklower 218026199Ssklower return(sizeof(struct NPREG)); /* CSR Registers */ 218126199Ssklower 218226199Ssklower } 218326199Ssklower 218426199Ssklower npattach(ui) 218526199Ssklower register struct uba_device *ui; 218626199Ssklower { 218726199Ssklower 218826199Ssklower if(NpDebug & DEBINIT) 218926199Ssklower printf("In npattach, ui is %x.\n",ui); 219026199Ssklower 219126199Ssklower npinit(ui->ui_unit); 219226199Ssklower if (IxAttach) 219326199Ssklower (*IxAttach)(ui); 219426199Ssklower 219526199Ssklower if(NpDebug & DEBINIT) 219626199Ssklower printf("npattach...\n"); 219726199Ssklower } 219826199Ssklower 219930865Skarels 220030865Skarels NpMem(mp, rp, uaddr) 220130865Skarels struct npmaster *mp; 220230865Skarels struct npreq *rp; 220330865Skarels unsigned long uaddr; 220430865Skarels { 220530865Skarels struct np_mem mem; 220630865Skarels register int error = 0; 220730865Skarels 220830865Skarels if(NpDebug & DEBENTRY) 220930865Skarels printf("npmem\n"); 221030865Skarels 221130865Skarels if (error = copyin(uaddr, &mem, sizeof(mem))) 221230865Skarels return (error); 221330865Skarels 221430865Skarels if (mem.mem_type == NP_SET) { 221530865Skarels if (np_mapreq[mp->unit] != (struct npreq *)NPCLEAR) 221630865Skarels error = EBUSY; 221730865Skarels else { 221830865Skarels error = NpMapMem(mp, rp, mem.mem_addr, mem.mem_count); 221930865Skarels if (error != 0) { 222030865Skarels np_mapreq[mp->unit] = rp; 222130865Skarels mem.mem_addr = rp->bufaddr; 222230865Skarels } 222330865Skarels } 222430865Skarels } else if (mem.mem_type == NP_USET) { 222530865Skarels error = NpUnMapMem(mp, np_mapreq[mp->unit]); 222630865Skarels NpFreeReq(mp->reqtab, rp); 222730865Skarels NpFreeReq(mp->reqtab, np_mapreq[mp->unit]); 222830865Skarels np_mapreq[mp->unit] = (struct npreq *)NPCLEAR; 222930865Skarels } else 223030865Skarels error = EIO; 223130865Skarels 223230865Skarels if (error != 0) 223330865Skarels error = copyout(&mem, uaddr, sizeof(mem)); 223430865Skarels 223530865Skarels if(NpDebug & DEBENTRY) 223630865Skarels printf("npmem...\n"); 223730865Skarels return (error); 223830865Skarels } 223926199Ssklower #endif 2240