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

📄 fas.c

📁 一个通讯程序源码
💻 C
📖 第 1 页 / 共 5 页
字号:
			{				port_stat [unit] = '?';				continue;	/* a hardware error */			}			/* test the chip thoroughly */			if ((port_stat [unit] = (fas_test_device (fip) + '0'))				!= '0')			{				continue;	/* a hardware error */			}			fip->lcr = 0;			fas_outb (fip, LINE_CTL_PORT, fip->lcr);			fip->mcr = fas_mcb [unit] | fip->modem.m.di;			fas_outb (fip, MDM_CTL_PORT, fip->mcr);			port_stat [unit] = '*';			/* let's see if it's an NS16550A */			fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_INIT_CMD);			if (!(~fas_inb (fip, INT_ID_PORT) & II_NS_FIFO_ENABLED))			{				fip->device_flags.s |= DF_DEVICE_IS_NS16550A;				fip->xmit_fifo_size = OUTPUT_NS_FIFO_SIZE;				port_stat [unit] = 'F';				fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);			}			else			{				fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);				/* or is it an i82510 ? */				fas_outb (fip, I_BANK_PORT, I_BANK_2);				if (!(~fas_inb (fip, I_BANK_PORT) & I_BANK_2))				{					fip->device_flags.s |= DF_DEVICE_IS_I82510;					fip->xmit_fifo_size = OUTPUT_I_FIFO_SIZE;					port_stat [unit] = 'f';					fas_outb (fip, I_BANK_PORT, I_BANK_1);					fas_outb (fip, I_TCM_PORT, I_FIFO_CLR_XMIT);					fas_outb (fip, I_RCM_PORT, I_FIFO_CLR_RECV);				}				fas_outb (fip, I_BANK_PORT, I_BANK_0);			}			/* disable FIFOs if requested in space.c */			if ((fas_port [unit] & NO_FIFO) && (fip->device_flags.i						& (DF_DEVICE_IS_NS16550A							| DF_DEVICE_IS_I82510)))			{				fip->device_flags.s &= ~(DF_DEVICE_IS_NS16550A							| DF_DEVICE_IS_I82510);				fip->xmit_fifo_size = 1;				port_stat [unit] = '+';			}			/* clear potential interrupts */			(void) fas_inb (fip, MDM_STATUS_PORT);			(void) fas_inb (fip, RCV_DATA_PORT);			(void) fas_inb (fip, RCV_DATA_PORT);			(void) fas_inb (fip, LINE_STATUS_PORT);			(void) fas_inb (fip, INT_ID_PORT);			if (port = fas_int_ack_port [fip->vec])				(void) outb (port, fas_int_ack [fip->vec]);			/* show that it is present and configured */			fip->device_flags.s |= DF_DEVICE_CONFIGURED;		}	}#if defined (NEED_PUT_GETCHAR)	fip = &fas_info [0];	fip->mcr &= ~fip->modem.m.di;	fip->mcr |= INITIAL_MDM_CONTROL;	fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);	fip->lcr = INITIAL_LINE_CONTROL;	fas_outb (fip, LINE_CTL_PORT, fip->lcr | LC_ENABLE_DIVISOR);	fas_outb (fip, DIVISOR_LSB_PORT, INITIAL_BAUD_RATE);	fas_outb (fip, DIVISOR_MSB_PORT, (INITIAL_BAUD_RATE) >> 8);	fas_outb (fip, LINE_CTL_PORT, fip->lcr);#endif#if defined (SCO) || defined (XENIX)	for (unit = 0; unit < fas_physical_units; unit++)		(void) printcfg ("fas", (uint) ((ushort) (fas_port [unit])), 7,					fas_vec [unit], -1,#if defined (FASI)					"unit=%d type=%c FAS/i 2.08.01",#else					"unit=%d type=%c release=2.08.0",#endif /* FASI */					unit, port_stat [unit]);#else	port_stat [unit] = '\0';	(void) printf ("\nFAS 2.08.0 async driver: Unit 0-%d init state is [%s]\n\n",			unit - 1,			port_stat);#endif	return (0);}/* Open a tty line. This function is called for every open, as opposed   to the fasclose function which is called only with the last close.*/intfasopen (dev, flag)int	dev;int	flag;{	register struct fas_info	*fip;	register struct tty		*ttyp;	register uint	open_mode;	uint	physical_unit;	int	old_level;	physical_unit = GET_UNIT (dev);	/* check for valid port number */	if (physical_unit >= fas_physical_units)	{		u.u_error = ENXIO;		return (-1);	}	fip = fas_info_ptr [physical_unit];	/* was the port present at init time ? */	if (!(fip->device_flags.i & DF_DEVICE_CONFIGURED))	{		u.u_error = ENXIO;		return (-1);	}	open_mode = GET_OPEN_MODE (dev);	old_level = SPLINT ();	get_device_lock (fip, TTIPRI);	/* If this is a getty open, the device is already open for           dialout and the FNDELAY flag is not set, wait until device           is closed.	*/	while ((open_mode & OS_OPEN_FOR_GETTY)			&& (fip->o_state & OS_OPEN_FOR_DIALOUT)			&& !(flag & FNDELAY))	{		release_device_lock (fip);		(void) sleep ((caddr_t) &fip->o_state, TTIPRI);		get_device_lock (fip, TTIPRI);	}		/* If the device is already open and another open uses a different	   open mode or if a getty open waits for carrier and doesn't allow	   parallel dialout opens, return with EBUSY error.	*/	if ((fip->o_state & ((open_mode & OS_OPEN_FOR_GETTY)				? (OS_OPEN_STATES | OS_WAIT_OPEN)				: (OS_OPEN_STATES | OS_NO_DIALOUT)))		&& ((flag & FEXCL)			|| ((open_mode ^ fip->o_state) & (u.u_uid						? OS_TEST_MASK						: OS_SU_TEST_MASK))))	{		u.u_error = EBUSY;		release_device_lock (fip);		(void) splx (old_level);		return (-1);	}	/* disable subsequent opens */	if (flag & FEXCL)		open_mode |= OS_EXCLUSIVE_OPEN_1;	/* set up pointer to tty structure */	ttyp = (open_mode & OS_OPEN_FOR_GETTY)		? fas_tty_ptr [physical_unit + fas_physical_units]		: fas_tty_ptr [physical_unit];	/* things to do on first open only */	if (!(fip->o_state & ((open_mode & OS_OPEN_FOR_GETTY)				? (OS_OPEN_STATES | OS_WAIT_OPEN)				: OS_OPEN_STATES)))	{		/* init data structures */		fip->tty = ttyp;		(void) ttinit (ttyp);		ttyp->t_proc = fas_proc;		fip->po_state = fip->o_state;		fip->o_state = open_mode & ~OS_OPEN_STATES;#if defined (HAVE_VPIX)		/* initialize VP/ix related variables */		fip->v86_proc = (v86_t *) NULL;		fip->v86_intmask = 0;		fip->v86_ss.ss_start = CSTART;		fip->v86_ss.ss_stop = CSTOP;#endif		fas_open_device (fip);		/* open physical device */		fas_param (fip, HARD_INIT);	/* set up port registers */		/* allow pending tty interrupts */		(void) SPLWRK ();		(void) SPLINT ();	}	/* If getty open and the FNDELAY flag is not set,	   block and wait for carrier if device not yet open.	*/	if ((open_mode & OS_OPEN_FOR_GETTY) && !(flag & FNDELAY))	{		/* sleep while open for dialout or no carrier */		while ((fip->o_state & OS_OPEN_FOR_DIALOUT)			|| !(ttyp->t_state & (ISOPEN | CARR_ON)))		{			ttyp->t_state |= WOPEN;			release_device_lock (fip);			(void) sleep ((caddr_t) &ttyp->t_canq, TTIPRI);			get_device_lock (fip, TTIPRI);		}		ttyp->t_state &= ~WOPEN;	}	/* wakeup processes that are still sleeping in getty open */	if (ttyp->t_state & WOPEN)#if defined(FASI)	{#endif		(void) wakeup ((caddr_t) &ttyp->t_canq);#if defined(FASI)		(void) wakeup ((caddr_t) &fip->device_flags.i);	}#endif	/* we need to flush the receiver with the first open */	if (!(fip->o_state & OS_OPEN_STATES))		fas_cmd (fip, ttyp, T_RFLUSH);	(*linesw [ttyp->t_line].l_open) (ttyp);	/* set open type flags */	fip->o_state = open_mode;	release_device_lock (fip);	(void) splx (old_level);	return (0);}/* Close a tty line. This is only called if there is no other   concurrent open left. A blocked getty open is not counted as   a concurrent open because in this state it isn't really open.*/intfasclose (dev)int	dev;{	register struct fas_info	*fip;	register struct tty		*ttyp;	uint	physical_unit;	uint	open_mode;	int	old_level;	void	(*old_sigkill)();	physical_unit = GET_UNIT (dev);	fip = fas_info_ptr [physical_unit];	open_mode = GET_OPEN_MODE (dev);	/* set up pointer to tty structure */	ttyp = (open_mode & OS_OPEN_FOR_GETTY)		? fas_tty_ptr [physical_unit + fas_physical_units]		: fas_tty_ptr [physical_unit];		old_level = SPLINT ();	get_device_lock (fip, TTIPRI);	/* wait for output buffer drain only if device was open */	if (ttyp->t_state & ISOPEN)	{		/* flush the output buffer immediately if the device		   has been shut down because of an error		*/		if (!(fip->device_flags.i & DF_DEVICE_CONFIGURED))		{			(void) ttyflush (ttyp, FWRITE);		}		/* wait for buffer drain and catch interrupts */		while (ttyp->t_outq.c_cc || (ttyp->t_state & (BUSY | TIMEOUT)))		{			old_sigkill = u.u_signal [SIGKILL - 1];			/* allow kill signal if close on exit */			if (old_sigkill == SIG_IGN)				u.u_signal [SIGKILL - 1] = SIG_DFL;			ttyp->t_state |= TTIOW;			if (sleep ((caddr_t) &ttyp->t_oflag, TTOPRI | PCATCH))			{				/* caught signal */				ttyp->t_state &= ~TTIOW;				/* If close on exit, flush output buffer to				   allow completion of the fasclose() function.				   Otherwise, do the normal signal handling.				*/				if (old_sigkill == SIG_IGN)					(void) ttyflush (ttyp, FWRITE);				else				{					release_device_lock (fip);					(void) splx (old_level);					longjmp (u.u_qsav);				}			}			if (old_sigkill == SIG_IGN)				u.u_signal [SIGKILL - 1] = old_sigkill;		}	}	(*linesw [ttyp->t_line].l_close) (ttyp);	/* allow pending tty interrupts */	(void) SPLWRK ();	(void) SPLINT ();	if (open_mode & OS_OPEN_FOR_GETTY)	{		/* not waiting any more */		ttyp->t_state &= ~WOPEN;		if (!(fip->o_state & OS_OPEN_FOR_DIALOUT))		{			fas_close_device (fip);			fip->o_state = OS_DEVICE_CLOSED;		}		else			fip->po_state = OS_DEVICE_CLOSED;	}	else	{		fas_close_device (fip);		fip->o_state = OS_DEVICE_CLOSED;		/* If there is a waiting getty open on		   this port, reopen the physical device.		*/		if (fip->po_state & OS_WAIT_OPEN)		{			/* get the getty version of the			   tty structure			*/			fip->tty = fas_tty_ptr [physical_unit					+ fas_physical_units];			fip->o_state = fip->po_state;			fip->po_state = OS_DEVICE_CLOSED;#if defined (HAVE_VPIX)			/* initialize VP/ix related variables */			fip->v86_proc = (v86_t *) NULL;			fip->v86_intmask = 0;			fip->v86_ss.ss_start = CSTART;			fip->v86_ss.ss_stop = CSTOP;#endif			if (!(fip->device_flags.i & DF_DO_HANGUP))			{				fas_open_device (fip);				/* set up port registers */				fas_param (fip, HARD_INIT);			}		}		(void) wakeup ((caddr_t) &fip->o_state);	}	if (!(fip->device_flags.i & DF_DO_HANGUP))		release_device_lock (fip);#if defined(FASI)	(void)wakeup((caddr_t)&fip->device_flags.i);#endif	(void) splx (old_level);	return (0);}/* read characters from the input buffer */intfasread (dev)int	dev;{	register struct fas_info	*fip;	register struct tty	*ttyp;	int	old_level;	fip = fas_info_ptr [GET_UNIT (dev)];	/* was the port present at init time ? */	if (!(fip->device_flags.i & DF_DEVICE_CONFIGURED))	{		u.u_error = ENXIO;		return (-1);	}	ttyp = fip->tty;	(*linesw [ttyp->t_line].l_read) (ttyp);	old_level = SPLINT ();	/* schedule character transfer to UNIX buffer */	if (fip->recv_ring_cnt#if defined (HAVE_VPIX)		&& (((fip->iflag & DOSMODE)			? MAX_VPIX_FILL - MIN_READ_CHUNK			: MAX_UNIX_FILL - MIN_READ_CHUNK)				>= ttyp->t_rawq.c_cc)#else		&& ((MAX_UNIX_FILL - MIN_READ_CHUNK) >= ttyp->t_rawq.c_cc)#endif		&& !(fip->flow_flags.i & FF_RXFER_STOPPED))	{		event_sched (fip, EF_DO_RXFER);	}#if defined(FASI)	(void)wakeup((caddr_t)&fip->device_flags.i);#endif	(void) splx (old_level);	return (0);}/* write characters to the output buffer */intfaswrite (dev)int	dev;{	register struct fas_info	*fip;	register struct tty	*ttyp;	fip = fas_info_ptr [GET_UNIT (dev)];	/* was the port present at init time ? */	if (!(fip->device_flags.i & DF_DEVICE_CONFIGURED))	{		u.u_error = ENXIO;		return (-1);	}	ttyp = fip->tty;	(*linesw [ttyp->t_line].l_write) (ttyp);	return (0);}/*+-------------------------------------------------------------------------	strlen(str)--------------------------------------------------------------------------*/#if defined(FASI)static intstrlen(str)register char *str;{register len = 0;	while(*str++)		len++;	return(len);}	/* end of strlen */#endif /* FASI *//* process ioctl calls */intfasioctl (dev, cmd, arg3, arg4)int	dev;int	cmd;union ioctl_arg	arg3;int	arg4;{	register struct fas_info	*fip;	register struct tty	*ttyp;	int	v86_cmd, v86_data;	int	old_level;	REGVAR;	fip = fas_info_ptr [GET_UNIT (dev)];	/* was the port present at init time ? */	if (!(fip->device_flags.i & DF_DEVICE_CONFIGURED))	{		u.u_error = ENXIO;		return (-1);	}	ttyp = fip->tty;	/* process ioctl commands */	switch (cmd)	{#if defined (FASI)		case FASIC_SIP_CHANGE:			(void) sleep ((caddr_t) &fip->device_flags.i, PZERO + 1);		case FASIC_SIP:			if(copyout((char *)fip,arg3.cparg,sizeof(*fip)))			{				u.u_error = EFAULT;				return(-1);			}			return(fasiintr_entries);		case FASIC_DVR_IDENT:			if(copyout(fasi_driver_ident,arg3.cparg,				strlen(fasi_driver_ident) + 1))			{				u.u_error = EFAULT;				return(-1);			}			break;		case FASIC_SPACE_IDENT:			if(copyout(fasi_space_ident,arg3.cparg,				strlen(fasi_space_ident) + 1))			{				u.u_error = EFAULT;				return(-1);			}			break;		case FASIC_MSR:			return((unsigned int)fip->msr);		case FASIC_LCR:			return((unsigned int)fip->lcr);		case FASIC_IER:			return((unsigned int)fip->ier);		case FASIC_MCR:			return((unsigned int)fip->mcr);		case FASIC_RESET_STAT:			old_level = SPLINT();			fip->characters_received = 0;

⌨️ 快捷键说明

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