📄 dhu.c
字号:
* 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 & DHU_PERR){ /* * If input parity checking is not enabled, clear out * parity error in this character. */#ifdef DHUDEBUG if (dhudebug > 5) mprintf("dhurint: Parity Error, tp=%x\n", tp);#endif DHUDEBUG if ((flg & INPCK) == 0) c &= ~DHU_PERR; 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; } } /* * Set if one or more previous characters on this line were * lost because of a full FIFO, or failure to service the * UART (possible indication of unibus overloading). */ if ((c & DHU_OVERR) && overrun == 0) { printf("dhu%d, line%d: recv. fifo overflow\n",dhu,unit); overrun = 1; } if (flg & ISTRIP){ /* Strip character to 7 bits. */ c &= 0177; } else { /* Take the full 8-bit character */ 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); }#ifdef DHUDEBUG if (dhudebug > 7) mprintf("dhurint: c=%c, line=%d\n",c,unit);#endif DHUDEBUG#if NHC > 0 if (tp->t_line == HCLDISC) { HCINPUT(c, tp); } else#endif (*linesw[tp->t_line].l_rint)(c, tp); }}/* * Ioctl for DHU11. *//*ARGSUSED*/dhuioctl(dev, cmd, data, flag) dev_t dev; register int cmd; caddr_t data; int flag;{ register int dhu, unit; register struct dhudevice *addr; register struct tty *tp; register int s; struct uba_device *ui; struct dhu_softc *sc; struct devget *devget; int error; unit = minor(dev); tp = &dhu11[unit]; dhu = unit >> 4; /* module number */ ui = dhuinfo[dhu]; sc = &dhu_softc[dhu];#ifdef DHUDEBUG if (dhudebug > 1) mprintf("dhuioctl: unit=%d, cmd=%d\n", unit, 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 */ dhuparam(unit); break; } return (error); } addr = (struct dhudevice *)tp->t_addr;#ifdef DHUDEBUG if (dhudebug > 1) mprintf("dhuioctl: unit=%d, cmd=%d\n", unit, cmd&0xff);#endif switch (cmd) { case TIOCSBRK: s = spltty(); addr->csr.low = DHU_RIE|(unit & LINEMASK); WBFLUSH(); addr->lnctrl |= DHU_BREAK; WBFLUSH(); splx(s); break; case TIOCCBRK: s = spltty(); addr->csr.low = DHU_RIE|(unit & LINEMASK); WBFLUSH(); addr->lnctrl &= ~DHU_BREAK; WBFLUSH(); splx(s); break; case TIOCSDTR: s = spltty(); addr->csr.low = DHU_RIE|(unit & LINEMASK); WBFLUSH(); addr->lnctrl |= (DHU_DTR|DHU_RTS); WBFLUSH(); splx(s); break; case TIOCCDTR: s = spltty(); addr->csr.low = DHU_RIE|(unit & LINEMASK); WBFLUSH(); addr->lnctrl &= ~(DHU_DTR|DHU_RTS); WBFLUSH(); splx(s); break; /* handle maintenance mode */ case TIOCSMLB: if (u.u_uid) return(EPERM); s=spltty(); addr->csr.low = DHU_RIE|(unit&LINEMASK ); /*enable interrupts*/ WBFLUSH(); addr->lnctrl |= (DHU_MAINT); WBFLUSH(); splx(s); break; case TIOCCMLB: if (u.u_uid) return(EPERM); s=spltty(); addr->csr.low = DHU_RIE|(unit & LINEMASK); WBFLUSH(); addr->lnctrl &= ~(DHU_MAINT); WBFLUSH(); splx(s); break; case TIOCNMODEM: /* ignore modem status */ s = spltty(); dhusoftCAR[dhu] |= (1<<(unit&LINEMASK)); if (*(int *)data) /* make mode permanent */ dhudefaultCAR[dhu] |= (1<<(unit&LINEMASK)); tp->t_state |= TS_CARR_ON; addr->csr.low = DHU_RIE|(unit & LINEMASK); WBFLUSH(); addr->lnctrl &= ~(DHU_MODEM); WBFLUSH(); dhumodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR; tp->t_cflag |= CLOCAL; /* Map to termio */ splx(s); break; case TIOCMODEM: /* dont ignore modem status */ s = spltty(); dhusoftCAR[dhu] &= ~(1<<(unit&LINEMASK)); if (*(int *)data) /* make mode permanent */ dhudefaultCAR[dhu] &= ~(1<<(unit&LINEMASK)); addr->csr.low = DHU_RIE|(unit & LINEMASK); WBFLUSH(); addr->lnctrl |= DHU_MODEM; WBFLUSH(); /* * If dhudsr is set look for DSR|CTS|CD, otherwise look * for CD|CTS only. */ if ((dhudsr && ((addr->fun.fs.stat&DHU_XMIT)==DHU_XMIT)) || ((dhudsr == 0) && ((addr->fun.fs.stat&(DHU_CD|DHU_CTS)) == (DHU_CD|DHU_CTS)))) { tp->t_state |= TS_CARR_ON; tp->t_state &= ~TS_ONDELAY; dhumodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR; } else { dhumodem[unit] &= ~(MODEM_CTS|MODEM_CD|MODEM_DSR); tp->t_state &= ~(TS_CARR_ON); } tp->t_cflag &= ~(CLOCAL); /* Map to termio */ splx(s); break; case TIOCWONLINE: s = spltty(); addr->csr.low = DHU_RIE|(unit & LINEMASK); WBFLUSH(); /* * If dhudsr is set look for DSR|CTS|CD, otherwise look * for CD|CTS only. */ if ((dhudsr && ((addr->fun.fs.stat&DHU_XMIT)==DHU_XMIT)) || ((dhudsr == 0) && ((addr->fun.fs.stat&(DHU_CD|DHU_CTS)) == (DHU_CD|DHU_CTS)))) { tp->t_state |= TS_CARR_ON; tp->t_state &= ~TS_ONDELAY; dhumodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR; } else while ((tp->t_state & TS_CARR_ON) == 0) sleep((caddr_t)&tp->t_rawq, TTIPRI); splx(s); break; case TIOCMGET: s = spltty(); addr->csr.low = DHU_RIE|(unit & LINEMASK); WBFLUSH(); *(int *)data = dhutodm(addr->lnctrl,addr->fun.fs.stat); splx(s); break; case TIOCMSET: s = spltty(); addr->csr.low = DHU_RIE|(unit & LINEMASK); WBFLUSH(); addr->lnctrl = dmtodhu(*(int *)data); WBFLUSH(); splx(s); break; case TIOCMBIS: s = spltty(); addr->csr.low = DHU_RIE|(unit & LINEMASK); WBFLUSH(); addr->lnctrl |= dmtodhu(*(int *)data); WBFLUSH(); splx(s); break; case TIOCMBIC: s = spltty(); addr->csr.low = DHU_RIE|(unit & LINEMASK); WBFLUSH(); addr->lnctrl &= ~(dmtodhu(*(int *)data)); WBFLUSH(); 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&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; if(ui->ui_hd->uba_type & (UBAUVI|UBAUVII)) { if (dhu_lines[ui->ui_unit] == 16) bcopy(DEV_CXAB16,devget->interface, strlen(DEV_CXAB16)); else bcopy(DEV_DHQVCXY,devget->interface, strlen(DEV_DHQVCXY)); } else { bcopy(DEV_DHU11,devget->interface, strlen(DEV_DHU11)); } 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/QB */ devget->ctlr_num = dhu; /* 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 "dhu" */ devget->unit_num = unit&LINEMASK; /* dh[vu] line #*/ 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. */ 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; dhuparam(unit); break; default: if (u.u_procp->p_progenv == A_POSIX) return (EINVAL); return (ENOTTY); } return (0);}dhutodm(lnctrl,lstat) register u_short lnctrl; register char lstat;{ register int b = 0; if (lnctrl&DHU_RTS) b |= TIOCM_RTS; if (lnctrl&DHU_DTR) b |= TIOCM_DTR; if (lstat&DHU_CD) b |= TIOCM_CD; if (lstat&DHU_CTS) b |= TIOCM_CTS; if (lstat&DHU_RING) b |= TIOCM_RI; if (lstat&DHU_DSR) b |= TIOCM_DSR; return(b);}dmtodhu(bits) register int bits;{ register u_short lnctrl = 0; if (bits&TIOCM_RTS) lnctrl |= DHU_RTS; if (bits&TIOCM_DTR) lnctrl |= DHU_DTR; return(lnctrl);}/* * Set parameters from open or stty into the DHU hardware * registers. */dhuparam(unit) register int unit;{ register struct tty *tp; register struct dhudevice *addr; register int lpar; int s; tp = &dhu11[unit]; if (tp->t_state & TS_BUSY) { tp->t_state |= TS_NEED_PARAM; return; } addr = (struct dhudevice *)tp->t_addr; /* * Block interrupts so parameters will be set * before the line interrupts. */ s = spltty(); addr->csr.low = DHU_RIE|(unit&LINEMASK); WBFLUSH(); /* * Disconnect modem line if baudrate is zero. POSIX checks the output * baud rate, while non-POSIX checks the input baud rate. */ if ((((tp->t_cflag & CBAUD)==B0) && (u.u_procp->p_progenv != A_POSIX)) || (((tp->t_cflag_ext & CBAUD)==B0) && (u.u_procp->p_progenv == A_POSIX))) { tp->t_cflag |= HUPCL; addr->lnctrl = DHU_REN; /*turn off DTR & RTS but leave enabled*/ WBFLUSH(); splx(s); return; } lpar = ((dhu_speeds[tp->t_cflag_ext&CBAUD])<<12) | ((dhu_speeds[tp->t_cflag&CBAUD])<<8); /* * Berkeley-only dinosaurs */ if (tp->t_line != TERMIODISC) { if ((tp->t_cflag & CBAUD) == B134){ lpar |= DHU_BITS6|DHU_PENABLE; /* no half duplex on dhu11 ? */ tp->t_cflag |= CS6|PARENB; } else if ((tp->t_cflag_ext & CBAUD) == B110){ lpar |= DHU_TWOSB; tp->t_cflag |= CSTOPB; } } /* * Set device registers according to the specifications of the termio * structure. */ if (tp->t_cflag & CREAD) addr->lnctrl |= DHU_REN; else addr->lnctrl &= ~DHU_REN; WBFLUSH(); if (tp->t_cflag & CSTOPB) lpar |= DHU_TWOSB; else lpar &= ~DHU_TWOSB; /* parity is enable */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -