?? dmb.c
字號:
} *modem |= MODEM_CD; modem_cont = 1; } /* CTS flow control check */ if (tp->t_state&TS_CARR_ON) if ((addr->dmb_lstatlow & DMB_CTS)==0) { tp->t_state |= TS_TTSTOP; *modem &= ~MODEM_CTS;# ifdef DEBUG printd("dmbrint: CTS stop, line=%d\n",line);# endif DEBUG DMB_UNLOCK(dmb); dmbstop(tp, 0); goto dmbrunlock; } else if ((*modem&MODEM_CTS)==0) { tp->t_state &= ~TS_TTSTOP; *modem |= MODEM_CTS;# ifdef DEBUG printd("dmbrint: CTS start, line=%d\n",line);# endif DEBUG DMB_UNLOCK(dmb); dmbstart(tp); goto dmbrunlock; } /* * Avoid calling dmb_start_tty due to a CD transition */ if (modem_cont) { DMB_UNLOCK(dmb); goto dmbrunlock; } /* * If 500 ms timer has not expired then don't * check anything yet. * Check to see if DSR|CTS|DCD 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 (dmbdsr) { if ((addr->dmb_lstatlow & DMB_XMIT) == DMB_XMIT && (*modem & MODEM_DSR_START)==0) dmb_start_tty(tp,&post_wakeup); else if ((addr->dmb_lstatlow & DMB_DSR) && (*modem & MODEM_DSR)==0) { *modem |= (MODEM_DSR_START|MODEM_DSR); /* * We should not look for CTS|CD for * about 500 ms. */ timeout(dmb_dsr_check_timeout,tp,hz*30); timeout(dmb_dsr_check_timeout,tp,hz/2); } } /* * Ignore DSR */ else if ((addr->dmb_lstatlow & DMB_NODSR) == DMB_NODSR) dmb_start_tty(tp,&post_wakeup); DMB_UNLOCK(dmb); goto dmbrunlock; } /* end of modem transition tests */ if ((tp->t_state&TS_ISOPEN)==0) { post_wakeup = WAKEUP_RAWQ; goto dmbrunlock; } /* * Check for framing or parity errors. */ if (c & (DMB_PARITYERR|DMB_FRAMEERR)) { /* * If input parity checking is not enabled, clear out * parity error in this character. Don't leave the * error checks because it could still contain a * framing error. */ if ((c & DMB_PARITYERR) && ((flg & INPCK) == 0)) c &= ~DMB_PARITYERR; /* * For POSIX: * A break is defined to be a character with a framing * error and data bits of all zero. Note that it is * possible to have a character with a framing error * that is not a break. * For non-POSIX: * For backward compatiblity, it used to be the case * that anything with a framing error was considered * to be a break. */ if ((c & DMB_FRAMEERR) && ((tp->t_line != TERMIODISC) || ((c & CHAR_MASK) == 0))) { /* * 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); goto dmbrunlock; } if (flg & IGNBRK) goto dmbrunlock; if (flg & BRKINT) { if ((tp->t_lflag_ext & PRAW) && (tp->t_line != TERMIODISC)) c = 0; else { ttyflush(tp, FREAD|FWRITE); gsignal(tp->t_pgrp, SIGINT); smp_unlock(&tp->t_lk_tty); 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; } } else if (c & (DMB_PARITYERR|DMB_FRAMEERR)) { if (flg & IGNPAR) goto dmbrunlock; /* dispose of char */ /* 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; } } /* * This is frequently an indication that the bus is overloaded. * For example a heavily used disk on the same uba may * cause overruns to occur. */ if ((c & DMB_OVERRUNERR) && overrun == 0) { printf("dmb%d: recv. fifo overflow\n", dmb); 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); } (*linesw[tp->t_line].l_rint)(c, tp);dmbrunlock: smp_unlock(&tp->t_lk_tty); if (post_wakeup) { if (post_wakeup & WAKEUP_RAWQ) wakeup((caddr_t)&tp->t_rawq); else wakeup((caddr_t) &tp->t_dev); } } /* end while c < 0 */}/* * Ioctl for DMB32. *//*ARGSUSED*/dmbioctl(dev, cmd, data, flag) dev_t dev; register int cmd; caddr_t data; int flag;{ register int unit = minor(dev); register struct tty *tp; register int dmb; register struct dmb_device *addr; register int s; struct uba_device *ui; struct dmb_softc *sc; struct devget *devget; int error; if (unit & 0200) return (ENOTTY); tp = &dmb_tty[unit]; dmb = unit >> LINEBITS; ui = dmbinfo[dmb]; sc = &dmb_softc[ui->ui_unit]; error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); if (error >= 0) return (error); error = ttioctl(tp, cmd, data, flag); DMB_TTY_LOCK(tp,s); 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 */ DMB_LOCK(dmb); dmbparam(unit); DMB_UNLOCK(dmb); break; } DMB_TTY_UNLOCK(tp,s); return (error); } addr = (struct dmb_device *)tp->t_addr;# ifdef DEBUG if (dmbdebug) printd("dmbioctl: unit = %d, cmd = %d, data = 0x%x, flag = 0x%x\n", unit, cmd & 0xff, data, flag);# endif DMB_LOCK(dmb); switch (cmd) { case TIOCSBRK: addr->dmb_acsr = (unit & LINEMASK) | DMB_IE; addr->dmb_lpr |= DMB_BREAK; break; case TIOCCBRK: addr->dmb_acsr = (unit & LINEMASK) | DMB_IE; addr->dmb_lpr &= ~DMB_BREAK; break; case TIOCSDTR: addr->dmb_acsr = (unit & LINEMASK) | DMB_IE; addr->dmb_lpr |= (DMB_DTR | DMB_RTS); break; case TIOCCDTR: addr->dmb_acsr = (unit & LINEMASK) | DMB_IE; addr->dmb_lpr &= ~(DMB_DTR | DMB_RTS); break; case TIOCMSET: addr->dmb_acsr = (unit & LINEMASK) | DMB_IE; addr->dmb_lpr &= ~(DMB_DTR | DMB_RTS); addr->dmb_lpr |= dmtodmb(*(int *)data); break; case TIOCMBIS: addr->dmb_acsr = (unit & LINEMASK) | DMB_IE; addr->dmb_lpr |= dmtodmb(*(int *)data); break; case TIOCMBIC: addr->dmb_acsr = (unit & LINEMASK) | DMB_IE; addr->dmb_lpr &= ~(dmtodmb(*(int *)data)); break; case TIOCMGET: addr->dmb_acsr = (unit & LINEMASK) | DMB_IE; *(int *)data = dmbtodm(addr->dmb_lpr, addr->dmb_lstatlow); break; case TIOCNMODEM: /* ignore modem status */ dmbsoftCAR[dmb] |= (1<<(unit&LINEMASK)); if (*(int *)data) /* make mode permanent */ dmbdefaultCAR[dmb] |= (1<<(unit&LINEMASK)); dmbmodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR; tp->t_state |= TS_CARR_ON; addr->dmb_acsr = (unit & LINEMASK) | DMB_IE; addr->dmb_lpr &= ~(DMB_REPORT); tp->t_cflag |= CLOCAL; /* Map to termio */ break; case TIOCMODEM: /* look at modem status */ dmbsoftCAR[dmb] &= ~(1<<(unit&LINEMASK)); if (*(int *)data) /* make mode permanent */ dmbdefaultCAR[dmb] &= ~(1<<(unit&LINEMASK)); addr->dmb_acsr = (unit & LINEMASK) | DMB_IE; /* line select */ addr->dmb_lpr |= DMB_REPORT; /* * If dmbdsr is set look for DSR|CTS|CD, otherwise look * for CD|CTS only. */ if ((dmbdsr && ((addr->dmb_lstatlow & DMB_XMIT) == DMB_XMIT)) || ((dmbdsr == 0) && ((addr->dmb_lstatlow & DMB_NODSR) == DMB_NODSR))) { tp->t_state |= TS_CARR_ON; tp->t_state &= ~TS_ONDELAY; dmbmodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR; } else { dmbmodem[unit] & = ~(MODEM_CTS|MODEM_CD|MODEM_DSR); tp->t_state &= ~(TS_CARR_ON); } tp->t_cflag &= ~CLOCAL; /* Map to termio */ break; case TIOCWONLINE: addr->dmb_acsr = (unit & LINEMASK) | DMB_IE; /* line select */ /* * If dmbdsr is set look for DSR|CTS|CD, otherwise look * for CD|CTS only. */ if ((dmbdsr && ((addr->dmb_lstatlow & DMB_XMIT) == DMB_XMIT)) || ((dmbdsr == 0) && ((addr->dmb_lstatlow & DMB_NODSR) == DMB_NODSR))) { tp->t_state |= TS_CARR_ON; tp->t_state &= ~TS_ONDELAY; dmbmodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR; } else { while ((tp->t_state & TS_CARR_ON) == 0) { DMB_UNLOCK(dmb); sleep_unlock((caddr_t)&tp->t_rawq, TTIPRI, &tp->t_lk_tty); DMB_TTY_LOCK(tp,s); DMB_LOCK(dmb); } } break; /* handle maintenance mode */ case TIOCSMLB: if (u.u_uid) { DMB_UNLOCK(dmb); DMB_TTY_UNLOCK(tp,s); return(EPERM); } addr->dmb_acsr = (unit & LINEMASK) | DMB_IE; addr->dmb_lpr |= (DMB_MAINT); break; case TIOCCMLB: if (u.u_uid) { DMB_UNLOCK(dmb); DMB_TTY_UNLOCK(tp,s); return(EPERM); } addr->dmb_acsr = (unit & LINEMASK) | DMB_IE; addr->dmb_lpr &= ~(DMB_MAINT); break; case DEVIOCGET: /* device status */ DMB_UNLOCK(dmb); DMB_TTY_UNLOCK(tp,s); devget = (struct devget *)data; bzero(devget,sizeof(struct devget)); if (tp->t_cflag & CLOCAL) { sc->sc_category_flags[unit&LINEMASK] |= DEV_MODEM; sc->sc_category_flags[unit&LINEMASK] &= ~DEV_MODEM_ON; } else sc->sc_category_flags[unit&LINEMASK] |= (DEV_MODEM|DEV_MODEM_ON); devget->category = DEV_TERMINAL; devget->bus = DEV_BI; if (dmb_lines[dmb] == DMB_8_LINES) bcopy(DEV_DMB32,devget->interface,strlen(DEV_DMB32)); else bcopy(DEV_DHB32,devget->interface,strlen(DEV_DHB32)); bcopy(DEV_UNKNOWN,devget->device, strlen(DEV_UNKNOWN)); /* terminal */ devget->adpt_num = ui->ui_adpt; /* which adapter*/ devget->nexus_num = ui->ui_nexus; /* which node */ devget->bus_num = ui->ui_ubanum; /* which BI */ devget->ctlr_num = dmb; /* which interf.*/ devget->slave_num = unit&LINEMASK; /* which line */ bcopy(ui->ui_driver->ud_dname, devget->dev_name, strlen(ui->ui_driver->ud_dname)); /* Ultrix "dmb" */ devget->unit_num = unit&LINEMASK; /* which dmb? */ devget->soft_count = sc->sc_softcnt[unit&LINEMASK]; /* soft er. cnt.*/ devget->hard_count = sc->sc_hardcnt[unit&LINEMASK]; /* hard er cnt. */ devget->stat = sc->sc_flags[unit&LINEMASK]; /* status */ devget->category_stat = sc->sc_category_flags[unit&LINEMASK]; /* cat. stat. */ return(0); /* * 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; /* * OAUTO doesn't work on the DHB. * Take this out if it ever does work. */ if (dmb_lines[dmb] == DMB_16_LINES) tp->t_cflag_ext &= ~PAUTOFLOW; dmbparam(unit); break; default: DMB_UNLOCK(dmb); DMB_TTY_UNLOCK(tp,s); if (u.u_procp->p_progenv == A_POSIX) return (EINVAL); return (ENOTTY); } DMB_UNLOCK(dmb); DMB_TTY_UNLOCK(tp,s); return (0);}dmbtodm(lpr,lstat) register long lpr; register u_short lstat;{ register int b = 0; if (lpr&DMB_RTS) b |= TIOCM_RTS;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -