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