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

📄 np.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
 * address to be used. The board is specified by mp. */NpSetXeqAddr(mp,addr)struct npmaster *mp;caddr_t addr;{	caddr_t shmaddr;	int error;	struct {		unsign16 cmd_word;		unsign16 hi_addr;		unsign16 lo_addr;		unsign16 mhi_addr;		unsign16 mlo_addr;	} cmd_block;	if(NpDebug & DEBENTRY)		printf("NpSetXeqAddr\n");	shmaddr = (caddr_t)((int)mp->iomapbase & UBADDRMASK);	cmd_block.cmd_word = NPBGN | NPCMD | NPLST | (BGNCNT + CMDCNT);	cmd_block.hi_addr = HIWORD(addr);	cmd_block.lo_addr = LOWORD(addr);	cmd_block.mhi_addr = HIWORD(shmaddr);	cmd_block.mlo_addr = LOWORD(shmaddr);	if(NpDebug & DEBINIT) {		printf("NpSetXeqAdddr: hi: %x lo: %x\n",HIWORD(addr), LOWORD(addr));		printf("NpSetXeqAdddr: mhi: %x mlo: %x\n",HIWORD(shmaddr),LOWORD(shmaddr));	}	error = NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block));	if(NpDebug & DEBENTRY)		printf("NpSetXeqAddr...\n");	return(error);}/* * NPIO issues a CSR0 load or dump request to the I-Board after packaging a * CSR0 Command Block. */NPIO(mp,src,dest,count,dir)struct npmaster *mp;paddr_t dest;paddr_t src;unsign16 count;int dir;		/* Direction  READ/WRITE */{	int error;	struct {		unsign16 cmd_word;	/* Command Word */		unsign16 shi_addr;	/* High word of Source Address */		unsign16 slo_addr;	/* Low word of Source Address */		unsign16 dhi_addr;	/* High word of Destination Address */		unsign16 dlo_addr;	/* Low word of Destination Address */		unsign16 count;		/* Byte count */		unsign16 intlevel;	/* Interrupt level to host */	} cmd_block;	if(NpDebug & DEBENTRY)		printf("NPIO\n");	if(NpDebug & DEBMAINT) {		printf("I/O src addr = %x, dest addr = %x \n",src,dest);		printf("I/O count = %d \n",count);	}	cmd_block.cmd_word = NPCBI | (CBICNT + IOCNT);	cmd_block.intlevel = mp->vector;	cmd_block.shi_addr = HIWORD(src);	cmd_block.slo_addr = LOWORD(src);	cmd_block.dhi_addr = HIWORD(dest);	cmd_block.dlo_addr = LOWORD(dest);	cmd_block.count = count;	if ((mp->flags & LSTCMD) == 0)		cmd_block.cmd_word |= NPLST;	if(dir == B_READ)		cmd_block.cmd_word |= NPDMP;	else		cmd_block.cmd_word |= NPLD;	if(NpDebug & DEBIO) {		printf("cmd: %x int: %o shi: %x slo: %x dhi: %x dlo: %x cnt: %x\n",	cmd_block.cmd_word,cmd_block.intlevel,cmd_block.shi_addr,cmd_block.slo_addr,	cmd_block.dhi_addr,cmd_block.dlo_addr,cmd_block.count);	}		mp->flags |= CSRPEND;		/* CSR0 command pending */	error = NpSendCSR0(mp->iobase,(unsign16 *)&cmd_block,(int)sizeof(cmd_block));	if(NpDebug & DEBENTRY)		printf("NPIO...\n");	return(error);}/* * NpKill will terminate all outstanding requests for the specified board. */NpKill(mp,curr_rp)struct npmaster *mp;struct npreq *curr_rp;{	struct npreq *rp;	int s;	if(NpDebug & DEBENTRY)		printf("NpKill\n");	mp->reqtab->reqcnt = 0;		/* Init request count */	s = spl5();			/* Disable interrupts */	/* Mark each active request as having an error and wake him up */	for(rp = mp->reqtab->forw;rp != mp->reqtab;rp = rp->forw) {		if(rp == curr_rp) continue;		rp->flags |= (IOABORT | REQDONE);		mp->reqtab->reqcnt++;		/* if(rp->flags & NPUIO)			iodone(&rp->buf);		else */		wakeup((caddr_t)rp);	}	if(NpDebug & DEBMAINT)		printf("NpKill, req count is %d\n",mp->reqtab->reqcnt);	splx(s);	if(NpDebug & DEBENTRY)		printf("NpKill...\n");	return(0);}/* Hardware and Software Initializations for the specified unit */NpReset(mp,rp)register struct npmaster *mp;struct npreq *rp;{	int error;	if(NpDebug & DEBENTRY)		printf("NpReset!\n");	/* Mark board as being reset and make unavailable */	mp->flags = BRDRESET;	/* Abort outstanding requests for this board */	mp->reqtab->reqcnt = 0;		/* Init request count */	/* Wakeup Poller if available and wait until he's gone */	if(NpState & ICPAVAIL) {		mp->flags |= BOARDREQ;		mp->reqtab->reqcnt++;		if(NpDebug & DEBMAINT)			printf("Waking ICP in reset!\n");		wakeup((caddr_t)&NpState);		while(mp->reqtab->reqcnt)			if (error = tsleep((caddr_t)(&mp->reqtab),			    (PZERO + 1) | PCATCH, devio, 0))				return (error);		if(NpDebug & DEBMAINT)			printf("Reset:awoken by ICP senior!\n");	}	/* Abort outstanding requests and wait till they're gone */	NpKill(mp,rp);	while(mp->reqtab->reqcnt) {		if(NpDebug & DEBMAINT) {			printf("Sleeping in NpReset on reqtab!\n");			printf("Reqcnt is %d.\n",mp->reqtab->reqcnt);		}		if (error = tsleep((caddr_t)(&mp->reqtab),		    (PZERO + 1) | PCATCH, devio, 0))			return (error);	}	/* Free up I/O Map registers if any allocated */	if(mp->iomapbase) {		if(NpDebug & DEBMEM)			printf("freeing shared memory map.\n");		ubarelse(mp->devp->ui_ubanum,&mp->iomapbase);		mp->iomapbase = 0;	}	/* Initialize S/W data structures in NP Driver */	NpSWinit(mp->unit);		/* Software initialization */	/* Hardware initialization of the board */	error = NpHWinit(mp->unit);	/* Hardware initialization */	mp->flags &= ~BRDRESET;		/* Initialization complete */	/* Initialize Pseudo-Drivers */	if (IxReset)		(*IxReset)(mp->unit, mp->devp->ui_ubanum, rp);	/* Clear Poller's State Flag */	NpState = NPCLEAR;	if(NpDebug & DEBENTRY)		printf("NpReset...\n");		return(error);}/* * General purpose timeout function which sets the flag passed to it * as argument. */NpTimer(flagp)int *flagp;{	*flagp = NPSET;}NpStats(){	if(NpDebug & DEBENTRY)		printf("npstats\n");	return(0);}/* * NpCloseConn is called to issue a close connection command to the I-Board. */NpCloseConn(mp,protocol)struct npmaster *mp;unsign16 protocol;{	register struct npreq *rp;	register struct CQE *ep;	int pri;	if(NpDebug & DEBENTRY)		printf("NpCloseConn\n");	/*	 * Don't issue the Close Connection command if the Board         * isn't up.         */	if(!((mp->shmemp->statblock.sb_dpm) & PROTOMASK(protocol))) {		return;	}	/* Get a Request structure */	while((rp = NpGetReq(mp->reqtab)) == NULL) {		mp->reqtab->flags |= WANTREQ;		sleep((caddr_t)(mp->reqtab),PZERO -1);	}	rp->intr = (int (*)())0;	/* Do not call interrupt routine */	rp->mapbase = 0;		/* Clear mapping information */	ep = rp->element;		/* Handy pointer */	/* Fill in CQE */	ep->cqe_wind = 0;		/* Entire buffer mapped */	ep->cqe_nbuf = 1;		/* Must be 1, no buffer chaining */	ep->cqe_char = 0;		/* Set to 0 for now */	ep->cqe_func = NPSTOP;		/* OS_STP to I-Board */	ep->cqe_prot = protocol;	/* Protocol of this connection */	ep->cqe_lenrpb = 0;		/* Parameter block length */	ep->cqe_ust0 = ep->cqe_ust1 = NPCLEAR;	/* Clear status flags */	ep->cqe_famid = (unsign32)u.u_procp->p_pid;  /* Process ID */	NpAddReq(mp->reqtab,rp);	/* Queue onto active list */	pri = spl5();			/* Mask our interrupts */	NpAddCQE(ep,&mp->shmemp->devcq,mp); /* Add CQE to device's queue */	/* Wait for command to complete */	while(!(rp->flags & REQDONE)) 		sleep((caddr_t)rp,PZERO - 1);	splx(pri);	NpRemReq(rp);			/* Remove request from active list */	NpFreeReq(mp->reqtab,rp);	/* Deallocate request structure */	if(NpDebug & DEBENTRY)		printf("NpCloseConn...\n");}/* * This function allows the protocol to be changed for a given connection. * It returns 0 for success, error code otherwise. */NpProtChange(protocol,unit)register unsign16 protocol;register int unit;{	register struct npmaster *mp;	/* Privileged users only for Maintenance Protocol */	if((protocol == NPMAINT) && (u.u_uid != 0)) 		return(EPERM);	if(NpDebug & DEBMAINT)		printf("NpProtChange = %x\n",protocol);	if(protocol != NPMAINT) {		/* Make sure the I-Board supports the protocol */		mp = &npmasters[unit];		if(!((mp->shmemp->statblock.sb_dpm) & PROTOMASK(protocol)))			return(ENXIO);	}	return(0);}/* * This function allows for the changing of the unit for a given connection. */struct npmaster *NpBoardChange(protocol,unit)register unsign16 protocol;register int unit;			/* Unit number */{	register struct npmaster *mp;	if(unit > NNP)		return((struct npmaster *)0);	if(protocol != NPMAINT) {		/*		 * Loop through the master structures finding a board which 		 * supports the requested protocol.		 */		for(mp = npmasters; mp ; mp = mp->next) {			if(mp->flags & BADBOARD)				continue;			if(((mp->shmemp->statblock.sb_dpm) & PROTOMASK(protocol)))				return(mp);		}		return((struct npmaster *)0);	}	return(&npmasters[unit]);}/* * NpMapMem - maps the user's memory updating the fields in the npreq * structure and returning the mapped address in rp->buffaddr. */NpMapMem(mp,rp,addr,count)register struct npmaster *mp;register struct npreq *rp;caddr_t	addr;int	count;{	if(NpDebug & DEBENTRY)		printf("NpMapMem\n");	if(NpDebug & DEBIO)		printf("mp %x rp %x addr %x count %x\n",mp,rp,addr,count);	rp->virtmem = addr;	rp->bytecnt = count;	rp->buf.b_un.b_addr = addr;	rp->buf.b_flags = B_PHYS | B_BUSY;	rp->buf.b_bcount = count;	rp->buf.b_proc = rp->procp;			rp->procp->p_flag |= P_PHYSIO;	if(NpDebug & DEBENTRY)		printf("vslock\n");	vslock(addr,count);	if(NpDebug & DEBENTRY)		printf("vslock...\n");	rp->mapbase = ubasetup(mp->devp->ui_ubanum,&rp->buf,0);	rp->bufaddr = (caddr_t)(rp->mapbase & UBADDRMASK);	if(NpDebug & DEBENTRY)		printf("NpMapMem...\n");}/* * Unmap the user's memory and free up mapping registers  */NpUnMapMem(mp,rp)struct npmaster *mp;struct npreq *rp;{	if(NpDebug & DEBENTRY)		printf("NpUnMapMem\n");	ubarelse(mp->devp->ui_ubanum,&rp->mapbase);	rp->mapbase = 0;	vsunlock(rp->virtmem,rp->bytecnt,B_READ);	rp->procp->p_flag &= ~P_PHYSIO;	if(NpDebug & DEBENTRY)		printf("NpUnMapMem...\n");}npprobe(reg, ui)caddr_t reg;struct uba_device *ui;{register int br,cvec;u_short csraddr;int i;#ifdef lint	br = 0; cvec = br; br = cvec;#endif	if(NpDebug & DEBINIT)		printf("In npprobe, regaddr is %x!\n",reg);	cvec = (uba_hd[numuba].uh_lastiv -= 4); #ifdef OLDBSD	/* Find unit number from npstd[] by matching the csr address */	csraddr = (u_short)((int)reg & 0x0FFFF);	for(i = 0; i < NNP; i++) {		if(csraddr == npstd[i]) {			npvectors[i] = cvec;			break;		}	}	if(i == NNP)		printf("Couldn't find device in npstd[]!\n");#else	npvectors[ui->ui_unit] = cvec;#endif	br = 0x15;	if(NpDebug & DEBINIT)		printf("npprobe...\n");	return(sizeof(struct NPREG));		/* CSR Registers */}npattach(ui)register struct uba_device *ui;{	if(NpDebug & DEBINIT)		printf("In npattach, ui is %x.\n",ui);	npinit(ui->ui_unit);	if (IxAttach)		(*IxAttach)(ui);	if(NpDebug & DEBINIT)		printf("npattach...\n");}NpMem(mp, rp, uaddr)struct npmaster *mp;struct npreq *rp;unsigned long uaddr;{	struct np_mem mem;	register int error = 0;	if(NpDebug & DEBENTRY)		printf("npmem\n");	if (error = copyin(uaddr, &mem, sizeof(mem)))		return (error);	if (mem.mem_type == NP_SET) {		if (np_mapreq[mp->unit] != (struct npreq *)NPCLEAR)			error = EBUSY;		else {			error = NpMapMem(mp, rp, mem.mem_addr, mem.mem_count);			if (error != 0) {				np_mapreq[mp->unit] = rp;				mem.mem_addr = rp->bufaddr;			}		}	} else if (mem.mem_type == NP_USET) {		error = NpUnMapMem(mp, np_mapreq[mp->unit]);		NpFreeReq(mp->reqtab, rp);		NpFreeReq(mp->reqtab, np_mapreq[mp->unit]);		np_mapreq[mp->unit] = (struct npreq *)NPCLEAR;	} else 		error = EIO;	if (error != 0)		error = copyout(&mem, uaddr, sizeof(mem));	if(NpDebug & DEBENTRY)		printf("npmem...\n");	return (error);}#endif

⌨️ 快捷键说明

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