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

📄 rioparam.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** -----------------------------------------------------------------------------****  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		: rioparam.c**	SID		: 1.3**	Last Modified	: 11/6/98 10:33:45**	Retrieved	: 11/6/98 10:33:50****  ident @(#)rioparam.c	1.3**** -----------------------------------------------------------------------------*/#ifdef SCCS_LABELSstatic char *_rioparam_c_sccs_ = "@(#)rioparam.c	1.3";#endif#include <linux/module.h>#include <linux/slab.h>#include <linux/errno.h>#include <linux/tty.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"/*** The Scam, based on email from jeremyr@bugs.specialix.co.uk....**** To send a command on a particular port, you put a packet with the** command bit set onto the port. The command bit is in the len field,** and gets ORed in with the actual byte count.**** When you send a packet with the command bit set, then the first** data byte ( data[0] ) is interpretted as the command to execute.** It also governs what data structure overlay should accompany the packet.** Commands are defined in cirrus/cirrus.h**** If you want the command to pre-emt data already on the queue for the** port, set the pre-emptive bit in conjunction with the command bit.** It is not defined what will happen if you set the preemptive bit** on a packet that is NOT a command.**** Pre-emptive commands should be queued at the head of the queue using** add_start(), whereas normal commands and data are enqueued using** add_end().**** Most commands do not use the remaining bytes in the data array. The** exceptions are OPEN MOPEN and CONFIG. (NB. As with the SI CONFIG and** OPEN are currently analagous). With these three commands the following** 11 data bytes are all used to pass config information such as baud rate etc.** The fields are also defined in cirrus.h. Some contain straightforward** information such as the transmit XON character. Two contain the transmit and** receive baud rates respectively. For most baud rates there is a direct** mapping between the rates defined in <sys/termio.h> and the byte in the** packet. There are additional (non UNIX-standard) rates defined in** /u/dos/rio/cirrus/h/brates.h.**** The rest of the data fields contain approximations to the Cirrus registers** that are used to program number of bits etc. Each registers bit fields is** defined in cirrus.h.** ** NB. Only use those bits that are defined as being driver specific** or common to the RTA and the driver.** ** All commands going from RTA->Host will be dealt with by the Host code - you** will never see them. As with the SI there will be three fields to look out** for in each phb (not yet defined - needs defining a.s.a.p).** ** modem_status	- current state of handshake pins.**** port_status	 - current port status - equivalent to hi_stat for SI, indicates** if port is IDLE_OPEN, IDLE_CLOSED etc.**** break_status	- bit X set if break has been received.** ** Happy hacking.** *//* ** RIOParam is used to open or configure a port. You pass it a PortP,** which will have a tty struct attached to it. You also pass a command,** either OPEN or CONFIG. The port's setup is taken from the t_ fields** of the tty struct inside the PortP, and the port is either opened** or re-configured. You must also tell RIOParam if the device is a modem** device or not (i.e. top bit of minor number set or clear - take special** care when deciding on this!).** RIOParam neither flushes nor waits for drain, and is NOT preemptive.**** RIOParam assumes it will be called at splrio(), and also assumes** that CookMode is set correctly in the port structure.**** NB. for MPX**	tty lock must NOT have been previously acquired.*/intRIOParam(PortP, cmd, Modem, SleepFlag)struct Port *PortP;int cmd;int Modem;int SleepFlag; {	register struct tty_struct *TtyP;	int	retval;	register struct phb_param *phb_param_ptr;	PKT *PacketP;	int res;	uchar Cor1=0, Cor2=0, Cor4=0, Cor5=0;	uchar TxXon=0, TxXoff=0, RxXon=0, RxXoff=0;	uchar LNext=0, TxBaud=0, RxBaud=0;	int		retries = 0xff;	unsigned long flags;	func_enter ();	TtyP = PortP->gs.tty;	rio_dprintk (RIO_DEBUG_PARAM, "RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n",	    PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP);	if (!TtyP) {	  rio_dprintk (RIO_DEBUG_PARAM, "Can't call rioparam with null tty.\n");	  func_exit ();	  return RIO_FAIL;	}	rio_spin_lock_irqsave(&PortP->portSem, flags );	if (cmd == OPEN) {		/*		** If the port is set to store or lock the parameters, and it is		** paramed with OPEN, we want to restore the saved port termio, but		** only if StoredTermio has been saved, i.e. NOT 1st open after reboot.		*/#if 0		if (PortP->FirstOpen) {			PortP->StoredTty.iflag = TtyP->tm.c_iflag;			PortP->StoredTty.oflag = TtyP->tm.c_oflag;			PortP->StoredTty.cflag = TtyP->tm.c_cflag;			PortP->StoredTty.lflag = TtyP->tm.c_lflag;			PortP->StoredTty.line = TtyP->tm.c_line;			for (i = 0; i < NCC + 5; i++)				PortP->StoredTty.cc[i] = TtyP->tm.c_cc[i];			PortP->FirstOpen = 0;		}		else if (PortP->Store || PortP->Lock) {			rio_dprintk (RIO_DEBUG_PARAM, "OPEN: Restoring stored/locked params\n");			TtyP->tm.c_iflag = PortP->StoredTty.iflag;			TtyP->tm.c_oflag = PortP->StoredTty.oflag;			TtyP->tm.c_cflag = PortP->StoredTty.cflag;			TtyP->tm.c_lflag = PortP->StoredTty.lflag;			TtyP->tm.c_line = PortP->StoredTty.line;			for (i = 0; i < NCC + 5; i++)				TtyP->tm.c_cc[i] = PortP->StoredTty.cc[i];		}#endif	}	/*	** wait for space	*/	while ( !(res=can_add_transmit(&PacketP,PortP)) || 			(PortP->InUse != NOT_INUSE) ) {		if (retries -- <= 0) {			break;		}		if ( PortP->InUse != NOT_INUSE ) {			rio_dprintk (RIO_DEBUG_PARAM, "Port IN_USE for pre-emptive command\n");		}		if ( !res ) {			rio_dprintk (RIO_DEBUG_PARAM, "Port has no space on transmit queue\n");		}		if ( SleepFlag != OK_TO_SLEEP ) {			rio_spin_unlock_irqrestore( &PortP->portSem, flags);			func_exit();						return RIO_FAIL;		}		rio_dprintk (RIO_DEBUG_PARAM, "wait for can_add_transmit\n");		rio_spin_unlock_irqrestore( &PortP->portSem, flags);		retval = RIODelay(PortP, HUNDRED_MS);		rio_spin_lock_irqsave( &PortP->portSem, flags);		if (retval == RIO_FAIL) {			rio_dprintk (RIO_DEBUG_PARAM, "wait for can_add_transmit broken by signal\n");			rio_spin_unlock_irqrestore( &PortP->portSem, flags);			pseterr(EINTR);			func_exit();			return RIO_FAIL;		}		if ( PortP->State & RIO_DELETED ) {			rio_spin_unlock_irqrestore( &PortP->portSem, flags);			func_exit ();			return RIO_SUCCESS;		}	}	if (!res) {		rio_spin_unlock_irqrestore( &PortP->portSem, flags);		func_exit ();		return RIO_FAIL;	}	rio_dprintk (RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n",res);	rio_dprintk (RIO_DEBUG_PARAM, "Packet is 0x%x\n",(int) PacketP);	phb_param_ptr = (struct phb_param *)PacketP->data;#if 0	/*	** COR 1	*/	if ( TtyP->tm.c_iflag & INPCK ) {		rio_dprintk (RIO_DEBUG_PARAM, "Parity checking on input enabled\n");		Cor1 |= COR1_INPCK;	}#endif	switch ( TtyP->termios->c_cflag & CSIZE ) {		case CS5:		{			rio_dprintk (RIO_DEBUG_PARAM, "5 bit data\n");			Cor1 |= COR1_5BITS;			break;		}		case CS6:		{			rio_dprintk (RIO_DEBUG_PARAM, "6 bit data\n");			Cor1 |= COR1_6BITS;			break;		}		case CS7:		{			rio_dprintk (RIO_DEBUG_PARAM, "7 bit data\n");			Cor1 |= COR1_7BITS;			break;		}		case CS8:		{			rio_dprintk (RIO_DEBUG_PARAM, "8 bit data\n");			Cor1 |= COR1_8BITS;			break;		}	}	if ( TtyP->termios->c_cflag & CSTOPB ) {		rio_dprintk (RIO_DEBUG_PARAM, "2 stop bits\n");		Cor1 |= COR1_2STOP;	}	else {		rio_dprintk (RIO_DEBUG_PARAM, "1 stop bit\n");		Cor1 |= COR1_1STOP;	}	if ( TtyP->termios->c_cflag & PARENB ) {		rio_dprintk (RIO_DEBUG_PARAM, "Enable parity\n");		Cor1 |= COR1_NORMAL;	}	else {		rio_dprintk (RIO_DEBUG_PARAM, "Disable parity\n");		Cor1 |= COR1_NOP;	}	if ( TtyP->termios->c_cflag & PARODD ) {		rio_dprintk (RIO_DEBUG_PARAM, "Odd parity\n");		Cor1 |= COR1_ODD;	}	else {		rio_dprintk (RIO_DEBUG_PARAM, "Even parity\n");		Cor1 |= COR1_EVEN; 	}	/*	** COR 2	*/	if ( TtyP->termios->c_iflag & IXON ) {		rio_dprintk (RIO_DEBUG_PARAM, "Enable start/stop output control\n");		Cor2 |= COR2_IXON;	}	else {		if ( PortP->Config & RIO_IXON ) {			rio_dprintk (RIO_DEBUG_PARAM, "Force enable start/stop output control\n");			Cor2 |= COR2_IXON;		}		else			rio_dprintk (RIO_DEBUG_PARAM, "IXON has been disabled.\n");	}	if (TtyP->termios->c_iflag & IXANY) {		if ( PortP->Config & RIO_IXANY ) {			rio_dprintk (RIO_DEBUG_PARAM, "Enable any key to restart output\n");			Cor2 |= COR2_IXANY;		}		else			rio_dprintk (RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n");	}	if ( TtyP->termios->c_iflag & IXOFF ) {		rio_dprintk (RIO_DEBUG_PARAM, "Enable start/stop input control 2\n");		Cor2 |= COR2_IXOFF;	}	if ( TtyP->termios->c_cflag & HUPCL ) {

⌨️ 快捷键说明

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