int mfcsparam(struct tty *tp, struct termios *t) { int cflag, unit, ospeed; struct mfcs_softc *sc = device_lookup_private(&mfcs_cd, tp->t_dev & 31); struct mfc_softc *scc= sc->sc_mfc; cflag = t->c_cflag; unit = tp->t_dev & 31; if (sc->flags & CT_USED) { --scc->ct_usecnt; sc->flags &= ~CT_USED; } ospeed = ttspeedtab(t->c_ospeed, scc->mfc_iii ? mfcs3speedtab2 : mfcs2speedtab2); /* * If Baud Rate Generator can't generate requested speed, * try to use the counter/timer. */ if (ospeed < 0 && (scc->clk_frq % t->c_ospeed) == 0) { ospeed = scc->clk_frq / t->c_ospeed; /* divisor */ if (scc->ct_usecnt > 0 && scc->ct_val != ospeed) ospeed = -1; else { scc->sc_regs->du_ctur = ospeed >> 8; scc->sc_regs->du_ctlr = ospeed; scc->ct_val = ospeed; ++scc->ct_usecnt; sc->flags |= CT_USED; ospeed = 0xdd; } }
int apciinit(struct apciregs *apci, u_int16_t rate, u_int16_t cfcr) { int s, stat; s = splhigh(); rate = ttspeedtab(rate, apcispeedtab); apci->ap_cfcr = CFCR_DLAB; apci->ap_data = rate & 0xff; apci->ap_ier = (rate >> 8) & 0xff; apci->ap_cfcr = cfcr; apci->ap_ier = IER_ERXRDY | IER_ETXRDY; apci->ap_fifo = FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1; apci->ap_mcr = MCR_DTR | MCR_RTS; delay(100); stat = apci->ap_iir; splx(s); return (stat); }
/* * siparam() : Configure line params * called at spltty(); * this may sleep, does not flush, nor wait for drain, nor block writes * caller must arrange this if it's important.. */ static int siparam(struct tty *tp, struct termios *t) { struct si_port *pp = tp->t_sc; volatile struct si_channel *ccbp; int oldspl, cflag, iflag, oflag, lflag; int error = 0; /* shutup gcc */ int ispeed = 0; /* shutup gcc */ int ospeed = 0; /* shutup gcc */ BYTE val; DPRINT((pp, DBG_ENTRY|DBG_PARAM, "siparam(%x,%x)\n", tp, t)); cflag = t->c_cflag; iflag = t->c_iflag; oflag = t->c_oflag; lflag = t->c_lflag; DPRINT((pp, DBG_PARAM, "OFLAG 0x%x CFLAG 0x%x IFLAG 0x%x LFLAG 0x%x\n", oflag, cflag, iflag, lflag)); /* XXX - if Jet host and SXDC module, use extended baud rates */ /* if not hung up.. */ if (t->c_ospeed != 0) { /* translate baud rate to firmware values */ ospeed = ttspeedtab(t->c_ospeed, bdrates); ispeed = t->c_ispeed ? ttspeedtab(t->c_ispeed, bdrates) : ospeed; /* enforce legit baud rate */ if (ospeed < 0 || ispeed < 0) return (EINVAL); } oldspl = spltty(); ccbp = pp->sp_ccb; /* ========== set hi_break ========== */ val = 0; if (iflag & IGNBRK) /* Breaks */ val |= BR_IGN; if (iflag & BRKINT) /* Interrupt on break? */ val |= BR_INT; if (iflag & PARMRK) /* Parity mark? */ val |= BR_PARMRK; if (iflag & IGNPAR) /* Ignore chars with parity errors? */ val |= BR_PARIGN; ccbp->hi_break = val; /* ========== set hi_csr ========== */ /* if not hung up.. */ if (t->c_ospeed != 0) { /* Set I/O speeds */ val = (ispeed << 4) | ospeed; } ccbp->hi_csr = val; /* ========== set hi_mr2 ========== */ val = 0; if (cflag & CSTOPB) /* Stop bits */ val |= MR2_2_STOP; else val |= MR2_1_STOP; /* * Enable H/W RTS/CTS handshaking. The default TA/MTA is * a DCE, hence the reverse sense of RTS and CTS */ /* Output Flow - RTS must be raised before data can be sent */ if (cflag & CCTS_OFLOW) val |= MR2_RTSCONT; ccbp->hi_mr2 = val; /* ========== set hi_mr1 ========== */ val = 0; if (!(cflag & PARENB)) /* Parity */ val |= MR1_NONE; else val |= MR1_WITH; if (cflag & PARODD) val |= MR1_ODD; if ((cflag & CS8) == CS8) { /* 8 data bits? */ val |= MR1_8_BITS; } else if ((cflag & CS7) == CS7) { /* 7 data bits? */ val |= MR1_7_BITS; } else if ((cflag & CS6) == CS6) { /* 6 data bits? */ val |= MR1_6_BITS; } else { /* Must be 5 */ val |= MR1_5_BITS; } /* * Enable H/W RTS/CTS handshaking. The default TA/MTA is * a DCE, hence the reverse sense of RTS and CTS */ /* Input Flow - CTS is raised when port is ready to receive data */ if (cflag & CRTS_IFLOW) val |= MR1_CTSCONT; ccbp->hi_mr1 = val; /* ========== set hi_mask ========== */ val = 0xff; if ((cflag & CS8) == CS8) { /* 8 data bits? */ val &= 0xFF; } else if ((cflag & CS7) == CS7) { /* 7 data bits? */ val &= 0x7F; } else if ((cflag & CS6) == CS6) { /* 6 data bits? */ val &= 0x3F; } else { /* Must be 5 */ val &= 0x1F; } if (iflag & ISTRIP) val &= 0x7F; ccbp->hi_mask = val; /* ========== set hi_prtcl ========== */ val = SP_DCEN; /* Monitor DCD always, or TIOCMGET misses it */ if (iflag & IXANY) val |= SP_TANY; if (iflag & IXON) val |= SP_TXEN; if (iflag & IXOFF) val |= SP_RXEN; if (iflag & INPCK) val |= SP_PAEN; ccbp->hi_prtcl = val; /* ========== set hi_{rx|tx}{on|off} ========== */ /* XXX: the card TOTALLY shields us from the flow control... */ ccbp->hi_txon = t->c_cc[VSTART]; ccbp->hi_txoff = t->c_cc[VSTOP]; ccbp->hi_rxon = t->c_cc[VSTART]; ccbp->hi_rxoff = t->c_cc[VSTOP]; /* ========== send settings to the card ========== */ /* potential sleep here */ if (ccbp->hi_stat == IDLE_CLOSE) /* Not yet open */ si_command(pp, LOPEN, SI_WAIT); /* open it */ else si_command(pp, CONFIG, SI_WAIT); /* change params */ /* ========== set DTR etc ========== */ /* Hangup if ospeed == 0 */ if (t->c_ospeed == 0) { (void) simodem(tp, 0, SER_DTR | SER_RTS); } else { /* * If the previous speed was 0, may need to re-enable * the modem signals */ (void) simodem(tp, SER_DTR | SER_RTS, 0); } DPRINT((pp, DBG_PARAM, "siparam, complete: MR1 %x MR2 %x HI_MASK %x PRTCL %x HI_BREAK %x\n", ccbp->hi_mr1, ccbp->hi_mr2, ccbp->hi_mask, ccbp->hi_prtcl, ccbp->hi_break)); splx(oldspl); return(error); }
static void btios2stios(struct termios *bt, struct sunos_termios *st) { u_long l, r; int s; l = bt->c_iflag; r = ((l & IGNBRK) ? 0x00000001 : 0); r |= ((l & BRKINT) ? 0x00000002 : 0); r |= ((l & IGNPAR) ? 0x00000004 : 0); r |= ((l & PARMRK) ? 0x00000008 : 0); r |= ((l & INPCK) ? 0x00000010 : 0); r |= ((l & ISTRIP) ? 0x00000020 : 0); r |= ((l & INLCR) ? 0x00000040 : 0); r |= ((l & IGNCR) ? 0x00000080 : 0); r |= ((l & ICRNL) ? 0x00000100 : 0); /* ((l & IUCLC) ? 0x00000200 : 0) */ r |= ((l & IXON) ? 0x00000400 : 0); r |= ((l & IXANY) ? 0x00000800 : 0); r |= ((l & IXOFF) ? 0x00001000 : 0); r |= ((l & IMAXBEL) ? 0x00002000 : 0); st->c_iflag = r; l = bt->c_oflag; r = ((l & OPOST) ? 0x00000001 : 0); /* ((l & OLCUC) ? 0x00000002 : 0) */ r |= ((l & ONLCR) ? 0x00000004 : 0); /* ((l & OCRNL) ? 0x00000008 : 0) */ /* ((l & ONOCR) ? 0x00000010 : 0) */ /* ((l & ONLRET) ? 0x00000020 : 0) */ /* ((l & OFILL) ? 0x00000040 : 0) */ /* ((l & OFDEL) ? 0x00000080 : 0) */ /* ((l & NLDLY) ? 0x00000100 : 0) */ /* ((l & NL1) ? 0x00000100 : 0) */ /* ((l & CRDLY) ? 0x00000600 : 0) */ /* ((l & CR1) ? 0x00000200 : 0) */ /* ((l & CR2) ? 0x00000400 : 0) */ /* ((l & CR3) ? 0x00000600 : 0) */ /* ((l & TABDLY) ? 0x00001800 : 0) */ /* ((l & TAB1) ? 0x00000800 : 0) */ /* ((l & TAB2) ? 0x00001000 : 0) */ r |= ((l & OXTABS) ? 0x00001800 : 0); /* ((l & BSDLY) ? 0x00002000 : 0) */ /* ((l & BS1) ? 0x00002000 : 0) */ /* ((l & VTDLY) ? 0x00004000 : 0) */ /* ((l & VT1) ? 0x00004000 : 0) */ /* ((l & FFDLY) ? 0x00008000 : 0) */ /* ((l & FF1) ? 0x00008000 : 0) */ /* ((l & PAGEOUT) ? 0x00010000 : 0) */ /* ((l & WRAP) ? 0x00020000 : 0) */ st->c_oflag = r; l = bt->c_cflag; switch (l & CSIZE) { case CS5: r = 0; break; case CS6: r = 0x00000010; break; case CS7: r = 0x00000020; break; case CS8: r = 0x00000030; break; } r |= ((l & CSTOPB) ? 0x00000040 : 0); r |= ((l & CREAD) ? 0x00000080 : 0); r |= ((l & PARENB) ? 0x00000100 : 0); r |= ((l & PARODD) ? 0x00000200 : 0); r |= ((l & HUPCL) ? 0x00000400 : 0); r |= ((l & CLOCAL) ? 0x00000800 : 0); /* ((l & LOBLK) ? 0x00001000 : 0) */ r |= ((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0); st->c_cflag = r; l = bt->c_lflag; r = ((l & ISIG) ? 0x00000001 : 0); r |= ((l & ICANON) ? 0x00000002 : 0); /* ((l & XCASE) ? 0x00000004 : 0) */ r |= ((l & ECHO) ? 0x00000008 : 0); r |= ((l & ECHOE) ? 0x00000010 : 0); r |= ((l & ECHOK) ? 0x00000020 : 0); r |= ((l & ECHONL) ? 0x00000040 : 0); r |= ((l & NOFLSH) ? 0x00000080 : 0); r |= ((l & TOSTOP) ? 0x00000100 : 0); r |= ((l & ECHOCTL) ? 0x00000200 : 0); r |= ((l & ECHOPRT) ? 0x00000400 : 0); r |= ((l & ECHOKE) ? 0x00000800 : 0); /* ((l & DEFECHO) ? 0x00001000 : 0) */ r |= ((l & FLUSHO) ? 0x00002000 : 0); r |= ((l & PENDIN) ? 0x00004000 : 0); st->c_lflag = r; s = ttspeedtab(bt->c_ospeed, sptab); if (s >= 0) st->c_cflag |= s; st->c_cc[0] = bt->c_cc[VINTR] != _POSIX_VDISABLE? bt->c_cc[VINTR]:0; st->c_cc[1] = bt->c_cc[VQUIT] != _POSIX_VDISABLE? bt->c_cc[VQUIT]:0; st->c_cc[2] = bt->c_cc[VERASE] != _POSIX_VDISABLE? bt->c_cc[VERASE]:0; st->c_cc[3] = bt->c_cc[VKILL] != _POSIX_VDISABLE? bt->c_cc[VKILL]:0; st->c_cc[4] = bt->c_cc[VEOF] != _POSIX_VDISABLE? bt->c_cc[VEOF]:0; st->c_cc[5] = bt->c_cc[VEOL] != _POSIX_VDISABLE? bt->c_cc[VEOL]:0; st->c_cc[6] = bt->c_cc[VEOL2] != _POSIX_VDISABLE? bt->c_cc[VEOL2]:0; st->c_cc[7] = 0; /* bt->c_cc[VSWTCH] != _POSIX_VDISABLE? bt->c_cc[VSWTCH]: */ st->c_cc[8] = bt->c_cc[VSTART] != _POSIX_VDISABLE? bt->c_cc[VSTART]:0; st->c_cc[9] = bt->c_cc[VSTOP] != _POSIX_VDISABLE? bt->c_cc[VSTOP]:0; st->c_cc[10]= bt->c_cc[VSUSP] != _POSIX_VDISABLE? bt->c_cc[VSUSP]:0; st->c_cc[11]= bt->c_cc[VDSUSP] != _POSIX_VDISABLE? bt->c_cc[VDSUSP]:0; st->c_cc[12]= bt->c_cc[VREPRINT]!= _POSIX_VDISABLE? bt->c_cc[VREPRINT]:0; st->c_cc[13]= bt->c_cc[VDISCARD]!= _POSIX_VDISABLE? bt->c_cc[VDISCARD]:0; st->c_cc[14]= bt->c_cc[VWERASE] != _POSIX_VDISABLE? bt->c_cc[VWERASE]:0; st->c_cc[15]= bt->c_cc[VLNEXT] != _POSIX_VDISABLE? bt->c_cc[VLNEXT]:0; st->c_cc[16]= bt->c_cc[VSTATUS] != _POSIX_VDISABLE? bt->c_cc[VSTATUS]:0; if (!(bt->c_lflag & ICANON)) { /* SunOS stores VMIN/VTIME in VEOF/VEOL (if ICANON is off) */ st->c_cc[4] = bt->c_cc[VMIN]; st->c_cc[5] = bt->c_cc[VTIME]; } st->c_line = 0; }
/* * Nudge the transmitter... * * XXX: I inherited some funny code here. It implies the host card only * interrupts when the transmit buffer reaches the low-water-mark, and does * not interrupt when it's actually hits empty. In some cases, we have * processes waiting for complete drain, and we need to simulate an interrupt * about when we think the buffer is going to be empty (and retry if not). * I really am not certain about this... I *need* the hardware manuals. */ static void si_start(struct tty *tp) { struct si_port *pp; volatile struct si_channel *ccbp; struct clist *qp; BYTE ipos; int nchar; int oldspl, count, n, amount, buffer_full; oldspl = spltty(); qp = &tp->t_outq; pp = tp->t_sc; DPRINT((pp, DBG_ENTRY|DBG_START, "si_start(%x) t_state %x sp_state %x t_outq.c_cc %d\n", tp, tp->t_state, pp->sp_state, qp->c_cc)); if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP)) goto out; buffer_full = 0; ccbp = pp->sp_ccb; count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos; DPRINT((pp, DBG_START, "count %d\n", (BYTE)count)); while ((nchar = qp->c_cc) > 0) { if ((BYTE)count >= 255) { buffer_full++; break; } amount = min(nchar, (255 - (BYTE)count)); ipos = (unsigned int)ccbp->hi_txipos; n = q_to_b(&tp->t_outq, si_txbuf, amount); /* will it fit in one lump? */ if ((SI_BUFFERSIZE - ipos) >= n) { si_bcopyv(si_txbuf, &ccbp->hi_txbuf[ipos], n); } else { si_bcopyv(si_txbuf, &ccbp->hi_txbuf[ipos], SI_BUFFERSIZE - ipos); si_bcopyv(si_txbuf + (SI_BUFFERSIZE - ipos), &ccbp->hi_txbuf[0], n - (SI_BUFFERSIZE - ipos)); } ccbp->hi_txipos += n; count = (int)ccbp->hi_txipos - (int)ccbp->hi_txopos; } if (count != 0 && nchar == 0) { tp->t_state |= TS_BUSY; } else { tp->t_state &= ~TS_BUSY; } /* wakeup time? */ ttwwakeup(tp); DPRINT((pp, DBG_START, "count %d, nchar %d, tp->t_state 0x%x\n", (BYTE)count, nchar, tp->t_state)); if (tp->t_state & TS_BUSY) { int time; time = ttspeedtab(tp->t_ospeed, chartimes); if (time > 0) { if (time < nchar) time = nchar / time; else time = 2; } else { DPRINT((pp, DBG_START, "bad char time value! %d\n", time)); time = hz/10; } if ((pp->sp_state & (SS_LSTART|SS_INLSTART)) == SS_LSTART) { untimeout(si_lstart, (caddr_t)pp, pp->lstart_ch); } else { pp->sp_state |= SS_LSTART; } DPRINT((pp, DBG_START, "arming lstart, time=%d\n", time)); pp->lstart_ch = timeout(si_lstart, (caddr_t)pp, time); } out: splx(oldspl); DPRINT((pp, DBG_EXIT|DBG_START, "leave si_start()\n")); }