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

📄 scc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
     */       if (!rex_base) {	 if ((atoi(prom_getenv("osconsole")) & 0x1) == 1) {	   slu.mouse_init = scc_mouse_init;	   slu.mouse_putc = scc_mouse_putc;	   slu.mouse_getc = scc_mouse_getc;	   slu.kbd_init = scc_kbd_init;	   slu.kbd_putc = scc_kbd_putc;	   slu.kbd_getc = scc_kbd_getc;	   slu.slu_tty  = scc_tty;	   slu.slu_putc = scc_putc;	   for( i = 0 ; vcons_init[i] ; i++ )	     if ((*vcons_init[i])()) {	/* found a virtual console */	       consDev = GRAPHIC_DEV;	       return;	     }	 }		 scc_init(0); /* need to initialize channel A for modem control */	 scc_init(1);	 /* 	  * set up line 3 as alternate console line: no parity, 9600 baud	  */	 scc_init(3);       } else {	 if ((strlen(rex_getenv("osconsole"))) > 1) {	   slu.mouse_init = scc_mouse_init;	   slu.mouse_putc = scc_mouse_putc;	   slu.mouse_getc = scc_mouse_getc;	   slu.kbd_init = scc_kbd_init;	   slu.kbd_putc = scc_kbd_putc;	   slu.kbd_getc = scc_kbd_getc;	   slu.slu_tty  = scc_tty;	   slu.slu_putc = scc_putc;	   for( i = 0 ; vcons_init[i] ; i++ )	     if ((*vcons_init[i])()) {	/* found a virtual console */	       consDev = GRAPHIC_DEV;	       return;	     }	 }	 scc_init(0); /* need to initialize channel A for modem control */	 scc_init(1);	 /* 	  * set up line 3 as alternate console line: no parity, 9600 baud	  */	 scc_init(3);       }        /* enable functions */    rsp = sc->sc_regs[3];    ssp = &sc->sc_saved_regs[3];    ssp->wr14 |= SCC_WR14_BRGEN_EN;    SCC_WRITE(rsp, SCC_WR14, ssp->wr14);	     /*	 WR14 BRG enable */    ssp->wr5 |= SCC_WR5_TXEN;    SCC_WRITE(rsp, SCC_WR5, ssp->wr5);        /*  WR5 Tx enable */    ssp->wr3 |= SCC_WR3_RXEN;    SCC_WRITE(rsp, SCC_WR3, ssp->wr3);	      /*  WR3 Rx enable */}sccopen(dev, flag)     dev_t dev;{    register struct scc_softc *sc = sccsc;    register struct tty *tp;    register int unit;    register int maj, error;    int inuse;  /*hold state of inuse bit while blocked waiting for carr*/    register struct scc_reg *rsp, *rsp0;    register struct scc_saved_reg *ssp0;    maj = major(dev);    unit = minor(dev);    /*     * If a diagnostic console is attached to SLU line 3,     * don't allow open of the printer port (also line 3).     * This could cause lpr to write to the console.     */    if((consDev != GRAPHIC_DEV) && (unit == 3))	return (ENXIO);        /* don't allow open of minor device 0 of major device SCCMAJOR */    /* because it is already reserved for /dev/console */    if ((maj != CONSOLEMAJOR) && (unit == 0))	return (ENXIO);    /* only allow open of /dev/console of major device 0 */    if ((maj == CONSOLEMAJOR) && (unit != 0)) 	return (ENXIO);    if ((consDev != GRAPHIC_DEV) && (maj == CONSOLEMAJOR) && (unit == 0))	unit |= 3;	/* diag console on SLU line 3 */        if (unit >= scc_cnt)	return (ENXIO);    /*     * Call the graphics device open routine     * if there is one and the open if for the fancy tube.     */    if (vs_gdopen && (unit <= 1)) {	error = (*vs_gdopen)(dev, flag);	if (error == 0) {	    sccparam(unit);  	    SCC_INT_ON(unit); /* turn on interrupts for kbd and mouse */	}	return(error);    }    tp = &scc_tty[unit];    rsp = sc->sc_regs[unit];    if (tp->t_state&TS_XCLUDE && u.u_uid != 0) {	return (EBUSY);    }        while (tp->t_state&TS_CLOSING) { /* let DTR stay down for awhile */	sleep((caddr_t)&tp->t_rawq, TTIPRI);    }    tp->t_addr = (caddr_t)tp;    tp->t_oproc = sccstart;    tp->t_baudrate = sccbaudrate;    tty_def_open(tp, dev, flag, (sccsoftCAR&(1<<(unit&LINEMASK))));        if ((tp->t_state & TS_ISOPEN) == 0) {	/*	 * Prevent spurious startups by making the 500ms timer	 * initially high.	 */	sccmodem[unit] = MODEM_DSR_START;	if((maj == CONSOLEMAJOR) && ((minor(dev)&3) == 0)) {	    tp->t_cflag &= ~CBAUD;	    tp->t_cflag |= B9600;	    /* modem control not supported on console */ 	    tp->t_cflag |= CLOCAL; 	    tp->t_cflag_ext &= ~CBAUD;	    tp->t_cflag_ext |= B9600;	    tp->t_flags = ANYP|ECHO|CRMOD;	    tp->t_iflag |= ICRNL; /* Map CRMOD */	    tp->t_oflag |= ONLCR; /* Map CRMOD */	}    }    sccparam(unit);	    SCC_INT_ON(unit);    /* enable interrupts */    (void) spltty();    /*     * No modem control provided for lines with softCAR set.     */    if (tp->t_cflag & CLOCAL) {	/*	 * This is a local connection - ignore carrier	 * receive enable interrupts enabled above	 */	tp->t_state |= TS_CARR_ON;			/* 	 * Turn off external modem interrupts	 */        SCC_MODEM_OFF(unit);	SCC_SET_DTR(unit);	SCC_SET_RTS(unit);	SCC_SET_SS(unit);	/*	 * Set state bit to tell tty.c not to assign this line as the	 * controlling terminal for the process which opens this line.	 */	if ((flag & O_NOCTTY) && (u.u_procp->p_progenv == A_POSIX))	    tp->t_state |= TS_ONOCTTY;	(void) spl0();	return ((*linesw[tp->t_line].l_open)(dev, tp));    }    /*     *  this is a modem line     */    SCC_MODEM_ON(unit);  /* enable modem interrupts */    SCC_SET_DTR(unit);    SCC_SET_RTS(unit);    SCC_SET_SS(unit);		/*	 * After DSR first comes up we must wait for the other signals	 * before commencing transmission.	 */    if ((flag & (O_NDELAY|O_NONBLOCK)) == 0) {	/*	 * Delay before examining other signals if DSR is being followed	 * otherwise proceed directly to scc_dsr_check to look for	 * carrier detect and clear to send.	 */	if (SCC_DSR(unit)) {	    sccmodem[unit] |= (MODEM_DSR_START|MODEM_DSR);	    tp->t_dev = dev; /* need it for timeouts */	    /*	     * Give CD and CTS 30 sec. to 	     * come up.  Start transmission	     * immediately, no longer need	     * 500ms delay.	     */	    timeout(scc_dsr_check, tp, hz*30);	    scc_dsr_check(tp);	}    }    if (flag & (O_NDELAY|O_NONBLOCK))	tp->t_state |= TS_ONDELAY;    else	while ((tp->t_state & TS_CARR_ON) == 0) {	    tp->t_state |= TS_WOPEN;	    inuse = tp->t_state&TS_INUSE;	    sleep((caddr_t)&tp->t_rawq, TTIPRI);	    /*	     * See if we were awoken by a false call to the modem	     * line by a non-modem.	     */	    if (sccmodem[unit]&MODEM_BADCALL){		(void) spl0();		return(EWOULDBLOCK);	    }	    /* if we opened "block if in use"  and	     *  the terminal was not inuse at that time	     *  but is became "in use" while we were	     *  waiting for carrier then return	     */	    if ((flag & O_BLKINUSE) && (inuse==0) &&		(tp->t_state&TS_INUSE)) {		(void) spl0();		return(EALREADY);	    }	}    /*     * Set state bit to tell tty.c not to assign this line as the     * controlling terminal for the process which opens this line.     */    if ((flag & O_NOCTTY) && (u.u_procp->p_progenv == A_POSIX))	tp->t_state |= TS_ONOCTTY;    (void) spl0();    return ((*linesw[tp->t_line].l_open)(dev, tp));}sccclose(dev, flag)     dev_t dev;{    register struct scc_softc *sc = sccsc;    register struct tty *tp;    register int unit, maj;    register int s;    extern int wakeup();        unit = minor(dev);    maj = major(dev);    if((consDev != GRAPHIC_DEV) && (major(dev) == CONSOLEMAJOR) && ((unit&LINEMASK) == 0))	unit |= 3;	/* diag console on SLU line 3 */    /*     * Call the graphics device close routine     * if ther is one and the close is for it.     */    if (vs_gdclose && (unit <= 1)) {	(*vs_gdclose)(dev, flag);	return;    }    tp = &scc_tty[unit];    /*     * Do line discipline specific close functions then return here     * in the old line disc for final closing.     */    if (tp->t_line)	(*linesw[tp->t_line].l_close)(tp);    /*     * Clear breaks for this line on close.     */    s = spltty();    SCC_CLR_BRK(unit);    splx(s);    if ((tp->t_cflag&HUPCL) || (tp->t_state&TS_WOPEN) || (tp->t_state&TS_ISOPEN)==0) {	tp->t_state &= ~TS_CARR_ON;   /* prevents recv intr. timeouts */	/*	 * Drop appropriate signals to terminate the connection.	 */	SCC_CLR_DTR(unit);	SCC_CLR_RTS(unit);	SCC_CLR_SS(unit);	if ((tp->t_cflag & CLOCAL) == 0) {	    s = spltty();	    /*drop DTR for at least a sec. if modem line*/	    tp->t_state |= TS_CLOSING;	    /*	     * Wait at most 5 sec for DSR to go off.	     * Also hold DTR down for a period.	     */	    if (SCC_DSR(unit)) {		timeout(wakeup,(caddr_t)&tp->t_dev,5*hz);		sleep((caddr_t)&tp->t_dev, PZERO-10);	    }	    /*	     * Hold DTR down for 200+ ms.	     */	    timeout(wakeup, (caddr_t) &tp->t_dev, hz/5);	    sleep((caddr_t)&tp->t_dev, PZERO-10);	    	    tp->t_state &= ~(TS_CLOSING);	    wakeup((caddr_t)&tp->t_rawq);	    splx(s);	}	/*	 * No disabling of interrupts is done.	Characters read in on	 * a non-open line will be discarded.	 */    }    /* reset line to default mode */    sccsoftCAR &= ~(1<<(unit&LINEMASK));    sccsoftCAR |= (1<<(unit&LINEMASK)) & sccdefaultCAR;    sccmodem[unit] = 0;    /* ttyclose() must be called before clear up termio flags */    ttyclose(tp);    tty_def_close(tp);}sccread(dev, uio)     dev_t dev;     struct uio *uio;{    register struct tty *tp;    register int unit;        unit = minor(dev);    if((consDev != GRAPHIC_DEV) && (major(dev) == CONSOLEMAJOR) && ((unit&LINEMASK) == 0))	unit |= 3;	/* diag console on SLU line 3 */    tp = &scc_tty[unit];    return ((*linesw[tp->t_line].l_read)(tp, uio));}sccwrite(dev, uio)     dev_t dev;     struct uio *uio;{    register struct tty *tp;    register int unit;        unit = minor(dev);    if((consDev != GRAPHIC_DEV) && (major(dev) == CONSOLEMAJOR) && ((unit&LINEMASK) == 0))	unit |= 3;	/* diag console on SLU line 3 */    /*     * Don't allow writes to the mouse,     * just fake the I/O and return.     */    if (vs_gdopen && (unit == 1)) {	uio->uio_offset = uio->uio_resid;	uio->uio_resid = 0;	return(0);    }        tp = &scc_tty[unit];    return ((*linesw[tp->t_line].l_write)(tp, uio));}sccselect(dev, rw)     dev_t dev;{    register int unit = minor(dev);        if((consDev != GRAPHIC_DEV) && (major(dev) == CONSOLEMAJOR) && (unit == 0))	dev |= 3;    if ((unit == 1) && vs_gdselect) {	return((*vs_gdselect)(dev, rw));    }    return(ttselect(dev, rw));}sccintr(){    register struct scc_reg *rsp;    register char ip;       register struct scc_softc *sc = sccsc;    register int sir;           IOC_RD(IOC_SIR, sir);                  /* read sir */    while (sir & SCC_INTR) { 	/* error routines must appear before the regular routines */	if (sir & SIR_COMM1_RERROR)            /* comm. port1 receive DMA error */	    scc_dma_rerror(SCC_COMM1);	if (sir & SIR_COMM1_RINT)              /* comm. port1 receive interrupt */	    scc_dma_rint(SCC_COMM1);	if (sir & SIR_COMM2_RERROR)            /* comm. port2 receive DMA error */	    scc_dma_rerror(SCC_COMM2);	if (sir & SIR_COMM2_RINT)              /* comm. port2 receive interrupt */	    scc_dma_rint(SCC_COMM2);	if (sir & SIR_COMM1_XERROR)            /* comm. port1 transmit DMA error */	    scc_dma_xerror(SCC_COMM1);	if (sir & SIR_COMM1_XINT)              /* comm. port1 transmit interrupt */	    scc_dma_xint(SCC_COMM1);         	if (sir & SIR_COMM2_XERROR)            /* comm. port2 transmit DMA error */	    scc_dma_xerror(SCC_COMM2);	if (sir & SIR_COMM2_XINT)              /* comm. port2 transmit interrupt */	    scc_dma_xint(SCC_COMM2);	if (sir & SIR_SCC1) {                  /* SCC(1) serial interrupt */	    rsp = sc->sc_regs[SCC1_A];         /* channel A of SCC(1) */	    SCC_READ(rsp, SCC_RR3, ip);        /* read RR3A for interrupts pending */	    while (ip) {		if (ip & SCC_RR3_B_EXT_IP) {   /* channel B external/status IP */		    scc_ext_rint(SCC_COMM2);		    sc->sc_regs[SCC1_B]->SCC_CMD = SCC_WR0_RESET_EXT_INT<<8;		}		if (ip & SCC_RR3_A_EXT_IP) {   /* channel A external/status IP */		    scc_ext_rint(SCC_COMM2);		    sc->sc_regs[SCC1_A]->SCC_CMD = SCC_WR0_RESET_EXT_INT<<8;		}		if (ip & SCC_RR3_B_RIP)        /* channel B receive IP */		    scc_spec_rint(SCC_COMM2);    		if (ip & SCC_RR3_A_RIP)        /* channel A receive IP */		    scc_mkbd_rint(SCC_KYBD);		SCC_READ(rsp, SCC_RR3, ip);    /* read RR3A */	    }	}	if (sir & SIR_SCC0) {                  /* SCC(0) serial interrupt */	    rsp = sc->sc_regs[SCC0_A];	    SCC_READ(rsp, SCC_RR3, ip);        /* read RR3A */	    while (ip) {		IOC_RD(IOC_SIR, sir);		if (ip & SCC_RR3_B_EXT_IP) {		    scc_ext_rint(SCC_COMM1);		    sc->sc_regs[SCC0_B]->SCC_CMD = SCC_WR0_RESET_EXT_INT<<8;		    SCC_READ(rsp, SCC_RR3, ip);  		}		if (ip & SCC_RR3_A_EXT_IP) {		    scc_ext_rint(SCC_COMM1);		    sc->sc_regs[SCC0_A]->SCC_CMD = SCC_WR0_RESET_EXT_INT<<8;		}		if (ip & SCC_RR3_B_RIP)		    scc_spec_rint(SCC_COMM1);		if (ip & SCC_RR3_A_RIP)		    scc_mkbd_rint(SCC_MOUSE);		SCC_READ(rsp, SCC_RR3, ip);    /* read RR3A */	    }	}	IOC_RD(IOC_SIR, sir);                  /* read sir */    } /* while */}/* should never happen */scc_dma_rerror(line)     register int line;{    register struct scc_softc *sc = sccsc;    printf("Com. Port. Receive DMA Overrun, line = %d\n", line);    sc->ioc_regs[line]->RDMA_REG = (u_long)   /* reset DMA pointer */	(svtophy(sc->rbuf[line][sc->rflag[line]] 	+ SCC_HALF_PAGE - SCC_WORD) << 3);    IOC_WR(IOC_SIR, ~scc_rerror[line]);	      /* clear error bit to restart */}scc_dma_xerror(line)     register int line;{    register struct scc_softc *sc = sccsc;    caddr_t pa;    struct tc_memerr_status status;    pa = (caddr_t)((sc->ioc_regs[line]->XDMA_REG) >> 3);    printf("Com. Port. Transmit DMA Read Error, line = %d\n", line);    status.pa = pa;    status.va = 0;    status.log = TC_LOG_MEMERR;    status.blocksize = 1;    tc_isolate_memerr(&status);    IOC_SET(IOC_SSR, scc_xdma_en[line]);     /* enable transmit DMA */

⌨️ 快捷键说明

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