📄 np.c
字号:
/*- * Copyright (c) 1986 MICOM-Interlan, Inc., Boxborough Mass * Copyright (c) 1991 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)np.c 7.11 (Berkeley) 9/23/93 *//* * From: * np.c version 1.5 * * This version retrieved: 8/18/86 @ 18:58:54 * This delta created: 8/18/86 @ 18:19:24 * * static char *SCCSID = "@(#)np.c 1.5"; * */ /****************************************** * * * NPDRIVER * * * ******************************************//* * The NP Driver is used to route requests, independent of protocol type, * to the NP series Intelligent Board. The facilities it provides are * used for board maintainance by the superuser and by protocol pseudo-drivers, * such as WN, for sending requests to a board. The board maintainance and * control functions are accessed via npioctl() by the NP support utilities. *//* * Modification History: * 4/9/86 DDW Removed pseudo-driver initialization flag resets from NpReset * 5/28/86 CJM Changed iodone() to wakeup() in NpProcQueue(). * *//* * Include Files */#include "np.h"#if NNP > 0#include "sys/param.h"#include "sys/buf.h"#include "sys/conf.h"#include "sys/ubavar.h"#include "sys/signal.h"#include "sys/systm.h"#include "sys/user.h"#include "sys/proc.h"#include "sys/uio.h"#include "sys/errno.h"#include "sys/ioctl.h"#include "../uba/npreg.h"#define b_uio b_forw#define b_rp av_back/* * Global variables for pseudo-drivers. */int WnInitFlag = 0;int IsInitFlag = 0;int (*IxAttach)();int (*IxReset)();/* * Debugging level. */int NpDebug = 0; /* Driver Wide State used by the ICP */int NpState = NPCLEAR;/* * Master structure, one per board, contains request queue header, * shared memory address, and memory mapping information. */struct npmaster npmasters[NNP];/* Structure of the shared memory area */static struct npspace npspaces[NNP];/* Panic Message data structures */static int panicmap; /* Mapping information */static char NpPbuf[PANLEN] = 0; /* Panic message buffer */static caddr_t pstring; /* Panic string address on board, absolute */static unsign16 panaddr[2]; /* Panic string address on board (seg/offset) *//* Driver Wide Connection Table */static struct npconn npcnxtab[NNP][NNPCNN];/* Head of the request queue, one per board */static struct npreq reqhdr[NNP];/* Require for diagnostic packages */typedef struct npreq *reqptr;reqptr np_mapreq[NNP];/* The request structures, one pool per board */static struct npreq npreqs[NNP][NUMCQE];/* * Data structures needed for BSD 4.2 Device Drivers */int npprobe(), npattach(), npintr();struct uba_device *npdinfo[NNP];/* UNIBUS address of Network Processors */u_short npstd[] = { 0166000, 0166020, 0 };/* Interrupt vectors used by the Network Processors */static unsign16 npvectors[NNP];struct uba_driver npdriver = { npprobe, 0, npattach, 0, npstd, "np", npdinfo };struct buf np_tab[NNP];static unsigned long np_icount[NNP];/* * External function and data structure declarations. */struct npreq * NpGetReq();struct npmaster *NpBoardChange();int NpTimer();struct CQE * NpRemCQE();extern struct user u;/* * Np_init() is responsible for hardware initializiation and the software * initialization of the connection table and driver software data structures. */npinit(unit)int unit;{ register int j; /* Software Initialization */ npmasters[unit].flags = NPCLEAR; NpSWinit(unit); /* Hardware Initialization */ NpHWinit(unit); /* Connection Table Initialization */ for(j=0;j<NNPCNN;j++) { npcnxtab[unit][j].protocol = NPCLCONN; npcnxtab[unit][j].unit = &npmasters[unit]; }}/* * Np_open establishes a connection to the NP Driver using the minor * device number as an identifier. A default protocol, NPMAINT, is assigned * with the specified unit. Protocol and unit may be changed using the * NpProtChange and NpBoardChange functions. * Since the maintainance protocol does not need a working I-Board, entries * are always made in the Connection Table, npcnxtab, if the board exists. *//*ARGSUSED*/npopen(dev,flag)dev_t dev;int flag;{ int unit; unsign16 conn; struct npmaster *mp; int error; if(NpDebug & DEBENTRY) printf("npopen\n"); /* Clear error */ error = 0; /* Make sure it's the superuser */ if(u.u_uid) return(EPERM); /* Get the connection identifier */ if(((conn = NPCONN(dev)) >= NNPCNN) || ((unit = NPUNIT(dev)) >= NNP)) return(ENODEV); if(NpDebug & DEBOPEN) printf("conn = %x unit = %d\n",conn,unit); /* Get the board for the specified unit */ mp = NpBoardChange(NPMAINT,unit); if(mp != (struct npmaster *) 0) { npcnxtab[unit][conn].unit = mp; npcnxtab[unit][conn].protocol = NPMAINT; } else error = ENXIO; if(NpDebug & DEBENTRY) printf("npopen...\n"); return(error);}/* * Np_close is responsible updating the connection table for * that connection by marking it closed. */npclose(dev)dev_t dev;{ if(NpDebug & DEBENTRY) printf("npclose\n"); /* Get the connection identifier */ npcnxtab[NPUNIT(dev)][NPCONN(dev)].protocol = NPCLCONN; if(NpDebug & DEBENTRY) printf("npclose...\n"); return(0);}/* * Npioctl is the main conduit of commands between the I-Board and the * NP support utilities. Relevant information for the request is found in the * cmd and addr parameters. Cmd specifies the function to perform, addr is * command specific. Npioctl returns 0 if successful, or an error number * (which winds up in errno). *//*ARGSUSED*/npioctl(dev,cmd,addr,flag)dev_t dev;int cmd;caddr_t *addr;int flag;{ unsign16 protocol; unsign16 conn; unsign16 unit; int error; register struct npmaster *mp; register struct npreq *rp; unsigned usrarg; if(NpDebug & DEBENTRY) printf("npioctl\n"); /* Clear error */ error = 0; /* Strip off IOC_VOID bit */ cmd &= CMDMASK; /* Get connection identifier */ conn = NPCONN(dev); unit = NPUNIT(dev); /* Master pointer for this unit */ mp = npcnxtab[unit][conn].unit; protocol = npcnxtab[unit][conn].protocol; /* Get a request structure from the pool and initialize it */ while((rp = NpGetReq(mp->reqtab)) == NULL) { mp->reqtab->flags |= WANTREQ; sleep((caddr_t)(mp->reqtab),PZERO -1); } if(NpDebug & DEBREQ) printf("NP Reqp is %x\n",rp); /* Initializations of request structure */ rp->intr = (int (*)())0; /* Do not call interrupt routine */ rp->bufoffset = 0; /* Offset into data buffer */ rp->procp = u.u_procp; /* Process structure for this user */ /* Copy in user's argument to ioctl() call */ if(error = copyin(*addr,&usrarg,sizeof(usrarg))) return(error); if(NpDebug & DEBIOCTL) printf("arg = %x\n",usrarg); /* Execute the specified command */ switch(cmd) { case NPSETPROT: if((error = NpProtChange(usrarg,mp->unit)) == 0) npcnxtab[unit][conn].protocol = usrarg; break; case NPSETBOARD: if(mp = NpBoardChange(protocol,usrarg)) npcnxtab[unit][conn].unit = mp; else { mp = npcnxtab[unit][conn].unit; error = ENXIO; } break; case NPRESET: error = NpReset(mp,rp); break; case NPSETNPDEB: NpDebug = usrarg; break; case NPINIT: error = NpSWinit(mp->unit); break; case NPSTART:#ifdef OLDROM /* * Kludge to work around I-Board boot from Host. Read two bytes * from the board into the Device Configuration Word * in Shared Memory. */ NPIO(mp,(paddr_t)0x500,(paddr_t)(&mp->shmemp->statblock.sb_dcw),2,B_READ); mp->shmemp->statblock.sb_drw = 0;#endif /* Set the Address at which to begin On-Board execution */ error = NpSetXeqAddr(mp,(caddr_t)usrarg); break; case NPSTATS: error = NpStats(); break; case NPGPANIC: error = copyout((caddr_t)NpPbuf,*addr,PANLEN); /* Clear panic request flag and leave */ mp->flags &= ~PANICREQ; break; case NPPOLL: error = NpPoll(mp,*addr); break; case NPKILL: error = NpKill(mp,rp); break; case NPSETADDR: error = NpSetMemAddr(mp,*addr); break; case NPRCSR0: usrarg = RCSR0(mp->iobase); error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); break; case NPRCSR1: usrarg = RCSR1(mp->iobase); error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); break; case NPRCSR2: usrarg = RCSR2(mp->iobase); error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); break; case NPRCSR3: usrarg = RCSR3(mp->iobase); error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); break; case NPWCSR0: WCSR0(mp->iobase,usrarg); break; case NPWCSR1: WCSR1(mp->iobase,usrarg); break; case NPWCSR2: WCSR2(mp->iobase,usrarg); break; case NPWCSR3: WCSR3(mp->iobase,usrarg); break; case NPNETBOOT: error = NpSetIntLevel(mp,mp->vector); if(error) break; error = NpSetXeqAddr(mp,(caddr_t)INETBOOT); break; case NPSETLAST: if (usrarg) mp->flags &= ~LSTCMD; else mp->flags |= LSTCMD; break; case NPCLRICNT: np_icount[unit] = NPCLEAR; break; case NPGETICNT: usrarg = np_icount[unit]; error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); break; case NPGETIVEC: usrarg = mp->vector; error = copyout((caddr_t)&usrarg,*addr,sizeof(usrarg)); break; case NPMAPMEM: error = NpMem(mp, rp, *addr); break; default: printf("Bad Maintenance command: %d!\n",cmd); error = EIO; break; } if((cmd != NPRESET) && (cmd != NPINIT) && (cmd != NPMAPMEM)) NpFreeReq(mp->reqtab,rp); if(NpDebug & DEBENTRY) printf("npioctl...\n"); return(error);}/* * np_start - start io activity */npstart(mp)register struct npmaster *mp;{ register struct uio *uio; register struct buf *bp; register struct npreq *rp; int error; /* Return from NPIO call */ if(NpDebug & DEBENTRY) printf("npstart\n"); if((bp = np_tab[mp->unit].b_actf) == (struct buf *)0) { np_tab[mp->unit].b_active = 0; return; } if((rp = (struct npreq *)(bp->b_rp)) == (struct npreq *)0) { bp->b_flags = B_ERROR; iodone(bp); return; } if ((uio = (struct uio *)bp->b_uio) == (struct uio *)0) { bp->b_flags = B_ERROR; iodone(bp); return; } np_tab[mp->unit].b_active = 1; if(NpDebug & DEBIO) printf("NP IO src %x dst = %x cnt = %x\n", bp->b_un.b_addr, uio->uio_offset, bp->b_bcount); /* Send the request to the board via the CSR0 command interface */ if(bp->b_flags & B_READ) error = NPIO(mp, (paddr_t)uio->uio_offset, (paddr_t)rp->bufaddr, bp->b_bcount, (bp->b_flags & B_READ)); else error = NPIO(mp, (paddr_t)rp->bufaddr, (paddr_t)uio->uio_offset, bp->b_bcount, (bp->b_flags & B_READ)); /* Check return from I/O */ if(error) { bp->b_flags |= B_ERROR; np_tab[mp->unit].b_actf = bp->av_forw; if(NpDebug & DEBIO) printf("NPIO return error: b_flags is %x \n",bp->b_flags); iodone(bp); } if(NpDebug & DEBENTRY) printf("npstart...\n");}/* * npstrategy - the strategy routine */npstrategy(bp)register struct buf *bp;{ register struct buf *ip; /* quick pointer */ register struct npmaster *mp; /* master structure for this device */ register struct npreq *rp; /* reqest struct pointer */ int s; /* priority to return to */ if(NpDebug & DEBENTRY) printf("npstrategy\n"); if(NpDebug & DEBIO) printf("flag = %x count = %x paddr = %x %x blkno = %x %x\n", bp->b_flags, bp->b_bcount, bp->b_un.b_addr, bp->b_un.b_addr,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -