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

📄 riotty.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
/*** -----------------------------------------------------------------------------****  Perle Specialix driver for Linux**  Ported from existing RIO Driver for SCO sources. * *  (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK. * *      This program is free software; you can redistribute it and/or modify *      it under the terms of the GNU General Public License as published by *      the Free Software Foundation; either version 2 of the License, or *      (at your option) any later version. * *      This program is distributed in the hope that it will be useful, *      but WITHOUT ANY WARRANTY; without even the implied warranty of *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *      GNU General Public License for more details. * *      You should have received a copy of the GNU General Public License *      along with this program; if not, write to the Free Software *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.****	Module		: riotty.c**	SID		: 1.3**	Last Modified	: 11/6/98 10:33:47**	Retrieved	: 11/6/98 10:33:50****  ident @(#)riotty.c	1.3**** -----------------------------------------------------------------------------*/#ifdef SCCS_LABELSstatic char *_riotty_c_sccs_ = "@(#)riotty.c	1.3";#endif#define __EXPLICIT_DEF_H__#include <linux/module.h>#include <linux/slab.h>#include <linux/errno.h>#include <linux/tty.h>#include <linux/string.h>#include <asm/io.h>#include <asm/system.h>#include <asm/string.h>#include <asm/semaphore.h>#include <asm/uaccess.h>#include <linux/termios.h>#include <linux/serial.h>#include <linux/generic_serial.h>#include "linux_compat.h"#include "rio_linux.h"#include "typdef.h"#include "pkt.h"#include "daemon.h"#include "rio.h"#include "riospace.h"#include "top.h"#include "cmdpkt.h"#include "map.h"#include "riotypes.h"#include "rup.h"#include "port.h"#include "riodrvr.h"#include "rioinfo.h"#include "func.h"#include "errors.h"#include "pci.h"#include "parmmap.h"#include "unixrup.h"#include "board.h"#include "host.h"#include "error.h"#include "phb.h"#include "link.h"#include "cmdblk.h"#include "route.h"#include "control.h"#include "cirrus.h"#include "rioioctl.h"#include "param.h"#include "list.h"#include "sam.h"#if 0static void ttyseth_pv(struct Port *, struct ttystatics *, 				struct termios *sg, int);#endifstatic void RIOClearUp(struct Port *PortP);int RIOShortCommand(struct rio_info *p, struct Port *PortP, 			   int command, int len, int arg);#if 0static int RIOCookMode(struct ttystatics *);#endifextern int	conv_vb[];	/* now defined in ttymgr.c */extern int	conv_bv[];	/* now defined in ttymgr.c */ /*** 16.09.1998 ARG - Fix to build riotty.k.o for Modular Kernel Support**** ep.def.h is necessary for Modular Kernel Support** DO NOT place any kernel 'extern's after this line** or this source file will not build riotty.k.o*/#ifdef uLYNX#include <ep.def.h>#endif#ifdef NEED_THIS2static struct old_sgttyb default_sg = { 	B19200, B19200,				/* input and output speed */ 	'H' - '@',					/* erase char */ 	-1,							/* 2nd erase char */ 	'U' - '@',					/* kill char */ 	ECHO | CRMOD,				/* mode */ 	'C' - '@',					/* interrupt character */ 	'\\' - '@',					/* quit char */ 	'Q' - '@',					/* start char */	'S' - '@',					/* stop char */ 	'D' - '@',					/* EOF */	-1,							/* brk */	(LCRTBS | LCRTERA | LCRTKIL | LCTLECH),	/* local mode word */ 	'Z' - '@',					/* process stop */	'Y' - '@',					/* delayed stop */	'R' - '@',					/* reprint line */ 	'O' - '@',					/* flush output */	'W' - '@',					/* word erase */	'V' - '@'					/* literal next char */};#endifextern struct rio_info *p;intriotopen(struct tty_struct * tty, struct file * filp){	register uint SysPort;	int Modem;	int repeat_this = 250;	struct Port *PortP;		 /* pointer to the port structure */	unsigned long flags;	int retval = 0;	func_enter ();	/* Make sure driver_data is NULL in case the rio isn't booted jet. Else gs_close	   is going to oops.	*/	tty->driver_data = NULL;        	SysPort = rio_minor(tty);	Modem   = rio_ismodem(tty);	if ( p->RIOFailed ) {		rio_dprintk (RIO_DEBUG_TTY, "System initialisation failed\n");		pseterr(ENXIO);		func_exit ();		return -ENXIO;	}	rio_dprintk (RIO_DEBUG_TTY, "port open SysPort %d (%s) (mapped:%d)\n",	       SysPort,  Modem ? "Modem" : "tty",				   p->RIOPortp[SysPort]->Mapped);	/*	** Validate that we have received a legitimate request.	** Currently, just check that we are opening a port on	** a host card that actually exists, and that the port	** has been mapped onto a host.	*/	if (SysPort >= RIO_PORTS) {	/* out of range ? */		rio_dprintk (RIO_DEBUG_TTY, "Illegal port number %d\n",SysPort);		pseterr(ENXIO);		func_exit();		return -ENXIO;	}	/*	** Grab pointer to the port stucture	*/	PortP = p->RIOPortp[SysPort];	/* Get control struc */	rio_dprintk (RIO_DEBUG_TTY, "PortP: %p\n", PortP);	if ( !PortP->Mapped ) {	/* we aren't mapped yet! */		/*		** The system doesn't know which RTA this port		** corresponds to.		*/		rio_dprintk (RIO_DEBUG_TTY, "port not mapped into system\n");		func_exit ();		pseterr(ENXIO);		return -ENXIO;	}	tty->driver_data = PortP;	PortP->gs.tty = tty;	PortP->gs.count++;	rio_dprintk (RIO_DEBUG_TTY, "%d bytes in tx buffer\n",				   PortP->gs.xmit_cnt);	retval = gs_init_port (&PortP->gs);	if (retval) {		PortP->gs.count--;		return -ENXIO;	}	/*	** If the host hasn't been booted yet, then 	** fail	*/	if ( (PortP->HostP->Flags & RUN_STATE) != RC_RUNNING ) {		rio_dprintk (RIO_DEBUG_TTY, "Host not running\n");		pseterr(ENXIO);		func_exit ();		return -ENXIO;	}	/*	** If the RTA has not booted yet and the user has choosen to block	** until the RTA is present then we must spin here waiting for	** the RTA to boot.	*/#if 0	if (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {		if (PortP->WaitUntilBooted) {			rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot\n");			do {				if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {					rio_dprintk (RIO_DEBUG_TTY, "RTA EINTR in delay \n");					func_exit ();					return -EINTR;				}				if (repeat_this -- <= 0) {					rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n");					RIOPreemptiveCmd(p, PortP, FCLOSE ); 					pseterr(EINTR);					func_exit ();					return -EIO;				}			} while(!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED));			rio_dprintk (RIO_DEBUG_TTY, "RTA has been booted\n");		} else {			rio_dprintk (RIO_DEBUG_TTY, "RTA never booted\n");			pseterr(ENXIO);			func_exit ();			return 0;		}	}#else	/* I find the above code a bit hairy. I find the below code           easier to read and shorter. Now, if it works too that would	   be great... -- REW 	*/	rio_dprintk (RIO_DEBUG_TTY, "Checking if RTA has booted... \n");	while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {	  if (!PortP->WaitUntilBooted) {	    rio_dprintk (RIO_DEBUG_TTY, "RTA never booted\n");	    func_exit ();	    return -ENXIO;	  }	  /* Under Linux you'd normally use a wait instead of this	     busy-waiting. I'll stick with the old implementation for	     now. --REW 	  */	  if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {	    rio_dprintk (RIO_DEBUG_TTY, "RTA_wait_for_boot: EINTR in delay \n");	    func_exit ();	    return -EINTR;	  }	  if (repeat_this -- <= 0) {	    rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n");	    func_exit ();	    return -EIO;	  }	}	rio_dprintk (RIO_DEBUG_TTY, "RTA has been booted\n");#endif#if 0	tp =  PortP->TtyP;		/* get tty struct */#endif	rio_spin_lock_irqsave(&PortP->portSem, flags);	if ( p->RIOHalted ) {		goto bombout;	}#if 0	retval = gs_init_port(&PortP->gs);	if (retval){		func_exit ();		return retval;	}#endif	/*	** If the port is in the final throws of being closed,	** we should wait here (politely), waiting	** for it to finish, so that it doesn't close us!	*/	while ( (PortP->State & RIO_CLOSING) && !p->RIOHalted ) {		rio_dprintk (RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n");		if (repeat_this -- <= 0) {			rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");			RIOPreemptiveCmd(p, PortP, FCLOSE ); 			retval = -EINTR;			goto bombout;		}		rio_spin_unlock_irqrestore(&PortP->portSem, flags);		if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {			rio_spin_lock_irqsave(&PortP->portSem, flags); 			retval = -EINTR;			goto bombout;		}		rio_spin_lock_irqsave(&PortP->portSem, flags); 	}	if ( !PortP->Mapped ) {		rio_dprintk (RIO_DEBUG_TTY, "Port unmapped while closing!\n");		rio_spin_unlock_irqrestore(&PortP->portSem, flags);		retval = -ENXIO;		func_exit ();		return retval;	}	if ( p->RIOHalted ) {		goto bombout;	}/*** 15.10.1998 ARG - ESIL 0761 part fix** RIO has it's own CTSFLOW and RTSFLOW flags in 'Config' in the port structure,** we need to make sure that the flags are clear when the port is opened.*/	/* Uh? Suppose I turn these on and then another process opens	   the port again? The flags get cleared! Not good. -- REW */	if ( !(PortP->State & (RIO_LOPEN | RIO_MOPEN)) ) {		PortP->Config &= ~(RIO_CTSFLOW|RIO_RTSFLOW);	}	if (!(PortP->firstOpen)) {	/* First time ? */		rio_dprintk (RIO_DEBUG_TTY, "First open for this port\n");			PortP->firstOpen++;		PortP->CookMode = 0; /* XXX RIOCookMode(tp); */		PortP->InUse = NOT_INUSE;		/* Tentative fix for bug PR27. Didn't work. */		/* PortP->gs.xmit_cnt = 0; */		rio_spin_unlock_irqrestore(&PortP->portSem, flags);#ifdef NEED_THIS		ttyseth(PortP, tp, (struct old_sgttyb *)&default_sg);#endif		/* Someone explain to me why this delay/config is                   here. If I read the docs correctly the "open"                   command piggybacks the parameters immediately. 		   -- REW */		RIOParam(PortP,OPEN,Modem,OK_TO_SLEEP);		/* Open the port */#if 0		/* This delay of 1 second was annoying. I removed it. -- REW */		RIODelay(PortP, HUNDRED_MS*10);		RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);	/* Config the port */#endif		rio_spin_lock_irqsave(&PortP->portSem, flags);		/*		** wait for the port to be not closed.		*/		while ( !(PortP->PortState & PORT_ISOPEN) && !p->RIOHalted ) {			rio_dprintk (RIO_DEBUG_TTY, "Waiting for PORT_ISOPEN-currently %x\n",PortP->PortState);/*** 15.10.1998 ARG - ESIL 0759** (Part) fix for port being trashed when opened whilst RTA "disconnected"** Take out the limited wait - now wait for ever or until user** bangs us out.**			if (repeat_this -- <= 0) {				rio_dprint(RIO_DEBUG_TTY, ("Waiting for open to finish timed out.\n"));				RIOPreemptiveCmd(p, PortP, FCLOSE ); 				rio_spin_unlock_irqrestore(&PortP->portSem, flags);				return -EINTR;			}***/			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {				rio_dprintk (RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n");				RIOPreemptiveCmd(p, PortP, FCLOSE );				func_exit ();				return -EINTR;			}			rio_spin_lock_irqsave(&PortP->portSem, flags);		}		if ( p->RIOHalted ) {		  retval = -EIO;bombout:		  /* 			RIOClearUp( PortP ); */			rio_spin_unlock_irqrestore(&PortP->portSem, flags);			return retval;		}		rio_dprintk (RIO_DEBUG_TTY, "PORT_ISOPEN found\n");	}#ifdef MODEM_SUPPORT 	if (Modem) {		rio_dprintk (RIO_DEBUG_TTY, "Modem - test for carrier\n");		/*		** ACTION		** insert test for carrier here. -- ???		** I already see that test here. What's the deal? -- REW		*/		if ((PortP->gs.tty->termios->c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD))		{			rio_dprintk (RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort);			/*			tp->tm.c_state |= CARR_ON;			wakeup((caddr_t) &tp->tm.c_canq);			*/			PortP->State |= RIO_CARR_ON;			wake_up_interruptible (&PortP->gs.open_wait);		}		else /* no carrier - wait for DCD */		{		  /*			while (!(PortP->gs.tty->termios->c_state & CARR_ON) && 			       !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted )		  */			while (!(PortP->State & RIO_CARR_ON) && 			       !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted ) {				rio_dprintk (RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n",SysPort);				/*				PortP->gs.tty->termios->c_state |= WOPEN;				*/				PortP->State |= RIO_WOPEN;				rio_spin_unlock_irqrestore(&PortP->portSem, flags);				if (RIODelay (PortP, HUNDRED_MS) == RIO_FAIL)#if 0				if ( sleep((caddr_t)&tp->tm.c_canqo, TTIPRI|PCATCH))#endif				{					/*

⌨️ 快捷键说明

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