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

📄 dc.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 1992, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Ralph Campbell and Rick Macklem. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)dc.c	8.2 (Berkeley) 11/30/93 *//* * devDC7085.c -- * *     	This file contains machine-dependent routines that handle the *	output queue for the serial lines. * *	Copyright (C) 1989 Digital Equipment Corporation. *	Permission to use, copy, modify, and distribute this software and *	its documentation for any purpose and without fee is hereby granted, *	provided that the above copyright notice appears in all copies. *	Digital Equipment Corporation makes no representations about the *	suitability of this software for any purpose.  It is provided "as is" *	without express or implied warranty. * * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devDC7085.c, *	v 1.4 89/08/29 11:55:30 nelson Exp $ SPRITE (DECWRL)"; */#include <dc.h>#if NDC > 0/* * DC7085 (DZ-11 look alike) Driver */#include <sys/param.h>#include <sys/systm.h>#include <sys/ioctl.h>#include <sys/tty.h>#include <sys/proc.h>#include <sys/map.h>#include <sys/buf.h>#include <sys/conf.h>#include <sys/file.h>#include <sys/uio.h>#include <sys/kernel.h>#include <sys/syslog.h>#include <machine/dc7085cons.h>#include <machine/pmioctl.h>#include <pmax/pmax/pmaxtype.h>#include <pmax/pmax/cons.h>#include <pmax/dev/device.h>#include <pmax/dev/pdma.h>#include <pmax/dev/fbreg.h>extern int pmax_boardtype;extern struct consdev cn_tab;/* * Driver information for auto-configuration stuff. */int	dcprobe();void	dcintr();struct	driver dcdriver = {	"dc", dcprobe, 0, 0, dcintr,};#define	NDCLINE 	(NDC*4)void dcstart	__P((struct tty *));void dcxint	__P((struct tty *));void dcPutc	__P((dev_t, int));void dcscan	__P((void *));extern void ttrstrt __P((void *));int dcGetc	__P((dev_t));int dcparam	__P((struct tty *, struct termios *));struct	tty dc_tty[NDCLINE];int	dc_cnt = NDCLINE;void	(*dcDivertXInput)();	/* X windows keyboard input routine */void	(*dcMouseEvent)();	/* X windows mouse motion event routine */void	(*dcMouseButtons)();	/* X windows mouse buttons event routine */#ifdef DEBUGint	debugChar;#endif/* * Software copy of brk register since it isn't readable */int	dc_brk[NDC];char	dcsoftCAR[NDC];		/* mask of dc's with carrier on (DSR) *//* * The DC7085 doesn't interrupt on carrier transitions, so * we have to use a timer to watch it. */int	dc_timer;		/* true if timer started *//* * Pdma structures for fast output code */struct	pdma dcpdma[NDCLINE];struct speedtab dcspeedtab[] = {	0,	0,	50,	LPR_B50,	75,	LPR_B75,	110,	LPR_B110,	134,	LPR_B134,	150,	LPR_B150,	300,	LPR_B300,	600,	LPR_B600,	1200,	LPR_B1200,	1800,	LPR_B1800,	2400,	LPR_B2400,	4800,	LPR_B4800,	9600,	LPR_B9600,	19200,	LPR_B19200,	-1,	-1};#ifndef	PORTSELECTOR#define	ISPEED	TTYDEF_SPEED#define	LFLAG	TTYDEF_LFLAG#else#define	ISPEED	B4800#define	LFLAG	(TTYDEF_LFLAG & ~ECHO)#endif/* * Test to see if device is present. * Return true if found and initialized ok. */dcprobe(cp)	register struct pmax_ctlr *cp;{	register dcregs *dcaddr;	register struct pdma *pdp;	register struct tty *tp;	register int cntr;	int s;	if (cp->pmax_unit >= NDC)		return (0);	if (badaddr(cp->pmax_addr, 2))		return (0);	/*	 * For a remote console, wait a while for previous output to	 * complete.	 */	if (major(cn_tab.cn_dev) == DCDEV && cp->pmax_unit == 0 &&		cn_tab.cn_screen == 0)		DELAY(10000);	/* reset chip */	dcaddr = (dcregs *)cp->pmax_addr;	dcaddr->dc_csr = CSR_CLR;	MachEmptyWriteBuffer();	while (dcaddr->dc_csr & CSR_CLR)		;	dcaddr->dc_csr = CSR_MSE | CSR_TIE | CSR_RIE;	/* init pseudo DMA structures */	pdp = &dcpdma[cp->pmax_unit * 4];	tp = &dc_tty[cp->pmax_unit * 4];	for (cntr = 0; cntr < 4; cntr++) {		pdp->p_addr = (void *)dcaddr;		pdp->p_arg = (int)tp;		pdp->p_fcn = dcxint;		pdp++, tp++;	}	dcsoftCAR[cp->pmax_unit] = cp->pmax_flags | 0xB;	if (dc_timer == 0) {		dc_timer = 1;		timeout(dcscan, (void *)0, hz);	}	/*	 * Special handling for consoles.	 */	if (cp->pmax_unit == 0) {		if (cn_tab.cn_screen) {			s = spltty();			dcaddr->dc_lpr = LPR_RXENAB | LPR_8_BIT_CHAR |				LPR_B4800 | DCKBD_PORT;			MachEmptyWriteBuffer();			dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR |				LPR_PARENB | LPR_8_BIT_CHAR | DCMOUSE_PORT;			MachEmptyWriteBuffer();			DELAY(1000);			KBDReset(makedev(DCDEV, DCKBD_PORT), dcPutc);			MouseInit(makedev(DCDEV, DCMOUSE_PORT), dcPutc, dcGetc);			splx(s);		} else if (major(cn_tab.cn_dev) == DCDEV) {			s = spltty();			dcaddr->dc_lpr = LPR_RXENAB | LPR_8_BIT_CHAR |				LPR_B9600 | minor(cn_tab.cn_dev);			MachEmptyWriteBuffer();			DELAY(1000);			cn_tab.cn_disabled = 0;			splx(s);		}	}	printf("dc%d at nexus0 csr 0x%x priority %d\n",		cp->pmax_unit, cp->pmax_addr, cp->pmax_pri);	return (1);}dcopen(dev, flag, mode, p)	dev_t dev;	int flag, mode;	struct proc *p;{	register struct tty *tp;	register int unit;	int s, error = 0;	unit = minor(dev);	if (unit >= dc_cnt || dcpdma[unit].p_addr == (void *)0)		return (ENXIO);	tp = &dc_tty[unit];	tp->t_oproc = dcstart;	tp->t_param = dcparam;	tp->t_dev = dev;	if ((tp->t_state & TS_ISOPEN) == 0) {		tp->t_state |= TS_WOPEN;		ttychars(tp);#ifndef PORTSELECTOR		if (tp->t_ispeed == 0) {#endif			tp->t_iflag = TTYDEF_IFLAG;			tp->t_oflag = TTYDEF_OFLAG;			tp->t_cflag = TTYDEF_CFLAG;			tp->t_lflag = LFLAG;			tp->t_ispeed = tp->t_ospeed = ISPEED;#ifdef PORTSELECTOR			tp->t_cflag |= HUPCL;#else		}#endif		(void) dcparam(tp, &tp->t_termios);		ttsetwater(tp);	} else if ((tp->t_state & TS_XCLUDE) && curproc->p_ucred->cr_uid != 0)		return (EBUSY);	(void) dcmctl(dev, DML_DTR, DMSET);	s = spltty();	while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) &&	       !(tp->t_state & TS_CARR_ON)) {		tp->t_state |= TS_WOPEN;		if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,		    ttopen, 0))			break;	}	splx(s);	if (error)		return (error);	return ((*linesw[tp->t_line].l_open)(dev, tp));}/*ARGSUSED*/dcclose(dev, flag, mode, p)	dev_t dev;	int flag, mode;	struct proc *p;{	register struct tty *tp;	register int unit, bit;	unit = minor(dev);	tp = &dc_tty[unit];	bit = 1 << ((unit & 03) + 8);	if (dc_brk[unit >> 2] & bit) {		dc_brk[unit >> 2] &= ~bit;		ttyoutput(0, tp);	}	(*linesw[tp->t_line].l_close)(tp, flag);	if ((tp->t_cflag & HUPCL) || (tp->t_state & TS_WOPEN) ||	    !(tp->t_state & TS_ISOPEN))		(void) dcmctl(dev, 0, DMSET);	return (ttyclose(tp));}dcread(dev, uio, flag)	dev_t dev;	struct uio *uio;{	register struct tty *tp;	tp = &dc_tty[minor(dev)];	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));}dcwrite(dev, uio, flag)	dev_t dev;	struct uio *uio;{	register struct tty *tp;	tp = &dc_tty[minor(dev)];	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));}/*ARGSUSED*/dcioctl(dev, cmd, data, flag, p)	dev_t dev;	int cmd;	caddr_t data;	int flag;	struct proc *p;{	register struct tty *tp;	register int unit = minor(dev);	register int dc = unit >> 2;	int error;	tp = &dc_tty[unit];	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);	if (error >= 0)		return (error);	error = ttioctl(tp, cmd, data, flag);	if (error >= 0)		return (error);	switch (cmd) {	case TIOCSBRK:		dc_brk[dc] |= 1 << ((unit & 03) + 8);		ttyoutput(0, tp);		break;	case TIOCCBRK:		dc_brk[dc] &= ~(1 << ((unit & 03) + 8));		ttyoutput(0, tp);		break;	case TIOCSDTR:		(void) dcmctl(dev, DML_DTR|DML_RTS, DMBIS);		break;	case TIOCCDTR:		(void) dcmctl(dev, DML_DTR|DML_RTS, DMBIC);		break;	case TIOCMSET:		(void) dcmctl(dev, *(int *)data, DMSET);		break;	case TIOCMBIS:		(void) dcmctl(dev, *(int *)data, DMBIS);		break;	case TIOCMBIC:		(void) dcmctl(dev, *(int *)data, DMBIC);		break;	case TIOCMGET:		*(int *)data = dcmctl(dev, 0, DMGET);		break;	default:		return (ENOTTY);	}	return (0);}dcparam(tp, t)	register struct tty *tp;	register struct termios *t;{	register dcregs *dcaddr;	register int lpr;	register int cflag = t->c_cflag;	int unit = minor(tp->t_dev);	int ospeed = ttspeedtab(t->c_ospeed, dcspeedtab);	/* check requested parameters */        if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed) ||            (cflag & CSIZE) == CS5 || (cflag & CSIZE) == CS6 ||	    (pmax_boardtype == DS_PMAX && t->c_ospeed == 19200))                return (EINVAL);        /* and copy to tty */        tp->t_ispeed = t->c_ispeed;        tp->t_ospeed = t->c_ospeed;        tp->t_cflag = cflag;	dcaddr = (dcregs *)dcpdma[unit].p_addr;	/*	 * Handle console cases specially.	 */	if (cn_tab.cn_screen) {		if (unit == DCKBD_PORT) {			dcaddr->dc_lpr = LPR_RXENAB | LPR_8_BIT_CHAR |				LPR_B4800 | DCKBD_PORT;			MachEmptyWriteBuffer();			return (0);		} else if (unit == DCMOUSE_PORT) {			dcaddr->dc_lpr = LPR_RXENAB | LPR_B4800 | LPR_OPAR |				LPR_PARENB | LPR_8_BIT_CHAR | DCMOUSE_PORT;			MachEmptyWriteBuffer();			return (0);		}	} else if (tp->t_dev == cn_tab.cn_dev) {		dcaddr->dc_lpr = LPR_RXENAB | LPR_8_BIT_CHAR |			LPR_B9600 | unit;		MachEmptyWriteBuffer();		return (0);	}	if (ospeed == 0) {		(void) dcmctl(unit, 0, DMSET);	/* hang up line */		return (0);	}	lpr = LPR_RXENAB | ospeed | (unit & 03);	if ((cflag & CSIZE) == CS7)		lpr |= LPR_7_BIT_CHAR;	else		lpr |= LPR_8_BIT_CHAR;	if (cflag & PARENB)		lpr |= LPR_PARENB;	if (cflag & PARODD)		lpr |= LPR_OPAR;	if (cflag & CSTOPB)		lpr |= LPR_2_STOP;	dcaddr->dc_lpr = lpr;	MachEmptyWriteBuffer();	DELAY(10);	return (0);}/* * Check for interrupts from all devices. */

⌨️ 快捷键说明

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