⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 np.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
		    bp->b_blkno,bp->b_blkno);	/* get master structure */	mp = npcnxtab[NPUNIT(bp->b_dev)][NPCONN(bp->b_dev)].unit;	/* make sure the boards ok */	if (mp->flags & BADBOARD) {		bp->b_flags |= B_ERROR;		if(NpDebug & DEBMEM)			printf("Bad Board %x bp %x\n",mp->flags,bp->b_flags);		np_tab[mp->unit].b_actf = bp->av_forw;		iodone(bp);		return;	}	/* Initializations of request structure */	while((rp = NpGetReq(mp->reqtab)) == NULL) {		mp->reqtab->flags |= WANTREQ;		sleep((caddr_t)(mp->reqtab),PZERO -1);	}	rp->bufoffset = 0;		/* This is the start of the buffer */	ip = &np_tab[mp->unit];	bp->b_rp = (struct buf *)rp;	rp->flags |= KERNREQ;		/* Mark it as kernel so not to map */	rp->mapbase = ubasetup(mp->devp->ui_ubanum,bp,0);	rp->bufaddr = (caddr_t)((int)(rp->mapbase) & UBADDRMASK);	s = spl5();	if(ip->b_actf ==(struct buf *)0)		ip->b_actf = bp;	else {		if(ip->b_actf->av_forw)			printf("Panic NP100 bad buffer chain\n");		ip->b_actf->av_forw = bp;	}	ip->b_actl = bp;	NpAddReq(mp->reqtab,rp);		/* Queue onto active list */	if(ip->b_active == 0) {		if(NpDebug & DEBIO)			printf("calling npstart %x\n",mp);		npstart(mp);	}	splx(s);	if(NpDebug & DEBIO)		printf("back from npstart\n");	/* Await completion of I/O */	iowait(bp);	if(NpDebug & DEBIO)		printf("after iowait in npstrategy\n");	/* Remove request from queue */	NpRemReq(rp);	/* Release mapping registers */	ubarelse(mp->devp->ui_ubanum,&rp->mapbase);	/* Free up request structure */	NpFreeReq(mp->reqtab,rp);	if(NpDebug & DEBENTRY)		printf("Leaving npstrategy flags is %x\n",bp->b_flags);}unsignednptrim(bp)register struct buf *bp;{	if(bp->b_bcount > NPMAXXFR)		bp->b_bcount = NPMAXXFR;}/* * Npread dumps data from the board to the user's buffer */npread(dev,uio)dev_t dev;struct uio *uio;{	struct buf *bp;	bp = &npcnxtab[NPUNIT(dev)][NPCONN(dev)].np_rbuf;	if(NpDebug & DEBENTRY)		printf("in npread\n");	bp->b_uio = (struct buf *)uio;	return(physio(npstrategy,bp,dev,B_READ ,nptrim,uio));}/* * Npwrite loads the np100 board from the user's buffer */npwrite(dev,uio)dev_t dev;struct uio *uio;{	struct buf *bp;	bp = &npcnxtab[NPUNIT(dev)][NPCONN(dev)].np_wbuf;	if(NpDebug & DEBENTRY)		printf("in npwrite \n");	bp->b_uio = (struct buf *)uio;	return(physio(npstrategy,bp,dev,B_WRITE ,nptrim,uio));}/* * npreset - called as result of a UNIBUS reset. */npreset(uban)int uban;{	register struct npmaster *mp;	register struct npreq *rp;	register struct uba_device *ui;	int i;	if(NpDebug & DEBENTRY)		printf("npreset(ubareset)\n");	for(i = 0; i < NNP; i++) {		if(((ui = npdinfo[i]) == (struct uba_device *)NULL) ||			(ui->ui_ubanum != uban))			continue;		mp = &npmasters[i];		/* Get a Request structure */		while((rp = NpGetReq(mp->reqtab)) == NULL) {			mp->reqtab->flags |= WANTREQ;			sleep((caddr_t)(mp->reqtab),PZERO -1);		}		NpReset(mp,rp);	}	if(NpDebug & DEBENTRY)		printf("npreset(ubareset)...\n");}/* * Nppoll looks for work by polling each board. He goes to sleep if there are * no outstanding requests for him but reminds the board that he's there when * needed. */NpPoll(mp,addr)struct npmaster *mp;caddr_t	addr;{	int error;	struct {		unsign16 request;		unsign16 unit;	}icpreq;	if(NpDebug & DEBMAINT)		printf("NpPoll: flags is %x.\n",mp->flags);	while(TRUE) {		for(mp = npmasters; mp; mp = mp->next) {			if(mp->flags & BOARDREQ) {				/* Get request type from master structure */				if(mp->flags & BRDRESET) {					icpreq.request = ICPPOLL;					mp->reqtab->reqcnt--;					if(NpDebug & DEBMAINT)						printf("Waking NpResetter!\n");					wakeup((caddr_t)(&mp->reqtab));				}				else if(mp->flags & PANICREQ)					icpreq.request = ICPPANIC;				else if(mp->flags & DUMPREQ)					icpreq.request = ICPDUMP;				else if(mp->flags & LOADREQ)					icpreq.request = ICPLOAD;				else {					mp->flags &= ~BOARDREQ;					continue;				}				if(NpDebug & DEBMAINT)					printf("ProcICP servicing %d \n",icpreq.request );				/* Request and unit number to be sent */				icpreq.unit = mp->unit;				/* Copy service request to calling process */				error = copyout(&icpreq,addr,sizeof(icpreq));				/* Mark Poller as being unavailable */				NpState &= ~ICPAVAIL;				return(error);			}		}		/* Mark Poller as being available */		NpState |= ICPAVAIL;		if (error = tsleep((caddr_t)&NpState, (PZERO + 1) | PCATCH,		    devio, 0))			return (error);		if(NpDebug & DEBMAINT)			printf("wakeup in NpPoll\n");	}}/* * Software initialization of Driver data structures for the specified unit. */NpSWinit(unit)int unit;{	register int j;	register struct npmaster *mp;	register struct npspace *npsp;	register struct CmdQue *cqp;	int offset;	if(NpDebug & DEBINIT)		printf("SW reset on unit %d.\n",unit);	np_icount[unit] = NPCLEAR;	np_mapreq[unit] = (struct npreq *) NPCLEAR;	/* Initialize master structure pointer for this unit */	mp = &npmasters[unit];	/* Initialize unit buffer headers */	np_tab[unit].b_active = 0;	np_tab[unit].b_actf = 0;	/* UBA device structure for this unit */	mp->devp = npdinfo[unit];	/* Interrupt vector for this unit */	mp->vector = npvectors[unit];	if(unit == (NNP -1))		mp->next = (struct npmaster *)NULL;	else mp->next = &npmasters[unit + 1];	/*	 * Guarantee alignment of shared memory area on a         * 16 byte boundary as required by I-Board	 */	mp->shmemp = &npspaces[unit];	mp->shmemp = (struct npspace *)ROUND16((int)(mp->shmemp));	/* Base address of this controller */	mp->iobase = (struct NPREG *)(mp->devp->ui_addr);	if(NpDebug & DEBMEM) { 		printf("Npspaces starts at %x.\n",npspaces);		printf("Shared memory starts at %x.\n",mp->shmemp);		printf("End of shared memory is %x.\n",&npspaces[unit + 1]);		printf("Iobase is %x.\n",mp->iobase);		printf("Npmasters start at %x\n",npmasters);		printf("Reqhdr start at %x\n",reqhdr);		printf("Npreqs start at %x\n",npreqs); 	}	/* Initialize the request header */	mp->reqtab = &reqhdr[unit];	/* Unit initialization */	mp->unit = unit;	/* Initialize Status Block */	npsp = mp->shmemp;	offset = (int) (mp->shmemp);	npsp->statblock.sb_drw = 0;	npsp->statblock.sb_hcw = HOSTCONF;	npsp->statblock.sb_dcw = 0;	npsp->statblock.sb_dpm = 0;	npsp->statblock.sb_dcq = (unsign16)((int)(&npsp->devcq))-offset;	npsp->statblock.sb_hcq = (unsign16)((int)(&npsp->hostcq))-offset;	/* Initialize Device Command Queue */	cqp = (struct CmdQue *) &npsp->devcq;	if(NpDebug & DEBCQ) 		printf("Device CQ at %x\n",cqp);	cqp->scanflag = NPCLEAR;	cqp->chngflag = NPCLEAR;	cqp->cq_add = (unsign16)(int)(&cqp->cq_cqe[0]) - offset;	cqp->cq_rem = cqp->cq_add;	cqp->cq_wrap = (unsign16)(int)(&cqp->cq_cqe[NUMCQE]) - offset;	for(j = 0; j < NUMCQE; j++)		cqp->cq_cqe[j] = (unsign16)NULL;	/* Initialize Host Command Queue */	cqp = (struct CmdQue *) &npsp->hostcq;	if(NpDebug & DEBCQ) 		printf("HOST CQ at %x\n",cqp);	cqp->scanflag = NPCLEAR;	cqp->chngflag = NPCLEAR;	cqp->cq_add = (unsign16)(int)(&cqp->cq_cqe[0]) - offset;	cqp->cq_rem = cqp->cq_add;	cqp->cq_wrap = (unsign16)(int)(&cqp->cq_cqe[NUMCQE]) - offset;	for(j = 0; j < NUMCQE; j++)		cqp->cq_cqe[j] = (unsign16)NULL;	/*	 * Initialize the reqid of the elements to the address	 * of the corresponding Npreq structure. These don't change. 	 */	for(j = 0; j < NUMCQE; j++)		npsp->elements[j].cqe_reqid = &npreqs[unit][j];	/*	 * Initialize the Request Header (reqhdr), free list of 	 * npreqs, and pointers to CQEs. 	 */	reqhdr[unit].forw = reqhdr[unit].back = &reqhdr[unit];	reqhdr[unit].free = &npreqs[unit][0];	for(j = 0; j < NUMCQE; j++) {		npreqs[unit][j].free = &npreqs[unit][j + 1];		npreqs[unit][j].element = &npsp->elements[j];		npreqs[unit][j].forw = npreqs[unit][j].back = (struct npreq *)NULL;		npreqs[unit][j].flags = NPCLEAR;	}	npreqs[unit][--j].free = &reqhdr[unit];	/*	 * Set up the UNIBUS I/O Map Registers for the	 * Shared memory area. 	 */	mp->iomapbase = uballoc(mp->devp->ui_ubanum,(caddr_t)(mp->shmemp),sizeof(struct npspace),0);	if(NpDebug & DEBENTRY)		printf("SW_Init...\n");	return(0);}/* * NpHWinit() issues a hardware reset to the specified board and waits * for on-board diagnostics to complete. It returns 0 if the board is * present and passed diagnostics, an error value otherwise. */NpHWinit(unit)int unit;{	register struct npmaster *mp;	struct NPREG *REG;	unsign16 status;	int dflag;	if(unit >= NNP)		return(ENXIO);	mp = &npmasters[unit];	if(NpDebug & DEBENTRY)		printf("NpHWinit\n");	/* See if the board is out there */	REG = (struct NPREG *)mp->iobase;	if(NpDebug & DEBINIT)		printf("REG in HWinit is %x.\n",mp->iobase);	if(!(mp->flags & BRDRESET))		if(badaddr(REG,2)) {			mp->flags |= BADBOARD;			printf("\nNP100 unit %d not found!\n",unit);			return(ENXIO);		}	if(NpDebug & DEBENTRY)		printf("Resetting the NP100 Board at %x\n",mp->iobase);	/* Reset the Board */	RESET(mp);	dflag = NPCLEAR;	timeout(NpTimer,&dflag,DIAGTIME);	/* Wait for Enable and Read Data Ready to go high */	while(! ((RCSR1(mp->iobase) & NPENB) && (RCSR1(mp->iobase) & NPRDR))) {		if(dflag)			break;	}	untimeout(NpTimer,&dflag);	if(NpDebug & DEBINIT)		printf("np reset %d \n",dflag);	if(dflag) {		mp->flags |= BADBOARD;		printf("NP100 Unit %d timed out!\n",unit);		return(EIO);	}	status = RCSR0(mp->iobase);	/* Check for Hardware OK */	if(!(RCSR1(mp->iobase) & NPHOK)) {		mp->flags |= BADBOARD;		printf("NP100 Unit %d Failed diagnostics!\n",unit);		printf("Status from CSR0: %x.\n",status);		return(EIO);	}	if(NpDebug & DEBENTRY)		printf("HWinit...\n");	return(0);}/* * NP Driver Interrupt Handler */npintr(unit)int unit;{	register struct npmaster *mp;	register struct buf	*bp;	if(NpDebug & DEBENTRY)		printf("npintr on unit %d!\n",unit);	mp = &npmasters[unit];	np_icount[unit]++;	if(NpDebug & DEBINTR)		printf("npintr mp->flags = %x  interupt count = %x\n",			mp->flags, np_icount[unit]);	/* Wake up anyone sleeping on a CSR0 Command */	if(mp->flags & CSRPEND) {		mp->flags &= ~CSRPEND;		if(np_tab[mp->unit].b_active) {			np_tab[mp->unit].b_active = 0;			bp = np_tab[mp->unit].b_actf;			np_tab[mp->unit].b_actf = bp->av_forw;			if(NpDebug & DEBINTR)				printf("bp = %x resid = %d forw = %x\n",bp,				    bp->b_resid,bp->av_forw);			bp->b_resid = 0;			iodone(bp);		}		if(mp->flags & PANIC3) {			mp->flags &= ~PANIC3;			mp->flags = AVAILABLE;			ubarelse(mp->devp->ui_ubanum,&panicmap);		}		if(mp->flags & PANIC2) {			mp->flags &= ~PANIC2;			printf("Panic Message: %s",NpPbuf);			mp->flags |= PANIC3;			NpPbuf[0] = 0;			NPIO(mp,(paddr_t)((int) panicmap & UBADDRMASK),(paddr_t)pstring,sizeof(NpPbuf),B_WRITE);		}		if(mp->flags & PANIC1) {			mp->flags &= ~PANIC1;			mp->flags |= PANIC2;			ubarelse(mp->devp->ui_ubanum,&panicmap);			panicmap = uballoc(mp->devp->ui_ubanum,(caddr_t)NpPbuf,sizeof(NpPbuf),0);			pstring = (caddr_t)((panaddr[1] << 4) + panaddr[0]);			NPIO(mp,(paddr_t)pstring,(paddr_t)((int) panicmap & UBADDRMASK),sizeof(NpPbuf),B_READ);		}		wakeup((caddr_t)mp);		goto out;	}	/* Mark unit as being available if Device Protocol Mask set */	if(!(mp->flags & AVAILABLE)) {		if((mp->shmemp->statblock.sb_dpm) && (!(mp->flags & BRDRESET)))			mp->flags = AVAILABLE;	}	/* Honor service requests from the device */	switch(mp->shmemp->statblock.sb_drw) {	    case NOREQ:		break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -