📄 np.c
字号:
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 + -