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