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

📄 riotty.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
		return -EIO;	}	if ( p->RIOHalted ) {		RIOClearUp( PortP );		rio_spin_unlock_irqrestore(&PortP->portSem, flags);		return -EIO;	}	/*	** Count ioctls for port statistics reporting	*/	if (PortP->statsGather)		PortP->ioctls++;	/*	** Specialix RIO Ioctl calls	*/	switch (cmd) {		case TCRIOTRIAD:			if ( arg )				PortP->State |= RIO_TRIAD_MODE;			else				PortP->State &= ~RIO_TRIAD_MODE;			/*			** Normally, when istrip is set on a port, a config is			** sent to the RTA instructing the CD1400 to do the			** stripping. In TRIAD mode, the interrupt receive routine			** must do the stripping instead, since it has to detect			** an 8 bit function key sequence. If istrip is set with			** TRIAD mode on(off), and 8 bit data is being read by			** the port, the user then turns TRIAD mode off(on), the RTA			** must be reconfigured (not) to do the stripping.			** Hence we call RIOParam here.			*/			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);				return 0;		case TCRIOTSTATE:			rio_dprintk (RIO_DEBUG_TTY, "tbusy/tstop monitoring %sabled\n",		 		arg ? "en" : "dis");			/* MonitorTstate = 0 ;*/			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			RIOParam(PortP, CONFIG, Modem, OK_TO_SLEEP);			return 0;		case TCRIOSTATE: /* current state of Modem input pins */			rio_dprintk (RIO_DEBUG_TTY, "TCRIOSTATE\n");			if (RIOPreemptiveCmd(p, PortP, MGET) == RIO_FAIL)				rio_dprintk (RIO_DEBUG_TTY, "TCRIOSTATE command failed\n");			PortP->State |= RIO_BUSY;			current = PortP->ModemState;			if ( copyout((caddr_t)&current, (int)arg,							sizeof(current))==COPYFAIL ) {				rio_dprintk (RIO_DEBUG_TTY, "Copyout failed\n");				rio_spin_unlock_irqrestore(&PortP->portSem, flags);				pseterr(EFAULT);			}			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			return 0;		case TCRIOMBIS:		/* Set modem lines */		case TCRIOMBIC:		/* Clear modem lines */			rio_dprintk (RIO_DEBUG_TTY, "TCRIOMBIS/TCRIOMBIC\n");			if (cmd == TCRIOMBIS) {				uint		state;				state = (uint)arg;				PortP->ModemState |= (ushort)state;				PortP->ModemLines = (ulong) arg;				if (RIOPreemptiveCmd(p, PortP, MBIS) == RIO_FAIL)					rio_dprintk (RIO_DEBUG_TTY, 					 "TCRIOMBIS command failed\n");			}			else {				uint		state;				state = (uint)arg;				PortP->ModemState &= ~(ushort)state;				PortP->ModemLines = (ulong) arg;				if (RIOPreemptiveCmd(p, PortP, MBIC) == RIO_FAIL)					rio_dprintk (RIO_DEBUG_TTY, "TCRIOMBIC command failed\n");			}			PortP->State |= RIO_BUSY;			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			return 0;		case TCRIOXPON: /* set Xprint ON string */			rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPON\n");			if ( copyin((int)arg, (caddr_t)PortP->Xprint.XpOn,						MAX_XP_CTRL_LEN)==COPYFAIL ) {				rio_dprintk (RIO_DEBUG_TTY, "Copyin failed\n");				PortP->Xprint.XpOn[0] = '\0';				rio_spin_unlock_irqrestore(&PortP->portSem, flags);				pseterr(EFAULT);			}			PortP->Xprint.XpOn[MAX_XP_CTRL_LEN-1] = '\0';			PortP->Xprint.XpLen = strlen(PortP->Xprint.XpOn)+												strlen(PortP->Xprint.XpOff);			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			return 0;		case TCRIOXPOFF: /* set Xprint OFF string */			rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPOFF\n");			if ( copyin( (int)arg, (caddr_t)PortP->Xprint.XpOff,						MAX_XP_CTRL_LEN)==COPYFAIL ) {				rio_dprintk (RIO_DEBUG_TTY, "Copyin failed\n");				PortP->Xprint.XpOff[0] = '\0';				rio_spin_unlock_irqrestore(&PortP->portSem, flags);				pseterr(EFAULT);			}			PortP->Xprint.XpOff[MAX_XP_CTRL_LEN-1] = '\0';			PortP->Xprint.XpLen = strlen(PortP->Xprint.XpOn)+										strlen(PortP->Xprint.XpOff);			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			return 0;		case TCRIOXPCPS: /* set Xprint CPS string */			rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPCPS\n");			if ( (uint)arg > p->RIOConf.MaxXpCps || 					(uint)arg < p->RIOConf.MinXpCps ) {				rio_dprintk (RIO_DEBUG_TTY, "%d CPS out of range\n",arg);				rio_spin_unlock_irqrestore(&PortP->portSem, flags);				pseterr(EINVAL);				return 0;			}			PortP->Xprint.XpCps = (uint)arg;			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			return 0;		case TCRIOXPRINT:			rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPRINT\n");			if ( copyout((caddr_t)&PortP->Xprint, (int)arg,					sizeof(struct Xprint))==COPYFAIL ) {			        rio_spin_unlock_irqrestore(&PortP->portSem, flags);				pseterr(EFAULT);			}			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			return 0;		case TCRIOIXANYON:			rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXANYON\n");			PortP->Config |= RIO_IXANY;			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			return 0;		case TCRIOIXANYOFF:			rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXANYOFF\n");			PortP->Config &= ~RIO_IXANY;			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			return 0;		case TCRIOIXONON:			rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXONON\n");			PortP->Config |= RIO_IXON;			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			return 0;		case TCRIOIXONOFF:			rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXONOFF\n");			PortP->Config &= ~RIO_IXON;			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			return 0;/*** 15.10.1998 ARG - ESIL 0761 part fix** Added support for CTS and RTS flow control ioctls :*/		case TCRIOCTSFLOWEN:			rio_dprintk (RIO_DEBUG_TTY, "TCRIOCTSFLOWEN\n");			PortP->Config |= RIO_CTSFLOW;			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);				return 0;		case TCRIOCTSFLOWDIS:			rio_dprintk (RIO_DEBUG_TTY, "TCRIOCTSFLOWDIS\n");			PortP->Config &= ~RIO_CTSFLOW;			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);				return 0;		case TCRIORTSFLOWEN:			rio_dprintk (RIO_DEBUG_TTY, "TCRIORTSFLOWEN\n");			PortP->Config |= RIO_RTSFLOW;			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);				return 0;		case TCRIORTSFLOWDIS:			rio_dprintk (RIO_DEBUG_TTY, "TCRIORTSFLOWDIS\n");			PortP->Config &= ~RIO_RTSFLOW;			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);				return 0;/* end ESIL 0761 part fix */	}	/* Lynx IOCTLS */	switch (cmd) {		case TIOCSETP:		case TIOCSETN:		case OTIOCSETP:		case OTIOCSETN:			ioctl_processed++;			ttyseth(PortP, tp, (struct old_sgttyb *)arg);			break;		case TCSETA:		case TCSETAW:		case TCSETAF:			ioctl_processed++;			rio_dprintk (RIO_DEBUG_TTY, "NON POSIX ioctl\n");			ttyseth_pv(PortP, tp, (struct termios *)arg, 0);			break;		case TCSETAP:	/* posix tcsetattr() */		case TCSETAWP:	/* posix tcsetattr() */		case TCSETAFP:	/* posix tcsetattr() */			rio_dprintk (RIO_DEBUG_TTY, "NON POSIX SYSV ioctl\n");			ttyseth_pv(PortP, tp, (struct termios *)arg, 1);			ioctl_processed++;			break;	}	/*	** If its any of the commands that require the port to be in the	** non-busy state wait until all output has drained 	*/	if (!ioctl_processed)	switch(cmd) {		case TCSETAW:		case TCSETAF:		case TCSETA:		case TCSBRK:#define OLD_POSIX ('x' << 8)#define OLD_POSIX_SETA (OLD_POSIX | 2)#define OLD_POSIX_SETAW (OLD_POSIX | 3)#define OLD_POSIX_SETAF (OLD_POSIX | 4)#define NEW_POSIX (('i' << 24) | ('X' << 16))#define NEW_POSIX_SETA (NEW_POSIX | 2)#define NEW_POSIX_SETAW (NEW_POSIX | 3)#define NEW_POSIX_SETAF (NEW_POSIX | 4)		case OLD_POSIX_SETA:		case OLD_POSIX_SETAW:		case OLD_POSIX_SETAF:		case NEW_POSIX_SETA:		case NEW_POSIX_SETAW:		case NEW_POSIX_SETAF:#ifdef TIOCSETP		case TIOCSETP:#endif		case TIOCSETD:		case TIOCSETN:			rio_dprintk (RIO_DEBUG_TTY, "wait for non-BUSY, semaphore set\n");			/*			** Wait for drain here, at least as far as the double buffer			** being empty.			*/			/* XXX Does the above comment mean that this has			   still to be implemented? -- REW */			/* XXX Is the locking OK together with locking                           in txenable? (Deadlock?) -- REW */						RIOTxEnable((char *)PortP);			break;		default:			break;	}	old_cflag = tp->tm.c_cflag;	old_iflag = tp->tm.c_iflag;	old_oflag = tp->tm.c_oflag;	oldcook = PortP->CookMode;	if ( p->RIOHalted ) {		RIOClearUp( PortP );		rio_spin_unlock_irqrestore(&PortP->portSem, flags);		pseterr(EIO);		return 0;	}	PortP->FlushCmdBodge = 0;	/*	** If the port is locked, and it is reconfigured, we want	** to restore the state of the tty structure so the change is NOT	** made.	*/	if (PortP->Lock) {		tp->tm.c_iflag = PortP->StoredTty.iflag;		tp->tm.c_oflag = PortP->StoredTty.oflag;		tp->tm.c_cflag = PortP->StoredTty.cflag;		tp->tm.c_lflag = PortP->StoredTty.lflag;		tp->tm.c_line = PortP->StoredTty.line;		for (i = 0; i < NCC + 1; i++)			tp->tm.c_cc[i] = PortP->StoredTty.cc[i];	}	else {		/*		** If the port is set to store the parameters, and it is		** reconfigured, we want to save the current tty struct so it		** may be restored on the next open.		*/		if (PortP->Store) {			PortP->StoredTty.iflag = tp->tm.c_iflag;			PortP->StoredTty.oflag = tp->tm.c_oflag;			PortP->StoredTty.cflag = tp->tm.c_cflag;			PortP->StoredTty.lflag = tp->tm.c_lflag;			PortP->StoredTty.line = tp->tm.c_line;			for (i = 0; i < NCC + 1; i++)				PortP->StoredTty.cc[i] = tp->tm.c_cc[i];		}	}	changed = (tp->tm.c_cflag != old_cflag) ||				(tp->tm.c_iflag != old_iflag) ||				(tp->tm.c_oflag != old_oflag);	PortP->CookMode = RIOCookMode(tp);	/* Set new cooking mode */	rio_dprintk (RIO_DEBUG_TTY, "RIOIoctl changed %d newcook %d oldcook %d\n",			changed,PortP->CookMode,oldcook);#ifdef MODEM_SUPPORT	/*	** kludge to force CARR_ON if CLOCAL set	*/	if ((tp->tm.c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD))	{		tp->tm.c_state |= CARR_ON;		wakeup ((caddr_t)&tp->tm.c_canq);	}#endif	if ( p->RIOHalted ) {		RIOClearUp( PortP );		rio_spin_unlock_irqrestore(&PortP->portSem, flags);		pseterr(EIO);		return 0;	}	/*	** Re-configure if modes or cooking have changed	*/	if (changed || oldcook != PortP->CookMode || (ioctl_processed)) {		rio_spin_unlock_irqrestore(&PortP->portSem, flags);		rio_dprintk (RIO_DEBUG_TTY, "Ioctl changing the PORT settings\n");		RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);			rio_spin_lock_irqsave(&PortP->portSem, flags);	}	if (p->RIOHalted) {		rio_spin_unlock_irqrestore(&PortP->portSem, flags);		RIOClearUp( PortP );		pseterr(EIO);		return 0;	}	rio_spin_unlock_irqrestore(&PortP->portSem, flags);	return 0;}/*	ttyseth -- set hardware dependent tty settings*/voidttyseth(PortP, s, sg)struct Port *		PortP;struct ttystatics *		s;struct old_sgttyb *sg;{	struct old_sgttyb *	tsg;	struct termios *tp = &s->tm;	tsg = &s->sg;	if (sg->sg_flags & (EVENP|ODDP))  {		tp->c_cflag &= PARENB;		if (sg->sg_flags & EVENP) {			if (sg->sg_flags & ODDP) {				tp->c_cflag &= V_CS7;				tp->c_cflag &= ~PARENB;			}			else {				tp->c_cflag &= V_CS7;				tp->c_cflag &= PARENB;				tp->c_cflag &= PARODD;			}		}		else if (sg->sg_flags & ODDP) {			tp->c_cflag &= V_CS7;			tp->c_cflag &= PARENB;			tp->c_cflag &= PARODD;		}		else {			tp->c_cflag &= V_CS7;			tp->c_cflag &= PARENB;		}	}/* * Use ispeed as the desired speed.  Most implementations don't handle  * separate input and output speeds very well. If the RIO handles this,  * I will have to use separate sets of flags to store them in the  * Port structure. */	if ( !sg->sg_ospeed )		sg->sg_ospeed = sg->sg_ispeed;	else		sg->sg_ispeed = sg->sg_ospeed;	if (sg->sg_ispeed > V_EXTB ) 		sg->sg_ispeed = V_EXTB;	if (sg->sg_ispeed < V_B0)		sg->sg_ispeed = V_B0;	*tsg = *sg;   tp->c_cflag = (tp->c_cflag & ~V_CBAUD) | conv_bv[(int)sg->sg_ispeed];}/*	ttyseth_pv -- set hardware dependent tty settings using either the			POSIX termios structure or the System V termio structure.				sysv = 0 => (POSIX):	 struct termios *sg				sysv != 0 => (System V): struct termio *sg*/static voidttyseth_pv(PortP, s, sg, sysv)struct Port *PortP;struct ttystatics *s;struct termios *sg;int sysv;{    int speed;    unsigned char csize;    unsigned char cread;    unsigned int lcr_flags;    int ps;     if (sysv) {        /* sg points to a System V termio structure */        csize = ((struct termio *)sg)->c_cflag & CSIZE;        cread = ((struct termio *)sg)->c_cflag & CREAD;        speed = conv_vb[((struct termio *)sg)->c_cflag & V_CBAUD];    }    else {        /* sg points to a POSIX termios structure */        csize = sg->c_cflag & CSIZE;        cread = sg->c_cflag & CREAD;        speed = conv_vb[sg->c_cflag & V_CBAUD];    }    if (s->sg.sg_ispeed != speed || s->sg.sg_ospeed != speed) {        s->sg.sg_ispeed = speed;        s->sg.sg_ospeed = speed;        s->tm.c_cflag = (s->tm.c_cflag & ~V_CBAUD) |                         conv_bv[(int)s->sg.sg_ispeed];    }}#endif

⌨️ 快捷键说明

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