📄 dc7085.c
字号:
dc_tty_drop(tp); } } else { /* DSR has come up */ /* * If DSR comes up for the first time we allow * 30 seconds for a live connection. */ if ((dcmodem[i] & MODEM_DSR)==0) { dcmodem[i] |= (MODEM_DSR_START|MODEM_DSR); if (!dc_modem_ctl) { /* * Assume carrier will come up in less * than 1 sec. If not DSR will drop * and the line will close */ timeout(dc_dsr_check, tp, hz); } else { /* * we should not look for CTS|CD for about * 500 ms. */ timeout(dc_dsr_check, tp, hz*30); dc_dsr_check(tp); } } } /* * look for modem transitions in an already * established connection. * * Ignore CD and CTS for PMAX. These signals * don't exist on the PMAX. */ if (dc_modem_ctl) { if (tp->t_state & TS_CARR_ON) { if (dcscan_modem & dc_rcd[i]) { /* * CD has come up again. * Stop timeout from occurring if set. * If interval is more than 2 secs then * drop DTR. */ if ((dcmodem[i] & MODEM_CD) == 0) { untimeout(dc_cd_drop, tp); if (dc_cd_down(tp)) { /* drop connection */ dc_tty_drop(tp); } dcmodem[i] |= MODEM_CD; } } else { /* * Carrier must be down for greater than * 2 secs before closing down the line. */ if (dcmodem[i] & MODEM_CD) { /* only start timer once */ dcmodem[i] &= ~MODEM_CD; /* * Record present time so that if carrier * comes up after 2 secs, the line will drop. */ dctimestamp[i] = time; timeout(dc_cd_drop, tp, hz * 2); } } /* CTS flow control check */ if (!(dcscan_modem & dc_rcts[i])) { /* * Only allow transmission when CTS is set. */ tp->t_state |= TS_TTSTOP; dcmodem[i] &= ~MODEM_CTS;#ifdef DEBUG if (dcdebug) cprintf("dcscan: CTS stop, tp=%x,line=%d\n",tp,i);#endif DEBUG dcstop(tp, 0); } else if (!(dcmodem[i] & MODEM_CTS)) { /* * Restart transmission upon return of CTS. */ tp->t_state &= ~TS_TTSTOP; dcmodem[i] |= MODEM_CTS;#ifdef DEBUG if (dcdebug) cprintf("dcscan: CTS start, tp=%x,line=%d\n",tp,i);#endif DEBUG dcstart(tp); } } /* * See if a modem transition has occured. If we are waiting * for this signal, cause action to be take via * dc_start_tty. */ if (((dcscan_modem & dc_xmit[i]) == dc_xmit[i]) && (!(dcmodem[i] & MODEM_DSR_START)) && (!(tp->t_state & TS_CARR_ON))) {#ifdef DEBUG if (dcdebug) cprintf("dcscan: MODEM transition: dcscan_modem = %x, dcscan_previous = %x\n", dcscan_modem, dcscan_previous);#endif DEBUG dc_start_tty(tp); } } } } dcscan_previous = dcscan_modem; /* save for next iteration */ if (dcmodem_active) timeout(dcscan, (caddr_t)0, hz/40); else timeout(dcscan, (caddr_t)0, hz);}int dcputc();int dcgetc();dcputc(c) register int c;{ if (consDev == GRAPHIC_DEV) { if ( v_consputc ) { (*v_consputc) (c); if ( c == '\n' ) (*v_consputc)( '\r' ); return; } } dc_putc(3, c); if ( c == '\n') dc_putc(3, '\r');}/* * This routine outputs one character to the console. * Characters must be printed without disturbing * output in progress on other lines! * This routines works with the SLU in interrupt or * non-interrupt mode of operation. BULL! * Characters are output as follows: * spl5, remember if console line active. * set console line tcr bit. * wait for TRDY on console line (save status if wrong line). * start output of character. * wait for output complete. * if any lines were active, set their tcr bits, * otherwise clear the xmit ready interrupt. * */dc_putc(unit, c) int unit; register int c;{ register struct dc_softc *sc = &dc_softc[0]; register int s; register u_short tcr; register int ln, tln = unit, timo; s = splhigh(); tcr = (sc->dctcr & (1<<tln)); sc->dctcr |= (1<<tln); while (1) { timo = 1000000; while ((sc->dccsr&DC_TRDY) == 0) /* while not ready */ if(--timo == 0) break; if(timo == 0) break; ln = (sc->dccsr>>8) & 3; if (ln != tln) { tcr |= (1 << ln); sc->dctcr &= ~(1 << ln); continue; } /* stuff char out, don't upset upper 8 bits */ sc->dcbrk_tbuf = ((dc_brk[0]) | (c&0xff)); DELAY(5); /* alow time for TRDY bit to become valid */ while (1) { while ((sc->dccsr&DC_TRDY) == 0); /* while not ready */ ln = (sc->dccsr>>8) & 3; if (ln != tln) { tcr |= (1 << ln); sc->dctcr &= ~(1 << ln); continue; } break; } break; } sc->dctcr &= ~(1<<tln); if (tcr != 0) sc->dctcr |= tcr; wbflush(); splx(s);}/* * This routine operates on the following assumptions: * 1. putc must have happened first, so SLU already inited. * 2. getc will happed before slu reveive interrupt enabled so * don't need to worry about int_req or int_msk registers. */dcgetc(){ register u_short c; register int line; /* * Line number we expect input from. */ if(consDev == GRAPHIC_DEV) line = 0x0; else line = 0x3; c = dc_getc(line); if(v_consgetc) return((*v_consgetc)(c & 0xff)); else return(c & 0xff);}dc_getc(unit)int unit;{ struct dc_softc *sc = &dc_softc[0]; register int timo; register u_short c; for(timo=1000000; timo > 0; --timo) { if(sc->dccsr&DC_RDONE) { c = sc->dcrbuf; DELAY(50000); if(((c >> 8) & 03) != unit) continue; if(c&(DC_DO|DC_FE|DC_PE)) continue; return(c & 0xff); } } return(-1);} dc_mouse_init(){ struct dc_softc *sc = &dc_softc[0]; /* * Set SLU line 1 parameters for mouse communication. */ sc->dclpr = (SER_POINTER | SER_CHARW | SER_PARENB | SER_ODDPAR | SER_SPEED | SER_RXENAB );}dc_mouse_putc(c)int c;{ dc_putc(1, c);}dc_mouse_getc(){ return (dc_getc(1));}dc_kbd_init(){ struct dc_softc *sc = &dc_softc[0]; /* * Set the line parameters on SLU line 0 for * the LK201 keyboard: 4800 BPS, 8-bit char, 1 stop bit, no parity. */ sc->dclpr = (SER_RXENAB | SER_KBD | SER_SPEED | SER_CHARW);}dc_kbd_putc(c)int c;{ dc_putc(0, c);}dc_kbd_getc(){ return (dc_getc(0));}/* * Modem Control Routines *//* * * Function: * * dc_cd_drop * * Functional description: * * Determine if carrier has dropped. If so call dc_tty_drop to terminate * the connection. * * Arguements: * * register struct tty *tp - terminal pointer ( for terminal attributes ) * * Return value: * * none * */dc_cd_drop(tp)register struct tty *tp;{ register struct dc_softc *sc; register int unit, ctlr; unit = minor(tp->t_dev); ctlr = unit >> 2; sc = &dc_softc[ctlr]; if ((tp->t_state & TS_CARR_ON) && (!(sc->dcmsr & dc_rcd[unit]))) {#ifdef DEBUG if (dcdebug) cprintf("dc_cd_drop: no CD, tp = %x, line = %d\n", tp, unit);#endif DEBUG dc_tty_drop(tp); return; } dcmodem[unit] |= MODEM_CD;#ifdef DEBUG if (dcdebug) cprintf("dc_cd_drop: CD is up, tp = %x, line = %d\n", tp, unit);#endif DEBUG} /* * * Function: * * dc_dsr_check * * Functional description: * * DSR must be asserted for a connection to be established. Here we * either start or terminate a connection on the basis of DSR. * * Arguements: * * register struct tty *tp - terminal pointer (for terminal attributes) * * Return value: * * none * */dc_dsr_check(tp)register struct tty *tp;{ register struct dc_softc *sc; register int unit, ctlr; unit = minor(tp->t_dev); ctlr = unit >> 2; sc = &dc_softc[ctlr];# ifdef DEBUG if (dcdebug) { cprintf("dc_dsr_check0: tp=%x\n", tp); PRINT_SIGNALS(); }# endif DEBUG if (dcmodem[unit] & MODEM_DSR_START) { dcmodem[unit] &= ~MODEM_DSR_START; /* * since dc7085 chip on PMAX only provides DSR then assume that CD * has come up after 1 sec and start tty. If CD has not * come up the modem should deassert DSR thus closing the line * * On 3max, we look for DSR|CTS|CD before establishing a * connection. */ if ((!dc_modem_ctl) || ((sc->dcmsr & dc_xmit[unit]) == dc_xmit[unit])) { dc_start_tty(tp); } return; } if ((tp->t_state&TS_CARR_ON)==0) dc_tty_drop(tp);}/* * * Function: * * dc_cd_down * * Functional description: * * Determine whether or not carrier has been down for > 2 sec. * * Arguements: * * register struct tty *tp - terminal pointer ( for terminal attributes ) * * Return value: * * 1 - if carrier was down for > 2 sec. * 0 - if carrier down <= 2 sec. * */dc_cd_down(tp)register struct tty *tp;{ register int msecs, unit; unit = minor(tp->t_dev); msecs = 1000000 * (time.tv_sec - dctimestamp[unit].tv_sec) + (time.tv_usec - dctimestamp[unit].tv_usec); if (msecs > 2000000){# ifdef DEBUG if (dcdebug) cprintf("dc_cd_down: msecs > 20000000\n");# endif DEBUG return(1); } else{# ifdef DEBUG if (dcdebug) cprintf("dc_cd_down: msecs < 20000000\n");# endif DEBUG return(0); }}/* * * Function: * * dc_tty_drop * * Functional description: * * Terminate a connection. * * Arguements: * * register struct tty *tp - terminal pointer ( for terminal attributes ) * * Return value: * * none * */dc_tty_drop(tp)struct tty *tp;{ register struct dc_softc *sc; register int unit, ctlr; unit = minor(tp->t_dev); ctlr = unit >> 2; sc = &dc_softc[ctlr]; dcmodem_active[ctlr] &= ~(1 << (unit & LINEMASK)); if (tp->t_flags & NOHANG) return;# ifdef DEBUG if (dcdebug) cprintf("dc_tty_drop: unit=%d\n",minor(tp->t_dev));# endif DEBUG /* * Notify any processes waiting to open this line. Useful in the * case of a false start. */ dcmodem[unit] = MODEM_BADCALL; tp->t_state &= ~(TS_CARR_ON|TS_TTSTOP|TS_BUSY|TS_ISUSP); wakeup((caddr_t)&tp->t_rawq); gsignal(tp->t_pgrp, SIGHUP); gsignal(tp->t_pgrp, SIGCONT); sc->dcdtr &= ~(dc_rdtr[unit] | dc_rrts[unit]);}/* * * Function: * * dc_start_tty * * Functional description: * * Establish a connection. * * Arguements: * * register struct tty *tp - terminal pointer ( for terminal attributes ) * * Return value: * * none * */dc_start_tty(tp) register struct tty *tp;{ register int unit, ctlr; unit = minor(tp->t_dev); ctlr = unit >> 2; dcmodem_active[ctlr] |= (1 << (unit & LINEMASK)); tp->t_state &= ~(TS_ONDELAY); tp->t_state |= TS_CARR_ON;# ifdef DEBUG if (dcdebug) cprintf("dc_start_tty: tp=%x\n", tp);# endif DEBUG if (dcmodem[unit] & MODEM_DSR) untimeout(dc_dsr_check, tp); dcmodem[unit] |= MODEM_CD|MODEM_CTS|MODEM_DSR; dctimestamp[unit].tv_sec = dctimestamp[unit].tv_usec = 0; wakeup((caddr_t)&tp->t_rawq);}dcbaudrate(speed)int speed;{ return(dc_speeds[speed & CBAUD].baud_support);}void dcsetbreak(tp)register struct tty *tp;{ wakeup((caddr_t)&tp->t_dev);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -