riotty.c
来自「linux2.6.16版本」· C语言 代码 · 共 747 行 · 第 1/2 页
C
747 行
/*** -----------------------------------------------------------------------------**** 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"static void RIOClearUp(struct Port *PortP);int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg);extern 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;int riotopen(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. */ /* 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"); rio_spin_lock_irqsave(&PortP->portSem, flags); if (p->RIOHalted) { goto bombout; } /* ** 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 */ 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); */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?