⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
	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);}      dmtoscc(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);}scctodm(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);}sccparam(unit)     register int unit;{    register struct scc_softc *sc = sccsc;    register struct tty *tp;    register struct scc_reg *rsp, *rsp0;    register struct scc_saved_reg *ssp, *ssp0;    register int rxen = 1, s, status;    register int timo;        s = spltty();    tp = &scc_tty[unit];    if (tp->t_state & TS_BUSY) {        tp->t_state |= TS_NEED_PARAM;	return;    }    rsp = sc->sc_regs[unit];    SCC_READ(rsp, SCC_RR1, status);	/* read status */    for(timo=10000; timo > 0; --timo) {        if (status & SCC_RR1_ALL_SENT) 	    break;		else {	    SCC_READ(rsp, SCC_RR1, status);	}    }    ssp = &sc->sc_saved_regs[unit];        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))) {	SCC_CLR_DTR(unit);	SCC_CLR_RTS(unit);	SCC_CLR_SS(unit);	splx(s);	return;    }    /*     * If diagnostic console on line 3,     * line parameters must be: 9600 BPS, 8 BIT, NO PARITY, 1 STOP.     */    if ((unit == 3) && (consDev != GRAPHIC_DEV)) {	/*          * do nothing here because line 3 parameters have already 	 * been set in scc_cons_init.	 */	;    } else if (unit == 2 || unit == 3) {        /*	 * Set parameters in accordance with user specification.	 */	ssp->wr4 = SCC_WR4_CLOCK16;	/*	 * Berkeley-only dinosaur	 */	if (tp->t_line != TERMIODISC) {	    if ((tp->t_cflag_ext&CBAUD) == B110)		tp->t_cflag |= CSTOPB;	}	/*	 * Set device registers according to the specifications of the	 * termio structure.	 */	if ((tp->t_cflag & CREAD) == 0)	    /* disable receiver */	    rxen = 0;            		if (tp->t_cflag & CSTOPB) 	    ssp->wr4 |= SCC_WR4_TWOSB;	else	    ssp->wr4 |= SCC_WR4_ONESB;	if (tp->t_cflag & PARENB) {	    if ((tp->t_cflag & PARODD) == 0) 		/* set even */		ssp->wr4 |= (SCC_WR4_EPAR | SCC_WR4_PENABLE);	    else		/* else set odd */		ssp->wr4 |= SCC_WR4_PENABLE;	}	SCC_WRITE(rsp, SCC_WR4, ssp->wr4);	/*	 * character size.	 * clear bits and check for 5, 6, 7 & 8 bits.	 */	ssp->wr3 &= ~(SCC_WR3_RBITS|SCC_WR3_RXEN);	ssp->wr5 &= ~(SCC_WR5_TBITS|SCC_WR5_TXEN);	switch(tp->t_cflag&CSIZE) {	  case CS5:	    ssp->wr3 |= SCC_WR3_RBITS5;	    ssp->wr5 |= SCC_WR5_TBITS5;	    break;	  case CS6:	    ssp->wr3 |= SCC_WR3_RBITS6;	    ssp->wr5 |= SCC_WR5_TBITS6;	    break;	  case CS7:	    ssp->wr3 |= SCC_WR3_RBITS7;	    ssp->wr5 |= SCC_WR5_TBITS7;	    break;	  case CS8:	    ssp->wr3 |= SCC_WR3_RBITS8;	    ssp->wr5 |= SCC_WR5_TBITS8;	    break;	}	SCC_WRITE(rsp, SCC_WR3, ssp->wr3);	SCC_WRITE(rsp, SCC_WR5, ssp->wr5);	ssp->wr14 &= ~(SCC_WR14_BRGEN_EN);	SCC_WRITE(rsp, SCC_WR14, ssp->wr14);	     /*	 WR14 BRG disable */	SCC_WRITE(rsp, SCC_WR12, scc_speeds[tp->t_cflag&CBAUD].baud_lo);	SCC_WRITE(rsp, SCC_WR13, scc_speeds[tp->t_cflag&CBAUD].baud_hi);	scc_cbaud[unit] = tp->t_cflag&CBAUD;	if ((tp->t_cflag & CLOCAL) == 0)	    sccspeedi(unit);  /* check speed indicate */	/* 	 * enable functions 	 */	ssp->wr14 |= SCC_WR14_BRGEN_EN;	SCC_WRITE(rsp, SCC_WR14, ssp->wr14);	     /*	 WR14 BRG enable */	if (rxen) {	    ssp->wr3 |= SCC_WR3_RXEN;	    SCC_WRITE(rsp, SCC_WR3, ssp->wr3);	      /*  WR3 Rx enable */	}	ssp->wr5 |= SCC_WR5_TXEN;	SCC_WRITE(rsp, SCC_WR5, ssp->wr5);        /*  WR5 Tx enable */    }    splx(s);}/* * scc_dma_xint(unit) - transmit DMA interrupt service routine *	 * algorithm: *	-clear transmit DMA interrupt *  	-disable transmit DMA for comm. port designated by 'unit' * 	-same as dcxint with pdma stuff removed and new ndflush: *		-get tty for 'unit' *		-reset 'unit' to 3 if line 0 is console *		-set t_state  *		-flush 'cc' bytes from output queue *              -if we need param, call sccparam *		-invoke start routine * */scc_dma_xint(unit)     register int unit; 	{    register struct scc_softc *sc = sccsc;    register struct tty *tp;    register char *ptr;    register struct scc_reg *rsp;    register int cc;    /* must disable the transmit DMA before clearing the interrupt */    IOC_CLR(IOC_SSR, scc_xdma_en[unit]);    /* disable transmit DMA */    IOC_WR(IOC_SIR, ~(scc_xint[unit]));       /* clear transmit int */    /* read transmit DMA offset */    ptr = (char *)(((sc->ioc_regs[unit]->XDMA_REG) >> 3) & 0xfff);    if (ptr == 0) 	ptr += (u_long)sc->tbuf[unit] + SCC_PAGE_SIZE;    else 	ptr += (u_long)sc->tbuf[unit];        tp = &scc_tty[unit];    if ((consDev != GRAPHIC_DEV) && (unit == 0) && /* ? */	(major(tp->t_dev) == CONSOLEMAJOR)) {	unit = 3;    }        tp->t_state &= ~TS_BUSY;    cc = (u_long *)ptr - (u_long *)sc->tptr[unit]; /* cc bytes */    ndflush(&tp->t_outq, cc); /* cc bytes */    if (tp->t_state & TS_NEED_PARAM) {        tp->t_state &= ~TS_NEED_PARAM;	sccparam(unit);    }    if (tp->t_line) {	(*linesw[tp->t_line].l_start)(tp);    } else  {	sccstart(tp);    }}sccstart(tp)     register struct tty *tp;{	    register struct scc_softc *sc = sccsc;    register int cc;    int s, unit;    register char *bp;    register char *cp;    register int c_mask;        s = spltty();    /*     * Do not do anything if currently delaying, or active.  Also only     * transmit when CTS is up.     */    unit = minor(tp->t_dev) & 3;    if ((tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) || 	(((tp->t_cflag & CLOCAL) == 0) && 	 ((tp->t_state&TS_CARR_ON) && (sccmodem[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;    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;        /*     * prepare for DMA:     *	-point cp to first char in clist block,     * 	-point bp to cc words from end of page,     *	-save bp in scc_softc for use by ndflush.     *	-using cp and bp, copy cc bytes from clist to     *		word-aligned DMA page.     */    cp = tp->t_outq.c_cf;    bp = sc->tbuf[unit] + SCC_PAGE_SIZE - (cc * SCC_WORD);    sc->tptr[unit] = bp;    /*     * need to do the following because when character size is set to five,     * the data format allows character sizes of one to five. See SCC     * manual.     */    if ((tp->t_cflag&CSIZE) == CS5)       c_mask = 0x1f;    else       c_mask = 0xff;    while (cc-- > 0) {	*(u_short *)bp = (((u_short)*cp++)&c_mask)<<8;	bp += SCC_WORD;    }    /*     * set DMA transmit ptr     */    sc->ioc_regs[unit]->XDMA_REG = (u_long)(svtophy(sc->tptr[unit]) << 3);    IOC_SET(IOC_SSR, scc_xdma_en[unit]);     /* enable transmit DMA */  out:	    splx(s);}sccstop(tp, flag)     register struct tty *tp;{    register struct scc_softc *sc = sccsc;    register int s, cc;    register char *ptr;    int	unit;        /*     * 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);    if ((consDev != GRAPHIC_DEV) && (unit == 0) && /* ? */	(major(tp->t_dev) == CONSOLEMAJOR)) {	unit = 3;    }    if (vs_gdstop && (unit <= 1)) {	(*vs_gdstop)(tp, flag);	return;    }        s = spltty();    if (tp->t_state & TS_BUSY) {	/* disable transmit DMA */	IOC_CLR(IOC_SSR, scc_xdma_en[unit]); 	/* 	 * pgt - need to clear transmit int to handle boundary condition, 	 * otherwise scc_dma_xint could be called and queue would be 	 * ndflushed twice	 */	IOC_WR(IOC_SIR, ~(scc_xint[unit]));       /* clear transmit int */	/* line discipline will flush entire queue */	if ((tp->t_state&TS_TTSTOP)==0) {	    ;	} else { /* suspend */	    /* read transmit DMA ptr */	    ptr = (char *)(((sc->ioc_regs[unit]->XDMA_REG) >> 3) & 0xfff);	    /* if we made it to a page boundary pointer will be zero */	    if (ptr == 0)		ptr += (long)(sc->tbuf[unit]) + SCC_PAGE_SIZE ;	    else 		ptr += (long)(sc->tbuf[unit]);	    cc = (u_long *)ptr - (u_long *)sc->tptr[unit]; /* cc bytes */	    ndflush(&tp->t_outq, cc); /* cc bytes */	}	tp->t_state &= ~TS_BUSY;    }    splx(s);}sccmctl(dev, bits, how)     dev_t dev;     int bits, how;{    register struct scc_softc *sc = sccsc;    register int unit, mbits;    int b, s;        unit = minor(dev);    if ((unit != 2) && (unit != 3))	return(0);	/* only line 2 and 3 has modem control */    s = spltty();    mbits = (SCC_DTR(unit)) ? DC_DTR : 0;    mbits |= (SCC_RTS(unit)) ? DC_RTS : 0;    mbits |= (SCC_DCD(unit)) ? DC_CD : 0;    mbits |= (SCC_DSR(unit)) ? DC_DSR : 0;    mbits |= (SCC_CTS(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) {	SCC_SET_DTR(unit);	SCC_SET_RTS(unit);	SCC_SET_SS(unit);    } else {	SCC_CLR_DTR(unit);	SCC_CLR_RTS(unit);	SCC_CLR_SS(unit);    }    (void) splx(s);    return(mbits);}scc_ext_rint(i)     register i;{    register struct scc_softc *sc = sccsc;    register struct tty *tp;    register struct scc_reg *rsp;    register int brk;    tp = &scc_tty[i];    /*     * assume break condition will last long enough for it to be processed by     * this routine. otherwise, null characters would be DMA'd into the receive     * buffer.     */    if (i == 2 || i == 3) {        rsp = sc->sc_regs[i];	brk = ((rsp->SCC_CMD)>>8) & SCC_RR0_BREAK;	/* check if there is a state change in BREAK */	if (brk && !scc_brk[i])  {	    scc_brk[i] = 1;		    sccbrkint(i);	} else if (!brk && scc_brk[i]) {	    scc_brk[i] = 0;	    sccbrkint(i);	} else if (brk && scc_brk[i]) {	    /*	     * handle the case where successive breaks arrive	     * need to call brkint twice to handle the termination of an	     * earlier break and the beginning of the next break	     */	    scc_brk[i] = 0;	    sccbrkint(i);	    scc_brk[i] = 1;	    sccbrkint(i);	}    }     if ((tp->t_cflag & CLOCAL) == 0) {	sccspeedi(i);	/* check for speed indicate changes */	/*	 * Drop DTR immediately if DSR has gone away.	 * If really an active close then do not	 *    send signals.	 */	if (!(SCC_DSR(i))) {	    if (tp->t_state&TS_CLOSING) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -