📄 dmf.c
字号:
addr->dmftbuf = *cp++; ndflush(&tp->t_outq, nch); tp->t_state |= TS_BUSY; }out: splx(s);}/* * Stop output on a line, e.g. for ^S/^Q or output flush. *//*ARGSUSED*/dmfstop(tp, flag) register struct tty *tp;{ register struct dmfdevice *addr; register int unit, s; addr = (struct dmfdevice *)tp->t_addr; /* * Block input/output interrupts while messing with state. */ s = spl5(); if (tp->t_state & TS_BUSY) { /* * Device is transmitting; stop output * by selecting the line and disabling * the transmitter. If this is a flush * request then flush the output silo, * otherwise we will pick up where we * left off by enabling the transmitter. */ unit = minor(tp->t_dev); addr->dmfcsr = DMFIR_LCR | (unit&LINEMASK) | DMF_IE; /* * If this test isn't done, the hardware will need to see a * start character to get it going again if DMF_AUTOX is set. */ if ((tp->t_cflag_ext & PAUTOFLOW) == 0) SETLCR(addr, addr->dmflcr &~ DMF_TE); if ((tp->t_state&TS_TTSTOP)==0) { tp->t_state |= TS_FLUSH; SETLCR(addr, addr->dmflcr|DMF_FLUSH); } else tp->t_state &= ~TS_BUSY; } splx(s);}/* * DMF32 modem control */dmfmctl(dev, bits, how) dev_t dev; int bits, how;{ register struct dmfdevice *dmfaddr; register int unit, mbits, lcr; int s; unit = minor(dev); dmfaddr = (struct dmfdevice *)(dmf_tty[unit].t_addr); unit &= LINEMASK; s = spl5(); dmfaddr->dmfcsr = DMF_IE | DMFIR_TBUF | unit; mbits = dmfaddr->dmfrms << 8; dmfaddr->dmfcsr = DMF_IE | DMFIR_LCR | unit; mbits |= dmfaddr->dmftms; lcr = dmfaddr->dmflcr; switch (how) { case DMSET: mbits = (mbits &0xff00) | bits; break; case DMBIS: mbits |= bits; break; case DMBIC: mbits &= ~bits; break; case DMGET: (void) splx(s); return(mbits); } if (mbits & DMF_BRK) lcr |= DMF_RBRK; else lcr &= ~DMF_RBRK; lcr = ((mbits & 037) << 8) | (lcr & 0xff); dmfaddr->dmfun.dmfirw = lcr; (void) splx(s); return(mbits);}/* * Reset state of driver if UBA reset was necessary. * Reset the csr, lpr, and lcr registers on open lines, and * restart transmitters. */dmfreset(uban) int uban;{ register int dmf, unit; register struct tty *tp; register struct uba_device *ui; register struct dmfdevice *addr; int i; if (tty_ubinfo[uban] == 0) return; cbase[uban] = tty_ubinfo[uban]&0x3ffff; for (dmf = 0; dmf < nNDMF; dmf++) { ui = dmfinfo[dmf]; if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban) continue; printf(" dmf%d", dmf); addr = (struct dmfdevice *)ui->ui_addr; addr->dmfcsr = DMF_IE; addr->dmfrsp = dmf_timeout; unit = dmf * 8; for (i = 0; i < 8; i++) { tp = &dmf_tty[unit]; if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { dmfparam(unit); (void) dmfmctl(unit, DMF_ON, DMSET); tp->t_state &= ~TS_BUSY; dmfstart(tp); } unit++; } }}/* dmflopen -- open the line printer port on a dmf32 * */dmflopen(dev,flag)dev_t dev;int flag;{ register int dmf; register struct dmfl_softc *sc; register struct uba_device *ui; register struct dmfdevice *addr; dmf = minor(dev) & LINEMASK ; if(((sc= &dmfl_softc[dmf])->dmfl_state & OPEN) || ((ui=dmfinfo[dmf]) == 0) || ui->ui_alive == 0) return(ENXIO); addr = (struct dmfdevice *)ui->ui_addr; if((addr->dmfl[0] & DMFL_OFFLINE)) { /*printf("dmf%d: line printer offline/jammed\n", dmf);*/ return(EIO); } if((addr->dmfl[0]&DMFL_CONV)) { printf("dmf%d: line printer disconnected\n", dmf); return(EIO); } addr->dmfl[0] = 0; sc->dmfl_state |= OPEN; return 0;}dmflclose(dev,flag)dev_t dev;int flag;{ register int dmf= minor(dev) & LINEMASK; register struct dmfl_softc *sc = &dmfl_softc[dmf]; dmflout(dev,"\f",1); sc->dmfl_state = 0; if(sc->dmfl_info != 0) ubarelse((struct dmfdevice *)(dmfinfo[dmf])->ui_ubanum, &(sc->dmfl_info)); ((struct dmfdevice *)(dmfinfo[dmf]->ui_addr))->dmfl[0]=0; return 0;}dmflwrite(dev,uio)dev_t dev;struct uio *uio;{ register unsigned int n; register int error; register struct dmfl_softc *sc; sc = &dmfl_softc[minor(dev)&LINEMASK]; if(sc->dmfl_state&ERROR) return(EIO); while(n=min(DMFL_BUFSIZ,(unsigned)uio->uio_resid)) { if(error=uiomove(&sc->dmfl_buf[0],(int)n, UIO_WRITE,uio)) { printf("uio move error\n"); return(error); } if(error=dmflout(dev,&sc->dmfl_buf[0],n)) { return(error); } } return 0;}/* dmflout -- start io operation to dmf line printer * cp is addr of buf of n chars to be sent. * * -- dmf will be put in formatted output mode, this will * be selectable from an ioctl if the * need ever arises. */dmflout(dev,cp,n)dev_t dev;char *cp;int n;{ register struct dmfl_softc *sc; register int dmf; register struct uba_device *ui; register struct dmfdevice *d; register unsigned info; register unsigned i; dmf = minor(dev) & LINEMASK ; sc= &dmfl_softc[dmf]; if(sc->dmfl_state&ERROR) return(EIO); ui= dmfinfo[dmf]; /* allocate unibus resources, will be released when io * operation is done */ sc->dmfl_info= info= uballoc(ui->ui_ubanum,cp,n,0); d= (struct dmfdevice *)ui->ui_addr; d->dmfl[0] = (2<<8) | DMFL_FORMAT; /* indir reg 2 */ /* indir reg auto increments on r/w */ /* SO DON'T CHANGE THE ORDER OF THIS CODE */ d->dmfl[1] = 0; /* prefix chars & num */ d->dmfl[1] = 0; /* suffix chars & num */ d->dmfl[1] = info; /* dma lo 16 bits addr */ /* NOT DOCUMENTED !! */ d->dmfl[1] = -n; /* number of chars */ /* ----------^-------- */ d->dmfl[1] = ((info>>16)&3) /* dma hi 2 bits addr */ | (1<<8) /* auto cr insert */ | (1<<9) /* use real ff */ | (1<<15); /* no u/l conversion */ d->dmfl[1] = sc->dmfl_lines /* lines per page */ | (sc->dmfl_cols<<8); /* carriage width */ sc->dmfl_state |= ASLP; i=spl5(); d->dmfl[0] |= DMFL_PEN|DMFL_IE; while(sc->dmfl_state & ASLP) { sleep(&sc->dmfl_buf[0],(PZERO+8)); while(sc->dmfl_state&ERROR) { timeout(dmflint,dmf,10*hz); sleep(&sc->dmfl_state,(PZERO+8)); } /*if(sc->dmfl_state&ERROR) return (EIO);*/ } splx(i); return(0);}/* dmflint -- handle an interrupt from the line printer part of the dmf32 * */dmflint(dmf)int dmf;{ register struct uba_device *ui; register struct dmfl_softc *sc; register struct dmfdevice *d; ui= dmfinfo[dmf]; sc= &dmfl_softc[dmf]; d= (struct dmfdevice *)ui->ui_addr; d->dmfl[0] &= ~DMFL_IE; if(sc->dmfl_state&ERROR) { /*printf("dmf%d: intr while in error state \n", dmf);*/ if((d->dmfl[0]&DMFL_OFFLINE) == 0) sc->dmfl_state &= ~ERROR; wakeup(&sc->dmfl_state); return; } if(d->dmfl[0]&DMFL_DMAERR) { printf("dmf%d:NXM\n", dmf); } if(d->dmfl[0]&DMFL_OFFLINE) { /*printf("dmf%d:printer error\n", dmf);*/ sc->dmfl_state |= ERROR; } if(d->dmfl[0]&DMFL_PDONE) {#ifdef notdef printf("bytes= %d\n",d->dmfl[1]); printf("lines= %d\n",d->dmfl[1]);#endif } sc->dmfl_state &= ~ASLP; wakeup(&sc->dmfl_buf[0]); if(sc->dmfl_info != 0) ubarelse(ui->ui_ubanum,&sc->dmfl_info); sc->dmfl_info = 0;}/* stubs for interrupt routines for devices not yet supported */dmfsrint() { printf("dmfsrint\n"); }dmfsxint() { printf("dmfsxint\n"); }dmfdaint() { printf("dmfdaint\n"); }dmfdbint() { printf("dmfdbint\n"); }dmf_cd_drop(tp)register struct tty *tp;{ register struct dmfdevice *addr = (struct dmfdevice *)tp->t_addr; register unit = minor(tp->t_dev); addr->dmfcsr = DMF_IE | DMFIR_TBUF | (unit&LINEMASK); if ((tp->t_state&TS_CARR_ON) && ((addr->dmfrms&DMF_CAR) == 0)) {#ifdef DMFDEBUG if (dmfdebug) mprintf("dmf_cd: no CD, tp=%x\n", tp);#endif dmf_tty_drop(tp); return; } dmfmodem[unit] |= MODEM_CD;#ifdef DMFDEBUG if (dmfdebug) mprintf("dmf_cd: CD is up, tp=%x\n", tp);#endif}dmf_dsr_check(tp)register struct tty *tp;{ int unit = minor(tp->t_dev); register struct dmfdevice *addr = (struct dmfdevice *)tp->t_addr; if (dmfmodem[unit]&MODEM_DSR_START) { dmfmodem[unit] &= ~MODEM_DSR_START; addr->dmfcsr = DMF_IE | DMFIR_TBUF | (unit&LINEMASK); /* * If dmfdsr is set look for DSR|CTS|CD, otherwise look * for CD|CTS only. */ if (dmfdsr) { if ((addr->dmfrms&DMF_XMIT)==DMF_XMIT) dmf_start_tty(tp); } else { if ((addr->dmfrms&DMF_NODSR)==DMF_NODSR) dmf_start_tty(tp); } return; } if ((tp->t_state&TS_CARR_ON)==0) { dmf_tty_drop(tp); if (dmfdebug) mprintf("dmf_dsr: no carrier, tp=%x\n", tp); }#ifdef DMFDEBUG else if (dmfdebug) mprintf("dmf_dsr: carrier is up, tp=%x\n", tp);#endif}/* * cd_down return 1 if carrier has been down for at least 2 secs. */dmf_cd_down(tp)struct tty *tp;{ int msecs; register int unit = minor(tp->t_dev); msecs = 1000000 * (time.tv_sec - dmftimestamp[unit].tv_sec) + (time.tv_usec - dmftimestamp[unit].tv_usec); if (msecs > 2000000) return(1); else return(0);}dmf_tty_drop(tp)struct tty *tp;{ register struct dmfdevice *addr = (struct dmfdevice *)tp->t_addr; register int line; register int unit; if (tp->t_flags&NOHANG) return; unit = minor(tp->t_dev); line = unit & LINEMASK; dmfmodem[unit] = MODEM_BADCALL; tp->t_state &= ~(TS_CARR_ON|TS_TTSTOP|TS_BUSY|TS_ISUSP); wakeup((caddr_t)&tp->t_rawq); gsignal(tp->t_pgrp, SIGHUP); gsignal(tp->t_pgrp, SIGCONT); addr->dmfcsr=DMF_IE | DMFIR_LCR | line; addr->dmftms = 0;}dmf_start_tty(tp) register struct tty *tp;{ register int unit = minor(tp->t_dev); tp->t_state &= ~TS_ONDELAY; tp->t_state |= TS_CARR_ON; if (dmfmodem[unit]&MODEM_DSR) untimeout(dmf_dsr_check, tp); dmfmodem[unit] |= MODEM_CD|MODEM_CTS|MODEM_DSR; dmftimestamp[unit] = dmfzerotime; wakeup((caddr_t)&tp->t_rawq);}dmfbaudrate(speed)register int speed;{ if (dmf_valid_speeds & (1 << speed)) return (1); else return (0);}/* * Time up for process to set a break on a transmission line. */void dmfsetbreak(tp)register struct tty *tp;{ wakeup((caddr_t)&tp->t_dev);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -