PageRenderTime 126ms CodeModel.GetById 19ms app.highlight 92ms RepoModel.GetById 1ms app.codeStats 1ms

/drivers/char/mxser.c

https://bitbucket.org/evzijst/gittest
C | 3170 lines | 2345 code | 422 blank | 403 comment | 619 complexity | 5f4faaf6c629796ead1d3f62fb60ccd8 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2 *          mxser.c  -- MOXA Smartio/Industio family multiport serial driver.
   3 *
   4 *      Copyright (C) 1999-2001  Moxa Technologies (support@moxa.com.tw).
   5 *
   6 *      This code is loosely based on the Linux serial driver, written by
   7 *      Linus Torvalds, Theodore T'so and others.
   8 *
   9 *      This program is free software; you can redistribute it and/or modify
  10 *      it under the terms of the GNU General Public License as published by
  11 *      the Free Software Foundation; either version 2 of the License, or
  12*      (at your option) any later version.
  13 *
  14 *      This program is distributed in the hope that it will be useful,
  15 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 *      GNU General Public License for more details.
  18 *
  19 *      You should have received a copy of the GNU General Public License
  20 *      along with this program; if not, write to the Free Software
  21 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22 *
  23 *	Original release	10/26/00
  24 *
  25 *	02/06/01	Support MOXA Industio family boards.
  26 *	02/06/01	Support TIOCGICOUNT.
  27 *	02/06/01	Fix the problem for connecting to serial mouse.
  28 *	02/06/01	Fix the problem for H/W flow control.
  29 *	02/06/01	Fix the compling warning when CONFIG_PCI
  30 *			don't be defined.
  31 *
  32 *	Fed through a cleanup, indent and remove of non 2.6 code by Alan Cox
  33 *	<alan@redhat.com>. The original 1.8 code is available on www.moxa.com.
  34 *	- Fixed x86_64 cleanness
  35 *	- Fixed sleep with spinlock held in mxser_send_break
  36 */
  37
  38
  39#include <linux/config.h>
  40#include <linux/module.h>
  41#include <linux/version.h>
  42#include <linux/autoconf.h>
  43#include <linux/errno.h>
  44#include <linux/signal.h>
  45#include <linux/sched.h>
  46#include <linux/timer.h>
  47#include <linux/interrupt.h>
  48#include <linux/tty.h>
  49#include <linux/tty_flip.h>
  50#include <linux/serial.h>
  51#include <linux/serial_reg.h>
  52#include <linux/major.h>
  53#include <linux/string.h>
  54#include <linux/fcntl.h>
  55#include <linux/ptrace.h>
  56#include <linux/gfp.h>
  57#include <linux/ioport.h>
  58#include <linux/mm.h>
  59#include <linux/smp_lock.h>
  60#include <linux/delay.h>
  61#include <linux/pci.h>
  62
  63#include <asm/system.h>
  64#include <asm/io.h>
  65#include <asm/irq.h>
  66#include <asm/segment.h>
  67#include <asm/bitops.h>
  68#include <asm/uaccess.h>
  69
  70#include "mxser.h"
  71
  72#define	MXSER_VERSION	"1.8"
  73#define	MXSERMAJOR	 174
  74#define	MXSERCUMAJOR	 175
  75
  76#define	MXSER_EVENT_TXLOW	 1
  77#define	MXSER_EVENT_HANGUP	 2
  78
  79#define MXSER_BOARDS		4	/* Max. boards */
  80#define MXSER_PORTS		32	/* Max. ports */
  81#define MXSER_PORTS_PER_BOARD	8	/* Max. ports per board */
  82#define MXSER_ISR_PASS_LIMIT	256
  83
  84#define	MXSER_ERR_IOADDR	-1
  85#define	MXSER_ERR_IRQ		-2
  86#define	MXSER_ERR_IRQ_CONFLIT	-3
  87#define	MXSER_ERR_VECTOR	-4
  88
  89#define SERIAL_TYPE_NORMAL	1
  90#define SERIAL_TYPE_CALLOUT	2
  91
  92#define WAKEUP_CHARS		256
  93
  94#define UART_MCR_AFE		0x20
  95#define UART_LSR_SPECIAL	0x1E
  96
  97#define RELEVANT_IFLAG(iflag)	(iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|IXON|IXOFF))
  98
  99#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
 100
 101#define C168_ASIC_ID    1
 102#define C104_ASIC_ID    2
 103#define C102_ASIC_ID	0xB
 104#define CI132_ASIC_ID	4
 105#define CI134_ASIC_ID	3
 106#define CI104J_ASIC_ID  5
 107
 108enum {
 109	MXSER_BOARD_C168_ISA = 1,
 110	MXSER_BOARD_C104_ISA,
 111	MXSER_BOARD_CI104J,
 112	MXSER_BOARD_C168_PCI,
 113	MXSER_BOARD_C104_PCI,
 114	MXSER_BOARD_C102_ISA,
 115	MXSER_BOARD_CI132,
 116	MXSER_BOARD_CI134,
 117	MXSER_BOARD_CP132,
 118	MXSER_BOARD_CP114,
 119	MXSER_BOARD_CT114,
 120	MXSER_BOARD_CP102,
 121	MXSER_BOARD_CP104U,
 122	MXSER_BOARD_CP168U,
 123	MXSER_BOARD_CP132U,
 124	MXSER_BOARD_CP134U,
 125	MXSER_BOARD_CP104JU,
 126	MXSER_BOARD_RC7000,
 127	MXSER_BOARD_CP118U,
 128	MXSER_BOARD_CP102UL,
 129	MXSER_BOARD_CP102U,
 130};
 131
 132static char *mxser_brdname[] = {
 133	"C168 series",
 134	"C104 series",
 135	"CI-104J series",
 136	"C168H/PCI series",
 137	"C104H/PCI series",
 138	"C102 series",
 139	"CI-132 series",
 140	"CI-134 series",
 141	"CP-132 series",
 142	"CP-114 series",
 143	"CT-114 series",
 144	"CP-102 series",
 145	"CP-104U series",
 146	"CP-168U series",
 147	"CP-132U series",
 148	"CP-134U series",
 149	"CP-104JU series",
 150	"Moxa UC7000 Serial",
 151	"CP-118U series",
 152	"CP-102UL series",
 153	"CP-102U series",
 154};
 155
 156static int mxser_numports[] = {
 157	8,			// C168-ISA
 158	4,			// C104-ISA
 159	4,			// CI104J
 160	8,			// C168-PCI
 161	4,			// C104-PCI
 162	2,			// C102-ISA
 163	2,			// CI132
 164	4,			// CI134
 165	2,			// CP132
 166	4,			// CP114
 167	4,			// CT114
 168	2,			// CP102
 169	4,			// CP104U
 170	8,			// CP168U
 171	2,			// CP132U
 172	4,			// CP134U
 173	4,			// CP104JU
 174	8,			// RC7000
 175	8,			// CP118U 
 176	2,			// CP102UL 
 177	2,			// CP102U
 178};
 179
 180#define UART_TYPE_NUM	2
 181
 182static const unsigned int Gmoxa_uart_id[UART_TYPE_NUM] = {
 183	MOXA_MUST_MU150_HWID,
 184	MOXA_MUST_MU860_HWID
 185};
 186
 187// This is only for PCI
 188#define UART_INFO_NUM	3
 189struct mxpciuart_info {
 190	int type;
 191	int tx_fifo;
 192	int rx_fifo;
 193	int xmit_fifo_size;
 194	int rx_high_water;
 195	int rx_trigger;
 196	int rx_low_water;
 197	long max_baud;
 198};
 199
 200static const struct mxpciuart_info Gpci_uart_info[UART_INFO_NUM] = {
 201	{MOXA_OTHER_UART, 16, 16, 16, 14, 14, 1, 921600L},
 202	{MOXA_MUST_MU150_HWID, 64, 64, 64, 48, 48, 16, 230400L},
 203	{MOXA_MUST_MU860_HWID, 128, 128, 128, 96, 96, 32, 921600L}
 204};
 205
 206
 207#ifdef CONFIG_PCI
 208
 209static struct pci_device_id mxser_pcibrds[] = {
 210	{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_C168_PCI},
 211	{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_C104_PCI},
 212	{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP132},
 213	{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP114},
 214	{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CT114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CT114},
 215	{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP102},
 216	{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP104U},
 217	{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP168U},
 218	{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP132U},
 219	{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP134U},
 220	{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104JU, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP104JU},
 221	{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_RC7000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_RC7000},
 222	{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP118U},
 223	{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102UL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP102UL},
 224	{PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102U, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MXSER_BOARD_CP102U},
 225	{0}
 226};
 227
 228MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
 229
 230
 231#endif
 232
 233typedef struct _moxa_pci_info {
 234	unsigned short busNum;
 235	unsigned short devNum;
 236	struct pci_dev *pdev;	// add by Victor Yu. 06-23-2003
 237} moxa_pci_info;
 238
 239static int ioaddr[MXSER_BOARDS] = { 0, 0, 0, 0 };
 240static int ttymajor = MXSERMAJOR;
 241static int calloutmajor = MXSERCUMAJOR;
 242static int verbose = 0;
 243
 244/* Variables for insmod */
 245
 246MODULE_AUTHOR("Casper Yang");
 247MODULE_DESCRIPTION("MOXA Smartio/Industio Family Multiport Board Device Driver");
 248MODULE_PARM(ioaddr, "1-4i");
 249MODULE_PARM(ttymajor, "i");
 250MODULE_PARM(calloutmajor, "i");
 251MODULE_PARM(verbose, "i");
 252MODULE_LICENSE("GPL");
 253
 254struct mxser_log {
 255	int tick;
 256	unsigned long rxcnt[MXSER_PORTS];
 257	unsigned long txcnt[MXSER_PORTS];
 258};
 259
 260
 261struct mxser_mon {
 262	unsigned long rxcnt;
 263	unsigned long txcnt;
 264	unsigned long up_rxcnt;
 265	unsigned long up_txcnt;
 266	int modem_status;
 267	unsigned char hold_reason;
 268};
 269
 270struct mxser_mon_ext {
 271	unsigned long rx_cnt[32];
 272	unsigned long tx_cnt[32];
 273	unsigned long up_rxcnt[32];
 274	unsigned long up_txcnt[32];
 275	int modem_status[32];
 276
 277	long baudrate[32];
 278	int databits[32];
 279	int stopbits[32];
 280	int parity[32];
 281	int flowctrl[32];
 282	int fifo[32];
 283	int iftype[32];
 284};
 285struct mxser_hwconf {
 286	int board_type;
 287	int ports;
 288	int irq;
 289	int vector;
 290	int vector_mask;
 291	int uart_type;
 292	int ioaddr[MXSER_PORTS_PER_BOARD];
 293	int baud_base[MXSER_PORTS_PER_BOARD];
 294	moxa_pci_info pciInfo;
 295	int IsMoxaMustChipFlag;	// add by Victor Yu. 08-30-2002
 296	int MaxCanSetBaudRate[MXSER_PORTS_PER_BOARD];	// add by Victor Yu. 09-04-2002
 297	int opmode_ioaddr[MXSER_PORTS_PER_BOARD];	// add by Victor Yu. 01-05-2004
 298};
 299
 300struct mxser_struct {
 301	int port;
 302	int base;		/* port base address */
 303	int irq;		/* port using irq no. */
 304	int vector;		/* port irq vector */
 305	int vectormask;		/* port vector mask */
 306	int rx_high_water;
 307	int rx_trigger;		/* Rx fifo trigger level */
 308	int rx_low_water;
 309	int baud_base;		/* max. speed */
 310	int flags;		/* defined in tty.h */
 311	int type;		/* UART type */
 312	struct tty_struct *tty;
 313	int read_status_mask;
 314	int ignore_status_mask;
 315	int xmit_fifo_size;
 316	int custom_divisor;
 317	int x_char;		/* xon/xoff character */
 318	int close_delay;
 319	unsigned short closing_wait;
 320	int IER;		/* Interrupt Enable Register */
 321	int MCR;		/* Modem control register */
 322	unsigned long event;
 323	int count;		/* # of fd on device */
 324	int blocked_open;	/* # of blocked opens */
 325	long session;		/* Session of opening process */
 326	long pgrp;		/* pgrp of opening process */
 327	unsigned char *xmit_buf;
 328	int xmit_head;
 329	int xmit_tail;
 330	int xmit_cnt;
 331	struct work_struct tqueue;
 332	struct termios normal_termios;
 333	struct termios callout_termios;
 334	wait_queue_head_t open_wait;
 335	wait_queue_head_t close_wait;
 336	wait_queue_head_t delta_msr_wait;
 337	struct async_icount icount;	/* kernel counters for the 4 input interrupts */
 338	int timeout;
 339	int IsMoxaMustChipFlag;	// add by Victor Yu. 08-30-2002
 340	int MaxCanSetBaudRate;	// add by Victor Yu. 09-04-2002
 341	int opmode_ioaddr;	// add by Victor Yu. 01-05-2004
 342	unsigned char stop_rx;
 343	unsigned char ldisc_stop_rx;
 344	long realbaud;
 345	struct mxser_mon mon_data;
 346	unsigned char err_shadow;
 347	spinlock_t slock;
 348};
 349
 350
 351struct mxser_mstatus {
 352	tcflag_t cflag;
 353	int cts;
 354	int dsr;
 355	int ri;
 356	int dcd;
 357};
 358
 359static struct mxser_mstatus GMStatus[MXSER_PORTS];
 360
 361static int mxserBoardCAP[MXSER_BOARDS] = {
 362	0, 0, 0, 0
 363	    /*  0x180, 0x280, 0x200, 0x320   */
 364};
 365
 366static struct tty_driver *mxvar_sdriver;
 367static struct mxser_struct mxvar_table[MXSER_PORTS];
 368static struct tty_struct *mxvar_tty[MXSER_PORTS + 1];
 369static struct termios *mxvar_termios[MXSER_PORTS + 1];
 370static struct termios *mxvar_termios_locked[MXSER_PORTS + 1];
 371static struct mxser_log mxvar_log;
 372static int mxvar_diagflag;
 373static unsigned char mxser_msr[MXSER_PORTS + 1];
 374static struct mxser_mon_ext mon_data_ext;
 375static int mxser_set_baud_method[MXSER_PORTS + 1];
 376static spinlock_t gm_lock;
 377
 378/*
 379 * This is used to figure out the divisor speeds and the timeouts
 380 */
 381
 382static struct mxser_hwconf mxsercfg[MXSER_BOARDS];
 383
 384/*
 385 * static functions:
 386 */
 387
 388static void mxser_getcfg(int board, struct mxser_hwconf *hwconf);
 389static int mxser_init(void);
 390
 391//static void   mxser_poll(unsigned long);
 392static int mxser_get_ISA_conf(int, struct mxser_hwconf *);
 393static int mxser_get_PCI_conf(int, int, int, struct mxser_hwconf *);
 394static void mxser_do_softint(void *);
 395static int mxser_open(struct tty_struct *, struct file *);
 396static void mxser_close(struct tty_struct *, struct file *);
 397static int mxser_write(struct tty_struct *, const unsigned char *, int);
 398static int mxser_write_room(struct tty_struct *);
 399static void mxser_flush_buffer(struct tty_struct *);
 400static int mxser_chars_in_buffer(struct tty_struct *);
 401static void mxser_flush_chars(struct tty_struct *);
 402static void mxser_put_char(struct tty_struct *, unsigned char);
 403static int mxser_ioctl(struct tty_struct *, struct file *, uint, ulong);
 404static int mxser_ioctl_special(unsigned int, void __user *);
 405static void mxser_throttle(struct tty_struct *);
 406static void mxser_unthrottle(struct tty_struct *);
 407static void mxser_set_termios(struct tty_struct *, struct termios *);
 408static void mxser_stop(struct tty_struct *);
 409static void mxser_start(struct tty_struct *);
 410static void mxser_hangup(struct tty_struct *);
 411static void mxser_rs_break(struct tty_struct *, int);
 412static irqreturn_t mxser_interrupt(int, void *, struct pt_regs *);
 413static void mxser_receive_chars(struct mxser_struct *, int *);
 414static void mxser_transmit_chars(struct mxser_struct *);
 415static void mxser_check_modem_status(struct mxser_struct *, int);
 416static int mxser_block_til_ready(struct tty_struct *, struct file *, struct mxser_struct *);
 417static int mxser_startup(struct mxser_struct *);
 418static void mxser_shutdown(struct mxser_struct *);
 419static int mxser_change_speed(struct mxser_struct *, struct termios *old_termios);
 420static int mxser_get_serial_info(struct mxser_struct *, struct serial_struct __user *);
 421static int mxser_set_serial_info(struct mxser_struct *, struct serial_struct __user *);
 422static int mxser_get_lsr_info(struct mxser_struct *, unsigned int __user *);
 423static void mxser_send_break(struct mxser_struct *, int);
 424static int mxser_tiocmget(struct tty_struct *, struct file *);
 425static int mxser_tiocmset(struct tty_struct *, struct file *, unsigned int, unsigned int);
 426static int mxser_set_baud(struct mxser_struct *info, long newspd);
 427static void mxser_wait_until_sent(struct tty_struct *tty, int timeout);
 428
 429static void mxser_startrx(struct tty_struct *tty);
 430static void mxser_stoprx(struct tty_struct *tty);
 431
 432
 433static int CheckIsMoxaMust(int io)
 434{
 435	u8 oldmcr, hwid;
 436	int i;
 437
 438	outb(0, io + UART_LCR);
 439	DISABLE_MOXA_MUST_ENCHANCE_MODE(io);
 440	oldmcr = inb(io + UART_MCR);
 441	outb(0, io + UART_MCR);
 442	SET_MOXA_MUST_XON1_VALUE(io, 0x11);
 443	if ((hwid = inb(io + UART_MCR)) != 0) {
 444		outb(oldmcr, io + UART_MCR);
 445		return (MOXA_OTHER_UART);
 446	}
 447
 448	GET_MOXA_MUST_HARDWARE_ID(io, &hwid);
 449	for (i = 0; i < UART_TYPE_NUM; i++) {
 450		if (hwid == Gmoxa_uart_id[i])
 451			return (int) hwid;
 452	}
 453	return MOXA_OTHER_UART;
 454}
 455
 456// above is modified by Victor Yu. 08-15-2002
 457
 458static struct tty_operations mxser_ops = {
 459	.open = mxser_open,
 460	.close = mxser_close,
 461	.write = mxser_write,
 462	.put_char = mxser_put_char,
 463	.flush_chars = mxser_flush_chars,
 464	.write_room = mxser_write_room,
 465	.chars_in_buffer = mxser_chars_in_buffer,
 466	.flush_buffer = mxser_flush_buffer,
 467	.ioctl = mxser_ioctl,
 468	.throttle = mxser_throttle,
 469	.unthrottle = mxser_unthrottle,
 470	.set_termios = mxser_set_termios,
 471	.stop = mxser_stop,
 472	.start = mxser_start,
 473	.hangup = mxser_hangup,
 474	.tiocmget = mxser_tiocmget,
 475	.tiocmset = mxser_tiocmset,
 476};
 477
 478/*
 479 * The MOXA Smartio/Industio serial driver boot-time initialization code!
 480 */
 481
 482static int __init mxser_module_init(void)
 483{
 484	int ret;
 485
 486	if (verbose)
 487		printk(KERN_DEBUG "Loading module mxser ...\n");
 488	ret = mxser_init();
 489	if (verbose)
 490		printk(KERN_DEBUG "Done.\n");
 491	return ret;
 492}
 493
 494static void __exit mxser_module_exit(void)
 495{
 496	int i, err = 0;
 497
 498	if (verbose)
 499		printk(KERN_DEBUG "Unloading module mxser ...\n");
 500
 501	if ((err |= tty_unregister_driver(mxvar_sdriver)))
 502		printk(KERN_ERR "Couldn't unregister MOXA Smartio/Industio family serial driver\n");
 503
 504	for (i = 0; i < MXSER_BOARDS; i++) {
 505		struct pci_dev *pdev;
 506
 507		if (mxsercfg[i].board_type == -1)
 508			continue;
 509		else {
 510			pdev = mxsercfg[i].pciInfo.pdev;
 511			free_irq(mxsercfg[i].irq, &mxvar_table[i * MXSER_PORTS_PER_BOARD]);
 512			if (pdev != NULL) {	//PCI
 513				release_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2));
 514				release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3));
 515			} else {
 516				release_region(mxsercfg[i].ioaddr[0], 8 * mxsercfg[i].ports);
 517				release_region(mxsercfg[i].vector, 1);
 518			}
 519		}
 520	}
 521	if (verbose)
 522		printk(KERN_DEBUG "Done.\n");
 523
 524}
 525
 526static void process_txrx_fifo(struct mxser_struct *info)
 527{
 528	int i;
 529
 530	if ((info->type == PORT_16450) || (info->type == PORT_8250)) {
 531		info->rx_trigger = 1;
 532		info->rx_high_water = 1;
 533		info->rx_low_water = 1;
 534		info->xmit_fifo_size = 1;
 535	} else {
 536		for (i = 0; i < UART_INFO_NUM; i++) {
 537			if (info->IsMoxaMustChipFlag == Gpci_uart_info[i].type) {
 538				info->rx_trigger = Gpci_uart_info[i].rx_trigger;
 539				info->rx_low_water = Gpci_uart_info[i].rx_low_water;
 540				info->rx_high_water = Gpci_uart_info[i].rx_high_water;
 541				info->xmit_fifo_size = Gpci_uart_info[i].xmit_fifo_size;
 542				break;
 543			}
 544		}
 545	}
 546}
 547
 548static int mxser_initbrd(int board, struct mxser_hwconf *hwconf)
 549{
 550	struct mxser_struct *info;
 551	int retval;
 552	int i, n;
 553
 554	n = board * MXSER_PORTS_PER_BOARD;
 555	info = &mxvar_table[n];
 556	/*if (verbose) */  {
 557		printk(KERN_DEBUG "        ttyM%d - ttyM%d ", n, n + hwconf->ports - 1);
 558		printk(" max. baud rate = %d bps.\n", hwconf->MaxCanSetBaudRate[0]);
 559	}
 560
 561	for (i = 0; i < hwconf->ports; i++, n++, info++) {
 562		info->port = n;
 563		info->base = hwconf->ioaddr[i];
 564		info->irq = hwconf->irq;
 565		info->vector = hwconf->vector;
 566		info->vectormask = hwconf->vector_mask;
 567		info->opmode_ioaddr = hwconf->opmode_ioaddr[i];	// add by Victor Yu. 01-05-2004
 568		info->stop_rx = 0;
 569		info->ldisc_stop_rx = 0;
 570
 571		info->IsMoxaMustChipFlag = hwconf->IsMoxaMustChipFlag;
 572		//Enhance mode enabled here
 573		if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) {
 574			ENABLE_MOXA_MUST_ENCHANCE_MODE(info->base);
 575		}
 576
 577		info->flags = ASYNC_SHARE_IRQ;
 578		info->type = hwconf->uart_type;
 579		info->baud_base = hwconf->baud_base[i];
 580
 581		info->MaxCanSetBaudRate = hwconf->MaxCanSetBaudRate[i];
 582
 583		process_txrx_fifo(info);
 584
 585
 586		info->custom_divisor = hwconf->baud_base[i] * 16;
 587		info->close_delay = 5 * HZ / 10;
 588		info->closing_wait = 30 * HZ;
 589		INIT_WORK(&info->tqueue, mxser_do_softint, info);
 590		info->normal_termios = mxvar_sdriver->init_termios;
 591		init_waitqueue_head(&info->open_wait);
 592		init_waitqueue_head(&info->close_wait);
 593		init_waitqueue_head(&info->delta_msr_wait);
 594		memset(&info->mon_data, 0, sizeof(struct mxser_mon));
 595		info->err_shadow = 0;
 596		spin_lock_init(&info->slock);
 597	}
 598	/*
 599	 * Allocate the IRQ if necessary
 600	 */
 601
 602
 603	/* before set INT ISR, disable all int */
 604	for (i = 0; i < hwconf->ports; i++) {
 605		outb(inb(hwconf->ioaddr[i] + UART_IER) & 0xf0, hwconf->ioaddr[i] + UART_IER);
 606	}
 607
 608	n = board * MXSER_PORTS_PER_BOARD;
 609	info = &mxvar_table[n];
 610
 611	retval = request_irq(hwconf->irq, mxser_interrupt, IRQ_T(info), "mxser", info);
 612	if (retval) {
 613		printk(KERN_ERR "Board %d: %s", board, mxser_brdname[hwconf->board_type - 1]);
 614		printk("  Request irq fail,IRQ (%d) may be conflit with another device.\n", info->irq);
 615		return retval;
 616	}
 617	return 0;
 618}
 619
 620
 621static void mxser_getcfg(int board, struct mxser_hwconf *hwconf)
 622{
 623	mxsercfg[board] = *hwconf;
 624}
 625
 626#ifdef CONFIG_PCI
 627static int mxser_get_PCI_conf(int busnum, int devnum, int board_type, struct mxser_hwconf *hwconf)
 628{
 629	int i, j;
 630//      unsigned int    val;
 631	unsigned int ioaddress;
 632	struct pci_dev *pdev = hwconf->pciInfo.pdev;
 633
 634	//io address
 635	hwconf->board_type = board_type;
 636	hwconf->ports = mxser_numports[board_type - 1];
 637	ioaddress = pci_resource_start(pdev, 2);
 638	request_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2), "mxser(IO)");
 639
 640	for (i = 0; i < hwconf->ports; i++) {
 641		hwconf->ioaddr[i] = ioaddress + 8 * i;
 642	}
 643
 644	//vector
 645	ioaddress = pci_resource_start(pdev, 3);
 646	request_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3), "mxser(vector)");
 647	hwconf->vector = ioaddress;
 648
 649	//irq
 650	hwconf->irq = hwconf->pciInfo.pdev->irq;
 651
 652	hwconf->IsMoxaMustChipFlag = CheckIsMoxaMust(hwconf->ioaddr[0]);
 653	hwconf->uart_type = PORT_16550A;
 654	hwconf->vector_mask = 0;
 655
 656
 657	for (i = 0; i < hwconf->ports; i++) {
 658		for (j = 0; j < UART_INFO_NUM; j++) {
 659			if (Gpci_uart_info[j].type == hwconf->IsMoxaMustChipFlag) {
 660				hwconf->MaxCanSetBaudRate[i] = Gpci_uart_info[j].max_baud;
 661
 662				//exception....CP-102
 663				if (board_type == MXSER_BOARD_CP102)
 664					hwconf->MaxCanSetBaudRate[i] = 921600;
 665				break;
 666			}
 667		}
 668	}
 669
 670	if (hwconf->IsMoxaMustChipFlag == MOXA_MUST_MU860_HWID) {
 671		for (i = 0; i < hwconf->ports; i++) {
 672			if (i < 4)
 673				hwconf->opmode_ioaddr[i] = ioaddress + 4;
 674			else
 675				hwconf->opmode_ioaddr[i] = ioaddress + 0x0c;
 676		}
 677		outb(0, ioaddress + 4);	// default set to RS232 mode
 678		outb(0, ioaddress + 0x0c);	//default set to RS232 mode
 679	}
 680
 681	for (i = 0; i < hwconf->ports; i++) {
 682		hwconf->vector_mask |= (1 << i);
 683		hwconf->baud_base[i] = 921600;
 684	}
 685	return (0);
 686}
 687#endif
 688
 689static int mxser_init(void)
 690{
 691	int i, m, retval, b, n;
 692	int ret1;
 693	struct pci_dev *pdev = NULL;
 694	int index;
 695	unsigned char busnum, devnum;
 696	struct mxser_hwconf hwconf;
 697
 698	mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1);
 699	if (!mxvar_sdriver)
 700		return -ENOMEM;
 701	spin_lock_init(&gm_lock);
 702
 703	for (i = 0; i < MXSER_BOARDS; i++) {
 704		mxsercfg[i].board_type = -1;
 705	}
 706
 707	printk(KERN_INFO "MOXA Smartio/Industio family driver version %s\n", MXSER_VERSION);
 708
 709	/* Initialize the tty_driver structure */
 710	memset(mxvar_sdriver, 0, sizeof(struct tty_driver));
 711	mxvar_sdriver->magic = TTY_DRIVER_MAGIC;
 712	mxvar_sdriver->name = "ttyM";
 713	mxvar_sdriver->major = ttymajor;
 714	mxvar_sdriver->minor_start = 0;
 715	mxvar_sdriver->num = MXSER_PORTS + 1;
 716	mxvar_sdriver->type = TTY_DRIVER_TYPE_SERIAL;
 717	mxvar_sdriver->subtype = SERIAL_TYPE_NORMAL;
 718	mxvar_sdriver->init_termios = tty_std_termios;
 719	mxvar_sdriver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
 720	mxvar_sdriver->flags = TTY_DRIVER_REAL_RAW;
 721	tty_set_operations(mxvar_sdriver, &mxser_ops);
 722	mxvar_sdriver->ttys = mxvar_tty;
 723	mxvar_sdriver->termios = mxvar_termios;
 724	mxvar_sdriver->termios_locked = mxvar_termios_locked;
 725
 726	mxvar_sdriver->open = mxser_open;
 727	mxvar_sdriver->close = mxser_close;
 728	mxvar_sdriver->write = mxser_write;
 729	mxvar_sdriver->put_char = mxser_put_char;
 730	mxvar_sdriver->flush_chars = mxser_flush_chars;
 731	mxvar_sdriver->write_room = mxser_write_room;
 732	mxvar_sdriver->chars_in_buffer = mxser_chars_in_buffer;
 733	mxvar_sdriver->flush_buffer = mxser_flush_buffer;
 734	mxvar_sdriver->ioctl = mxser_ioctl;
 735	mxvar_sdriver->throttle = mxser_throttle;
 736	mxvar_sdriver->unthrottle = mxser_unthrottle;
 737	mxvar_sdriver->set_termios = mxser_set_termios;
 738	mxvar_sdriver->stop = mxser_stop;
 739	mxvar_sdriver->start = mxser_start;
 740	mxvar_sdriver->hangup = mxser_hangup;
 741	mxvar_sdriver->break_ctl = mxser_rs_break;
 742	mxvar_sdriver->wait_until_sent = mxser_wait_until_sent;
 743
 744	mxvar_diagflag = 0;
 745	memset(mxvar_table, 0, MXSER_PORTS * sizeof(struct mxser_struct));
 746	memset(&mxvar_log, 0, sizeof(struct mxser_log));
 747
 748	memset(&mxser_msr, 0, sizeof(unsigned char) * (MXSER_PORTS + 1));
 749	memset(&mon_data_ext, 0, sizeof(struct mxser_mon_ext));
 750	memset(&mxser_set_baud_method, 0, sizeof(int) * (MXSER_PORTS + 1));
 751	memset(&hwconf, 0, sizeof(struct mxser_hwconf));
 752
 753	m = 0;
 754	/* Start finding ISA boards here */
 755	for (b = 0; b < MXSER_BOARDS && m < MXSER_BOARDS; b++) {
 756		int cap;
 757		if (!(cap = mxserBoardCAP[b]))
 758			continue;
 759
 760		retval = mxser_get_ISA_conf(cap, &hwconf);
 761
 762		if (retval != 0)
 763			printk(KERN_INFO "Found MOXA %s board (CAP=0x%x)\n", mxser_brdname[hwconf.board_type - 1], ioaddr[b]);
 764
 765		if (retval <= 0) {
 766			if (retval == MXSER_ERR_IRQ)
 767				printk(KERN_ERR "Invalid interrupt number,board not configured\n");
 768			else if (retval == MXSER_ERR_IRQ_CONFLIT)
 769				printk(KERN_ERR "Invalid interrupt number,board not configured\n");
 770			else if (retval == MXSER_ERR_VECTOR)
 771				printk(KERN_ERR "Invalid interrupt vector,board not configured\n");
 772			else if (retval == MXSER_ERR_IOADDR)
 773				printk(KERN_ERR "Invalid I/O address,board not configured\n");
 774
 775			continue;
 776		}
 777
 778		hwconf.pciInfo.busNum = 0;
 779		hwconf.pciInfo.devNum = 0;
 780		hwconf.pciInfo.pdev = NULL;
 781
 782		mxser_getcfg(m, &hwconf);
 783		//init mxsercfg first, or mxsercfg data is not correct on ISR.
 784		//mxser_initbrd will hook ISR.
 785		if (mxser_initbrd(m, &hwconf) < 0)
 786			continue;
 787
 788
 789		m++;
 790	}
 791
 792	/* Start finding ISA boards from module arg */
 793	for (b = 0; b < MXSER_BOARDS && m < MXSER_BOARDS; b++) {
 794		int cap;
 795		if (!(cap = ioaddr[b]))
 796			continue;
 797
 798		retval = mxser_get_ISA_conf(cap, &hwconf);
 799
 800		if (retval != 0)
 801			printk(KERN_INFO "Found MOXA %s board (CAP=0x%x)\n", mxser_brdname[hwconf.board_type - 1], ioaddr[b]);
 802
 803		if (retval <= 0) {
 804			if (retval == MXSER_ERR_IRQ)
 805				printk(KERN_ERR "Invalid interrupt number,board not configured\n");
 806			else if (retval == MXSER_ERR_IRQ_CONFLIT)
 807				printk(KERN_ERR "Invalid interrupt number,board not configured\n");
 808			else if (retval == MXSER_ERR_VECTOR)
 809				printk(KERN_ERR "Invalid interrupt vector,board not configured\n");
 810			else if (retval == MXSER_ERR_IOADDR)
 811				printk(KERN_ERR "Invalid I/O address,board not configured\n");
 812
 813			continue;
 814		}
 815
 816		hwconf.pciInfo.busNum = 0;
 817		hwconf.pciInfo.devNum = 0;
 818		hwconf.pciInfo.pdev = NULL;
 819
 820		mxser_getcfg(m, &hwconf);
 821		//init mxsercfg first, or mxsercfg data is not correct on ISR.
 822		//mxser_initbrd will hook ISR.
 823		if (mxser_initbrd(m, &hwconf) < 0)
 824			continue;
 825
 826		m++;
 827	}
 828
 829	/* start finding PCI board here */
 830#ifdef CONFIG_PCI
 831	n = (sizeof(mxser_pcibrds) / sizeof(mxser_pcibrds[0])) - 1;
 832	index = 0;
 833	b = 0;
 834	while (b < n) {
 835		pdev = pci_find_device(mxser_pcibrds[b].vendor, mxser_pcibrds[b].device, pdev);
 836			if (pdev == NULL) {
 837			b++;
 838			continue;
 839		}
 840		hwconf.pciInfo.busNum = busnum = pdev->bus->number;
 841		hwconf.pciInfo.devNum = devnum = PCI_SLOT(pdev->devfn) << 3;
 842		hwconf.pciInfo.pdev = pdev;
 843		printk(KERN_INFO "Found MOXA %s board(BusNo=%d,DevNo=%d)\n", mxser_brdname[(int) (mxser_pcibrds[b].driver_data) - 1], busnum, devnum >> 3);
 844		index++;
 845		if (m >= MXSER_BOARDS) {
 846			printk(KERN_ERR "Too many Smartio/Industio family boards find (maximum %d),board not configured\n", MXSER_BOARDS);
 847		} else {
 848			if (pci_enable_device(pdev)) {
 849				printk(KERN_ERR "Moxa SmartI/O PCI enable fail !\n");
 850				continue;
 851			}
 852			retval = mxser_get_PCI_conf(busnum, devnum, (int) mxser_pcibrds[b].driver_data, &hwconf);
 853			if (retval < 0) {
 854				if (retval == MXSER_ERR_IRQ)
 855					printk(KERN_ERR "Invalid interrupt number,board not configured\n");
 856				else if (retval == MXSER_ERR_IRQ_CONFLIT)
 857					printk(KERN_ERR "Invalid interrupt number,board not configured\n");
 858				else if (retval == MXSER_ERR_VECTOR)
 859					printk(KERN_ERR "Invalid interrupt vector,board not configured\n");
 860				else if (retval == MXSER_ERR_IOADDR)
 861					printk(KERN_ERR "Invalid I/O address,board not configured\n");
 862				continue;
 863			}
 864			mxser_getcfg(m, &hwconf);
 865			//init mxsercfg first, or mxsercfg data is not correct on ISR.
 866			//mxser_initbrd will hook ISR.
 867			if (mxser_initbrd(m, &hwconf) < 0)
 868				continue;
 869			m++;
 870		}
 871	}
 872#endif
 873
 874	ret1 = 0;
 875	if (!(ret1 = tty_register_driver(mxvar_sdriver))) {
 876		return 0;
 877	} else
 878		printk(KERN_ERR "Couldn't install MOXA Smartio/Industio family driver !\n");
 879
 880
 881	if (ret1) {
 882		for (i = 0; i < MXSER_BOARDS; i++) {
 883			if (mxsercfg[i].board_type == -1)
 884				continue;
 885			else {
 886				free_irq(mxsercfg[i].irq, &mxvar_table[i * MXSER_PORTS_PER_BOARD]);
 887				//todo: release io, vector
 888			}
 889		}
 890		return -1;
 891	}
 892
 893	return (0);
 894}
 895
 896static void mxser_do_softint(void *private_)
 897{
 898	struct mxser_struct *info = (struct mxser_struct *) private_;
 899	struct tty_struct *tty;
 900
 901	tty = info->tty;
 902
 903	if (tty) {
 904		if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event))
 905			tty_wakeup(tty);
 906		if (test_and_clear_bit(MXSER_EVENT_HANGUP, &info->event))
 907			tty_hangup(tty);
 908	}
 909}
 910
 911static unsigned char mxser_get_msr(int baseaddr, int mode, int port, struct mxser_struct *info)
 912{
 913	unsigned char status = 0;
 914
 915	status = inb(baseaddr + UART_MSR);
 916
 917	mxser_msr[port] &= 0x0F;
 918	mxser_msr[port] |= status;
 919	status = mxser_msr[port];
 920	if (mode)
 921		mxser_msr[port] = 0;
 922
 923	return status;
 924}
 925
 926/*
 927 * This routine is called whenever a serial port is opened.  It
 928 * enables interrupts for a serial port, linking in its async structure into
 929 * the IRQ chain.   It also performs the serial-specific
 930 * initialization for the tty structure.
 931 */
 932static int mxser_open(struct tty_struct *tty, struct file *filp)
 933{
 934	struct mxser_struct *info;
 935	int retval, line;
 936
 937	line = tty->index;
 938	if (line == MXSER_PORTS)
 939		return 0;
 940	if (line < 0 || line > MXSER_PORTS)
 941		return -ENODEV;
 942	info = mxvar_table + line;
 943	if (!info->base)
 944		return (-ENODEV);
 945
 946	tty->driver_data = info;
 947	info->tty = tty;
 948	/*
 949	 * Start up serial port
 950	 */
 951	retval = mxser_startup(info);
 952	if (retval)
 953		return (retval);
 954
 955	retval = mxser_block_til_ready(tty, filp, info);
 956	if (retval)
 957		return (retval);
 958
 959	info->count++;
 960
 961	if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
 962		if (tty->driver->subtype == SERIAL_TYPE_NORMAL)
 963			*tty->termios = info->normal_termios;
 964		else
 965			*tty->termios = info->callout_termios;
 966		mxser_change_speed(info, NULL);
 967	}
 968
 969	info->session = current->signal->session;
 970	info->pgrp = process_group(current);
 971	clear_bit(TTY_DONT_FLIP, &tty->flags);
 972
 973	//status = mxser_get_msr(info->base, 0, info->port);
 974	//mxser_check_modem_status(info, status);
 975
 976/* unmark here for very high baud rate (ex. 921600 bps) used
 977*/
 978	tty->low_latency = 1;
 979	return 0;
 980}
 981
 982/*
 983 * This routine is called when the serial port gets closed.  First, we
 984 * wait for the last remaining data to be sent.  Then, we unlink its
 985 * async structure from the interrupt chain if necessary, and we free
 986 * that IRQ if nothing is left in the chain.
 987 */
 988static void mxser_close(struct tty_struct *tty, struct file *filp)
 989{
 990	struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
 991
 992	unsigned long timeout;
 993	unsigned long flags;
 994	struct tty_ldisc *ld;
 995
 996	if (tty->index == MXSER_PORTS)
 997		return;
 998	if (!info)
 999		BUG();
1000
1001	spin_lock_irqsave(&info->slock, flags);
1002
1003	if (tty_hung_up_p(filp)) {
1004		spin_unlock_irqrestore(&info->slock, flags);
1005		return;
1006	}
1007	if ((tty->count == 1) && (info->count != 1)) {
1008		/*
1009		 * Uh, oh.  tty->count is 1, which means that the tty
1010		 * structure will be freed.  Info->count should always
1011		 * be one in these conditions.  If it's greater than
1012		 * one, we've got real problems, since it means the
1013		 * serial port won't be shutdown.
1014		 */
1015		printk(KERN_ERR "mxser_close: bad serial port count; tty->count is 1, " "info->count is %d\n", info->count);
1016		info->count = 1;
1017	}
1018	if (--info->count < 0) {
1019		printk(KERN_ERR "mxser_close: bad serial port count for ttys%d: %d\n", info->port, info->count);
1020		info->count = 0;
1021	}
1022	if (info->count) {
1023		spin_unlock_irqrestore(&info->slock, flags);
1024		return;
1025	}
1026	info->flags |= ASYNC_CLOSING;
1027	spin_unlock_irqrestore(&info->slock, flags);
1028	/*
1029	 * Save the termios structure, since this port may have
1030	 * separate termios for callout and dialin.
1031	 */
1032	if (info->flags & ASYNC_NORMAL_ACTIVE)
1033		info->normal_termios = *tty->termios;
1034	/*
1035	 * Now we wait for the transmit buffer to clear; and we notify
1036	 * the line discipline to only process XON/XOFF characters.
1037	 */
1038	tty->closing = 1;
1039	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
1040		tty_wait_until_sent(tty, info->closing_wait);
1041	/*
1042	 * At this point we stop accepting input.  To do this, we
1043	 * disable the receive line status interrupts, and tell the
1044	 * interrupt driver to stop checking the data ready bit in the
1045	 * line status register.
1046	 */
1047	info->IER &= ~UART_IER_RLSI;
1048	if (info->IsMoxaMustChipFlag)
1049		info->IER &= ~MOXA_MUST_RECV_ISR;
1050/* by William
1051	info->read_status_mask &= ~UART_LSR_DR;
1052*/
1053	if (info->flags & ASYNC_INITIALIZED) {
1054		outb(info->IER, info->base + UART_IER);
1055		/*
1056		 * Before we drop DTR, make sure the UART transmitter
1057		 * has completely drained; this is especially
1058		 * important if there is a transmit FIFO!
1059		 */
1060		timeout = jiffies + HZ;
1061		while (!(inb(info->base + UART_LSR) & UART_LSR_TEMT)) {
1062			set_current_state(TASK_INTERRUPTIBLE);
1063			schedule_timeout(5);
1064			if (time_after(jiffies, timeout))
1065				break;
1066		}
1067	}
1068	mxser_shutdown(info);
1069
1070	if (tty->driver->flush_buffer)
1071		tty->driver->flush_buffer(tty);
1072		
1073	ld = tty_ldisc_ref(tty);
1074	if (ld) {
1075		if(ld->flush_buffer)
1076			ld->flush_buffer(tty);
1077		tty_ldisc_deref(ld);
1078	}
1079		
1080	tty->closing = 0;
1081	info->event = 0;
1082	info->tty = NULL;
1083	if (info->blocked_open) {
1084		if (info->close_delay) {
1085			set_current_state(TASK_INTERRUPTIBLE);
1086			schedule_timeout(info->close_delay);
1087		}
1088		wake_up_interruptible(&info->open_wait);
1089	}
1090
1091	info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1092	wake_up_interruptible(&info->close_wait);
1093
1094}
1095
1096static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count)
1097{
1098	int c, total = 0;
1099	struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
1100	unsigned long flags;
1101
1102	if (!tty || !info->xmit_buf)
1103		return (0);
1104
1105	while (1) {
1106		c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, SERIAL_XMIT_SIZE - info->xmit_head));
1107		if (c <= 0)
1108			break;
1109
1110		memcpy(info->xmit_buf + info->xmit_head, buf, c);
1111		spin_lock_irqsave(&info->slock, flags);
1112		info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1);
1113		info->xmit_cnt += c;
1114		spin_unlock_irqrestore(&info->slock, flags);
1115
1116		buf += c;
1117		count -= c;
1118		total += c;
1119
1120	}
1121
1122	if (info->xmit_cnt && !tty->stopped && !(info->IER & UART_IER_THRI)) {
1123		if (!tty->hw_stopped || (info->type == PORT_16550A) || (info->IsMoxaMustChipFlag)) {
1124			spin_lock_irqsave(&info->slock, flags);
1125			info->IER |= UART_IER_THRI;
1126			outb(info->IER, info->base + UART_IER);
1127			spin_unlock_irqrestore(&info->slock, flags);
1128		}
1129	}
1130	return total;
1131}
1132
1133static void mxser_put_char(struct tty_struct *tty, unsigned char ch)
1134{
1135	struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
1136	unsigned long flags;
1137
1138	if (!tty || !info->xmit_buf)
1139		return;
1140
1141	if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
1142		return;
1143
1144	spin_lock_irqsave(&info->slock, flags);
1145	info->xmit_buf[info->xmit_head++] = ch;
1146	info->xmit_head &= SERIAL_XMIT_SIZE - 1;
1147	info->xmit_cnt++;
1148	spin_unlock_irqrestore(&info->slock, flags);
1149	if (!tty->stopped && !(info->IER & UART_IER_THRI)) {
1150		if (!tty->hw_stopped || (info->type == PORT_16550A) || info->IsMoxaMustChipFlag) {
1151			spin_lock_irqsave(&info->slock, flags);
1152			info->IER |= UART_IER_THRI;
1153			outb(info->IER, info->base + UART_IER);
1154			spin_unlock_irqrestore(&info->slock, flags);
1155		}
1156	}
1157}
1158
1159
1160static void mxser_flush_chars(struct tty_struct *tty)
1161{
1162	struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
1163	unsigned long flags;
1164
1165	if (info->xmit_cnt <= 0 || tty->stopped || !info->xmit_buf || (tty->hw_stopped && (info->type != PORT_16550A) && (!info->IsMoxaMustChipFlag)))
1166		return;
1167
1168	spin_lock_irqsave(&info->slock, flags);
1169
1170	info->IER |= UART_IER_THRI;
1171	outb(info->IER, info->base + UART_IER);
1172
1173	spin_unlock_irqrestore(&info->slock, flags);
1174}
1175
1176static int mxser_write_room(struct tty_struct *tty)
1177{
1178	struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
1179	int ret;
1180
1181	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
1182	if (ret < 0)
1183		ret = 0;
1184	return (ret);
1185}
1186
1187static int mxser_chars_in_buffer(struct tty_struct *tty)
1188{
1189	struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
1190	return info->xmit_cnt;
1191}
1192
1193static void mxser_flush_buffer(struct tty_struct *tty)
1194{
1195	struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
1196	char fcr;
1197	unsigned long flags;
1198
1199
1200	spin_lock_irqsave(&info->slock, flags);
1201	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1202
1203	/* below added by shinhay */
1204	fcr = inb(info->base + UART_FCR);
1205	outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), info->base + UART_FCR);
1206	outb(fcr, info->base + UART_FCR);
1207
1208	spin_unlock_irqrestore(&info->slock, flags);
1209	/* above added by shinhay */
1210
1211	wake_up_interruptible(&tty->write_wait);
1212	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
1213		(tty->ldisc.write_wakeup) (tty);
1214}
1215
1216static int mxser_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
1217{
1218	struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
1219	int retval;
1220	struct async_icount cprev, cnow;	/* kernel counter temps */
1221	struct serial_icounter_struct __user *p_cuser;
1222	unsigned long templ;
1223	unsigned long flags;
1224	void __user *argp = (void __user *)arg;
1225
1226	if (tty->index == MXSER_PORTS)
1227		return (mxser_ioctl_special(cmd, argp));
1228
1229	// following add by Victor Yu. 01-05-2004
1230	if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) {
1231		int opmode, p;
1232		static unsigned char ModeMask[] = { 0xfc, 0xf3, 0xcf, 0x3f };
1233		int shiftbit;
1234		unsigned char val, mask;
1235
1236		p = info->port % 4;
1237		if (cmd == MOXA_SET_OP_MODE) {
1238			if (get_user(opmode, (int __user *) argp))
1239				return -EFAULT;
1240			if (opmode != RS232_MODE && opmode != RS485_2WIRE_MODE && opmode != RS422_MODE && opmode != RS485_4WIRE_MODE)
1241				return -EFAULT;
1242			mask = ModeMask[p];
1243			shiftbit = p * 2;
1244			val = inb(info->opmode_ioaddr);
1245			val &= mask;
1246			val |= (opmode << shiftbit);
1247			outb(val, info->opmode_ioaddr);
1248		} else {
1249			shiftbit = p * 2;
1250			opmode = inb(info->opmode_ioaddr) >> shiftbit;
1251			opmode &= OP_MODE_MASK;
1252			if (copy_to_user(argp, &opmode, sizeof(int)))
1253				return -EFAULT;
1254		}
1255		return 0;
1256	}
1257	// above add by Victor Yu. 01-05-2004
1258
1259	if ((cmd != TIOCGSERIAL) && (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
1260		if (tty->flags & (1 << TTY_IO_ERROR))
1261			return (-EIO);
1262	}
1263	switch (cmd) {
1264	case TCSBRK:		/* SVID version: non-zero arg --> no break */
1265		retval = tty_check_change(tty);
1266		if (retval)
1267			return (retval);
1268		tty_wait_until_sent(tty, 0);
1269		if (!arg)
1270			mxser_send_break(info, HZ / 4);	/* 1/4 second */
1271		return (0);
1272	case TCSBRKP:		/* support for POSIX tcsendbreak() */
1273		retval = tty_check_change(tty);
1274		if (retval)
1275			return (retval);
1276		tty_wait_until_sent(tty, 0);
1277		mxser_send_break(info, arg ? arg * (HZ / 10) : HZ / 4);
1278		return (0);
1279	case TIOCGSOFTCAR:
1280		return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp);
1281	case TIOCSSOFTCAR:
1282		if (get_user(templ, (unsigned long __user *) argp))
1283			return -EFAULT;
1284		arg = templ;
1285		tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0));
1286		return (0);
1287	case TIOCGSERIAL:
1288		return mxser_get_serial_info(info, argp);
1289	case TIOCSSERIAL:
1290		return mxser_set_serial_info(info, argp);
1291	case TIOCSERGETLSR:	/* Get line status register */
1292		return mxser_get_lsr_info(info, argp);
1293		/*
1294		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
1295		 * - mask passed in arg for lines of interest
1296		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
1297		 * Caller should use TIOCGICOUNT to see which one it was
1298		 */
1299	case TIOCMIWAIT:{
1300			DECLARE_WAITQUEUE(wait, current);
1301			int ret;
1302			spin_lock_irqsave(&info->slock, flags);
1303			cprev = info->icount;	/* note the counters on entry */
1304			spin_unlock_irqrestore(&info->slock, flags);
1305
1306			add_wait_queue(&info->delta_msr_wait, &wait);
1307			while (1) {
1308				spin_lock_irqsave(&info->slock, flags);
1309				cnow = info->icount;	/* atomic copy */
1310				spin_unlock_irqrestore(&info->slock, flags);
1311
1312				set_current_state(TASK_INTERRUPTIBLE);
1313				if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
1314					ret = 0;
1315					break;
1316				}
1317				/* see if a signal did it */
1318				if (signal_pending(current)) {
1319					ret = -ERESTARTSYS;
1320					break;
1321				}
1322				cprev = cnow;
1323			}
1324			current->state = TASK_RUNNING;
1325			remove_wait_queue(&info->delta_msr_wait, &wait);
1326			break;
1327		}
1328		/* NOTREACHED */
1329		/*
1330		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
1331		 * Return: write counters to the user passed counter struct
1332		 * NB: both 1->0 and 0->1 transitions are counted except for
1333		 *     RI where only 0->1 is counted.
1334		 */
1335	case TIOCGICOUNT:
1336		spin_lock_irqsave(&info->slock, flags);
1337		cnow = info->icount;
1338		spin_unlock_irqrestore(&info->slock, flags);
1339		p_cuser = argp;
1340		/* modified by casper 1/11/2000 */
1341		if (put_user(cnow.frame, &p_cuser->frame))
1342			return -EFAULT;
1343		if (put_user(cnow.brk, &p_cuser->brk))
1344			return -EFAULT;
1345		if (put_user(cnow.overrun, &p_cuser->overrun))
1346			return -EFAULT;
1347		if (put_user(cnow.buf_overrun, &p_cuser->buf_overrun))
1348			return -EFAULT;
1349		if (put_user(cnow.parity, &p_cuser->parity))
1350			return -EFAULT;
1351		if (put_user(cnow.rx, &p_cuser->rx))
1352			return -EFAULT;
1353		if (put_user(cnow.tx, &p_cuser->tx))
1354			return -EFAULT;
1355		put_user(cnow.cts, &p_cuser->cts);
1356		put_user(cnow.dsr, &p_cuser->dsr);
1357		put_user(cnow.rng, &p_cuser->rng);
1358		put_user(cnow.dcd, &p_cuser->dcd);
1359
1360/* */
1361		return 0;
1362	case MOXA_HighSpeedOn:
1363		return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *) argp);
1364
1365	case MOXA_SDS_RSTICOUNTER:{
1366			info->mon_data.rxcnt = 0;
1367			info->mon_data.txcnt = 0;
1368			return 0;
1369		}
1370// (above) added by James.
1371	case MOXA_ASPP_SETBAUD:{
1372			long baud;
1373			if (get_user(baud, (long __user *) argp))
1374				return -EFAULT;
1375			mxser_set_baud(info, baud);
1376			return 0;
1377		}
1378	case MOXA_ASPP_GETBAUD:
1379		if (copy_to_user(argp, &info->realbaud, sizeof(long)))
1380			return -EFAULT;
1381
1382		return 0;
1383
1384	case MOXA_ASPP_OQUEUE:{
1385			int len, lsr;
1386
1387			len = mxser_chars_in_buffer(tty);
1388
1389			lsr = inb(info->base + UART_LSR) & UART_LSR_TEMT;
1390
1391			len += (lsr ? 0 : 1);
1392
1393			if (copy_to_user(argp, &len, sizeof(int)))
1394				return -EFAULT;
1395
1396			return 0;
1397		}
1398	case MOXA_ASPP_MON:{
1399			int mcr, status;
1400//      info->mon_data.ser_param = tty->termios->c_cflag;
1401
1402			status = mxser_get_msr(info->base, 1, info->port, info);
1403			mxser_check_modem_status(info, status);
1404
1405			mcr = inb(info->base + UART_MCR);
1406			if (mcr & MOXA_MUST_MCR_XON_FLAG)
1407				info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD;
1408			else
1409				info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFHOLD;
1410
1411			if (mcr & MOXA_MUST_MCR_TX_XON)
1412				info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFXENT;
1413			else
1414				info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT;
1415
1416			if (info->tty->hw_stopped)
1417				info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD;
1418			else
1419				info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD;
1420
1421
1422			if (copy_to_user(argp, &info->mon_data, sizeof(struct mxser_mon)))
1423				return -EFAULT;
1424
1425			return 0;
1426
1427		}
1428
1429	case MOXA_ASPP_LSTATUS:{
1430			if (copy_to_user(argp, &info->err_shadow, sizeof(unsigned char)))
1431				return -EFAULT;
1432
1433			info->err_shadow = 0;
1434			return 0;
1435
1436		}
1437	case MOXA_SET_BAUD_METHOD:{
1438			int method;
1439			if (get_user(method, (int __user *) argp))
1440				return -EFAULT;
1441			mxser_set_baud_method[info->port] = method;
1442			if (copy_to_user(argp, &method, sizeof(int)))
1443				return -EFAULT;
1444
1445			return 0;
1446		}
1447	default:
1448		return -ENOIOCTLCMD;
1449	}
1450	return 0;
1451}
1452
1453#ifndef CMSPAR
1454#define	CMSPAR 010000000000
1455#endif
1456
1457static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
1458{
1459	int i, result, status;
1460
1461	switch (cmd) {
1462	case MOXA_GET_CONF:
1463		if (copy_to_user(argp, mxsercfg, sizeof(struct mxser_hwconf) * 4))
1464			return -EFAULT;
1465		return 0;
1466	case MOXA_GET_MAJOR:
1467		if (copy_to_user(argp, &ttymajor, sizeof(int)))
1468			return -EFAULT;
1469		return 0;
1470
1471	case MOXA_GET_CUMAJOR:
1472		if (copy_to_user(argp, &calloutmajor, sizeof(int)))
1473			return -EFAULT;
1474		return 0;
1475
1476	case MOXA_CHKPORTENABLE:
1477		result = 0;
1478		for (i = 0; i < MXSER_PORTS; i++) {
1479			if (mxvar_table[i].base)
1480				result |= (1 << i);
1481		}
1482		return put_user(result, (unsigned long __user *) argp);
1483	case MOXA_GETDATACOUNT:
1484		if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log)))
1485			return -EFAULT;
1486		return (0);
1487	case MOXA_GETMSTATUS:
1488		for (i = 0; i < MXSER_PORTS; i++) {
1489			GMStatus[i].ri = 0;
1490			if (!mxvar_table[i].base) {
1491				GMStatus[i].dcd = 0;
1492				GMStatus[i].dsr = 0;
1493				GMStatus[i].cts = 0;
1494				continue;
1495			}
1496
1497			if (!mxvar_table[i].tty || !mxvar_table[i].tty->termios)
1498				GMStatus[i].cflag = mxvar_table[i].normal_termios.c_cflag;
1499			else
1500				GMStatus[i].cflag = mxvar_table[i].tty->termios->c_cflag;
1501
1502			status = inb(mxvar_table[i].base + UART_MSR);
1503			if (status & 0x80 /*UART_MSR_DCD */ )
1504				GMStatus[i].dcd = 1;
1505			else
1506				GMStatus[i].dcd = 0;
1507
1508			if (status & 0x20 /*UART_MSR_DSR */ )
1509				GMStatus[i].dsr = 1;
1510			else
1511				GMStatus[i].dsr = 0;
1512
1513
1514			if (status & 0x10 /*UART_MSR_CTS */ )
1515				GMStatus[i].cts = 1;
1516			else
1517				GMStatus[i].cts = 0;
1518		}
1519		if (copy_to_user(argp, GMStatus, sizeof(struct mxser_mstatus) * MXSER_PORTS))
1520			return -EFAULT;
1521		return 0;
1522	case MOXA_ASPP_MON_EXT:{
1523			int status;
1524			int opmode, p;
1525			int shiftbit;
1526			unsigned cflag, iflag;
1527
1528			for (i = 0; i < MXSER_PORTS; i++) {
1529
1530				if (!mxvar_table[i].base)
1531					continue;
1532
1533				status = mxser_get_msr(mxvar_table[i].base, 0, i, &(mxvar_table[i]));
1534//                      mxser_check_modem_status(&mxvar_table[i], status);
1535				if (status & UART_MSR_TERI)
1536					mxvar_table[i].icount.rng++;
1537				if (status & UART_MSR_DDSR)
1538					mxvar_table[i].icount.dsr++;
1539				if (status & UART_MSR_DDCD)
1540					mxvar_table[i].icount.dcd++;
1541				if (status & UART_MSR_DCTS)
1542					mxvar_table[i].icount.cts++;
1543
1544				mxvar_table[i].mon_data.modem_status = status;
1545				mon_data_ext.rx_cnt[i] = mxvar_table[i].mon_data.rxcnt;
1546				mon_data_ext.tx_cnt[i] = mxvar_table[i].mon_data.txcnt;
1547				mon_data_ext.up_rxcnt[i] = mxvar_table[i].mon_data.up_rxcnt;
1548				mon_data_ext.up_txcnt[i] = mxvar_table[i].mon_data.up_txcnt;
1549				mon_data_ext.modem_status[i] = mxvar_table[i].mon_data.modem_status;
1550				mon_data_ext.baudrate[i] = mxvar_table[i].realbaud;
1551
1552				if (!mxvar_table[i].tty || !mxvar_table[i].tty->termios) {
1553					cflag = mxvar_table[i].normal_termios.c_cflag;
1554					iflag = mxvar_table[i].normal_termios.c_iflag;
1555				} else {
1556					cflag = mxvar_table[i].tty->termios->c_cflag;
1557					iflag = mxvar_table[i].tty->termios->c_iflag;
1558				}
1559
1560				mon_data_ext.databits[i] = cflag & CSIZE;
1561
1562				mon_data_ext.stopbits[i] = cflag & CSTOPB;
1563
1564				mon_data_ext.parity[i] = cflag & (PARENB | PARODD | CMSPAR);
1565
1566				mon_data_ext.flowctrl[i] = 0x00;
1567
1568				if (cflag & CRTSCTS)
1569					mon_data_ext.flowctrl[i] |= 0x03;
1570
1571				if (iflag & (IXON | IXOFF))
1572					mon_data_ext.flowctrl[i] |= 0x0C;
1573
1574				if (mxvar_table[i].type == PORT_16550A)
1575					mon_data_ext.fifo[i] = 1;
1576				else
1577					mon_data_ext.fifo[i] = 0;
1578
1579				p = i % 4;
1580				shiftbit = p * 2;
1581				opmode = inb(mxvar_table[i].opmode_ioaddr) >> shiftbit;
1582				opmode &= OP_MODE_MASK;
1583
1584				mon_data_ext.iftype[i] = opmode;
1585
1586			}
1587			if (copy_to_user(argp, &mon_data_ext, sizeof(struct mxser_mon_ext)))
1588				return -EFAULT;
1589
1590			return 0;
1591
1592		}
1593	default:
1594		return -ENOIOCTLCMD;
1595	}
1596	return 0;
1597}
1598
1599
1600static void mxser_stoprx(struct tty_struct *tty)
1601{
1602	struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
1603	//unsigned long flags;
1604
1605
1606	info->ldisc_stop_rx = 1;
1607	if (I_IXOFF(tty)) {
1608
1609		//MX_LOCK(&info->slock);
1610		// following add by Victor Yu. 09-02-2002
1611		if (info->IsMoxaMustChipFlag) {
1612			info->IER &= ~MOXA_MUST_RECV_ISR;
1613			outb(info->IER, info->base + UART_IER);
1614		} else {
1615			// above add by Victor Yu. 09-02-2002
1616
1617			info->x_char = STOP_CHAR(tty);
1618			//      outb(info->IER, 0); // mask by Victor Yu. 09-02-2002
1619			outb(0, info->base + UART_IER);
1620			info->IER |= UART_IER_THRI;
1621			outb(info->IER, info->base + UART_IER);	/* force Tx interrupt */
1622		}		// add by Victor Yu. 09-02-2002
1623		//MX_UNLOCK(&info->slock);
1624	}
1625
1626	if (info->tty->termios->c_cflag & CRTSCTS) {
1627		//MX_LOCK(&info->slock);
1628		info->MCR &= ~UART_MCR_RTS;
1629		outb(info->MCR, info->base + UART_MCR);
1630		//MX_UNLOCK(&info->slock);
1631	}
1632}
1633
1634static void mxser_startrx(struct tty_struct *tty)
1635{
1636	struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
1637	//unsigned long flags;
1638
1639	info->ldisc_stop_rx = 0;
1640	if (I_IXOFF(tty)) {
1641		if (info->x_char)
1642			info->x_char = 0;
1643		else {
1644			//MX_LOCK(&info->slock);
1645
1646			// following add by Victor Yu. 09-02-2002
1647			if (info->IsMoxaMustChipFlag) {
1648				info->IER |= MOXA_MUST_RECV_ISR;
1649				outb(info->IER, info->base + UART_IER);
1650			} else {
1651				// above add by Victor Yu. 09-02-2002
1652
1653				info->x_char = START_CHAR(tty);
1654				//          outb(info->IER, 0); // mask by Victor Yu. 09-02-2002
1655				outb(0, info->base + UART_IER);	// add by Victor Yu. 09-02-2002
1656				info->IER |= UART_IER_THRI;	/* force Tx interrupt */
1657				outb(info->IER, info->base + UART_IER);
1658			}	// add by Victor Yu. 09-02-2002
1659			//MX_UNLOCK(&info->slock);
1660		}
1661	}
1662
1663	if (info->tty->termios->c_cflag & CRTSCTS) {
1664		//MX_LOCK(&info->slock);
1665		info->MCR |= UART_MCR_RTS;
1666		outb(info->MCR, info->base + UART_MCR);
1667		//MX_UNLOCK(&info->slock);
1668	}
1669}
1670
1671/*
1672 * This routine is called by the upper-layer tty layer to signal that
1673 * incoming characters should be throttled.
1674 */
1675static void mxser_throttle(struct tty_struct *tty)
1676{
1677	//struct mxser_struct *info = (struct mxser_struct *)tty->driver_data;
1678	//unsigned long flags;
1679	//MX_LOCK(&info->slock);
1680	mxser_stoprx(tty);
1681	//MX_UNLOCK(&info->slock);
1682}
1683
1684static void mxser_unthrottle(struct tty_struct *tty)
1685{
1686	//struct mxser_struct *info = (struct mxser_struct *)tty->driver_data;
1687	//unsigned long flags;
1688	//MX_LOCK(&info->slock);
1689	mxser_startrx(tty);
1690	//MX_UNLOCK(&info->slock);
1691}
1692
1693static void mxser_set_termios(struct tty_struct *tty, struct termios *old_termios)
1694{
1695	struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
1696	unsigned long flags;
1697
1698	if ((tty->termios->c_cflag != old_termios->c_cflag) || (RELEVANT_IFLAG(tty->termios->c_iflag) != RELEVANT_IFLAG(old_termios->c_iflag))) {
1699
1700		mxser_change_speed(info, old_termios);
1701
1702		if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) {
1703			tty->hw_stopped = 0;
1704			mxser_start(tty);
1705		}
1706	}
1707
1708/* Handle sw stopped */
1709	if ((old_termios->c_iflag & IXON) && !(tty->termios->c_iflag & IXON)) {
1710		tty->stopped = 0;
1711
1712		// following add by Victor Yu. 09-02-2002
1713		if (info->IsMoxaMustChipFlag) {
1714			spin_lock_irqsave(&info->slock, flags);
1715			DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->base);
1716			spin_unlock_irqrestore(&info->slock, flags);
1717		}
1718		// above add by Victor Yu. 09-02-2002
1719
1720		mxser_start(tty);
1721	}
1722}
1723
1724/*
1725 * mxser_stop() and mxser_start()
1726 *
1727 * This routines are called before setting or resetting tty->stopped.
1728 * They enable or disable transmitter interrupts, as necessary.
1729 */
1730static void mxser_stop(struct tty_struct *tty)
1731{
1732	struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
1733	unsigned long flags;
1734
1735	spin_lock_irqsave(&info->slock, flags);
1736	if (info->IER & UART_IER_THRI) {
1737		info->IER &= ~UART_IER_THRI;
1738		outb(info->IER, info->base + UART_IER);
1739	}
1740	spin_unlock_irqrestore(&info->slock, flags);
1741}
1742
1743static void mxser_start(struct tty_struct *tty)
1744{
1745	struct mxser_struct *info = (struct mxser_struct *) tty->driver_data;
1746	unsigned long flags;
1747
1748	spin_lock_irqsave(&info->slock, flags);
1749	if (info->xmit_cnt && info->xmit_buf && !(info->IER & UART_IER_THRI)) {
1750		info->IER |= UART_IER_THRI;
1751		outb(info->IER, info->base + UART_IER);
1752	}
1753	spin_unlock_irqrestore(&info->slock, flags);
1754}
1755
1756/*
1757 * mxser_wait_until_sent() --- wait until the transmitter is empty
1758 */
1759static void mxser_wait_until_sent(struct tty_struct *tty, int timeout)
1760{
1761	struct mxser_struct *info = (struct mxser_struct 

Large files files are truncated, but you can click here to view the full file