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

📄 vx.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1988 Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Computer Consoles Inc. * * 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. * *	@(#)vx.c	7.13 (Berkeley) 5/16/91 */#include "vx.h"#if NVX > 0/* * VIOC-X driver */#ifdef VXPERF#define	DOSCOPE#endif#include "sys/param.h"#include "sys/ioctl.h"#include "sys/tty.h"#include "sys/user.h"#include "sys/map.h"#include "sys/buf.h"#include "sys/conf.h"#include "sys/file.h"#include "sys/proc.h"#include "sys/vm.h"#include "sys/kernel.h"#include "sys/syslog.h"#include "../include/pte.h"#include "../vba/vbavar.h"#include "../vba/vbaparam.h"#include "../vba/vxreg.h"#include "../vba/scope.h"#ifdef VX_DEBUGlong	vxintr4 = 0;#define	VXERR4	1#define	VXNOBUF	2long	vxdebug = 0;#define	VXVCM	1#define	VXVCC	2#define	VXVCX	4#endif/* * Interrupt type bits passed to vinthandl(). */#define	CMDquals 0		/* command completed interrupt */#define	RSPquals 1		/* command response interrupt */#define	UNSquals 2		/* unsolicited interrupt */#define	VXUNIT(n)	((n) >> 4)#define	VXPORT(n)	((n) & 0xf)struct	tty vx_tty[NVX*16];#ifndef lintint	nvx = NVX*16;#endifint	vxstart(), ttrstrt();struct	vxcmd *vobtain(), *nextcmd();/* * Driver information for auto-configuration stuff. */int	vxprobe(), vxattach(), vxrint();struct	vba_device *vxinfo[NVX];long	vxstd[] = { 0 };struct	vba_driver vxdriver =    { vxprobe, 0, vxattach, 0, vxstd, "vx", vxinfo };struct	vx_softc {	struct	vxdevice *vs_addr;	/* H/W address */	u_char	vs_type;	/* 0: viox-x/vioc-b, 1: vioc-bop */	u_char	vs_bop;		/* bop board # for vioc-bop's */	u_char	vs_loport;	/* low port nbr */	u_char	vs_hiport;	/* high port nbr */	u_short	vs_nbr;		/* viocx number */	u_short	vs_maxcmd;	/* max number of concurrent cmds */	u_short	vs_silosiz;	/* silo size */	short	vs_vers;	/* vioc/pvioc version */#define	VXV_OLD	0		/* PVIOCX | VIOCX */#define	VXV_NEW	1		/* NPVIOCX | NVIOCX */	short 	vs_state;	/* controller state */#define	VXS_READY	0	/* ready for commands */#define	VXS_RESET	1	/* in process of reseting */	u_short	vs_softCAR;	/* soft carrier */	u_int	vs_ivec;	/* interrupt vector base */	caddr_t vs_mricmd;	/* most recent issued cmd */	/* The remaining fields are zeroed on reset... */#define vs_zero vs_xmtcnt	int	vs_xmtcnt;	/* xmit commands pending */	struct	vxcmd *vs_avail;/* next available command buffer */	struct	vxcmd *vs_build;	struct	vxcmd vs_lst[NVCXBUFS];	struct	vcmds vs_cmds;} vx_softc[NVX];struct speedtab vxspeedtab[] = {	EXTA,	V19200,	EXTB,	V19200,	19200,	V19200,	9600,	13,	4800,	12,	2400,	11,	1800,	10,	1200,	9,	600,	8,	300,	7,	200,	6,	150,	5,	134,	4,	110,	3,	75,	2,	50,	1,	0,	0,	-1,	-1,};vxprobe(reg, vi)	caddr_t reg;	struct vba_device *vi;{	register int br, cvec;			/* must be r12, r11 */	register struct vxdevice *vp;	register struct vx_softc *vs;	struct pte *dummypte;#ifdef lint	br = 0; cvec = br; br = cvec;	vackint(0); vunsol(0); vcmdrsp(0);#ifdef VX_DEBUG	vxfreset(0);#endif#endif /* lint */	/*	 * If on an HCX-9, the device has a 32-bit address,	 * and we receive that address so we can set up a map.	 * On VERSAbus devices, the address is 24-bit, and is	 * already mapped (into vmem[]) by autoconf.	 */	if (!(reg >= vmem && reg < &vmem[ctob(VBIOSIZE)]) &&	/* XXX */	    !vbmemalloc(16, reg, &dummypte, &reg)) {		printf("vx%d: vbmemalloc failed.\n", vi->ui_unit);		return(0);	}	vp = (struct vxdevice *)reg;	if (badaddr((caddr_t)vp, 1))		return (0);	vp->v_fault = 0;	vp->v_vioc = V_BSY;	vp->v_hdwre = V_RESET;		/* reset interrupt */	DELAY(4000000);	if (vp->v_fault != VXF_READY)		return (0);	vs = &vx_softc[vi->ui_unit];#ifdef notdef	/*	 * Align vioc interrupt vector base to 4 vector	 * boundary and fitting in 8 bits (is this necessary,	 * wish we had documentation).	 */	if ((vi->ui_hd->vh_lastiv -= 3) > 0xff)		vi->ui_hd->vh_lastiv = 0xff;	vs->vs_ivec = vi->ui_hd->vh_lastiv = vi->ui_hd->vh_lastiv &~ 0x3;#else	vs->vs_ivec = 0x40+vi->ui_unit*4;#endif	br = 0x18, cvec = vs->vs_ivec;	/* XXX */	return (sizeof (struct vxdevice));}vxattach(vi)	register struct vba_device *vi;{	register struct vx_softc *vs = &vx_softc[vi->ui_unit];	vs->vs_softCAR = vi->ui_flags;	vs->vs_addr = (struct vxdevice *)vi->ui_addr;	vxinit(vi->ui_unit, 1);}/* * Open a VX line. *//*ARGSUSED*/vxopen(dev, flag)	dev_t dev;	int flag;{	register struct tty *tp;	/* pointer to tty struct for port */	register struct vx_softc *vs;	register struct vba_device *vi;	int unit, vx, s, error = 0;	int vxparam();	unit = minor(dev);	vx = VXUNIT(unit);	if (vx >= NVX || (vi = vxinfo[vx])== 0 || vi->ui_alive == 0)		return (ENXIO);	vs = &vx_softc[vx];	tp = &vx_tty[unit];	unit = VXPORT(unit);	if (tp->t_state&TS_XCLUDE && u.u_uid != 0)		return (EBUSY);	if (unit < vs->vs_loport || unit > vs->vs_hiport)		return (ENXIO);	tp->t_addr = (caddr_t)vs;	tp->t_oproc = vxstart;	tp->t_param = vxparam;	tp->t_dev = dev;	s = spl8();	if ((tp->t_state&TS_ISOPEN) == 0) {		tp->t_state |= TS_WOPEN;		ttychars(tp);		if (tp->t_ispeed == 0) {			tp->t_iflag = TTYDEF_IFLAG;			tp->t_oflag = TTYDEF_OFLAG;			tp->t_lflag = TTYDEF_LFLAG;			tp->t_cflag = TTYDEF_CFLAG;			tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;		}		vxparam(tp, &tp->t_termios);		ttsetwater(tp);	}	vcmodem(dev, VMOD_ON);	while (!(flag&O_NONBLOCK) && !(tp->t_cflag&CLOCAL) && 	      (tp->t_state&TS_CARR_ON) == 0) {		tp->t_state |= TS_WOPEN;		if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,		    ttopen, 0))			break;	}	if (error == 0)		error = (*linesw[tp->t_line].l_open)(dev,tp);	splx(s);	return (error);}/* * Close a VX line. *//*ARGSUSED*/vxclose(dev, flag, mode, p)	dev_t dev;	int flag, mode;	struct proc *p;{	register struct tty *tp;	int unit, s, error = 0;	unit = minor(dev);	tp = &vx_tty[unit];	s = spl8();	(*linesw[tp->t_line].l_close)(tp, flag);	if (tp->t_cflag & HUPCL || (tp->t_state & TS_ISOPEN) == 0)		vcmodem(dev, VMOD_OFF);	/* wait for the last response */	while (tp->t_state&TS_FLUSH && error == 0)		error = tsleep((caddr_t)&tp->t_state, TTOPRI | PCATCH,		    ttclos, 0);	splx(s);	if (error)		return (error);	return (ttyclose(tp));}/* * Read from a VX line. */vxread(dev, uio, flag)	dev_t dev;	struct uio *uio;{	struct tty *tp = &vx_tty[minor(dev)];	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));}/* * write on a VX line */vxwrite(dev, uio, flag)	dev_t dev;	struct uio *uio;{	register struct tty *tp = &vx_tty[minor(dev)];	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));}/* * VIOCX unsolicited interrupt. */vxrint(vx)	register vx;{	register struct tty *tp, *tp0;	register struct vxdevice *addr;	register struct vx_softc *vs;	struct vba_device *vi;	register int nc, c;	register struct silo {		u_char	data, port;	} *sp;	short *osp;	int overrun = 0;	vi = vxinfo[vx];	if (vi == 0 || vi->ui_alive == 0)		return;	addr = (struct vxdevice *)vi->ui_addr;	switch (addr->v_uqual&037) {	case 0:		break;	case 2:		if (addr->v_ustat == VP_SILO_OFLOW)			log(LOG_ERR, "vx%d: input silo overflow\n", vx);		else {			printf("vx%d: vc proc err, ustat %x\n",			    vx, addr->v_ustat);			vxstreset(vx);		}		return;	case 3:		vcmintr(vx);		return;	case 4:		return;	default:		printf("vx%d: vc uqual err, uqual %x\n", vx, addr->v_uqual);		vxstreset(vx);		return;	}	vs = &vx_softc[vx];	if (vs->vs_vers == VXV_NEW)		sp = (struct silo *)((caddr_t)addr + *(short *)addr->v_usdata);	else		sp = (struct silo *)((caddr_t)addr+VX_SILO+(addr->v_usdata[0]<<6));	nc = *(osp = (short *)sp);	if (nc == 0)		return;	if (vs->vs_vers == VXV_NEW && nc > vs->vs_silosiz) {		printf("vx%d: %d exceeds silo size\n", nc);		nc = vs->vs_silosiz;	}	tp0 = &vx_tty[vx*16];	sp = (struct silo *)(((short *)sp)+1);	for (; nc > 0; nc--, sp = (struct silo *)(((short *)sp)+1)) {		c = sp->port & 017;		if (vs->vs_loport > c || c > vs->vs_hiport)			continue;		tp = tp0 + c;		if( (tp->t_state&TS_ISOPEN) == 0) {			wakeup((caddr_t)&tp->t_rawq);			continue;		}		c = sp->data&((tp->t_cflag&CSIZE)==CS8 ? 0xff : 0x7f);		if ((sp->port&VX_RO) == VX_RO && !overrun) {			log(LOG_ERR, "vx%d: receiver overrun\n", vi->ui_unit);			overrun = 1;			continue;		}		if (sp->port&VX_PE)			c |= TTY_PE;		if (sp->port&VX_FE) 			c |= TTY_FE;		(*linesw[tp->t_line].l_rint)(c, tp);	}	*osp = 0;}/* * Ioctl for VX. */vxioctl(dev, cmd, data, flag)	dev_t dev;	caddr_t	data;{	register struct tty *tp;	int error;	tp = &vx_tty[minor(dev)];	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);	if (error >= 0)		return (error);	error = ttioctl(tp, cmd, data, flag);	if (error >= 0) 		return (error);	return (ENOTTY);}vxparam(tp, t)	struct tty *tp;	struct termios *t;{	return (vxcparam(tp, t, 1));}/* * Set parameters from open or stty into the VX hardware * registers. */vxcparam(tp, t, wait)	struct tty *tp;	struct termios *t;	int wait;{	register struct vx_softc *vs;	register struct vxcmd *cp;	int s, error = 0;	int speedcode = ttspeedtab(t->c_ospeed, vxspeedtab);	if (speedcode < 0 || (t->c_ispeed != t->c_ospeed && t->c_ispeed))		return (EINVAL);	vs = (struct vx_softc *)tp->t_addr;	cp = vobtain(vs);	s = spl8();	/*	 * Construct ``load parameters'' command block	 * to setup baud rates, xon-xoff chars, parity,	 * and stop bits for the specified port.	 */	cp->cmd = VXC_LPARAX;	cp->par[1] = VXPORT(minor(tp->t_dev));	/*	 * note: if the hardware does flow control, ^V doesn't work	 * to escape ^S	 */	if (t->c_iflag&IXON) {		if (t->c_cc[VSTART] == _POSIX_VDISABLE)			cp->par[2] = 0;		else			cp->par[2] = t->c_cc[VSTART];		if (t->c_cc[VSTOP] == _POSIX_VDISABLE)			cp->par[3] = 0;		else			cp->par[3] = t->c_cc[VSTOP];	} else 		cp->par[2] = cp->par[3] = 0;

⌨️ 快捷键说明

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