aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/serial/hayes-esp.txt154
-rw-r--r--Documentation/serial/tty.txt9
-rw-r--r--arch/xtensa/platforms/iss/console.c2
-rw-r--r--drivers/char/Kconfig13
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/bfin_jtag_comm.c2
-rw-r--r--drivers/char/epca.c2
-rw-r--r--drivers/char/esp.c2533
-rw-r--r--drivers/char/isicom.c115
-rw-r--r--drivers/char/istallion.c185
-rw-r--r--drivers/char/moxa.c289
-rw-r--r--drivers/char/mxser.c248
-rw-r--r--drivers/char/pcmcia/ipwireless/tty.c2
-rw-r--r--drivers/char/pty.c2
-rw-r--r--drivers/char/riscom8.c89
-rw-r--r--drivers/char/stallion.c129
-rw-r--r--drivers/char/tty_io.c151
-rw-r--r--drivers/char/tty_ldisc.c23
-rw-r--r--drivers/char/tty_port.c97
-rw-r--r--drivers/mmc/card/sdio_uart.c303
-rw-r--r--drivers/serial/8250.c24
-rw-r--r--drivers/serial/jsm/jsm.h8
-rw-r--r--drivers/serial/jsm/jsm_driver.c48
-rw-r--r--drivers/serial/jsm/jsm_neo.c8
-rw-r--r--drivers/serial/jsm/jsm_tty.c6
-rw-r--r--drivers/serial/pxa.c13
-rw-r--r--drivers/serial/serial_core.c33
-rw-r--r--drivers/usb/serial/opticon.c7
-rw-r--r--drivers/usb/serial/usb-serial.c83
-rw-r--r--fs/devpts/inode.c16
-rw-r--r--include/linux/Kbuild1
-rw-r--r--include/linux/hayesesp.h114
-rw-r--r--include/linux/isicom.h1
-rw-r--r--include/linux/tty.h25
-rw-r--r--include/linux/usb/serial.h3
-rw-r--r--kernel/exit.c2
36 files changed, 921 insertions, 3820 deletions
diff --git a/Documentation/serial/hayes-esp.txt b/Documentation/serial/hayes-esp.txt
deleted file mode 100644
index 09b5d585675..00000000000
--- a/Documentation/serial/hayes-esp.txt
+++ /dev/null
@@ -1,154 +0,0 @@
-HAYES ESP DRIVER VERSION 2.1
-
-A big thanks to the people at Hayes, especially Alan Adamson. Their support
-has enabled me to provide enhancements to the driver.
-
-Please report your experiences with this driver to me (arobinso@nyx.net). I
-am looking for both positive and negative feedback.
-
-*** IMPORTANT CHANGES FOR 2.1 ***
-Support for PIO mode. Five situations will cause PIO mode to be used:
-1) A multiport card is detected. PIO mode will always be used. (8 port cards
-do not support DMA).
-2) The DMA channel is set to an invalid value (anything other than 1 or 3).
-3) The DMA buffer/channel could not be allocated. The port will revert to PIO
-mode until it is reopened.
-4) Less than a specified number of bytes need to be transferred to/from the
-FIFOs. PIO mode will be used for that transfer only.
-5) A port needs to do a DMA transfer and another port is already using the
-DMA channel. PIO mode will be used for that transfer only.
-
-Since the Hayes ESP seems to conflict with other cards (notably sound cards)
-when using DMA, DMA is turned off by default. To use DMA, it must be turned
-on explicitly, either with the "dma=" option described below or with
-setserial. A multiport card can be forced into DMA mode by using setserial;
-however, most multiport cards don't support DMA.
-
-The latest version of setserial allows the enhanced configuration of the ESP
-card to be viewed and modified.
-***
-
-This package contains the files needed to compile a module to support the Hayes
-ESP card. The drivers are basically a modified version of the serial drivers.
-
-Features:
-
-- Uses the enhanced mode of the ESP card, allowing a wider range of
- interrupts and features than compatibility mode
-- Uses DMA and 16 bit PIO mode to transfer data to and from the ESP's FIFOs,
- reducing CPU load
-- Supports primary and secondary ports
-
-
-If the driver is compiled as a module, the IRQs to use can be specified by
-using the irq= option. The format is:
-
-irq=[0x100],[0x140],[0x180],[0x200],[0x240],[0x280],[0x300],[0x380]
-
-The address in brackets is the base address of the card. The IRQ of
-nonexistent cards can be set to 0. If an IRQ of a card that does exist is set
-to 0, the driver will attempt to guess at the correct IRQ. For example, to set
-the IRQ of the card at address 0x300 to 12, the insmod command would be:
-
-insmod esp irq=0,0,0,0,0,0,12,0
-
-The custom divisor can be set by using the divisor= option. The format is the
-same as for the irq= option. Each divisor value is a series of hex digits,
-with each digit representing the divisor to use for a corresponding port. The
-divisor value is constructed RIGHT TO LEFT. Specifying a nonzero divisor value
-will automatically set the spd_cust flag. To calculate the divisor to use for
-a certain baud rate, divide the port's base baud (generally 921600) by the
-desired rate. For example, to set the divisor of the primary port at 0x300 to
-4 and the divisor of the secondary port at 0x308 to 8, the insmod command would
-be:
-
-insmod esp divisor=0,0,0,0,0,0,0x84,0
-
-The dma= option can be used to set the DMA channel. The channel can be either
-1 or 3. Specifying any other value will force the driver to use PIO mode.
-For example, to set the DMA channel to 3, the insmod command would be:
-
-insmod esp dma=3
-
-The rx_trigger= and tx_trigger= options can be used to set the FIFO trigger
-levels. They specify when the ESP card should send an interrupt. Larger
-values will decrease the number of interrupts; however, a value too high may
-result in data loss. Valid values are 1 through 1023, with 768 being the
-default. For example, to set the receive trigger level to 512 bytes and the
-transmit trigger level to 700 bytes, the insmod command would be:
-
-insmod esp rx_trigger=512 tx_trigger=700
-
-The flow_off= and flow_on= options can be used to set the hardware flow off/
-flow on levels. The flow on level must be lower than the flow off level, and
-the flow off level should be higher than rx_trigger. Valid values are 1
-through 1023, with 1016 being the default flow off level and 944 being the
-default flow on level. For example, to set the flow off level to 1000 bytes
-and the flow on level to 935 bytes, the insmod command would be:
-
-insmod esp flow_off=1000 flow_on=935
-
-The rx_timeout= option can be used to set the receive timeout value. This
-value indicates how long after receiving the last character that the ESP card
-should wait before signalling an interrupt. Valid values are 0 though 255,
-with 128 being the default. A value too high will increase latency, and a
-value too low will cause unnecessary interrupts. For example, to set the
-receive timeout to 255, the insmod command would be:
-
-insmod esp rx_timeout=255
-
-The pio_threshold= option sets the threshold (in number of characters) for
-using PIO mode instead of DMA mode. For example, if this value is 32,
-transfers of 32 bytes or less will always use PIO mode.
-
-insmod esp pio_threshold=32
-
-Multiple options can be listed on the insmod command line by separating each
-option with a space. For example:
-
-insmod esp dma=3 trigger=512
-
-The esp module can be automatically loaded when needed. To cause this to
-happen, add the following lines to /etc/modprobe.conf (replacing the last line
-with options for your configuration):
-
-alias char-major-57 esp
-alias char-major-58 esp
-options esp irq=0,0,0,0,0,0,3,0 divisor=0,0,0,0,0,0,0x4,0
-
-You may also need to run 'depmod -a'.
-
-Devices must be created manually. To create the devices, note the output from
-the module after it is inserted. The output will appear in the location where
-kernel messages usually appear (usually /var/adm/messages). Create two devices
-for each 'tty' mentioned, one with major of 57 and the other with major of 58.
-The minor number should be the same as the tty number reported. The commands
-would be (replace ? with the tty number):
-
-mknod /dev/ttyP? c 57 ?
-mknod /dev/cup? c 58 ?
-
-For example, if the following line appears:
-
-Oct 24 18:17:23 techno kernel: ttyP8 at 0x0140 (irq = 3) is an ESP primary port
-
-...two devices should be created:
-
-mknod /dev/ttyP8 c 57 8
-mknod /dev/cup8 c 58 8
-
-You may need to set the permissions on the devices:
-
-chmod 666 /dev/ttyP*
-chmod 666 /dev/cup*
-
-The ESP module and the serial module should not conflict (they can be used at
-the same time). After the ESP module has been loaded the ports on the ESP card
-will no longer be accessible by the serial driver.
-
-If I/O errors are experienced when accessing the port, check for IRQ and DMA
-conflicts ('cat /proc/interrupts' and 'cat /proc/dma' for a list of IRQs and
-DMAs currently in use).
-
-Enjoy!
-Andrew J. Robinson <arobinso@nyx.net>
diff --git a/Documentation/serial/tty.txt b/Documentation/serial/tty.txt
index 8e65c4498c5..5e5349a4fcd 100644
--- a/Documentation/serial/tty.txt
+++ b/Documentation/serial/tty.txt
@@ -42,7 +42,8 @@ TTY side interfaces:
open() - Called when the line discipline is attached to
the terminal. No other call into the line
discipline for this tty will occur until it
- completes successfully. Can sleep.
+ completes successfully. Returning an error will
+ prevent the ldisc from being attached. Can sleep.
close() - This is called on a terminal when the line
discipline is being unplugged. At the point of
@@ -52,7 +53,7 @@ close() - This is called on a terminal when the line
hangup() - Called when the tty line is hung up.
The line discipline should cease I/O to the tty.
No further calls into the ldisc code will occur.
- Can sleep.
+ The return value is ignored. Can sleep.
write() - A process is writing data through the line
discipline. Multiple write calls are serialized
@@ -83,6 +84,10 @@ ioctl() - Called when an ioctl is handed to the tty layer
that might be for the ldisc. Multiple ioctl calls
may occur in parallel. May sleep.
+compat_ioctl() - Called when a 32 bit ioctl is handed to the tty layer
+ that might be for the ldisc. Multiple ioctl calls
+ may occur in parallel. May sleep.
+
Driver Side Interfaces:
receive_buf() - Hand buffers of bytes from the driver to the ldisc
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c
index 4c559cf7da2..e60a1f57022 100644
--- a/arch/xtensa/platforms/iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -196,7 +196,7 @@ static const struct file_operations rs_proc_fops = {
.release = single_release,
};
-static struct tty_operations serial_ops = {
+static const struct tty_operations serial_ops = {
.open = rs_open,
.close = rs_close,
.write = rs_write,
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 6aad99ec4e0..6f31c947210 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -201,19 +201,6 @@ config DIGIEPCA
To compile this driver as a module, choose M here: the
module will be called epca.
-config ESPSERIAL
- tristate "Hayes ESP serial port support"
- depends on SERIAL_NONSTANDARD && ISA && ISA_DMA_API && BROKEN
- help
- This is a driver which supports Hayes ESP serial ports. Both single
- port cards and multiport cards are supported. Make sure to read
- <file:Documentation/hayes-esp.txt>.
-
- To compile this driver as a module, choose M here: the
- module will be called esp.
-
- If unsure, say N.
-
config MOXA_INTELLIO
tristate "Moxa Intellio support"
depends on SERIAL_NONSTANDARD && (ISA || EISA || PCI)
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 19a79dd79ee..f957edf7e45 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -18,7 +18,6 @@ obj-$(CONFIG_CONSOLE_TRANSLATIONS) += consolemap.o consolemap_deftbl.o
obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o
obj-$(CONFIG_AUDIT) += tty_audit.o
obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
-obj-$(CONFIG_ESPSERIAL) += esp.o
obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o
obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o
obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o
diff --git a/drivers/char/bfin_jtag_comm.c b/drivers/char/bfin_jtag_comm.c
index 1d7c34c73b2..2628c7415ea 100644
--- a/drivers/char/bfin_jtag_comm.c
+++ b/drivers/char/bfin_jtag_comm.c
@@ -226,7 +226,7 @@ bfin_jc_wait_until_sent(struct tty_struct *tty, int timeout)
}
}
-static struct tty_operations bfin_jc_ops = {
+static const struct tty_operations bfin_jc_ops = {
.open = bfin_jc_open,
.close = bfin_jc_close,
.write = bfin_jc_write,
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index dde5134713e..17b044a71e0 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -935,7 +935,7 @@ static int info_open(struct tty_struct *tty, struct file *filp)
return 0;
}
-static struct tty_operations info_ops = {
+static const struct tty_operations info_ops = {
.open = info_open,
.ioctl = info_ioctl,
};
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
deleted file mode 100644
index b19d43cd954..00000000000
--- a/drivers/char/esp.c
+++ /dev/null
@@ -1,2533 +0,0 @@
-/*
- * esp.c - driver for Hayes ESP serial cards
- *
- * --- Notices from serial.c, upon which this driver is based ---
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- *
- * 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äupl 05/17/96.
- *
- * --- End of notices from serial.c ---
- *
- * Support for the ESP serial card by Andrew J. Robinson
- * <arobinso@nyx.net> (Card detection routine taken from a patch
- * by Dennis J. Boylan). Patches to allow use with 2.1.x contributed
- * by Chris Faylor.
- *
- * Most recent changes: (Andrew J. Robinson)
- * Support for PIO mode. This allows the driver to work properly with
- * multiport cards.
- *
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br> -
- * several cleanups, use module_init/module_exit, etc
- *
- * This module exports the following rs232 io functions:
- *
- * int espserial_init(void);
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.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/init.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <linux/io.h>
-
-#include <asm/dma.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-
-#include <linux/hayesesp.h>
-
-#define NR_PORTS 64 /* maximum number of ports */
-#define NR_PRIMARY 8 /* maximum number of primary ports */
-#define REGION_SIZE 8 /* size of io region to request */
-
-/* The following variables can be set by giving module options */
-static int irq[NR_PRIMARY]; /* IRQ for each base port */
-static unsigned int divisor[NR_PRIMARY]; /* custom divisor for each port */
-static unsigned int dma = ESP_DMA_CHANNEL; /* DMA channel */
-static unsigned int rx_trigger = ESP_RX_TRIGGER;
-static unsigned int tx_trigger = ESP_TX_TRIGGER;
-static unsigned int flow_off = ESP_FLOW_OFF;
-static unsigned int flow_on = ESP_FLOW_ON;
-static unsigned int rx_timeout = ESP_RX_TMOUT;
-static unsigned int pio_threshold = ESP_PIO_THRESHOLD;
-
-MODULE_LICENSE("GPL");
-
-module_param_array(irq, int, NULL, 0);
-module_param_array(divisor, uint, NULL, 0);
-module_param(dma, uint, 0);
-module_param(rx_trigger, uint, 0);
-module_param(tx_trigger, uint, 0);
-module_param(flow_off, uint, 0);
-module_param(flow_on, uint, 0);
-module_param(rx_timeout, uint, 0);
-module_param(pio_threshold, uint, 0);
-
-/* END */
-
-static char *dma_buffer;
-static int dma_bytes;
-static struct esp_pio_buffer *free_pio_buf;
-
-#define DMA_BUFFER_SZ 1024
-
-#define WAKEUP_CHARS 1024
-
-static char serial_name[] __initdata = "ESP serial driver";
-static char serial_version[] __initdata = "2.2";
-
-static struct tty_driver *esp_driver;
-
-/*
- * Serial driver configuration section. Here are the various options:
- *
- * SERIAL_PARANOIA_CHECK
- * Check the magic number for the esp_structure where
- * ever possible.
- */
-
-#undef SERIAL_PARANOIA_CHECK
-#define SERIAL_DO_RESTART
-
-#undef SERIAL_DEBUG_INTR
-#undef SERIAL_DEBUG_OPEN
-#undef SERIAL_DEBUG_FLOW
-
-#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
-#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
- tty->name, info->port.flags, \
- serial_driver.refcount, \
- info->port.count, tty->count, s)
-#else
-#define DBG_CNT(s)
-#endif
-
-static struct esp_struct *ports;
-
-static void change_speed(struct esp_struct *info);
-static void rs_wait_until_sent(struct tty_struct *, int);
-
-/*
- * The ESP card has a clock rate of 14.7456 MHz (that is, 2**ESPC_SCALE
- * times the normal 1.8432 Mhz clock of most serial boards).
- */
-#define BASE_BAUD ((1843200 / 16) * (1 << ESPC_SCALE))
-
-/* Standard COM flags (except for COM4, because of the 8514 problem) */
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-
-static inline int serial_paranoia_check(struct esp_struct *info,
- char *name, const char *routine)
-{
-#ifdef SERIAL_PARANOIA_CHECK
- static const char badmagic[] = KERN_WARNING
- "Warning: bad magic number for serial struct (%s) in %s\n";
- static const char badinfo[] = KERN_WARNING
- "Warning: null esp_struct for (%s) in %s\n";
-
- if (!info) {
- printk(badinfo, name, routine);
- return 1;
- }
- if (info->magic != ESP_MAGIC) {
- printk(badmagic, name, routine);
- return 1;
- }
-#endif
- return 0;
-}
-
-static inline unsigned int serial_in(struct esp_struct *info, int offset)
-{
- return inb(info->io_port + offset);
-}
-
-static inline void serial_out(struct esp_struct *info, int offset,
- unsigned char value)
-{
- outb(value, info->io_port+offset);
-}
-
-/*
- * ------------------------------------------------------------
- * rs_stop() and rs_start()
- *
- * This routines are called before setting or resetting tty->stopped.
- * They enable or disable transmitter interrupts, as necessary.
- * ------------------------------------------------------------
- */
-static void rs_stop(struct tty_struct *tty)
-{
- struct esp_struct *info = tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_stop"))
- return;
-
- spin_lock_irqsave(&info->lock, flags);
- if (info->IER & UART_IER_THRI) {
- info->IER &= ~UART_IER_THRI;
- serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, info->IER);
- }
- spin_unlock_irqrestore(&info->lock, flags);
-}
-
-static void rs_start(struct tty_struct *tty)
-{
- struct esp_struct *info = tty->driver_data;
- unsigned long flags;
-
- if (serial_paranoia_check(info, tty->name, "rs_start"))
- return;
-
- spin_lock_irqsave(&info->lock, flags);
- if (info->xmit_cnt && info->xmit_buf && !(info->IER & UART_IER_THRI)) {
- info->IER |= UART_IER_THRI;
- serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, info->IER);
- }
- spin_unlock_irqrestore(&info->lock, flags);
-}
-
-/*
- * ----------------------------------------------------------------------
- *
- * Here starts the interrupt handling routines. All of the following
- * subroutines are declared as inline and are folded into
- * rs_interrupt(). They were separated out for readability's sake.
- *
- * Note: rs_interrupt() is a "fast" interrupt, which means that it
- * runs with interrupts turned off. People who may want to modify
- * rs_interrupt() should try to keep the interrupt handler as fast as
- * possible. After you are done making modifications, it is not a bad
- * idea to do:
- *
- * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
- *
- * and look at the resulting assemble code in serial.s.
- *
- * - Ted Ts'o (tytso@mit.edu), 7-Mar-93
- * -----------------------------------------------------------------------
- */
-
-static DEFINE_SPINLOCK(pio_lock);
-
-static inline struct esp_pio_buffer *get_pio_buffer(void)
-{
- struct esp_pio_buffer *buf;
- unsigned long flags;
-
- spin_lock_irqsave(&pio_lock, flags);
- if (free_pio_buf) {
- buf = free_pio_buf;
- free_pio_buf = buf->next;
- } else {
- buf = kmalloc(sizeof(struct esp_pio_buffer), GFP_ATOMIC);
- }
- spin_unlock_irqrestore(&pio_lock, flags);
- return buf;
-}
-
-static inline void release_pio_buffer(struct esp_pio_buffer *buf)
-{
- unsigned long flags;
- spin_lock_irqsave(&pio_lock, flags);
- buf->next = free_pio_buf;
- free_pio_buf = buf;
- spin_unlock_irqrestore(&pio_lock, flags);
-}
-
-static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
-{
- struct tty_struct *tty = info->port.tty;
- int i;
- struct esp_pio_buffer *pio_buf;
- struct esp_pio_buffer *err_buf;
- unsigned char status_mask;
-
- pio_buf = get_pio_buffer();
-
- if (!pio_buf)
- return;
-
- err_buf = get_pio_buffer();
-
- if (!err_buf) {
- release_pio_buffer(pio_buf);
- return;
- }
-
- status_mask = (info->read_status_mask >> 2) & 0x07;
-
- for (i = 0; i < num_bytes - 1; i += 2) {
- *((unsigned short *)(pio_buf->data + i)) =
- inw(info->io_port + UART_ESI_RX);
- err_buf->data[i] = serial_in(info, UART_ESI_RWS);
- err_buf->data[i + 1] = (err_buf->data[i] >> 3) & status_mask;
- err_buf->data[i] &= status_mask;
- }
-
- if (num_bytes & 0x0001) {
- pio_buf->data[num_bytes - 1] = serial_in(info, UART_ESI_RX);
- err_buf->data[num_bytes - 1] =
- (serial_in(info, UART_ESI_RWS) >> 3) & status_mask;
- }
-
- /* make sure everything is still ok since interrupts were enabled */
- tty = info->port.tty;
-
- if (!tty) {
- release_pio_buffer(pio_buf);
- release_pio_buffer(err_buf);
- info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
- return;
- }
-
- status_mask = (info->ignore_status_mask >> 2) & 0x07;
-
- for (i = 0; i < num_bytes; i++) {
- if (!(err_buf->data[i] & status_mask)) {
- int flag = 0;
-
- if (err_buf->data[i] & 0x04) {
- flag = TTY_BREAK;
- if (info->port.flags & ASYNC_SAK)
- do_SAK(tty);
- } else if (err_buf->data[i] & 0x02)
- flag = TTY_FRAME;
- else if (err_buf->data[i] & 0x01)
- flag = TTY_PARITY;
- tty_insert_flip_char(tty, pio_buf->data[i], flag);
- }
- }
-
- tty_schedule_flip(tty);
-
- info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
- release_pio_buffer(pio_buf);
- release_pio_buffer(err_buf);
-}
-
-static void program_isa_dma(int dma, int dir, unsigned long addr, int len)
-{
- unsigned long flags;
-
- flags = claim_dma_lock();
- disable_dma(dma);
- clear_dma_ff(dma);
- set_dma_mode(dma, dir);
- set_dma_addr(dma, addr);
- set_dma_count(dma, len);
- enable_dma(dma);
- release_dma_lock(flags);
-}
-
-static void receive_chars_dma(struct esp_struct *info, int num_bytes)
-{
- info->stat_flags &= ~ESP_STAT_RX_TIMEOUT;
- dma_bytes = num_bytes;
- info->stat_flags |= ESP_STAT_DMA_RX;
-
- program_isa_dma(dma, DMA_MODE_READ, isa_virt_to_bus(dma_buffer),
- dma_bytes);
- serial_out(info, UART_ESI_CMD1, ESI_START_DMA_RX);
-}
-
-static inline void receive_chars_dma_done(struct esp_struct *info,
- int status)
-{
- struct tty_struct *tty = info->port.tty;
- int num_bytes;
- unsigned long flags;
-
- flags = claim_dma_lock();
- disable_dma(dma);
- clear_dma_ff(dma);
-
- info->stat_flags &= ~ESP_STAT_DMA_RX;
- num_bytes = dma_bytes - get_dma_residue(dma);
- release_dma_lock(flags);
-
- info->icount.rx += num_bytes;
-
- if (num_bytes > 0) {
- tty_insert_flip_string(tty, dma_buffer, num_bytes - 1);
-
- status &= (0x1c & info->read_status_mask);
-
- /* Is the status significant or do we throw the last byte ? */
- if (!(status & info->ignore_status_mask)) {
- int statflag = 0;
-
- if (status & 0x10) {
- statflag = TTY_BREAK;
- (info->icount.brk)++;
- if (info->port.flags & ASYNC_SAK)
- do_SAK(tty);
- } else if (status & 0x08) {
- statflag = TTY_FRAME;
- info->icount.frame++;
- } else if (status & 0x04) {
- statflag = TTY_PARITY;
- info->icount.parity++;
- }
- tty_insert_flip_char(tty, dma_buffer[num_bytes - 1],
- statflag);
- }
- tty_schedule_flip(tty);
- }
-
- if (dma_bytes != num_bytes) {
- num_bytes = dma_bytes - num_bytes;
- dma_bytes = 0;
- receive_chars_dma(info, num_bytes);
- } else
- dma_bytes = 0;
-}
-
-/* Caller must hold info->lock */
-
-static inline void transmit_chars_pio(struct esp_struct *info,
- int space_avail)
-{
- int i;
- struct esp_pio_buffer *pio_buf;
-
- pio_buf = get_pio_buffer();
-
- if (!pio_buf)
- return;
-
- while (space_avail && info->xmit_cnt) {
- if (info->xmit_tail + space_avail <= ESP_XMIT_SIZE) {
- memcpy(pio_buf->data,
- &(info->xmit_buf[info->xmit_tail]),
- space_avail);
- } else {
- i = ESP_XMIT_SIZE - info->xmit_tail;
- memcpy(pio_buf->data,
- &(info->xmit_buf[info->xmit_tail]), i);
- memcpy(&(pio_buf->data[i]), info->xmit_buf,
- space_avail - i);
- }
-
- info->xmit_cnt -= space_avail;
- info->xmit_tail = (info->xmit_tail + space_avail) &
- (ESP_XMIT_SIZE - 1);
-
- for (i = 0; i < space_avail - 1; i += 2) {
- outw(*((unsigned short *)(pio_buf->data + i)),
- info->io_port + UART_ESI_TX);
- }
-
- if (space_avail & 0x0001)
- serial_out(info, UART_ESI_TX,
- pio_buf->data[space_avail - 1]);
-
- if (info->xmit_cnt) {
- serial_out(info, UART_ESI_CMD1, ESI_NO_COMMAND);
- serial_out(info, UART_ESI_CMD1, ESI_GET_TX_AVAIL);
- space_avail = serial_in(info, UART_ESI_STAT1) << 8;
- space_avail |= serial_in(info, UART_ESI_STAT2);
-
- if (space_avail > info->xmit_cnt)
- space_avail = info->xmit_cnt;
- }
- }
-
- if (info->xmit_cnt < WAKEUP_CHARS) {
- if (info->port.tty)
- tty_wakeup(info->port.tty);
-
-#ifdef SERIAL_DEBUG_INTR
- printk("THRE...");
-#endif
-
- if (info->xmit_cnt <= 0) {
- info->IER &= ~UART_IER_THRI;
- serial_out(info, UART_ESI_CMD1,
- ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, info->IER);
- }
- }
-
- release_pio_buffer(pio_buf);
-}
-
-/* Caller must hold info->lock */
-static inline void transmit_chars_dma(struct esp_struct *info, int num_bytes)
-{
- dma_bytes = num_bytes;
-
- if (info->xmit_tail + dma_bytes <= ESP_XMIT_SIZE) {
- memcpy(dma_buffer, &(info->xmit_buf[info->xmit_tail]),
- dma_bytes);
- } else {
- int i = ESP_XMIT_SIZE - info->xmit_tail;
- memcpy(dma_buffer, &(info->xmit_buf[info->xmit_tail]),
- i);
- memcpy(&(dma_buffer[i]), info->xmit_buf, dma_bytes - i);
- }
-
- info->xmit_cnt -= dma_bytes;
- info->xmit_tail = (info->xmit_tail + dma_bytes) & (ESP_XMIT_SIZE - 1);
-
- if (info->xmit_cnt < WAKEUP_CHARS) {
- if (info->port.tty)
- tty_wakeup(info->port.tty);
-
-#ifdef SERIAL_DEBUG_INTR
- printk("THRE...");
-#endif
-
- if (info->xmit_cnt <= 0) {
- info->IER &= ~UART_IER_THRI;
- serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
- serial_out(info, UART_ESI_CMD2, info->IER);
- }
- }
-
- info->stat_flags |= ESP_STAT_DMA_TX;
-
- program_isa_dma(dma, DMA_MODE_WRITE, isa_virt_to_bus(dma_buffer),
- dma_bytes);
- serial_out(info, UART_ESI_CMD1, ESI_START_DMA_TX);
-}
-
-static inline void transmit_chars_dma_done(struct esp_struct *info)
-{
- int num_bytes;
- unsigned long flags;
-
- flags = claim_dma_lock();
- disable_dma(dma);
- clear_dma_ff(dma);
-
- num_bytes = dma_bytes - get_dma_residue(dma);
- info->icount.tx += dma_bytes;
- release_dma_lock(flags);
-</