📄 mp.c
字号:
} mp_freein(ev); adjptr(mp->mp_off, MPINSET); mpstart(tp); break; default: mplog(unit, port, A_INVCMD, (int)ev->ev_cmd); mp_freein(ev); adjptr(mp->mp_off, MPINSET); break; } } }#undef nextevent}mp_freein(ev) register struct mpevent *ev;{ /* re-init all values in this entry */ ev->ev_cmd = 0; ev->ev_opts = 0; ev->ev_error = 0; ev->ev_flags = 0; ev->ev_count = 0; /* show this entry is available for use */ ev->ev_status = EVSTATUS_FREE;}/* * Handler for processing received events. */mprintr(unit, list) u_char *list;{ register struct tty *tp; register struct mpport *mp; register struct mpevent *ev; struct mblok *mb; register int cc; register char *cp; struct mpsoftc *ms; caddr_t ptr; char *rcverr; int port, i; ms = &mp_softc[unit]; mb = mp_softc[unit].ms_mb; for (i = 0; i < MPMAXPORT && (port = *list++) != MPPORT_EOL; i++) { tp = &mp_tty[unit*MPCHUNK + port]; mp = &mb->mb_port[port]; ev = &mp->mp_sendq[mp->mp_nextrcv]; while (ev->ev_status & EVSTATUS_DONE) { switch(ev->ev_cmd) { case EVCMD_STATUS: /* * Status change, look for carrier changes. */ switch(ev->ev_opts) { case DCDASRT: (*linesw[tp->t_line].l_modem)(tp, 1); wakeup((caddr_t)&tp->t_canq); break; case DCDDROP: (*linesw[tp->t_line].l_modem)(tp, 0); wakeup((caddr_t)&tp->t_canq); break; case NORBUF: case NOEBUF: mplog(unit, port, "out of receive events", 0); break; default: mplog(unit, port, "unexpect status command", (int)ev->ev_opts); break; } break; case EVCMD_READ: /* * Process received data. */ if ((tp->t_state & TS_ISOPEN) == 0) { wakeup((caddr_t)&tp->t_rawq); break; } if ((cc = ev->ev_count) == 0) break; cp = ms->ms_cbuf[port][mp->mp_nextrcv]; mppurge(cp, CBSIZE); while (cc-- > 0) { /* * A null character is inserted, * potentially when a break or framing * error occurs. If we're not in raw * mode, substitute the interrupt * character. */ /*** XXX - FIXUP ***/ if (*cp == 0 && (ev->ev_error == BRKASRT || ev->ev_error == FRAMERR)) if ((tp->t_flags&RAW) == 0) ; /* XXX was break */ (*linesw[tp->t_line].l_rint)(*cp++, tp); } /* setup for next read */ ptr = (caddr_t)&mp_softc[unit].ms_cbuf[port][mp->mp_nextrcv][0]; ev->ev_un.rcvblk = (u_char *)kvtophys(ptr); ev->ev_params = (caddr_t) kvtophys(ptr); switch(ev->ev_error) { case RCVDTA: /* Normal (good) rcv data do not * report the following they are * "normal" errors */ case FRAMERR: /* frame error */ case BRKASRT: /* Break condition */ case PARERR: /* parity error */ rcverr = (char *)0; break; case OVRNERR: /* Overrun error */ rcverr = "overrun error"; break; case OVFERR: /* Overflow error */ rcverr = "overflow error"; break; default: rcverr = "undefined rcv error"; break; } if (rcverr != (char *)0) mplog(unit, port, rcverr, (int)ev->ev_error); break; default: mplog(unit, port, "unexpected command", (int)ev->ev_cmd); break; } ev->ev_cmd = 0; ev->ev_opts = 0; ev->ev_error = 0; ev->ev_flags = 0; ev->ev_count = 0; ev->ev_status = EVSTATUS_GO; /* start next read */ adjptr(mp->mp_nextrcv, MPOUTSET); ev = &mp->mp_sendq[mp->mp_nextrcv]; } }}/* * Log an mpcc diagnostic. */mplog(unit, port, cp, flags) char *cp;{ if (flags) log(LOG_ERR, "mp%d: port%d, %s (%d)\n", unit, port, cp, flags); else log(LOG_ERR, "mp%d: port%d, %s\n", unit, port, cp);}int MPHOSTINT = 1;mptimeint(mb) register struct mblok *mb;{ mb->mb_mpintcnt = 0; mb->mb_mpintclk = (caddr_t)0; *(u_short *)mpinfo[mb->mb_unit]->ui_addr = 2;}/* * Interupt mpcc */mpintmpcc(mb, port) register struct mblok *mb;{ mb->mb_intr[port] |= MPSEMA_WORK; if (++mb->mb_mpintcnt == MPHOSTINT) { mb->mb_mpintcnt = 0; *(u_short *)mpinfo[mb->mb_unit]->ui_addr = 2; if (mb->mb_mpintclk) { untimeout(mptimeint, (caddr_t)mb); mb->mb_mpintclk = 0; } } else { if (mb->mb_mpintclk == 0) { timeout(mptimeint, (caddr_t)mb, 4); mb->mb_mpintclk = (caddr_t)1; } }}static char *mpherrmsg[] = { "", "Bus error", /* MPBUSERR */ "Address error", /* ADDRERR */ "Undefined ecc interrupt", /* UNDECC */ "Undefined interrupt", /* UNDINT */ "Power failure occurred", /* PWRFL */ "Stray transmit done interrupt", /* NOXENTRY */ "Two fast timers on one port", /* TWOFTMRS */ "Interrupt queue full", /* INTQFULL */ "Interrupt queue ack error", /* INTQERR */ "Uncorrectable dma parity error", /* CBPERR */ "32 port ACAP failed power up", /* ACPDEAD */};#define NHERRS (sizeof (mpherrmsg) / sizeof (mpherrmsg[0]))mperror(mb, unit) register struct mblok *mb; int unit;{ register char *cp; register int i; if (mb->mb_softerr) { switch (mb->mb_softerr) { case DMAPERR: /* dma parity error */ cp = "dma parity error"; break; case ECCERR: cp = "local memory ecc error"; break; default: cp = "unknown error"; break; } log(LOG_ERR, "mp%d: soft error, %s", unit, cp); mb->mb_softerr = 0; } if (mb->mb_harderr) { if (mb->mb_harderr < NHERRS) cp = mpherrmsg[mb->mb_harderr]; else cp = "unknown error"; log(LOG_ERR, "mp%d: hard error, %s", unit, cp); if (mb->mb_status == MP_OPOPEN) { for (i = 0; i < MPMAXPORT; i++) { mpcleanport(mb, i); mb->mb_proto[i] = MPPROTO_UNUSED; } } mb->mb_harderr = 0; mb->mb_status = 0; }}mppurge(addr, cc) register caddr_t addr; register int cc;{ for (; cc >= 0; addr += NBPG, cc -= NBPG) mtpr(P1DC, addr);}/* * MPCC Download Pseudo-device. */char mpdlbuf[MPDLBUFSIZE];int mpdlbusy; /* interlock on download buffer */int mpdlerr;mpdlopen(dev) dev_t dev;{ int unit, mpu; struct vba_device *vi; unit = minor(dev); mpu = MPUNIT(unit); if (mpu >= NMP || (vi = mpinfo[mpu]) == 0 || vi->ui_alive == 0) return (ENODEV); return (0);}mpdlwrite(dev, uio) dev_t dev; struct uio *uio;{ register struct mpsoftc *ms = &mp_softc[MPUNIT(minor(dev))]; register struct mpdl *dl; int error; if (ms->ms_mb == 0 || ms->ms_mb->mb_status != MP_DLOPEN) return (EFAULT); dl = &ms->ms_mb->mb_dl; dl->mpdl_count = uio->uio_iov->iov_len; dl->mpdl_data = (caddr_t) kvtophys(mpdlbuf); if (error = uiomove(mpdlbuf, (int)dl->mpdl_count, uio)) return (error); uio->uio_resid -= dl->mpdl_count; /* set up return from write */ dl->mpdl_cmd = MPDLCMD_NORMAL; error = mpdlwait(dl); return (error);}mpdlclose(dev) dev_t dev;{ register struct mblok *mb = mp_softc[MPUNIT(minor(dev))].ms_mb; if (mb == 0 || mb->mb_status != MP_DLDONE) { mpbogus.status = 0; if (mpbogus.mb == mpbogus.mbloks[MPUNIT(minor(dev))]) mpdlbusy--; return (EEXIST); } mb->mb_status = MP_OPOPEN; mpbogus.status = 0; /* set to dead, for board handshake */ mb->mb_hostint.imok = MPIMOK_DEAD; return (0);}/* ARGSUSED */mpdlioctl(dev, cmd, data, flag) dev_t dev; caddr_t data;{ register struct mblok *mb; register struct mpdl *dl; int unit, error = 0, s, i; mb = mp_softc[unit=MPUNIT(minor(dev))].ms_mb; if (mb == 0) return (EEXIST); dl = &mb->mb_dl; error = 0; switch (cmd) { case MPIOPORTMAP: bcopy(data, (caddr_t)mb->mb_proto, sizeof (mb->mb_proto)); break; case MPIOHILO: bcopy(data, (caddr_t)&mb->mb_hiport, 2*(sizeof(mb->mb_hiport))); break; case MPIOENDDL: dl->mpdl_count = 0; dl->mpdl_data = 0; dl->mpdl_cmd = MPIOENDDL&IOCPARM_MASK; error = mpdlwait(dl); mpccinit(unit); mb->mb_status = MP_DLDONE; mpdlbusy--; break; case MPIOENDCODE: dl->mpdl_count = 0; dl->mpdl_data = 0; dl->mpdl_cmd = MPIOENDCODE&IOCPARM_MASK; error = mpdlwait(dl); break; case MPIOASYNCNF: bcopy(data, mpdlbuf, sizeof (struct abdcf)); dl->mpdl_data = (caddr_t) kvtophys(mpdlbuf); dl->mpdl_count = sizeof (struct abdcf); dl->mpdl_cmd = MPIOASYNCNF&IOCPARM_MASK; error = mpdlwait(dl); break; case MPIOSTARTDL: s = spl8(); while (mpdlbusy) if (error = tsleep((caddr_t)&mpdlbusy, (PZERO+1) | PCATCH, devioc, 0)) break; splx(s); if (error) break; mpdlbusy++; /* initialize the downloading interface */ mpbogus.magic = MPMAGIC; mpbogus.mb = mpbogus.mbloks[unit]; mpbogus.status = 1; dl->mpdl_status = EVSTATUS_FREE; dl->mpdl_count = 0; dl->mpdl_cmd = 0; dl->mpdl_data = (char *) 0; mpdlerr = 0; mb->mb_magic = MPMAGIC; mb->mb_ivec = mp_softc[unit].ms_ivec+1; /* download vector */ mb->mb_status = MP_DLPEND; mb->mb_diagswitch[0] = 'A'; mb->mb_diagswitch[1] = 'P'; s = spl8(); *(u_short *)mpinfo[unit]->ui_addr = 2; error = tsleep((caddr_t)&mb->mb_status, (PZERO+1) | PCATCH, devio, 30*hz); splx(s); if (error == EWOULDBLOCK) error = ETIMEDOUT; if (error) mpbogus.status = 0; bzero((caddr_t)mb->mb_port, sizeof (mb->mb_port)); break; case MPIORESETBOARD: s = spl8(); if (mb->mb_imokclk) mb->mb_imokclk = 0; *(u_short *)mpinfo[unit]->ui_addr = 0x100; if (mb->mb_status == MP_DLOPEN || mb->mb_status == MP_DLDONE) { mpdlerr = MP_DLERROR; dl->mpdl_status = EVSTATUS_FREE; wakeup((caddr_t)&dl->mpdl_status); mpbogus.status = 0; } for (i = 0; i < MPMAXPORT; i++) { if (mb->mb_harderr || mb->mb_softerr) mperror(mb, i); mpcleanport(mb, i); mb->mb_proto[i] = MPPROTO_UNUSED; } mb->mb_status = 0; splx(s); break; default: error = EINVAL; break; } return (error);}mpccinit(unit) int unit;{ register struct mblok *mb = mp_softc[unit].ms_mb; register struct his *his; register int i, j; mb->mb_status = MP_DLDONE; mb->mb_ivec = mp_softc[unit].ms_ivec; mb->mb_magic = MPMAGIC; /* Init host interface structure */ his = &mb->mb_hostint; his->semaphore = MPSEMA_AVAILABLE; for (i = 0; i < NMPPROTO; i++) for (j = 0; j < MPMAXPORT; j++) { his->proto[i].inbdone[j] = MPPORT_EOL; his->proto[i].outbdone[j] = MPPORT_EOL; } mb->mb_unit = unit;}mpdlintr(mpcc) int mpcc;{ register struct mblok *mb; register struct mpdl *dl; mb = mp_softc[mpcc].ms_mb; if (mb == 0) { printf("mp%d: stray download interrupt\n", mpcc); return; } dl = &mb->mb_dl; switch (mb->mb_status) { case MP_DLOPEN: if (dl->mpdl_status != EVSTATUS_DONE) mpdlerr = MP_DLERROR; dl->mpdl_status = EVSTATUS_FREE; wakeup((caddr_t)&dl->mpdl_status); return; case MP_DLPEND: mb->mb_status = MP_DLOPEN; wakeup((caddr_t)&mb->mb_status); /* fall thru... */ case MP_DLTIME: return; case MP_OPOPEN: if (mb->mb_imokclk) mb->mb_imokclk = 0; mb->mb_nointcnt = 0; /* reset no interrupt count */ mb->mb_hostint.imok = MPIMOK_DEAD; mb->mb_imokclk = (caddr_t)1; break; default: log(LOG_ERR, "mp%d: mpdlintr, status %x\n", mpcc, mb->mb_status); break; }}/* * Wait for a transfer to complete or a timeout to occur. */mpdlwait(dl) register struct mpdl *dl;{ int s, error = 0; s = spl8(); dl->mpdl_status = EVSTATUS_GO; while (dl->mpdl_status != EVSTATUS_FREE) { error = tsleep((caddr_t)&dl->mpdl_status, (PZERO+1) | PCATCH, devout, 0); if (mpdlerr == MP_DLERROR) error = EIO; if (error) break; } splx(s); return (error);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -