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