149567Sbostic /*-
226266Ssklower * Copyright (c) 1986 MICOM-Interlan, Inc., Boxborough Mass
349567Sbostic * Copyright (c) 1991 The Regents of the University of California.
449567Sbostic * All rights reserved.
526199Ssklower *
649567Sbostic * %sccs.include.redist.c%
730865Skarels *
8*64624Sbostic * @(#)np.c 7.11 (Berkeley) 09/23/93
949567Sbostic */
1049567Sbostic
1149567Sbostic /*
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
npinit(unit)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*/
npopen(dev,flag)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
npclose(dev)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*/
npioctl(dev,cmd,addr,flag)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 */
npstart(mp)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
npstrategy(bp)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
nptrim(bp)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 */
npread(dev,uio)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
npwrite(dev,uio)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
npreset(uban)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
NpSWinit(unit)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
NpHWinit(unit)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
npintr(unit)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 */
NpIFC(mp,rp)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 *
NpGetReq(head)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
NpFreeReq(head,nprp)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 *
NpRemCQE(cqp,base)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
NpAddReq(head,rp)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
NpRemReq(rp)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
NpReset(mp,rp)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
NpTimer(flagp)191726199Ssklower NpTimer(flagp)
191826199Ssklower int *flagp;
191926199Ssklower {
192026199Ssklower *flagp = NPSET;
192126199Ssklower }
192226199Ssklower
NpStats()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
NpProtChange(protocol,unit)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 *
NpBoardChange(protocol,unit)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 */
NpMapMem(mp,rp,addr,count)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
2096*64624Sbostic rp->procp->p_flag |= P_PHYSIO;
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);
2125*64624Sbostic rp->procp->p_flag &= ~P_PHYSIO;
212626199Ssklower
212726199Ssklower if(NpDebug & DEBENTRY)
212826199Ssklower printf("NpUnMapMem...\n");
212926199Ssklower }
213026199Ssklower
npprobe(reg,ui)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
npattach(ui)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