📄 dc7085.c
字号:
case TIOCSDTR: (void) dcmctl(dev, DC_DTR | DC_RTS, DMBIS); break; case TIOCCDTR: (void) dcmctl(dev, DC_DTR | DC_RTS, DMBIC); break; case TIOCMSET: (void) dcmctl(dev, dmtodc(*(int *)data), DMSET); break; case TIOCMBIS: (void) dcmctl(dev, dmtodc(*(int *)data), DMBIS); break; case TIOCMBIC: (void) dcmctl(dev, dmtodc(*(int *)data), DMBIC); break; case TIOCMGET: *(int *)data = dctodm(dcmctl(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 = spltty(); dcsoftCAR[ctlr] |= (1<<(unit&LINEMASK)); if (*(int *)data) /* make mode permanent */ dcdefaultCAR[ctlr] |= (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 */ s = spltty(); dcsoftCAR[ctlr] &= ~(1<<(unit&LINEMASK)); if (*(int *)data) /* make mode permanent */ dcdefaultCAR[ctlr] &= ~(1<<(unit&LINEMASK)); /* * See if signals necessary for modem connection are present * * dc7085 chip on PMAX only provides DSR * */ if ((sc->dcmsr & dc_xmit[unit]) == dc_xmit[unit]) { tp->t_state &= ~(TS_ONDELAY); tp->t_state |= TS_CARR_ON; dcmodem[unit] = MODEM_CTS|MODEM_CD|MODEM_DSR; } else { tp->t_state &= ~(TS_CARR_ON); dcmodem[unit] &= ~(MODEM_CTS|MODEM_CD|MODEM_DSR); } tp->t_cflag &= ~CLOCAL; /* Map to termio */ splx(s); break; case TIOCWONLINE: s = spltty(); /* * See if signals necessary for modem connection are present * * dc7085 chip on PMAX only provides DSR * */ if ((sc->dcmsr & dc_xmit[unit]) == dc_xmit[unit]) { tp->t_state |= TS_CARR_ON; tp->t_state &= ~(TS_ONDELAY); dcmodem[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 DEVIOCGET: /* device status */ devget = (struct devget *)data; bzero(devget,sizeof(struct devget)); if (dc_modem_line[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 = ctlr; /* cntlr number */ devget->slave_num = unit&LINEMASK; /* line number */ bcopy("dc", devget->dev_name, 3); /* Ultrix "dc" */ devget->unit_num = unit&LINEMASK; /* dc 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);}dmtodc(bits) register int bits;{ register int b; b = (bits >>1) & 0370; if (bits & SML_ST) b |= DC_ST; if (bits & SML_RTS) b |= DC_RTS; if (bits & SML_DTR) b |= DC_DTR; if (bits & SML_LE) b |= DC_LE; return(b);}dctodm(bits) register int bits;{ register int b; b = (bits << 1) & 0360; if (bits & DC_DSR) b |= SML_DSR; if (bits & DC_DTR) b |= SML_DTR; if (bits & DC_ST) b |= SML_ST; if (bits & DC_RTS) b |= SML_RTS; return(b);}dcparam(unit) register int unit;{ register struct dc_softc *sc; register struct tty *tp; register u_short lpr; register int ctlr, s; ctlr = unit >> 2; sc = &dc_softc[ctlr]; tp = &dc_tty[unit]; s = spltty();/* * 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 dcparam() be called as spl5?????? */ 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))) { dcmodem_active[ctlr] &= ~(1 << (unit & LINEMASK)); sc->dcdtr &= ~(dc_rdtr[unit] | dc_rrts[unit]); /* hang up line */ splx(s); 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 (dc_base_board && (ctlr == 0)) { if ((unit == 3) && (consDev != GRAPHIC_DEV)) { sc->dclpr = (DC_RE | DC_B9600 | BITS8 | 3); sc->dccsr = DC_MSE | DC_TIE | DC_RIE; splx(s); return; } if (unit <= 1) { sc->dccsr = DC_MSE |DC_TIE | DC_RIE; splx(s); return; } } lpr = (DC_RE) | (dc_speeds[tp->t_cflag&CBAUD].baud_param) | (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 &= ~DC_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; } sc->dclpr = lpr; sc->dccsr = DC_MSE | DC_TIE | DC_RIE; splx(s);}_dcpdma(ctlr)int ctlr;{ register struct dc_softc *sc; register struct dcpdma *dp; register int unit, linenum; sc = &dc_softc[ctlr]; linenum = (sc->dccsr >> 8) & LINEMASK; unit = (ctlr * NDCLINE) + linenum; dp = &sc->dc_pdma[linenum]; if (brk_start[unit]) { brk_start[unit] = 0; /* only set break bit if it is not already set */ if ((dc_brk[ctlr] & (1 << (linenum + 0x8))) == 0) { switch (cpu) { case DS_3100: sc->dcbrk_tbuf = (dc_brk[ctlr] |= (1 << (linenum + 0x8))); break; case DS_5000: /* dcbrk is a char on 3MAX and option card */ case DS_5000_100: sc->dcbrk = ((dc_brk[ctlr] |= (1 << (linenum + 0x8))) >> 8); dcxint(unit); /* turn off intr if not busy */ break; } } } else if (brk_stop[unit]) { brk_stop[unit] = 0; /* only clear break bit if it is already set */ if (dc_brk[ctlr] & (1 << (linenum + 0x8))) { switch (cpu) { case DS_3100: /* Disable line transmission first */ sc->dctcr &= ~(1 << linenum); sc->dcbrk_tbuf = (dc_brk[ctlr] &= ~(1 << (linenum + 0x8))); break; case DS_5000: /* dcbrk is a char on 3max and option card */ case DS_5000_100: sc->dcbrk = ((dc_brk[ctlr] &= ~(1 << (linenum + 0x8))) >> 8); dcxint(unit); break; } } } else if (dp->p_mem == dp->p_end) { dcxint(unit); } else { sc->dcbrk_tbuf = ((dc_brk[ctlr]) | (unsigned char)(*dp->p_mem++)); }}dcxint(unit) register int unit;{ register struct dc_softc *sc; register struct dcpdma *dp; register struct tty *tp; register int ctlr; ctlr = unit >> 2; sc = &dc_softc[ctlr]; tp = &dc_tty[unit]; if ((consDev != GRAPHIC_DEV) && (unit == 0) && (major(tp->t_dev) == CONSOLEMAJOR)) { unit = 3; }#ifdef DEBUG if (dcdebug > 4) mprintf("dcxint: unit = %d, tp = %x, c_cc = %d\n", unit, tp, tp->t_outq.c_cc);#endif DEBUG tp->t_state &= ~TS_BUSY; dp = &sc->dc_pdma[unit & LINEMASK]; 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); } else { dcstart(tp); } /* The BUSY flag will not be set in two cases: */ /* 1. if there are no more chars in the outq OR */ /* 2. there are chars in the outq but tty is in */ /* stopped state. */ if ((tp->t_state&TS_BUSY) == 0) { sc->dctcr &= ~(1<< (unit & LINEMASK)); }}dcstart(tp) register struct tty *tp;{ register struct dc_softc *sc; register struct dcpdma *dp; register int cc; int s, unit, ctlr; unit = minor(tp->t_dev); ctlr = unit >> 2; sc = &dc_softc[ctlr]; s = spltty(); /* * Do not do anything if currently delaying, or active. Also only * transmit when CTS is up. */ if ((tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) || (((tp->t_cflag & CLOCAL) == 0) && ((tp->t_state&TS_CARR_ON) && (dcmodem[unit]&MODEM_CTS)==0))) goto out; if (tp->t_outq.c_cc <= TTLOWAT(tp)) { if (tp->t_state&TS_ASLEEP) { tp->t_state &= ~TS_ASLEEP; wakeup((caddr_t)&tp->t_outq); } if (tp->t_wsel) { selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); tp->t_wsel = 0; tp->t_state &= ~TS_WCOLL; } } if (tp->t_outq.c_cc == 0) goto out;#ifdef DEBUG if (dcdebug > 7) { mprintf("dcstart: unit = %d, tp = %x, c_cc = %d\n", unit, tp, tp->t_outq.c_cc); }#endif DEBUG if ((tp->t_lflag_ext & PRAW) || (tp->t_oflag_ext & PLITOUT) || ((tp->t_oflag & OPOST) == 0)) cc = ndqb(&tp->t_outq, 0); else { cc = ndqb(&tp->t_outq, DELAY_FLAG); if (cc == 0) { cc = getc(&tp->t_outq); timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); tp->t_state |= TS_TIMEOUT; goto out; } } tp->t_state |= TS_BUSY; if ((consDev != GRAPHIC_DEV) && (unit == 0) && (major(tp->t_dev) == CONSOLEMAJOR)) unit = 3; dp = &sc->dc_pdma[unit & LINEMASK]; dp->p_end = dp->p_mem = tp->t_outq.c_cf; dp->p_end += cc; sc->dccsr |= DC_TIE; sc->dctcr |= (1<< (unit & LINEMASK));out: splx(s);}dcstop(tp, flag) register struct tty *tp;{ register struct dc_softc *sc; register struct dcpdma *dp; register int s; int unit, ctlr; /* * If there is a graphics device and the stop call * is for it, pass the call to the graphics device driver. */ unit = minor(tp->t_dev); ctlr = unit >> 2; sc = &dc_softc[ctlr]; if ((consDev != GRAPHIC_DEV) && (unit == 0) && (major(tp->t_dev) == CONSOLEMAJOR)) { unit = 3; } if (dc_base_board && (ctlr == 0)) if (vs_gdstop && (unit <= 1)) { (*vs_gdstop)(tp, flag); return; } dp = &sc->dc_pdma[unit & LINEMASK]; s = spltty(); if (tp->t_state & TS_BUSY) { dp->p_end = dp->p_mem; if ((tp->t_state&TS_TTSTOP)==0) tp->t_state |= TS_FLUSH; } splx(s);}dcmctl(dev, bits, how) dev_t dev; int bits, how;{ register struct dc_softc *sc; register int unit, ctlr, mbits; int b, s; unit = minor(dev); ctlr = unit >> 2; sc = &dc_softc[ctlr]; if (dc_modem_line[unit] == 0) return(0); /* only line 2 and 3 on base board have modem control */ s = spltty(); mbits = (sc->dcdtr & dc_rdtr[unit]) ? DC_DTR : 0; mbits |= (sc->dcdtr & dc_rrts[unit]) ? DC_RTS : 0; mbits |= (sc->dcmsr & dc_rcd[unit]) ? DC_CD : 0; mbits |= (sc->dcmsr & dc_rdsr[unit]) ? DC_DSR : 0; mbits |= (sc->dcmsr & dc_rcts[unit]) ? DC_CTS : 0; switch (how) { case DMSET: mbits = bits; break; case DMBIS: mbits |= bits; break; case DMBIC: mbits &= ~bits; break; case DMGET: (void) splx(s); return(mbits); } if (mbits & DC_DTR) sc->dcdtr |= (dc_rdtr[unit] | dc_rrts[unit]); else sc->dcdtr &= ~(dc_rdtr[unit] | dc_rrts[unit]); (void) splx(s); return(mbits);}#ifdef DEBUGint dcscan_ctr = 1;#endif DEBUG/* * WARNING: This routine should only be called if the dc is on the * base board. The option card has NO modem control . */dcscan(){ register int i; register struct dc_softc *sc = &dc_softc[0]; register struct tty *tp; register u_short dcscan_modem; static u_short dcscan_previous; /* Used to detect modem transitions */#ifdef DEBUG if (dcdebug) { if (dcscan_ctr++ == 45) { cprintf("dcscan: "); PRINT_SIGNALS(); dcscan_ctr = 1; } }#endif DEBUG dcscan_modem = sc->dcmsr; /* read copy of modem status register */ if (dcscan_modem == dcscan_previous) { /* no work to do reschedule scan routine */ if (dcmodem_active) timeout(dcscan, (caddr_t)0, hz/40); else timeout(dcscan, (caddr_t)0, hz); return; } for (i = 2; i < 4; i++) { tp = &dc_tty[i]; if ((tp->t_cflag & CLOCAL) == 0) { /* * Drop DTR immediately if DSR has gone away. * If really an active close then do not * send signals. */ if (!(dcscan_modem & dc_rdsr[i])) { if (tp->t_state&TS_CLOSING) { untimeout(wakeup, (caddr_t) &tp->t_dev); wakeup((caddr_t) &tp->t_dev); } if (tp->t_state&TS_CARR_ON) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -