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

📄 vx.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
		printf("vx%d: ackint error type %x v_dcd %x\n", vx,		    vp->v_vcid & 07, vp->v_dcd & 0xff);		resp = (char *)vs->vs_mricmd;		for (i = 0; i < 16; i++)			printf("%x ", resp[i]&0xff);		printf("\n");		splx(s);		vxstreset(vx);		return;	}	if ((vp->v_hdwre&017) == CMDquals) {#ifdef VX_DEBUG		if (vxintr4 & VXERR4) {	/* causes VIOC INTR ERR 4 */			struct vxcmd *cp1, *cp0;			cp0 = (struct vxcmd *)			    ((caddr_t)cp->cmdbuf[cp->v_empty]-sizeof (cp0->c_fwd));			if (cp0->cmd == VXC_XMITDTA || cp0->cmd == VXC_XMITIMM) {				cp1 = vobtain(vs);				*cp1 = *cp0;				vxintr4 &= ~VXERR4;				(void) vcmd(vx, &cp1->cmd);			}		}#endif		cp->v_curcmd[vp->v_vcid & VCMDLEN-1] = cp->cmdbuf[cp->v_empty];		if (++cp->v_empty >= VC_CMDBUFL)			cp->v_empty = 0;	}	if (++cp->v_itrempt >= VC_IQLEN)		cp->v_itrempt = 0;	vintempt(vx);	splx(s);	(void) vcmd(vx, (caddr_t)0);	/* queue next cmd, if any */}/* * Command Response interrupt.  The Vioc has completed * a command.  The command may now be returned to * the appropriate device driver. */vcmdrsp(vx)	register vx;{	register struct vxdevice *vp;	register struct vcmds *cp;	register caddr_t cmd;	register struct vx_softc *vs;	register char *resp;	register k;	register int s;	scope_out(6);	vs = &vx_softc[vx];	if (vs->vs_type) {	/* Its a BOP */		printf("vx%d: vcmdrsp interrupt\n", vx);		return;	}	s = spl8();	vp = vs->vs_addr;	cp = &vs->vs_cmds;	resp = (char *)vp + (vp->v_rspoff&0x7fff);	if (((k = resp[1])&V_UNBSY) == 0) {		printf("vx%d: cmdresp debug\n", vx);		splx(s);		vxstreset(vx);		return;	}	k &= VCMDLEN-1;	cmd = cp->v_curcmd[k];	cp->v_curcmd[k] = (caddr_t)0;	cp->v_curcnt--;	k = *((short *)&resp[4]);	/* cmd operation code */	if ((k&0xff00) == VXC_LIDENT)	/* want hiport number */		for (k = 0; k < VRESPLEN; k++)			cmd[k] = resp[k+4];	resp[1] = 0;	vxxint(vx, (struct vxcmd *)cmd);	if (vs->vs_state == VXS_READY)		vinthandl(vx, ((V_BSY|RSPquals) << 8)|V_INTR);	splx(s);}/* * Unsolicited interrupt. */vunsol(vx)	register vx;{	register struct vxdevice *vp;	struct vx_softc *vs;	int s;	scope_out(1);	vs = &vx_softc[vx];	if (vs->vs_type) {	/* Its a BOP */		printf("vx%d: vunsol from BOP\n", vx);		return;	}	s = spl8();	vp = vs->vs_addr;	if (vp->v_uqual&V_UNBSY) {		vxrint(vx);		vinthandl(vx, ((V_BSY|UNSquals) << 8)|V_INTR);#ifdef notdef	} else {		printf("vx%d: unsolicited interrupt error\n", vx);		splx(s);		vxstreset(vx);#endif	}	splx(s);}/* * Enqueue an interrupt. */vinthandl(vx, item)	register int vx;	register item;{	register struct vcmds *cp;	int empty;	cp = &vx_softc[vx].vs_cmds;	empty = (cp->v_itrfill == cp->v_itrempt);	cp->v_itrqueu[cp->v_itrfill] = item;	if (++cp->v_itrfill >= VC_IQLEN)		cp->v_itrfill = 0;	if (cp->v_itrfill == cp->v_itrempt) {		printf("vx%d: interrupt q overflow\n", vx);		vxstreset(vx);	} else if (empty)		vintempt(vx);}vintempt(vx)	int vx;{	register struct vcmds *cp;	register struct vxdevice *vp;	register struct vx_softc *vs;	register short item;	register short *intr;	vs = &vx_softc[vx];	vp = vs->vs_addr;	if (vp->v_vioc&V_BSY)		return;	cp = &vs->vs_cmds;	if (cp->v_itrempt == cp->v_itrfill)		return;	item = cp->v_itrqueu[cp->v_itrempt];	intr = (short *)&vp->v_vioc;	switch ((item >> 8)&03) {	case CMDquals: {		/* command */		int phys;		if (cp->v_empty == cp->v_fill || vp->v_vcbsy&V_BSY)			break;		vs->vs_mricmd = (caddr_t)cp->cmdbuf[cp->v_empty];		phys = vtoph((struct proc *)0, 		    (unsigned)cp->cmdbuf[cp->v_empty]);		vp->v_vcp[0] = ((short *)&phys)[0];		vp->v_vcp[1] = ((short *)&phys)[1];		vp->v_vcbsy = V_BSY;		*intr = item;		scope_out(4);		break;	}	case RSPquals:		/* command response */		*intr = item;		scope_out(7);		break;	case UNSquals:		/* unsolicited interrupt */		vp->v_uqual = 0;		*intr = item;		scope_out(2);		break;	}}/* * Start a reset on a vioc after error (hopefully) */vxstreset(vx)	register int vx;{	register struct vx_softc *vs;	register struct vxdevice *vp;	register struct vxcmd *cp;	register int j;	extern int vxinreset();	int s;	vs = &vx_softc[vx];	s = spl8();	if (vs->vs_state == VXS_RESET) {	/* avoid recursion */		splx(s);		return;	}	vp = vs->vs_addr;	/*	 * Zero out the vioc structures, mark the vioc as being	 * reset, reinitialize the free command list, reset the vioc	 * and start a timer to check on the progress of the reset.	 */	bzero((caddr_t)&vs->vs_zero,	    (unsigned)((caddr_t)(vs + 1) - (caddr_t)&vs->vs_zero));	/*	 * Setting VXS_RESET prevents others from issuing	 * commands while allowing currently queued commands to	 * be passed to the VIOC.	 */	vs->vs_state = VXS_RESET;	/* init all cmd buffers */	for (j = 0; j < NVCXBUFS; j++) {		cp = &vs->vs_lst[j];		cp->c_fwd = &vs->vs_lst[j+1];	}	vs->vs_avail = &vs->vs_lst[0];	cp->c_fwd = (struct vxcmd *)0;	printf("vx%d: reset...", vx);	vp->v_fault = 0;	vp->v_vioc = V_BSY;	vp->v_hdwre = V_RESET;		/* generate reset interrupt */	timeout(vxinreset, (caddr_t)vx, hz*5);	splx(s);}/* continue processing a reset on a vioc after an error (hopefully) */vxinreset(vx)	int vx;{	register struct vxdevice *vp;	int s = spl8();	vp = vx_softc[vx].vs_addr;	/*	 * See if the vioc has reset.	 */	if (vp->v_fault != VXF_READY) {		printf(" vxreset failed\n");		splx(s);		return;	}	/*	 * Send a LIDENT to the vioc and mess with carrier flags	 * on parallel printer ports.	 */	vxinit(vx, 0);	splx(s);}/* * Finish the reset on the vioc after an error (hopefully). * * Restore modem control, parameters and restart output. * Since the vioc can handle no more then 24 commands at a time * and we could generate as many as 48 commands, we must do this in * phases, issuing no more then 16 commands at a time. */vxfnreset(vx, cp)	register int vx;	register struct vxcmd *cp;{	register struct vx_softc *vs;	register struct vxdevice *vp;	register struct tty *tp, *tp0;	register int i;#ifdef notdef	register int on;#endif	extern int vxrestart();	int s = spl8();	vs = &vx_softc[vx];	vrelease(vs, cp);	vs->vs_state = VXS_READY;	vp = vs->vs_addr;	vp->v_vcid = 0;	/*	 * Restore modem information and control.	 */	tp0 = &vx_tty[vx*16];	for (i = vs->vs_loport; i <= vs->vs_hiport; i++) {		tp = tp0 + i;		if (tp->t_state&(TS_ISOPEN|TS_WOPEN)) {			tp->t_state &= ~TS_CARR_ON;			vcmodem(tp->t_dev, VMOD_ON);			if (tp->t_state&TS_CARR_ON)				(void)(*linesw[tp->t_line].l_modem)(tp, 1);			else if (tp->t_state & TS_ISOPEN)				(void)(*linesw[tp->t_line].l_modem)(tp, 0);		}#ifdef notdef		/*		 * If carrier has changed while we were resetting,		 * take appropriate action.		 */		on = vp->v_dcd & 1<<i;		if (on && (tp->t_state&TS_CARR_ON) == 0)			(void)(*linesw[tp->t_line].l_modem)(tp, 1);		else if (!on && tp->t_state&TS_CARR_ON)			(void)(*linesw[tp->t_line].l_modem)(tp, 0);#endif	}	vs->vs_state = VXS_RESET;	timeout(vxrestart, (caddr_t)vx, hz);	splx(s);}/* * Restore a particular aspect of the VIOC. */vxrestart(vx)	int vx;{	register struct tty *tp, *tp0;	register struct vx_softc *vs;	register int i, count;	int s = spl8();	count = vx >> 8;	vx &= 0xff;	vs = &vx_softc[vx];	vs->vs_state = VXS_READY;	tp0 = &vx_tty[vx*16];	for (i = vs->vs_loport; i <= vs->vs_hiport; i++) {		tp = tp0 + i;		if (count != 0) {			tp->t_state &= ~(TS_BUSY|TS_TIMEOUT);			if (tp->t_state&(TS_ISOPEN|TS_WOPEN))				vxstart(tp);	/* restart pending output */		} else {			if (tp->t_state&(TS_WOPEN|TS_ISOPEN))				vxcparam(tp, &tp->t_termios, 0);		}	}	if (count == 0) {		vs->vs_state = VXS_RESET;		timeout(vxrestart, (caddr_t)(vx + 1*256), hz);	} else		printf(" vx reset done\n");	splx(s);}vxreset(dev)	dev_t dev;{	vxstreset((int)VXUNIT(minor(dev)));	/* completes asynchronously */}#ifdef VX_DEBUGvxfreset(vx)	register int vx;{	struct vba_device *vi;	if ((unsigned)vx > NVX || (vi = vxinfo[vx]) == 0 || vi->ui_addr == 0)		return (ENODEV);	vx_softc[vx].vs_state = VXS_READY;	vxstreset(vx);	return (0);		/* completes asynchronously */}#endifvcmodem(dev, flag)	dev_t dev;{	struct tty *tp;	register struct vxcmd *cp;	register struct vx_softc *vs;	register struct vxdevice *kp;	register port;	int unit;	unit = minor(dev);	tp = &vx_tty[unit];	vs = (struct vx_softc *)tp->t_addr;	if (vs->vs_state != VXS_READY)		return;	cp = vobtain(vs);	kp = vs->vs_addr;	port = VXPORT(unit);	/*	 * Issue MODEM command	 */	cp->cmd = VXC_MDMCTL;	if (flag == VMOD_ON) {		if (vs->vs_softCAR & (1 << port)) {			cp->par[0] = V_MANUAL | V_DTR_ON | V_RTS;			kp->v_dcd |= (1 << port);		} else			cp->par[0] = V_AUTO | V_DTR_ON;	} else		cp->par[0] = V_DTR_OFF;	cp->par[1] = port;	(void) vcmd((int)vs->vs_nbr, (caddr_t)&cp->cmd);	if ((kp->v_dcd | vs->vs_softCAR) & (1 << port) && flag == VMOD_ON)		tp->t_state |= TS_CARR_ON;}/* * VCMINTR called when an unsolicited interrupt occurs signaling * some change of modem control state. */vcmintr(vx)	register vx;{	register struct vxdevice *kp;	register struct tty *tp;	register port;	register struct vx_softc *vs;	vs = &vx_softc[vx];	kp = vs->vs_addr;	port = kp->v_usdata[0] & 017;	tp = &vx_tty[vx*16+port];	if (kp->v_ustat & DCD_ON)		(void)(*linesw[tp->t_line].l_modem)(tp, 1);	else if ((kp->v_ustat & DCD_OFF) &&	    ((vs->vs_softCAR & (1 << port))) == 0 &&	    (*linesw[tp->t_line].l_modem)(tp, 0) == 0) {		register struct vcmds *cp;		register struct vxcmd *cmdp;		/* clear all pending transmits */		if (tp->t_state&(TS_BUSY|TS_FLUSH) &&		    vs->vs_vers == VXV_NEW) {			int i, cmdfound = 0;			cp = &vs->vs_cmds;			for (i = cp->v_empty; i != cp->v_fill; ) {				cmdp = (struct vxcmd *)((long *)cp->cmdbuf[i]-1);				if ((cmdp->cmd == VXC_XMITDTA ||				    cmdp->cmd == VXC_XMITIMM) &&				    ((struct vxmit *)cmdp->par)->line == port) {					cmdfound++;					cmdp->cmd = VXC_FDTATOX;					cmdp->par[1] = port;				}				if (++i >= VC_CMDBUFL)					i = 0;			}			if (cmdfound)				tp->t_state &= ~(TS_BUSY|TS_FLUSH);			/* cmd is already in vioc, have to flush it */			else {				cmdp = vobtain(vs);				cmdp->cmd = VXC_FDTATOX;				cmdp->par[1] = port;				(void) vcmd(vx, (caddr_t)&cmdp->cmd);			}		}	} else if ((kp->v_ustat&BRK_CHR) && (tp->t_state&TS_ISOPEN)) {		(*linesw[tp->t_line].l_rint)(TTY_FE, tp);		return;	}}#endif

⌨️ 快捷键说明

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