📄 ss.c
字号:
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 & SS_PE){ /* * If input parity checking is not enabled, clear out * parity error in this character. */# ifdef SSDEBUG if (ssdebug > 1) mprintf("ssrint: Parity Error\n");# endif SSDEBUG if ((flg & INPCK) == 0) c &= ~SS_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&SS_DO) { if(overrun == 0) { printf("ss%d: input silo overflow\n", ss); overrun = 1; } sc->sc_softcnt[unit]++; } 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); } ssaddr->nb_int_msk |= SINT_SR;}/*ARGSUSED*/ssioctl(dev, cmd, data, flag) dev_t dev; register int cmd; caddr_t data; int flag;{ register int unit; register struct tty *tp; register int ss; register struct nb_regs *ssaddr = (struct nb_regs *)nexus; register int s; struct uba_device *ui; struct ss_softc *sc; struct devget *devget; int error; unit = minor(dev); if((vs_cfgtst&VS_L3CON) && (major(dev) == CONSOLE_MAJOR) && ((unit&LINEMASK) == 0)) unit |= 3; /* diag console on SLU line 3 */ /* * If there is a graphics device and the ioctl call * is for it, pass the call to the graphics driver. */ if (vs_gdioctl && (unit <= 1)) { error = (*vs_gdioctl)(dev, cmd, data, flag); return(error); } if (vs_gdioctl && (unit == 2) && (major(dev) == CONSOLE_MAJOR)) { error = (*vs_gdioctl)(dev, cmd, data, flag); return(error); } tp = &ss_tty[unit]; ss = unit >> 2; ui = ssinfo[ss]; sc = &ss_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); 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 */ ssparam(unit); break; } return (error); } switch (cmd) { case TIOCSBRK: timeout(sssetbreak, tp, ss_delay[tp->t_cflag & CBAUD]); TTY_SLEEP(tp, (caddr_t)&tp->t_dev, TTOPRI); s = spltty(); ssaddr->ssbrk = (ss_brk[ss] |= 1 << (unit&LINEMASK)); splx(s); break; case TIOCCBRK: s = spltty(); ssaddr->ssbrk = (ss_brk[ss] &= ~(1 << (unit&LINEMASK))); splx(s); break; case TIOCSDTR: (void) ssmctl(dev, SS_DTR|SS_RTS, DMBIS); break; case TIOCCDTR: (void) ssmctl(dev, SS_DTR|SS_RTS, DMBIC); break; case TIOCMSET: (void) ssmctl(dev, dmtoss(*(int *)data), DMSET); break; case TIOCMBIS: (void) ssmctl(dev, dmtoss(*(int *)data), DMBIS); break; case TIOCMBIC: (void) ssmctl(dev, dmtoss(*(int *)data), DMBIC); break; case TIOCMGET: *(int *)data = sstodm(ssmctl(dev, 0, DMGET)); break; case TIOCNMODEM: /* ignore modem status */ /* * By setting the software representation of modem signals * to "on" we fake the system into thinking that this is an * established modem connection. */ s = spl5(); sssoftCAR[ss] |= (1<<(unit&LINEMASK)); if (*(int *)data) /* make mode permanent */ ssdefaultCAR[ss] |= (1<<(unit&LINEMASK)); tp->t_state |= TS_CARR_ON; tp->t_cflag |= CLOCAL; /* Map to termio */ splx(s); break; case TIOCMODEM: /* look at modem status - sleep if no carrier */ if(unit != MODEM_UNIT) break; /* ONLY line 2 has modem control */ s = spl5(); sssoftCAR[ss] &= ~(1<<(unit&LINEMASK)); if (*(int *)data) /* make mode permanent */ ssdefaultCAR[ss] &= ~(1<<(unit&LINEMASK)); /* * See if all signals necessary for modem connection are present * * If ssdsr is set look for DSR|CTS|CD, otherwise look * for CD|CTS only. */ if ((ssdsr && ((ssaddr->ssmsr&SS_XMIT) == SS_XMIT)) || ((ssdsr==0) && ((ssaddr->ssmsr&SS_NODSR) == SS_NODSR)) || ((!ss_modem_ctl) && (ssaddr->ssmsr&SS_RDSR))) { tp->t_state &= ~(TS_ONDELAY); tp->t_state |= TS_CARR_ON; ssmodem = MODEM_CTS|MODEM_CD|MODEM_DSR; } else { tp->t_state &= ~(TS_CARR_ON); ssmodem &= ~(MODEM_CTS|MODEM_CD|MODEM_DSR); } tp->t_cflag &= ~CLOCAL; /* Map to termio */ splx(s); break; case TIOCWONLINE: if(unit != MODEM_UNIT) break; /* ONLY line 2 has modem control */ s = spl5(); /* * See if all signals necessary for modem connection are present * * If ssdsr is set look for DSR|CTS|CD, otherwise look * for CD|CTS only. */ if ((ssdsr && ((ssaddr->ssmsr&SS_XMIT) == SS_XMIT)) || ((ssdsr==0) && ((ssaddr->ssmsr&SS_NODSR) == SS_NODSR)) || ((!ss_modem_ctl) && (ssaddr->ssmsr&SS_RDSR))) { tp->t_state |= TS_CARR_ON; tp->t_state &= ~(TS_ONDELAY); ssmodem = 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 DEVIOCGET: /* device status */ devget = (struct devget *)data; bzero(devget,sizeof(struct devget)); if(unit == MODEM_UNIT) { 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; /* terminal cat.*/ devget->bus = DEV_NB; /* NO bus */ bcopy(DEV_VS_SLU,devget->interface, strlen(DEV_VS_SLU)); /* interface */ bcopy(DEV_UNKNOWN,devget->device, strlen(DEV_UNKNOWN)); /* terminal */ devget->adpt_num = 0; /* NO adapter */ devget->nexus_num = 0; /* fake nexus 0 */ devget->bus_num = 0; /* NO bus */ devget->ctlr_num = ss; /* cntlr number */ devget->slave_num = unit&LINEMASK; /* line number */ bcopy(ui->ui_driver->ud_dname, devget->dev_name, strlen(ui->ui_driver->ud_dname)); /* Ultrix "ss" */ devget->unit_num = unit&LINEMASK; /* ss line? */ devget->soft_count = sc->sc_softcnt[unit&LINEMASK]; /* soft err cnt */ devget->hard_count = sc->sc_hardcnt[unit&LINEMASK]; /* hard err cnt */ devget->stat = sc->sc_flags[unit&LINEMASK]; /* status */ devget->category_stat = sc->sc_category_flags[unit&LINEMASK]; /* cat. stat. */ break; default: if (u.u_procp->p_progenv == A_POSIX) return (EINVAL); return (ENOTTY); } return (0);}dmtoss(bits) register int bits;{ register int b; b = (bits >>1) & 0370; if (bits & SML_ST) b |= SS_ST; if (bits & SML_RTS) b |= SS_RTS; if (bits & SML_DTR) b |= SS_DTR; if (bits & SML_LE) b |= SS_LE; return(b);}sstodm(bits) register int bits;{ register int b; b = (bits << 1) & 0360; if (bits & SS_DSR) b |= SML_DSR; if (bits & SS_DTR) b |= SML_DTR; if (bits & SS_ST) b |= SML_ST; if (bits & SS_RTS) b |= SML_RTS; return(b);}ssparam(unit) register int unit;{ register struct tty *tp; register struct nb_regs *ssaddr = (struct nb_regs *)nexus; register int lpr; tp = &ss_tty[unit]; if (sssilos & (1 << (unit >> 2))) ssaddr->sscsr = SS_MSE | SS_SAE; else ssaddr->sscsr = SS_MSE;/* * Reversing the order of the following two lines fixes the * problem where the console device locks up if you type a * character during autoconf and you must halt/continue to * unlock the console. Interrupts were being enabled on the SLU * before the ssact flag was set, so the driver would just return * and not process the waiting character (caused by you typing). * This locked up the cosnole SLU (interrupt posted but never really * servcied). Halting the system caused the console firmware to unlock * the SLU because it needs to use it. * Should ssparam() be called as spl5?????? */ ssact |= (1<<(unit>>2)); ssaddr->nb_int_msk |= (SINT_ST|SINT_SR); 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))) { (void) ssmctl(unit, SS_OFF, DMSET); /* hang up line */ return; } /* * If diagnostic console on line 3, * line parameters must be: 9600 BPS, 8 BIT, NO PARITY, 1 STOP. * Same for color/monochrome video, except 4800 BPS. * Mouse/tablet: 4800 BPS, 8 BIT, ODD PARITY, 1 STOP. * If none of the above, assume attached console on line 0, * same paramaters as diagnostic console on line 3. */ if ((unit == 3) && (vs_cfgtst&VS_L3CON)) ssaddr->sslpr = (SS_RE | SS_B9600 | BITS8 | 3); else if (unit == 0) { if (vs_gdopen) ssaddr->sslpr = (SS_RE | SS_B4800 | BITS8); else ssaddr->sslpr = (SS_RE | SS_B9600 | BITS8); } else if (vs_gdopen && (unit == 1)) ssaddr->sslpr = (SS_RE | SS_B4800 | OPAR | PENABLE | BITS8 | 1); /* * Set parameters in accordance with user specification. */ else { lpr = (ss_speeds[tp->t_cflag&CBAUD]<<8) | (unit & LINEMASK); /* * Berkeley-only dinosaur */ if (tp->t_line != TERMIODISC) { if ((tp->t_cflag_ext&CBAUD) == B110){ lpr |= TWOSB; tp->t_cflag |= CSTOPB; } } /* * Set device registers according to the specifications of the * termio structure. */ if ((tp->t_cflag & CREAD) == 0) lpr &= ~SS_RE; /* This was set from speeds */ if (tp->t_cflag & CSTOPB) lpr |= TWOSB; else lpr &= ~TWOSB; if (tp->t_cflag & PARENB) { if ((tp->t_cflag & PARODD) == 0) /* set even */ lpr = (lpr | PENABLE)&~OPAR; else /* else set odd */ lpr |= PENABLE|OPAR; } /* * character size. * clear bits and check for 6,7,and 8, else its 5 bits. */ lpr &= ~BITS8; switch(tp->t_cflag&CSIZE) { case CS6: lpr |= BITS6; break; case CS7: lpr |= BITS7; break; case CS8: lpr |= BITS8; break; }# ifdef DEBUG if (ssdebug) mprintf("ssparam: tp = %x, lpr = %x\n",tp,lpr);# endif DEBUG ssaddr->sslpr = lpr; }}ssxint(tp) register struct tty *tp;{ register struct nb_regs *ssaddr = (struct nb_regs *)nexus; register struct pdma *dp; register unit; dp = (struct pdma *)tp->t_addr; unit = minor(tp->t_dev) & 3; if ((vs_cfgtst&VS_L3CON) && (unit == 0) && (major(tp->t_dev) == CONSOLE_MAJOR)) { unit = 3; } /* * Don't know if the following is true for the * VAXstar SLU, but it stays in just to be safe. * Fred Canter -- 6/28/86 */ /* it appears that the ss will ocassionally give spurious transmit ready interupts even when not enabled. If the line was never opened, the following is necessary */ if (dp == NULL) { tp->t_addr = (caddr_t) &sspdma[unit]; dp = (struct pdma *) tp->t_addr; } tp->t_state &= ~TS_BUSY; if (tp->t_state & TS_FLUSH) tp->t_state &= ~TS_FLUSH; else { ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); dp->p_end = dp->p_mem = tp->t_outq.c_cf; } if (tp->t_line) (*linesw[tp->t_line].l_start)(tp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -