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

📄 mdc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifndef lintstatic char *sccsid = "@(#)mdc.c	4.3      (ULTRIX)        9/10/90";#endif	lint/************************************************************************ *									* *			Copyright (c) 1990 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any	other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or	reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************ * * mdc.c * * Mipsmate DC7085 SLU console driver -the real thing!!!!! * * Modification history * * *  August 22, 1990     Paul Grist *      Changed initilazation of console baud rate to use "baud0", it *      was left "baud1" from some early prom debug, hence was broke. * *  July 14, 1990	Kuo-Hsiung Hsieh *	Asserted Speed Select (SS) modem control signal in open routine. *	Deasserted SS when process exits.  As requested by PTT test. * *  July 5, 1990	Kuo-Hsiung Hsieh *      Fixed data corrupted problem due to setting break condition *      on a transmission line.  On DC type of chip, a specific delay *      period has to be imposed on the transmission line if the next *      thing to transmit is a break condition.  Data could be corrupted *      even though TRDY bit may say it is ready to send the next * 	character. * *  June 4, 1990	Kuo-Hsiung Hsieh *	Fixed duplicated assertion of break.  It is caused by reading *	the transmit data register which is the modem status register. * *  May 10, 1990	Kuo-Hsiung Hsieh *	Fixed linenum typo which caused system hung and added modem stuff. * *  March 23, 1990	Tim Burke * *	Created file. Contents based on dc7085.c file.  Due to time constraints *	a separate copy of this driver is being developed instead of modifying *	the original source to accomodate all three device types.  The main *	changes from the dc7085 sources is to remove all references to graphic *	capabilities.  This driver can accomodate up to 3 DC7085 chips while *	the original driver could only have 1 such chip.   * *	Extensive cleanups of the original dc7085.c driver were also done. *	These cleanups include using #define constants, overhaul of the buad *	rate representation scheme.  Use consistent variable terminology, *	specifically unit means dc number, linenum is the particular line of *	a dc and minor_num is the device minor number. */#include "../machine/pte.h"#include "../h/param.h"#include "../h/systm.h"#include "../h/ioctl.h"#include "../h/tty.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/proc.h"#include "../h/map.h"#include "../h/buf.h"#include "../h/vm.h"#include "../h/conf.h"#include "../h/file.h"#include "../h/uio.h"#include "../h/kernel.h"#include "../h/devio.h"#include "../../machine/common/cpuconf.h"#include "../h/exec.h"#include "../h/kmalloc.h"#include "../h/sys_tpath.h"#include "../io/uba/ubavar.h"	/* auto-config headers */#include "../machine/cpu.h"#include "../machine/mips/mdcreg.h"/* * Declare the data structures used to represent the terminal attributes. */struct	tty mdc_tty[NDC * NDCLINE]; /* Allocate 1 tty structure per line*/u_char	mdcmodem[NDC];	   	   /* keeps track of modem state 	*/u_short mdcscan_previous[NDC];	   /* Used to detect modem transitions  */int 	mdcmodem_active;	   /* Determines scan rate		*/int 	console_baud;		   /* Specifies console baud rate	*/int	mdcdefaultCAR[NDC];	   /* Default status of modem/nomodem   */int	mdcsoftCAR[NDC];	   /* Present status of modem/nomodem   */int	mdc_cnt;	   	   /* The number of configured lines	*/u_char  mdc_brk[NDC];extern  int nMDC;                  /* Configuration - # of DC chips     */struct	timeval mdctimestamp[NDC]; /* Timer for modem control		*/int	mdc_attach_called = 0;	   /* Attach routine has been called    */int	mdcprobe(), mdcattach(), mdcrint(), mdc_unit_init();int	mdc_dsr_check(), mdc_tty_drop(), mdc_cd_drop(); int	mdcputc(), mdcgetc();void	mdcsetbreak();u_short mdcstd[] = { 0 };struct uba_device *mdcinfo[1];/* * Unibus device driver definition.  These routines are used at boot time by * the configuration program. */struct	uba_driver mdcdriver = { 	mdcprobe, 			/* probe routine		   */	0, 				/* slave routine		   */	mdcattach, 			/* attach routine		   */	0, 				/* ud_dgo routine		   */	mdcstd, 			/* device csr address		   */	"mdc", 				/* device name			   */	mdcinfo 			/* backpointers to ubdinit structs */					/* I guess the rest are just 0's   */					/* name of a controller		   */					/* backpointers to ubminit structs */					/* want exclusive use of bdp's	   */    };int	mdcstart(), mdcxint(), mdcbaudrate();int	ttrstrt();#define MODEM_LINE	2		/* Modem control only on line 2     */#define NOMODEM_UNIT	2		/* DC #2 does not have full modem   */#define LINEMASK	0x03		/* line unit mask, each DC has 4 lines*/#define LINEBITS	2		/* The linemask occupies 2 bits     *//* * Baud Rate Support * * When the baud rate on the right is specified, the line parameter register * is setup with the appropriate bits as specified in the left column. */#define BAUD_UNSUPPORTED 0	/* Device does not provide this baud rate */#define BAUD_SUPPORTED   1	/* Device does provide this baud rate     *//* * If the BAUD38 bit of the System Control and Status Register is set the * chip can do 38400 baud in which case EXTB would be supported.  This bit * applies to all 4 lines such that it is not possible to simultaneously do * 19200 and 38400.  To keep things simple, only provide support for 19.2. * The third column is the minimum delay value for setting a break * condition.  If we set a break condition without delaying this minimum * interval, we might corrupt character which is still in the shift * register.  The delay values are calculated based on the equation: * 12 (bits/char) * 256 (hz) / baudrate + 2 (safety factor). */struct baud_support mdc_speeds[] = {     	{0,			BAUD_UNSUPPORTED,	0},	/* B0    */	{DC_B50,		BAUD_SUPPORTED,		78},	/* B50   */	{DC_B75,		BAUD_SUPPORTED,		42},	/* B75   */	{DC_B110,		BAUD_SUPPORTED,		30},	/* B110  */	{DC_B134_5,		BAUD_SUPPORTED,		25},	/* B134  */	{DC_B150,		BAUD_SUPPORTED,		22},	/* B150  */	{0,			BAUD_UNSUPPORTED,	0},	/* B200  */	{DC_B300,		BAUD_SUPPORTED,		12},	/* B300  */	{DC_B600,		BAUD_SUPPORTED,		7},	/* B600  */	{DC_B1200,		BAUD_SUPPORTED,		5},	/* B1200 */	{DC_B1800,		BAUD_SUPPORTED,		4},	/* B1800 */	{DC_B2400,		BAUD_SUPPORTED,		3},	/* B2400 */	{DC_B4800,		BAUD_SUPPORTED,		2},	/* B4800 */	{DC_B9600,		BAUD_SUPPORTED,		2},	/* B9600 */	{DC_B19200,		BAUD_SUPPORTED,		2},	/* EXTA  */	{0,			BAUD_UNSUPPORTED,	0}, 	/* EXTB  */   };extern int pmcons_init();extern int prom_getenv();extern int cpu;#ifdef DEBUGint mdcdebug = 0;/* * Print out the modem leads for this DC unit. */#define PRINT_SIGNALS(dcaddr) { cprintf("Modem signals: "); \	if (dcaddr->dcmsr & DC_DSR) cprintf(" DSR "); \	if (dcaddr->dcmsr & DC_CTS) cprintf(" CTS "); \	if (dcaddr->dcmsr & DC_CD) cprintf(" CD "); \	cprintf("\n"); } #endif DEBUG/* * Probe to see if the device is alive.  Since this is a bounded configuration * there must be a DC chip present for the console.  The intialization is done * through dc_cons_init out of startup(). */mdcprobe(reg)int reg;{	return(1);}/* * Initialize the device and setup initial values of relevant variables. */mdcattach(){    register int unit;    extern mdcscan();    /*     * If the option card is in place this routine may end up being called     * more than once.  Use mdc_attach_called to insure that the body of this     * routine is only executed once.     */    if (mdc_attach_called == 0) {	mdc_attach_called = 1;	/*	 * Setup per-DC registers and software status.	 */	mdc_cnt = 0;	if (nMDC <= 0) {		panic("mdcattach: no units configured.\n");	}	if (nMDC > MAX_NDC) {		nMDC = MAX_NDC;		cprintf("Too many DC chips configured: nMDC = %d\n",nMDC);	}	for (unit = 0; unit < nMDC; unit++) {		mdc_brk[unit] = 0;		mdc_unit_init(unit);		mdc_cnt += NDCLINE;	}	/* 	 * Initialize the scanner process.  Since the chip does not 	 * interrupt on modem transitions it is necessary to have a scanner	 * thread that occasionally checks the modem leads and looks for	 * changes.  Start up this to examine the modem leads once per second.	 */ 	mdcmodem_active = 0;	timeout(mdcscan, (caddr_t)0, hz);    }}/* * Initalizes the DC registers and associated software attributes. * Called on a per unit basis from attach(). */mdc_unit_init(unit)	register int unit;{	register volatile struct mdz_reg *dcaddr;#	ifdef DEBUG	if (mdcdebug)		cprintf("mdc_unit_init: unit = %d.\n",unit);#	endif DEBUG	if (unit > MAX_NDC) {		/* paranoia */		return;	}	dcaddr = mdz_regs[unit];	/*	 * Note that the dcsoftCAR and dcdefaultCAR do not look at the flags	 * field of the config file.  This may need to be fixed up.	 */	mdcsoftCAR[unit] = 0xf;		/* Set lines to direct connect     */	mdcdefaultCAR[unit] = 0xf;	/* Default lines to direct connect */	mdcscan_previous[unit] = 0;	/* Initial modem status		   */	/*	 * DC0 and DC1 allow modem control on line 2.  Initialize these leads	 * to clear the modem control signals.	 */	if (unit != NOMODEM_UNIT) {		dcaddr->dctcr &= ~(DC_RDTR | DC_RRTS | DC_RSS);	}}/* * Called early from startup.  The purpose of this routine is to setup the * console line to enable output so the startup messages can be displayed. */mdc_cons_init(){	register int linenum = CONSOLE_LINE;	register volatile struct mdz_reg *dcaddr = mdz_regs[CONSOLE_UNIT];	register int prom_baud;	/*	 * The console will default to 9600 baud.  This can be changed via	 * the baud environment variable.  Read in the console baud rate	 * for later use.  This presently only supports a selected number of	 * baud rates.	 */	prom_baud = atoi(prom_getenv("baud0"));	switch (prom_baud) {		case 75:	console_baud = B75; 	break;		case 110:	console_baud = B110; 	break;		case 150:	console_baud = B150; 	break;		case 300:	console_baud = B300; 	break;		case 600:	console_baud = B600; 	break;		case 1200:	console_baud = B1200; 	break;		case 2400:	console_baud = B2400; 	break;		case 4800:	console_baud = B4800; 	break;		case 9600:	console_baud = B9600; 	break;		default:	console_baud = B9600;	}	dcaddr->dclpr = linenum | mdc_speeds[console_baud].baud_param 			| BITS8 | DC_RE;}/* * Open line and set default parameters.  If this is a modem line wait for * the appropriate leads to be asserted. */mdcopen(dev, flag)	dev_t dev;{	register volatile struct mdz_reg *dcaddr;	register struct tty *tp;	register int unit;	register int linenum;	register int minor_num;	int inuse;  /*hold state of inuse bit while blocked waiting for carr*/	minor_num = minor(dev);	unit = minor_num >> LINEBITS;	dcaddr = mdz_regs[unit];	linenum = minor_num & LINEMASK;	if (minor_num >= mdc_cnt) {		return (ENXIO);	}	tp = &mdc_tty[minor_num];	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 = mdcstart;	tp->t_baudrate = mdcbaudrate;	tty_def_open(tp, dev, flag, (mdcsoftCAR[unit]&(1<<(linenum))));	/*	 * If the line is not presently open setup the default terminal	 * attributes.	 */	if ((tp->t_state & TS_ISOPEN) == 0) {	    /*	     * Prevent spurious startups by making the 500ms timer	     * initially high.	     */	    /* Tim  - Should this only be set if opening modem line? */	    mdcmodem[unit] = MODEM_DSR_START;	    /*	     * Specify console terminal attributes.  Do not allow modem control 	     * on the console.  Setup <NL> to <CR> <LF> mapping.	     */	    if ((unit == CONSOLE_UNIT) && (linenum == CONSOLE_LINE)) {		tp->t_cflag |= CLOCAL;		tp->t_flags = ANYP|ECHO|CRMOD;		tp->t_iflag |= ICRNL;		tp->t_oflag |= ONLCR;	    }	}	mdcparam(minor_num);		/* enables interrupts */	(void) spltty();	/*	 * No modem control provided for lines with softCAR set.	 * Modem control provided only for line 2.	 */#	ifdef DEBUG	if (mdcdebug)		cprintf("mdcopen: unit = %d, linenum = %d\n",unit, linenum);#	endif DEBUG	/*	 * Modem control is only provided on line 2 of DC0 and DC1.  All other	 * lines are restricted to be direct connect.  For this reason set	 * CLOCAL as a sanity check.	 */	if ((unit == NOMODEM_UNIT) || (linenum != MODEM_LINE)) {		tp->t_cflag |= CLOCAL;	}	if (tp->t_cflag & CLOCAL) {		/*		 * This is a local connection - ignore carrier		 * receive enable interrupts enabled above via dcparam()		 */		tp->t_state |= TS_CARR_ON;		/* dcscan sets */		if (linenum == MODEM_LINE) {			dcaddr->dctcr |= (DC_RDTR | DC_RRTS | DC_RSS);		}		/*		 * 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	 */	/* receive enable interrupts enabled above via dcparam() */	if (linenum == MODEM_LINE) {		dcaddr->dctcr |= (DC_RDTR | DC_RRTS | DC_RSS);	}	/*	 * After DSR first comes up we must wait for the other signals	 * before commencing transmission.         */#ifdef DEBUG	if (mdcdebug) {		cprintf("open flag : %x\n", flag);		if (flag & (O_NDELAY|O_NONBLOCK)) 			cprintf("flag & (O_NDELAY|O_NONBLOCK)\n");	}#endif DEBUG	if ((flag & (O_NDELAY|O_NONBLOCK)) == 0) {		/*		 * Delay before examining other signals if DSR is being followed		 * otherwise proceed directly to dc_dsr_check to look for		 * carrier detect and clear to send.		 */#ifdef DEBUG		if (mdcdebug) {			cprintf("mdcopen: ");			PRINT_SIGNALS(dcaddr);		}#endif DEBUG		if (dcaddr->dcmsr & DC_DSR) {			mdcmodem[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(mdc_dsr_check, tp, hz*30);			    mdc_dsr_check(tp);		}	}#	ifdef DEBUG	if (mdcdebug)		cprintf("mdcopen:  linenum=%d, state=0x%x, tp=0x%x\n", linenum,			tp->t_state, tp);#	endif DEBUG	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;#ifdef DEBUG			if (mdcdebug) {				cprintf("mdc_open: going to sleep\n");			}#endif DEBUG			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 (mdcmodem[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();

⌨️ 快捷键说明

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