📄 lpa.c
字号:
}lpamcode(lpaaddr, sc, uio) register struct lpadevice *lpaaddr; register struct lpa_softc *sc; struct uio *uio;{ short v, r; register int mcaddr; int error; mcaddr = 0; while (uio->uio_resid) { error = uiomove(&v, 2, UIO_WRITE, uio); if (error) break; lpaaddr->lcim = 0; /* load microcode word */ lpaaddr->lrda = mcaddr; lpaaddr->lms = v; lpaaddr->lcim = ROMO; lpaaddr->lcim |= CWRITE; lpaaddr->lcim = 0; /* verify microcode word */ lpaaddr->lrda = mcaddr; lpaaddr->lcim = ROMO; if ((r = lpaaddr->lms) != v) { /* download failure */ printf("LPA MICROCODE FAIL: exp:%o got:%o\n", v, r); return (ENXIO); } mcaddr++; } lpaaddr->lcim = RUN | EA; /* turn it on */ sc->sc_flag |= MCODE; lpaaddr->lcim |= IIE; lpaaddr->lcos |= OIE; return (error);TRACER("MCODE\n");}lpadmdt(lpaaddr, sc, ubanum, uio) register struct lpadevice *lpaaddr; register struct lpa_softc *sc; register short ubanum; struct uio *uio;{ register short *p; register int n; int error; p = (short *) sc->sc_buffer->b_un.b_addr; /* INIT */ *p++ = (MCVERS << 8) | INIT; /* mode */ *p++ = ACLOCKA; /* LPA bus device addresses */ *p++ = ACLOCKB; *p++ = AAD1; *p++ = AAD2; *p++ = ADA; *p++ = ADIO1; *p++ = ADIO2; *p++ = ADIO3; *p++ = ADIO4; *p++ = ADIO5; n = min(uio->uio_resid, 256); /* dedicated mode dispatch table */ error = uiomove((char *)p, n, UIO_WRITE, uio); if (error) return (error); n >>= 1; p += n; while (n++ < 128) *p++ = 0; lpacmd(sc->sc_buffer, lpaaddr, sc, ubanum); sc->sc_flag |= DMDT; return (0);TRACER("DMDT\n");}lpaioctl(dev, cmd, data, flag) dev_t dev; caddr_t data;{ register int unit = LPAUNIT(dev); register struct lpa_softc *sc = &lpa_softc[unit]; register struct uba_device *ui = lpadinfo[unit]; register struct lpadevice *lpaaddr = (struct lpadevice *) ui->ui_addr; register short *p; register int i; register int v; struct iocb { short *baddr; short rate; short wc; } *iocb;TRACER("IOCTL IN\n"); if (cmd != TIOCSETP || (sc->sc_flag & DMDT) == 0) return (ENXIO); iocb = (struct iocb *)data; p = (short *) sc->sc_buffer->b_un.b_addr; /* CLOCK START */ *p++ = CLOCK | CLOCKA; /* mode */ *p++ = ENACTR | R1M | MFIE | MRI; /* clock status */ *p = iocb->rate; /* clock preset */ lpacmd(sc->sc_buffer, lpaaddr, sc, ui->ui_ubanum);TRACER("CLOCK STARTED\n"); p = (short *) sc->sc_buffer->b_un.b_addr; /* DATA TRANSFER START*/ *p++ = (sc->sc_device << 7) | DTS | SCHAN; /* mode */ sc->sc_count = iocb->wc & 017777; /* word count per buffer */ *p++ = sc->sc_count; /* user status word */ sc->sc_ustatbuf.b_un.b_addr = (caddr_t) &sc->sc_ustat; sc->sc_ustatbuf.b_flags = 0; sc->sc_ustatbuf.b_bcount = 2; sc->sc_ustatbuf.b_proc = u.u_procp; sc->sc_ubaustat = ubasetup(ui->ui_ubanum, &sc->sc_ustatbuf, 0); v = sc->sc_ubaustat; *p++ = v; *p = (v >> 16) & 03; /* into low portion of word */ sc->sc_nbuf = (iocb->wc >> 13) & 07; /* number of buffers */ *p++ |= sc->sc_nbuf++ << 8; /* into high portion of word */ /* buffer addresses */ if (useracc(sc->sc_ubuffer.b_un.b_addr = (caddr_t) iocb->baddr, sc->sc_ubuffer.b_bcount = sc->sc_count * sc->sc_nbuf * 2, (i = (sc->sc_device)? B_READ : B_WRITE) ) == NULL) {TRACER("USER BUFFER FAULT\n"); return (EFAULT); } sc->sc_ubuffer.b_flags = B_PHYS | B_BUSY | i; sc->sc_ubuffer.b_proc = u.u_procp; u.u_procp->p_flag |= SPHYSIO; vslock(sc->sc_ubuffer.b_un.b_addr, sc->sc_ubuffer.b_bcount); sc->sc_ubabuf = ubasetup(ui->ui_ubanum, &sc->sc_ubuffer, 0); v = sc->sc_ubabuf; for (i = 0; i < sc->sc_nbuf; i++) { *p++ = v; *p++ = (v >> 16) & 03; v += sc->sc_count * 2; } for ( ; i <= 7; i++) { *p++ = 0; *p++ = 0; } *p++ = 0; *p++ = 0; /* random channel list address */ *p++ = 0; /* delay */ *p++ = sc->sc_channel; /* start channel, channel inc */ *p++ = 1; /* number of samples in a sequence */ *p++ = 0; /* dwell */ *p++ = 0; /* start word no., event mark word */ *p++ = 0; /* start word mask */ *p = 0; /* event mark mask */ sc->sc_ustat = 0; sc->sc_start = (sc->sc_device)? sc->sc_nbuf+1 : 1; sc->sc_lbufn = 0; sc->sc_lbufnx = 0; sc->sc_flag |= STTY;TRACER("IOCTL OUT\n"); return (0);}lparead(dev, uio) dev_t dev; struct uio *uio;{ register int unit = LPAUNIT(dev); register struct lpa_softc *sc = &lpa_softc[unit]; register struct uba_device *ui = lpadinfo[unit]; register struct lpadevice *lpaaddr = (struct lpadevice *) ui->ui_addr;TRACER("READ\n"); if ((sc->sc_flag & STTY) == 0) return (ENXIO); if (sc->sc_flag & ERROR) return (ENXIO); if (sc->sc_start) if (--sc->sc_start == 0) { lpacmd(sc->sc_buffer, lpaaddr, sc, ui->ui_ubanum);TRACER("START\n"); } inc(sc_ubufn); if (sc->sc_start == 0) { (void) spl5(); while (sc->sc_ubufn == sc->sc_lbufn) { if (sc->sc_flag & ERROR) return (ENXIO);TRACER("SLEEP\n"); sc->sc_flag |= SLEEP; sleep(sc, LPAPRI); } (void) spl0(); }TRACERN("READ %d\n", sc->sc_ubufn); return (uiomove(&sc->sc_ubufn, 1, UIO_READ, uio));}lpacmd(bp, lpaaddr, sc, ubanum) register struct buf *bp; register struct lpadevice *lpaaddr; register struct lpa_softc *sc; register short ubanum;{ int ubareg;TRACER("CMD\n"); ubareg = ubasetup(ubanum, bp, UBA_NEEDBDP); lpawait(lpaaddr, sc); lpaaddr->lrda = ubareg; lpaaddr->lcim &= ~RDAEXT; lpaaddr->lcim |= ((ubareg >> (16-RDAEXTOFFSET)) & RDAEXT) | GO; lpawait(lpaaddr, sc); ubarelse(ubanum, &ubareg);}lpawait(lpaaddr, sc) register struct lpadevice *lpaaddr; register struct lpa_softc *sc;{ (void) spl5(); while ((lpaaddr->lcim & READYI) == 0) {TRACER("SLEEP\n"); sc->sc_flag |= SLEEP; sleep((caddr_t)sc, LPAPRI); } (void) spl0();}lpaiintr(unit) int unit;{ register struct lpa_softc *sc = &lpa_softc[unit];TRACER("{I"); if (sc->sc_flag & SLEEP) {TRACER("<WAKEUP>"); wakeup((caddr_t)sc); sc->sc_flag &= ~SLEEP; }TRACER("}");}lpaointr(unit) int unit;{ register int c, m; register struct lpa_softc *sc = &lpa_softc[unit]; register struct uba_device *ui = lpadinfo[unit]; register struct lpadevice *lpaaddr = (struct lpadevice *) ui->ui_addr; int spx;TRACER("{O"); if (sc->sc_flag & SLEEP) {TRACER("<WAKEUP>"); wakeup(sc); sc->sc_flag &= ~SLEEP; } c = lpaaddr->lcos; m = lpaaddr->lms; lpaaddr->lcos &= ~READYO; if (c & ERROR) {TRACER("<ERROR>"); c = (c >> 8) & 0377; if ((sc->sc_flag & STOP) == 0 || (c != OVERRUN)) { printf("LPA ERROR %o %o\n", c, m&0177777); sc->sc_flag |= ERROR; } sc->sc_flag &= ~STOP;TRACER("}\n"); return; }TRACERN("<LPA %d>", sc->sc_lbufnx); sc->sc_lbufn = sc->sc_lbufnx; if (sc->sc_ubufn == sc->sc_lbufnx && c & ECODE) {TRACER("<STOP?>"); if (sc->sc_flag & STOP) return; printf("LPA OVERRUN\n"); sc->sc_flag |= ERROR; } inc(sc_lbufnx);TRACERN("<USTAT %o>", sc->sc_ustat); spx = spl7(); sc->sc_ustat &= ~NBI; sc->sc_ustat |= sc->sc_lbufnx << 8; sc->sc_ustat &= ~DONE; (void) splx(spx);TRACERN("<LPAN %d>}", sc->sc_lbufnx);}lpareset(uban) int uban;{ register struct uba_device *ui; register struct lpadevice *lpaaddr; register struct lpa_softc *sc; register int unit;TRACER("LPA RESET\n"); for (unit = 0; unit < nNLPA; unit++) { if ((ui = lpadinfo[unit]) == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) continue; printf(" lpa%d", unit); lpaaddr = (struct lpadevice *)ui->ui_addr; sc = &lpa_softc[unit]; sc->sc_flag |= ERROR; (void) spl7(); lpaaddr->lcim = RESET; lpaaddr->lcim = 0; (void) spl0(); if (sc->sc_flag & SLEEP) { wakeup((caddr_t)sc); sc->sc_flag &= ~SLEEP; } }}#endif NLPA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -