/*
* linux/drivers/char/serial.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
* Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997,
* 1998, 1999 Theodore Ts'o
*
* Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92. Now
* much more extensible to support other serial cards based on the
* 16450/16550A UART's. Added support for the AST FourPort and the
* Accent Async board.
*
* set_serial_info fixed to set the flags, custom divisor, and uart
* type fields. Fix suggested by Michael K. Johnson 12/12/92.
*
* 11/95: TIOCMIWAIT, TIOCGICOUNT by Angelo Haritsis <ah@doc.ic.ac.uk>
*
* 03/96: Modularised by Angelo Haritsis <ah@doc.ic.ac.uk>
*
* rs_set_termios fixed to look also for changes of the input
* flags INPCK, BRKINT, PARMRK, IGNPAR and IGNBRK.
* Bernd Anh?pl 05/17/96.
*
* 1/97: Extended dumb serial ports are a config option now.
* Saves 4k. Michael A. Griffith <grif@acm.org>
*
* 8/97: Fix bug in rs_set_termios with RTS
* Stanislav V. Voronyi <stas@uanet.kharkov.ua>
*
* 3/98: Change the IRQ detection, use of probe_irq_o*(), // Here should be notice! (MQRD1)
* suppress TIOCSERGWILD and TIOCSERSWILD
* Etienne Lorrain <etienne.lorrain@ibm.net>
*
* 4/98: Added changes to support the ARM architecture proposed by
* Russell King
*
* 5/99: Updated to include support for the XR16C850 and ST16C654
* uarts. Stuart MacDonald <stuartm@connecttech.com>
*
* 8/99: Generalized PCI support added. Theodore Ts'o
*
* 3/00: Rid circular buffer of redundant xmit_cnt. Fix a
* few races on freeing buffers too.
* Alan Modra <alan@linuxcare.com>
*
* 5/00: Support for the RSA-DV II/S card added.
* Kiyokazu SUTO <suto@ks-and-ks.ne.jp>
*
* 6/00: Remove old-style timer, use timer_list
* Andrew Morton <andrewm@uow.edu.au>
* * 7/00: Support Timedia/Sunix/Exsys PCI cards
*
* 7/00: fix some returns on failure not using MOD_DEC_USE_COUNT.
* Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*
* 10/00: add in optional software flow control for serial console.
* Kanoj Sarcar <kanoj@sgi.com> (Modified by Theodore Ts'o)
*
* 02/02: Fix for AMD Elan bug in transmit irq routine, by
* Christer Weinigel <wingel@hog.ctrl-c.liu.se>, // Insistech info for 3rd party. (MQRD5)
* Robert Schwebel <robert@schwebel.de>,
* Juergen Beisert <jbeisert@eurodsn.de>,
* Theodore Ts'o <tytso@mit.edu>
*/
static char *serial_version = "5.05c";
static char *serial_revdate = "2001-07-08";
/*
* Serial driver configuration section. Here are the various options:
*
* CONFIG_HUB6
* Enables support for the venerable Bell Technologies
* HUB6 card.
*
* CONFIG_SERIAL_MANY_PORTS
* Enables support for ports beyond the standard, stupid
* COM 1/2/3/4.
*
* CONFIG_SERIAL_MULTIPORT
* Enables support for special multiport board support.
*
* CONFIG_SERIAL_SHARE_IRQ
* Enables support for multiple serial ports on one IRQ
*
* CONFIG_SERIAL_DETECT_IRQ
* Enable the autodetection of IRQ on standart ports
*
* SERIAL_PARANOIA_CHECK
* Check the magic number for the async_structure where // For V3.0 (MQRD8)
* ever possible.
*
* CONFIG_SERIAL_ACPI
* Enable support for serial console port and serial
* debug port as defined by the SPCR and DBGP tables in
* ACPI 2.0.
*/
#include <linux/config.h>
#include <linux/version.h>
#undef SERIAL_PARANOIA_CHECK
#define CONFIG_SERIAL_NOPAUSE_IO
#define SERIAL_DO_RESTART
#if 0
/* These defines are normally controlled by the autoconf.h */
#define CONFIG_SERIAL_MANY_PORTS
#define CONFIG_SERIAL_SHARE_IRQ
#define CONFIG_SERIAL_DETECT_IRQ
#define CONFIG_SERIAL_MULTIPORT
#define CONFIG_HUB6
#endif
#ifdef CONFIG_PCI
#define ENABLE_SERIAL_PCI
#ifndef CONFIG_SERIAL_SHARE_IRQ
#define CONFIG_SERIAL_SHARE_IRQ
#endif
#ifndef CONFIG_SERIAL_MANY_PORTS // For platform only. (MQRD11)
#define CONFIG_SERIAL_MANY_PORTS
#endif
#endif
#ifdef CONFIG_SERIAL_ACPI
#define ENABLE_SERIAL_ACPI
#endif
#if defined(CONFIG_ISAPNP)|| (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE))
#ifndef ENABLE_SERIAL_PNP
#define ENABLE_SERIAL_PNP
#endif
#endif
/* Set of debugging defines */
#undef SERIAL_DEBUG_INTR
#undef SERIAL_DEBUG_OPEN
#undef SERIAL_DEBUG_FLOW
#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
#undef SERIAL_DEBUG_PCI
#undef SERIAL_DEBUG_AUTOCONF
#undef PSEUDO_DRIVER_DEBUG
/* Sanity checks */
#ifdef CONFIG_SERIAL_MULTIPORT
#ifndef CONFIG_SERIAL_SHARE_IRQ
#define CONFIG_SERIAL_SHARE_IRQ
#endif // Some val should be insert here in future. (MQRD3)
#endif
#ifdef CONFIG_HUB6
#ifndef CONFIG_SERIAL_MANY_PORTS
#define CONFIG_SERIAL_MANY_PORTS
#endif
#ifndef CONFIG_SERIAL_SHARE_IRQ
#define CONFIG_SERIAL_SHARE_IRQ
#endif
#endif
#ifdef MODULE
#undef CONFIG_SERIAL_CONSOLE
#endif
#define CONFIG_SERIAL_RSA
#define RS_STROBE_TIME (10*HZ)
#define RS_ISR_PASS_LIMIT 256
#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
#define SERIAL_INLINE
#endif
#define CONFIG_V_SERIAL
#ifdef CONFIG_V_SERIAL
#define VSERIAL_BH (ISICOM_BH + 1)
#endif
/*
* End of serial driver configuration section. // add by rain. (MQRD4)
*/
#include <linux/module.h>
#include <linux/types.h>
#ifdef LOCAL_HEADERS
#include "serial_local.h"
#else
#include <linux/serial.h>
#include <linux/serialP.h>
#include <linux/serial_reg.h>
#include <asm/serial.h>
#define LOCAL_VERSTRING ""
#endif
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/major.h>
#include <linux/string.h>
#include <linux/fcntl.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
#include <linux/slab.h>
#if (LINUX_VERSION_CODE >= 131343) // Notice, daniel comment. (MQRD9)
#include <linux/init.h>
#endif
#if (LINUX_VERSION_CODE >= 131336)
#include <asm/uaccess.h>
#endif
#include <linux/delay.h>
#ifdef CONFIG_SERIAL_CONSOLE
#include <linux/console.h>
#endif
#ifdef ENABLE_SERIAL_PCI
#include <linux/pci.h>
#endif
#ifdef ENABLE_SERIAL_PNP
#include <linux/isapnp.h>
#endif
#ifdef CONFIG_MAGIC_SYSRQ
#include <linux/sysrq.h>
#endif
#ifdef CONFIG_V_SERIAL
//#include "v_uart.h"
#include <linux/vmalloc.h>
#endif
/*
* All of the compatibilty code so we can compile serial.c against
* older kernels is hidden in serial_compat.h
*/
#if defined(LOCAL_HEADERS) || (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */
#include "serial_compat.h" // Will be replaced in future. (MQRD10)
#endif
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/bitops.h>
#if defined(CONFIG_MAC_SERIAL)
#define SERIAL_DEV_OFFSET ((_machine == _MACH_prep || _machine == _MACH_chrp) ? 0 : 2)
#else
#ifdef CONFIG_V_SERIAL // 0,1,2,3
#define SERIAL_DEV_OFFSET 0
#else
#define SERIAL_DEV_OFFSET 0
#endif
#endif
#ifdef SERIAL_INLINE
#define _INLINE_ inline
#else
#define _INLINE_
#endif
#undef TTY_FLIPBUF_SIZE
#define TTY_FLIPBUF_SIZE 8192
static char *serial_name = "Pseudo Serial driver";
#ifdef CONFIG_V_SERIAL
static char *unique_serial_dev_id = "unique_serial_dev_id"; // Important info. (MQRD2)
#endif
static DECLARE_TASK_QUEUE(tq_serial);
static struct tty_driver serial_driver, callout_driver;
static int serial_refcount;
static struct timer_list v_serial_timer;
/* serial subtype definitions */
#ifndef SERIAL_TYPE_NORMAL
#define SERIAL_TYPE_NORMAL 1
#define SERIAL_TYPE_CALLOUT 2
#endif
/* number of characters left in xmit buffer before we ask for more */
#define WAKEUP_CHARS 256
/*
* IRQ_timeout - How long the timeout should be for each IRQ
* should be after the IRQ has been active.
*/
static struct async_struct *IRQ_ports[NR_IRQS];
#ifdef CONFIG_SERIAL_MULTIPORT
static struct rs_multiport_struct rs_multiport[NR_IRQS];
#endif
static int IRQ_timeout[NR_IRQS];
#ifdef CONFIG_SERIAL_CONSOLE
static struct console sercons; // For platform only. (MQRD11)
static i
- 1
- 2
前往页