📄 dmz.c
字号:
register struct tty *tp; tp = &dmz_tty[minor(dev)]; return ((*linesw[tp->t_line].l_write)(tp, uio));}/* * DMZ32 receiver interrupt. */dmzrint(dmz, octetnum) int dmz, octetnum;{ register struct tty *tp; register c, flg; register struct octet *oaddr; register struct tty *tp0; struct uba_device *ui; register unsigned short line; int overrun = 0; u_char *modem0, *modem; int modem_cont; ui = dmzinfo[dmz]; /* dmz is the module number that interrupted */ if (ui == 0 || ui->ui_alive == 0) return; /* point to the octet that interrupted */ oaddr = &((struct dmzdevice *)ui->ui_addr)->octets[octetnum]; /* tp0 points to the first tty structure on the desired octet */ line = (dmz*NUMLINES) + (octetnum<<3); /* Get DMZ number and octet */ tp0 = &dmz_tty[line]; /* line number filled in */ modem0 = &dmzmodem[line]; /* later. */ /* * Loop fetching characters from the silo for this * dmz until there are no more in the silo. */ while ((c = oaddr->dmzrbuf) < 0) { line = (c>>8)&07; /* interrupting line */ tp = tp0 + line; flg = tp->t_iflag; modem = modem0 + line;#ifdef DMZDEBUG if (dmzdebug>2) mprintf("dmzrint0: oct#=%d, c=%x, oaddr=%x, tp=%x\n", octetnum, c, tp->t_addr, tp);#endif if ((c&DMZ_DSC)&& ((tp->t_cflag & CLOCAL) == 0)) { /* modem transition and we are not ignoring modem signals*/ oaddr->dmzcsr = DMZ_IE | DMZIR_TBUF | ((c>>8)&07); modem_cont = 0;#ifdef DMZDEBUG if (dmzdebug>1) mprintf("dmzrint1: line=%d, md=%x, %x, rms=%x\n", line, modem, *modem, oaddr->dmzrms);#endif /* * Drop DTR immediately if DSR gone away. * If really an active close then do not * send signals. */ if ((oaddr->dmzrms&DMZ_DSR)==0) { if (tp->t_state&TS_CLOSING) { untimeout(wakeup, (caddr_t) &tp->t_dev); wakeup((caddr_t) &tp->t_dev);#ifdef DMZDEBUG if (dmzdebug) mprintf("dmzrint: dsr closing down , tp=%x\n", tp);#endif continue; } if (tp->t_state&TS_CARR_ON) { /* * Only drop if DECSTD52 is followed. */ if (dmzdsr) { dmz_tty_drop(tp); continue; } } } /* * Check for transient CD drops. * Only drop DTR if CD is down for more than 2 secs. */ if (tp->t_state&TS_CARR_ON) if ((oaddr->dmzrms&DMZ_CAR)==0) { if (*modem & MODEM_CD) { /* only start timer once */#ifdef DMZDEBUG if (dmzdebug) mprintf("dmzrint, cd_drop, tp=%x\n", tp);#endif *modem &= ~MODEM_CD; dmztimestamp[minor(tp->t_dev)] = time; timeout(dmz_cd_drop, tp, hz*dmzcdtime); modem_cont = 1; } } else /* * CD has come up again. * Stop timeout from occurring if set. * If interval is more than 2 secs then * drop DTR. */ if ((*modem&MODEM_CD)==0) { untimeout(dmz_cd_drop, tp); if (dmz_cd_down(tp)) /* drop connection */ dmz_tty_drop(tp); *modem |= MODEM_CD; modem_cont = 1; } /* CTS flow control check */ if (tp->t_state&TS_CARR_ON) if ((oaddr->dmzrms&DMZ_CTS)==0) { tp->t_state |= TS_TTSTOP; *modem &= ~MODEM_CTS;#ifdef DMZDEBUG if (dmzdebug) mprintf("dmzrint: CTS stop, tp=%x\n", tp);#endif dmzstop(tp, 0); continue; } else if ((*modem&MODEM_CTS)==0) { tp->t_state &= ~TS_TTSTOP; *modem |= MODEM_CTS;#ifdef DMZDEBUG if (dmzdebug) mprintf("dmzrint: CTS start, tp=%x\n", tp);#endif dmzstart(tp); continue; } /* Avoid calling dmz_start_tty due to a CD transition */ if (modem_cont) continue; /* * If 500 ms timer has not expired then dont * check anything yet. * Check to see if DSR|CTS|CD are asserted. * If so we have a live connection. * If DSR is set for the first time we allow * 30 seconds for a live connection. * * If the DSR signal is being followed, wait at most * 30 seconds for CD, and don't transmit in the first * 500ms. Otherwise immediately look for CD|CTS. */ if (dmzdsr) { if ((oaddr->dmzrms&DMZ_XMIT)==DMZ_XMIT && (*modem&MODEM_DSR_START)==0) dmz_start_tty(tp); else if ((oaddr->dmzrms&DMZ_DSR) && (*modem&MODEM_DSR)==0) { /* * we should not look for CTS|CD for * about 500 ms. lets assume that * there is 200 ms latency for timeouts. */ *modem |= MODEM_DSR; timeout(dmz_dsr_check, tp, hz*30); timeout(dmz_dsr_check, tp, hz/2); } } /* Ignore DSR */ else if ((oaddr->dmzrms&DMZ_NODSR)==DMZ_NODSR) dmz_start_tty(tp); continue; } /* end of modem transition tests */ if ((tp->t_state&TS_ISOPEN)==0) { wakeup((caddr_t)tp); continue; }/* This code handles the following termio input flags. Also * listed is what the default should be for propper Ultrix * backward compatibility. * * IGNBRK FALSE * BRKINT TRUE * IGNPAR TRUE * PARMRK FALSE * INPCK TRUE * ISTRIP TRUE */ /* DMZ_FE is interpreted as a break */ if (c & DMZ_FE) { /* * If configured for trusted path, initiate * trusted path handling. */ if (do_tpath) { tp->t_tpath |= TP_DOSAK; (*linesw[tp->t_line].l_rint)(c, tp); break; } if (flg & IGNBRK) continue; if (flg & BRKINT) {#ifdef DMZDEBUG if (dmzdebug) mprintf("dmzrint: BREAK RECEIVED\n");#endif DMZDEBUG if ((tp->t_lflag_ext & PRAW) && (tp->t_line != TERMIODISC)) c = 0; else { ttyflush(tp, FREAD|FWRITE);#ifdef DMZDEBUG if (dmzdebug) mprintf("sending signal to tp->t_pgrp = %d\n", tp->t_pgrp);#endif DMZDEBUG gsignal(tp->t_pgrp, SIGINT); continue; } } /* * TERMIO: If neither IGNBRK or BRKINT is set, a * break condition is read as a single '\0', * or if PARMRK is set as '\377','\0,'\0'. */ else { if (flg & PARMRK){ (*linesw[tp->t_line].l_rint)(0377,tp); (*linesw[tp->t_line].l_rint)(0,tp); } c = 0; } } /* Parity Error */ else if (c & DMZ_PE){ /* * If input parity checking is not enabled, clear out * parity error in this character. */#ifdef DMZDEBUG if (dmzdebug > 1) mprintf("dmzrint: Parity Error\n");#endif DMZDEBUG if ((flg & INPCK) == 0) c &= ~DMZ_PE; else { if (flg & IGNPAR) continue; /* If PARMRK is set, return a character with * framing or parity errors as a 3 character * sequence (0377,0,c). */ if (flg & PARMRK){ (*linesw[tp->t_line].l_rint)(0377,tp); (*linesw[tp->t_line].l_rint)(0,tp); } /* * TERMIO: If neither PARMRK or IGNPAR is set, a * parity error is read as a single '\0'. */ else c = 0; } } /* SVID does not say what to do with overrun errors */ if ((c & DMZ_DO) && overrun == 0) { printf("dmz%d: recv. fifo overflow\n", dmz); overrun = 1; } if (flg & ISTRIP){ c &= 0177; } else { c &= 0377; /* If ISTRIP is not set a valid character of 377 * is read as 0377,0377 to avoid ambiguity with * the PARMARK sequence. */ if ((c == 0377) && (tp->t_line == TERMIODISC) && (flg & PARMRK)) (*linesw[tp->t_line].l_rint)(0377,tp); }#if NHC > 0 if (tp->t_line == HCLDISC) { HCINPUT(c, tp); } else#endif (*linesw[tp->t_line].l_rint)(c, tp); }}/* * Ioctl for DMZ32. *//*ARGSUSED*/dmzioctl(dev, cmd, data, flag) dev_t dev; register int cmd; caddr_t data; int flag;{ register int unit = minor(dev); register struct tty *tp = &dmz_tty[unit]; register int dmz = unit / NUMLINES; register struct octet *oaddr; struct uba_device *ui = dmzinfo[dmz]; struct dmz_softc *sc = &dmz_softc[ui->ui_unit]; struct devget *devget; int error, s;#ifdef DMZDEBUG if (dmzdebug) mprintf("dmzioctl: oaddr=%x, cmd=%d\n", tp->t_addr, cmd&0xff);#endif error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); if (error >= 0) return (error); error = ttioctl(tp, cmd, data, flag); if (error >= 0) { /* * If the call is to set terminal attributes which are * represented in the device's line parameter register then * call the param routine to update the device registers. */ switch(cmd) { case TCSANOW: /* POSIX termios */ case TCSADRAIN: /* POSIX termios */ case TCSAFLUSH: /* POSIX termios */ case TCSETA: /* SVID termio */ case TCSETAW: /* SVID termio */ case TCSETAF: /* SVID termio */ case TIOCSETP: /* Berkeley sgttyb */ case TIOCSETN: /* Berkeley sgttyb */ case TIOCLBIS: /* Berkeley lmode */ case TIOCLBIC: /* Berkeley lmode */ case TIOCLSET: /* Berkeley lmode */ case TIOCLGET: /* Berkeley lmode */ dmzparam(unit); break; } return (error); } switch (cmd) { case TIOCSBRK: (void) dmzmctl(dev, DMZ_BRK, DMBIS); break; case TIOCCBRK: (void) dmzmctl(dev, DMZ_BRK, DMBIC); break; case TIOCSDTR: (void) dmzmctl(dev, DMZ_DTR|DMZ_RTS, DMBIS); break; case TIOCCDTR: (void) dmzmctl(dev, DMZ_DTR|DMZ_RTS, DMBIC); break; case TIOCMSET: (void) dmzmctl(dev, dmtodmz(*(int *)data), DMSET); break; case TIOCMBIS: (void) dmzmctl(dev, dmtodmz(*(int *)data), DMBIS); break; case TIOCMBIC: (void) dmzmctl(dev, dmtodmz(*(int *)data), DMBIC); break; case TIOCMGET: *(int *)data = dmztodm(dmzmctl(dev, 0, DMGET)); break;#ifdef 0 /* Doesn't work yet! */ /* Set local loopback mode */ case TIOCSMLB: if (u.u_uid) return(EPERM); s=spl5(); oaddr = (struct octet *)tp->t_addr; oaddr->dmzcsr = DMZ_IE | DMZIR_LCR | (unit & 07); SETLCR(oaddr, oaddr->dmzlcr|DMZ_MAINT); splx(s); break; /* Clear local loopback mode */ case TIOCCMLB: if (u.u_uid) return(EPERM); s=spl5(); oaddr = (struct octet *)tp->t_addr; oaddr->dmzcsr = DMZ_IE | DMZIR_LCR | (unit & 07); SETLCR(oaddr, oaddr->dmzlcr&~DMZ_MAINT); splx(s); break;#endif 0 case TIOCNMODEM: /* ignore modem status */ s = spl5(); dmzsoftCAR[dmz] |= (1<<(unit%NUMLINES)); if (*(int *)data) /* make mode permanent */ dmzdefaultCAR[dmz] |= (1<<(unit%NUMLINES));#ifdef DMZDEBUG if (dmzdebug) mprintf("dmzioctl:NMODEM unit=%d, flags=%x\n", unit, dmzsoftCAR[dmz]);#endif tp->t_state |= TS_CARR_ON; dmzmodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR; tp->t_cflag |= CLOCAL; /* Map to termio */ splx(s); break; case TIOCMODEM: /* look at modem status - sleep if no carrier */ s = spl5(); dmzsoftCAR[dmz] &= ~(1<<(unit%NUMLINES));#ifdef DMZDEBUG if (dmzdebug) mprintf("dmzioctl:MODEM unit=%d, flags=%x\n", unit, dmzsoftCAR[dmz]);#endif if (*(int *)data) /* make mode permanent */ dmzdefaultCAR[dmz] &= ~(1<<(unit%NUMLINES)); oaddr = (struct octet *)tp->t_addr; oaddr->dmzcsr = DMZ_IE | DMZIR_TBUF | (unit & 07); /* * If dmzdsr is set look for DSR|CTS|CD, otherwise look * for CD|CTS only. */ if ((dmzdsr && ((oaddr->dmzrms & DMZ_XMIT)==DMZ_XMIT)) || ((dmzdsr==0) && ((oaddr->dmzrms & DMZ_NODSR)==DMZ_NODSR))) { tp->t_state |= TS_CARR_ON; tp->t_state &= ~TS_ONDELAY; dmzmodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR; } else { tp->t_state &= ~(TS_CARR_ON); dmzmodem[unit] &= ~(MODEM_CTS|MODEM_CD|MODEM_DSR); } tp->t_cflag &= ~CLOCAL; /* Map to termio */ splx(s); break; case TIOCWONLINE: s = spl5(); oaddr = (struct octet *)tp->t_addr; oaddr->dmzcsr = DMZ_IE | DMZIR_TBUF | (unit & 07); /* * If dmzdsr is set look for DSR|CTS|CD, otherwise look * for CD|CTS only. */ if ((dmzdsr && ((oaddr->dmzrms & DMZ_XMIT)==DMZ_XMIT)) || ((dmzdsr==0) && ((oaddr->dmzrms & DMZ_NODSR)==DMZ_NODSR))) { tp->t_state |= TS_CARR_ON; tp->t_state &= ~TS_ONDELAY; dmzmodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR; } else while ((tp->t_state & TS_CARR_ON) == 0) {#ifdef DMZDEBUG if (dmzdebug) mprintf("dmzioctl: wait, unit=%d\n", unit);#endif sleep((caddr_t)&tp->t_rawq, TTIPRI); } splx(s); break; case DEVIOCGET: /* device status */ devget = (struct devget *)data; bzero(devget,sizeof(struct devget)); if (tp->t_cflag & CLOCAL) { sc->sc_category_flags[unit%NUMLINES] |= DEV_MODEM; sc->sc_category_flags[unit%NUMLINES] &= ~DEV_MODEM_ON; } else sc->sc_category_flags[unit%NUMLINES] |= (DEV_MODEM|DEV_MODEM_ON); devget->category = DEV_TERMINAL; devget->bus = DEV_UB; bcopy(DEV_DMZ32,devget->interface, strlen(DEV_DMZ32)); bcopy(DEV_UNKNOWN,devget->device, strlen(DEV_UNKNOWN)); /* terminal */ devget->adpt_num = ui->ui_adpt; /* which adapter*/ devget->nexus_num = ui->ui_nexus; /* which nexus */ devget->bus_num = ui->ui_ubanum; /* which UBA */ devget->ctlr_num = dmz; /* which interf.*/ devget->slave_num = unit%NUMLINES; /* which line */ bcopy(ui->ui_driver->ud_dname, devget->dev_name, strlen(ui->ui_driver->ud_dname)); /* Ultrix "dmz" */ devget->unit_num = unit%NUMLINES; /* dmz line? */ devget->soft_count = sc->sc_softcnt[unit%NUMLINES]; /* soft er. cnt.*/ devget->hard_count = sc->sc_hardcnt[unit%NUMLINES]; /* hard er cnt. */ devget->stat = sc->sc_flags[unit%NUMLINES]; /* status */ devget->category_stat = sc->sc_category_flags[unit%NUMLINES]; /* cat. stat. */ break; /* * Used to specify that this device has outgoing auto flow control. * Set appropriate bit in lpar. */ case TIOAUTO: /* * Outgoing Auto flow control. * No auto flow control allowed if startc != ^q and startc != * ^s. Most drivers do not allow these chars to be changed. */ if ((tp->t_cflag_ext&PAUTOFLOW) && (tp->t_cc[VSTOP] != CTRL('s')) || (tp->t_cc[VSTART] != CTRL('q'))) tp->t_cflag_ext &= ~PAUTOFLOW; dmzparam(unit); break; default: if (u.u_procp->p_progenv == A_POSIX) return (EINVAL); return (ENOTTY); } return (0);}dmtodmz(bits) register int bits;{ register int b; b = bits & 012; if (bits & DML_ST) b |= DMZ_RATE; if (bits & DML_RTS) b |= DMZ_RTS; if (bits & DML_USR) b |= DMZ_USRW; return(b);}dmztodm(bits) register int bits;{ register int b; b = (bits & 012) | ((bits >> 7) & 0760) | DML_LE; if (bits & DMZ_USRR) b |= DML_USR; if (bits & DMZ_RTS) b |= DML_RTS; return(b);}/* * Set parameters from open or stty into the DMZ hardware * registers. */dmzparam(unit) register int unit; /* unit is the minor device number */{ register struct tty *tp; register struct octet *oaddr; register int lpar, lcr; int s; tp = &dmz_tty[unit]; oaddr = (struct octet *)tp->t_addr; /* * Block interrupts so parameters will be set * before the line interrupts. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -