summaryrefslogtreecommitdiff
path: root/Documentation/serial
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-08-05 17:04:01 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-08-05 17:04:01 -0300
commit57f0f512b273f60d52568b8c6b77e17f5636edc0 (patch)
tree5e910f0e82173f4ef4f51111366a3f1299037a7b /Documentation/serial
Initial import
Diffstat (limited to 'Documentation/serial')
-rw-r--r--Documentation/serial/00-INDEX16
-rw-r--r--Documentation/serial/README.cycladesZ8
-rw-r--r--Documentation/serial/driver460
-rw-r--r--Documentation/serial/moxa-smartio523
-rw-r--r--Documentation/serial/n_gsm.txt89
-rw-r--r--Documentation/serial/rocket.txt189
-rw-r--r--Documentation/serial/serial-rs485.txt136
-rw-r--r--Documentation/serial/tty.txt304
8 files changed, 1725 insertions, 0 deletions
diff --git a/Documentation/serial/00-INDEX b/Documentation/serial/00-INDEX
new file mode 100644
index 000000000..8021a9f29
--- /dev/null
+++ b/Documentation/serial/00-INDEX
@@ -0,0 +1,16 @@
+00-INDEX
+ - this file.
+README.cycladesZ
+ - info on Cyclades-Z firmware loading.
+driver
+ - intro to the low level serial driver.
+moxa-smartio
+ - file with info on installing/using Moxa multiport serial driver.
+n_gsm.txt
+ - GSM 0710 tty multiplexer howto.
+rocket.txt
+ - info on the Comtrol RocketPort multiport serial driver.
+serial-rs485.txt
+ - info about RS485 structures and support in the kernel.
+tty.txt
+ - guide to the locking policies of the tty layer.
diff --git a/Documentation/serial/README.cycladesZ b/Documentation/serial/README.cycladesZ
new file mode 100644
index 000000000..024a69443
--- /dev/null
+++ b/Documentation/serial/README.cycladesZ
@@ -0,0 +1,8 @@
+
+The Cyclades-Z must have firmware loaded onto the card before it will
+operate. This operation should be performed during system startup,
+
+The firmware, loader program and the latest device driver code are
+available from Cyclades at
+ ftp://ftp.cyclades.com/pub/cyclades/cyclades-z/linux/
+
diff --git a/Documentation/serial/driver b/Documentation/serial/driver
new file mode 100644
index 000000000..c415b0ef4
--- /dev/null
+++ b/Documentation/serial/driver
@@ -0,0 +1,460 @@
+
+ Low Level Serial API
+ --------------------
+
+
+This document is meant as a brief overview of some aspects of the new serial
+driver. It is not complete, any questions you have should be directed to
+<rmk@arm.linux.org.uk>
+
+The reference implementation is contained within amba_pl011.c.
+
+
+
+Low Level Serial Hardware Driver
+--------------------------------
+
+The low level serial hardware driver is responsible for supplying port
+information (defined by uart_port) and a set of control methods (defined
+by uart_ops) to the core serial driver. The low level driver is also
+responsible for handling interrupts for the port, and providing any
+console support.
+
+
+Console Support
+---------------
+
+The serial core provides a few helper functions. This includes identifing
+the correct port structure (via uart_get_console) and decoding command line
+arguments (uart_parse_options).
+
+There is also a helper function (uart_write_console) which performs a
+character by character write, translating newlines to CRLF sequences.
+Driver writers are recommended to use this function rather than implementing
+their own version.
+
+
+Locking
+-------
+
+It is the responsibility of the low level hardware driver to perform the
+necessary locking using port->lock. There are some exceptions (which
+are described in the uart_ops listing below.)
+
+There are three locks. A per-port spinlock, a per-port tmpbuf semaphore,
+and an overall semaphore.
+
+From the core driver perspective, the port->lock locks the following
+data:
+
+ port->mctrl
+ port->icount
+ info->xmit.head (circ->head)
+ info->xmit.tail (circ->tail)
+
+The low level driver is free to use this lock to provide any additional
+locking.
+
+The core driver uses the info->tmpbuf_sem lock to prevent multi-threaded
+access to the info->tmpbuf bouncebuffer used for port writes.
+
+The port_sem semaphore is used to protect against ports being added/
+removed or reconfigured at inappropriate times. Since v2.6.27, this
+semaphore has been the 'mutex' member of the tty_port struct, and
+commonly referred to as the port mutex (or port->mutex).
+
+
+uart_ops
+--------
+
+The uart_ops structure is the main interface between serial_core and the
+hardware specific driver. It contains all the methods to control the
+hardware.
+
+ tx_empty(port)
+ This function tests whether the transmitter fifo and shifter
+ for the port described by 'port' is empty. If it is empty,
+ this function should return TIOCSER_TEMT, otherwise return 0.
+ If the port does not support this operation, then it should
+ return TIOCSER_TEMT.
+
+ Locking: none.
+ Interrupts: caller dependent.
+ This call must not sleep
+
+ set_mctrl(port, mctrl)
+ This function sets the modem control lines for port described
+ by 'port' to the state described by mctrl. The relevant bits
+ of mctrl are:
+ - TIOCM_RTS RTS signal.
+ - TIOCM_DTR DTR signal.
+ - TIOCM_OUT1 OUT1 signal.
+ - TIOCM_OUT2 OUT2 signal.
+ - TIOCM_LOOP Set the port into loopback mode.
+ If the appropriate bit is set, the signal should be driven
+ active. If the bit is clear, the signal should be driven
+ inactive.
+
+ Locking: port->lock taken.
+ Interrupts: locally disabled.
+ This call must not sleep
+
+ get_mctrl(port)
+ Returns the current state of modem control inputs. The state
+ of the outputs should not be returned, since the core keeps
+ track of their state. The state information should include:
+ - TIOCM_CAR state of DCD signal
+ - TIOCM_CTS state of CTS signal
+ - TIOCM_DSR state of DSR signal
+ - TIOCM_RI state of RI signal
+ The bit is set if the signal is currently driven active. If
+ the port does not support CTS, DCD or DSR, the driver should
+ indicate that the signal is permanently active. If RI is
+ not available, the signal should not be indicated as active.
+
+ Locking: port->lock taken.
+ Interrupts: locally disabled.
+ This call must not sleep
+
+ stop_tx(port)
+ Stop transmitting characters. This might be due to the CTS
+ line becoming inactive or the tty layer indicating we want
+ to stop transmission due to an XOFF character.
+
+ The driver should stop transmitting characters as soon as
+ possible.
+
+ Locking: port->lock taken.
+ Interrupts: locally disabled.
+ This call must not sleep
+
+ start_tx(port)
+ Start transmitting characters.
+
+ Locking: port->lock taken.
+ Interrupts: locally disabled.
+ This call must not sleep
+
+ send_xchar(port,ch)
+ Transmit a high priority character, even if the port is stopped.
+ This is used to implement XON/XOFF flow control and tcflow(). If
+ the serial driver does not implement this function, the tty core
+ will append the character to the circular buffer and then call
+ start_tx() / stop_tx() to flush the data out.
+
+ Do not transmit if ch == '\0' (__DISABLED_CHAR).
+
+ Locking: none.
+ Interrupts: caller dependent.
+
+ stop_rx(port)
+ Stop receiving characters; the port is in the process of
+ being closed.
+
+ Locking: port->lock taken.
+ Interrupts: locally disabled.
+ This call must not sleep
+
+ enable_ms(port)
+ Enable the modem status interrupts.
+
+ This method may be called multiple times. Modem status
+ interrupts should be disabled when the shutdown method is
+ called.
+
+ Locking: port->lock taken.
+ Interrupts: locally disabled.
+ This call must not sleep
+
+ break_ctl(port,ctl)
+ Control the transmission of a break signal. If ctl is
+ nonzero, the break signal should be transmitted. The signal
+ should be terminated when another call is made with a zero
+ ctl.
+
+ Locking: none.
+ Interrupts: caller dependent.
+ This call must not sleep
+
+ startup(port)
+ Grab any interrupt resources and initialise any low level driver
+ state. Enable the port for reception. It should not activate
+ RTS nor DTR; this will be done via a separate call to set_mctrl.
+
+ This method will only be called when the port is initially opened.
+
+ Locking: port_sem taken.
+ Interrupts: globally disabled.
+
+ shutdown(port)
+ Disable the port, disable any break condition that may be in
+ effect, and free any interrupt resources. It should not disable
+ RTS nor DTR; this will have already been done via a separate
+ call to set_mctrl.
+
+ Drivers must not access port->info once this call has completed.
+
+ This method will only be called when there are no more users of
+ this port.
+
+ Locking: port_sem taken.
+ Interrupts: caller dependent.
+
+ flush_buffer(port)
+ Flush any write buffers, reset any DMA state and stop any
+ ongoing DMA transfers.
+
+ This will be called whenever the port->info->xmit circular
+ buffer is cleared.
+
+ Locking: port->lock taken.
+ Interrupts: locally disabled.
+ This call must not sleep
+
+ set_termios(port,termios,oldtermios)
+ Change the port parameters, including word length, parity, stop
+ bits. Update read_status_mask and ignore_status_mask to indicate
+ the types of events we are interested in receiving. Relevant
+ termios->c_cflag bits are:
+ CSIZE - word size
+ CSTOPB - 2 stop bits
+ PARENB - parity enable
+ PARODD - odd parity (when PARENB is in force)
+ CREAD - enable reception of characters (if not set,
+ still receive characters from the port, but
+ throw them away.
+ CRTSCTS - if set, enable CTS status change reporting
+ CLOCAL - if not set, enable modem status change
+ reporting.
+ Relevant termios->c_iflag bits are:
+ INPCK - enable frame and parity error events to be
+ passed to the TTY layer.
+ BRKINT
+ PARMRK - both of these enable break events to be
+ passed to the TTY layer.
+
+ IGNPAR - ignore parity and framing errors
+ IGNBRK - ignore break errors, If IGNPAR is also
+ set, ignore overrun errors as well.
+ The interaction of the iflag bits is as follows (parity error
+ given as an example):
+ Parity error INPCK IGNPAR
+ n/a 0 n/a character received, marked as
+ TTY_NORMAL
+ None 1 n/a character received, marked as
+ TTY_NORMAL
+ Yes 1 0 character received, marked as
+ TTY_PARITY
+ Yes 1 1 character discarded
+
+ Other flags may be used (eg, xon/xoff characters) if your
+ hardware supports hardware "soft" flow control.
+
+ Locking: caller holds port->mutex
+ Interrupts: caller dependent.
+ This call must not sleep
+
+ pm(port,state,oldstate)
+ Perform any power management related activities on the specified
+ port. State indicates the new state (defined by
+ enum uart_pm_state), oldstate indicates the previous state.
+
+ This function should not be used to grab any resources.
+
+ This will be called when the port is initially opened and finally
+ closed, except when the port is also the system console. This
+ will occur even if CONFIG_PM is not set.
+
+ Locking: none.
+ Interrupts: caller dependent.
+
+ type(port)
+ Return a pointer to a string constant describing the specified
+ port, or return NULL, in which case the string 'unknown' is
+ substituted.
+
+ Locking: none.
+ Interrupts: caller dependent.
+
+ release_port(port)
+ Release any memory and IO region resources currently in use by
+ the port.
+
+ Locking: none.
+ Interrupts: caller dependent.
+
+ request_port(port)
+ Request any memory and IO region resources required by the port.
+ If any fail, no resources should be registered when this function
+ returns, and it should return -EBUSY on failure.
+
+ Locking: none.
+ Interrupts: caller dependent.
+
+ config_port(port,type)
+ Perform any autoconfiguration steps required for the port. `type`
+ contains a bit mask of the required configuration. UART_CONFIG_TYPE
+ indicates that the port requires detection and identification.
+ port->type should be set to the type found, or PORT_UNKNOWN if
+ no port was detected.
+
+ UART_CONFIG_IRQ indicates autoconfiguration of the interrupt signal,
+ which should be probed using standard kernel autoprobing techniques.
+ This is not necessary on platforms where ports have interrupts
+ internally hard wired (eg, system on a chip implementations).
+
+ Locking: none.
+ Interrupts: caller dependent.
+
+ verify_port(port,serinfo)
+ Verify the new serial port information contained within serinfo is
+ suitable for this port type.
+
+ Locking: none.
+ Interrupts: caller dependent.
+
+ ioctl(port,cmd,arg)
+ Perform any port specific IOCTLs. IOCTL commands must be defined
+ using the standard numbering system found in <asm/ioctl.h>
+
+ Locking: none.
+ Interrupts: caller dependent.
+
+ poll_init(port)
+ Called by kgdb to perform the minimal hardware initialization needed
+ to support poll_put_char() and poll_get_char(). Unlike ->startup()
+ this should not request interrupts.
+
+ Locking: tty_mutex and tty_port->mutex taken.
+ Interrupts: n/a.
+
+ poll_put_char(port,ch)
+ Called by kgdb to write a single character directly to the serial
+ port. It can and should block until there is space in the TX FIFO.
+
+ Locking: none.
+ Interrupts: caller dependent.
+ This call must not sleep
+
+ poll_get_char(port)
+ Called by kgdb to read a single character directly from the serial
+ port. If data is available, it should be returned; otherwise
+ the function should return NO_POLL_CHAR immediately.
+
+ Locking: none.
+ Interrupts: caller dependent.
+ This call must not sleep
+
+Other functions
+---------------
+
+uart_update_timeout(port,cflag,baud)
+ Update the FIFO drain timeout, port->timeout, according to the
+ number of bits, parity, stop bits and baud rate.
+
+ Locking: caller is expected to take port->lock
+ Interrupts: n/a
+
+uart_get_baud_rate(port,termios,old,min,max)
+ Return the numeric baud rate for the specified termios, taking
+ account of the special 38400 baud "kludge". The B0 baud rate
+ is mapped to 9600 baud.
+
+ If the baud rate is not within min..max, then if old is non-NULL,
+ the original baud rate will be tried. If that exceeds the
+ min..max constraint, 9600 baud will be returned. termios will
+ be updated to the baud rate in use.
+
+ Note: min..max must always allow 9600 baud to be selected.
+
+ Locking: caller dependent.
+ Interrupts: n/a
+
+uart_get_divisor(port,baud)
+ Return the divsor (baud_base / baud) for the specified baud
+ rate, appropriately rounded.
+
+ If 38400 baud and custom divisor is selected, return the
+ custom divisor instead.
+
+ Locking: caller dependent.
+ Interrupts: n/a
+
+uart_match_port(port1,port2)
+ This utility function can be used to determine whether two
+ uart_port structures describe the same port.
+
+ Locking: n/a
+ Interrupts: n/a
+
+uart_write_wakeup(port)
+ A driver is expected to call this function when the number of
+ characters in the transmit buffer have dropped below a threshold.
+
+ Locking: port->lock should be held.
+ Interrupts: n/a
+
+uart_register_driver(drv)
+ Register a uart driver with the core driver. We in turn register
+ with the tty layer, and initialise the core driver per-port state.
+
+ drv->port should be NULL, and the per-port structures should be
+ registered using uart_add_one_port after this call has succeeded.
+
+ Locking: none
+ Interrupts: enabled
+
+uart_unregister_driver()
+ Remove all references to a driver from the core driver. The low
+ level driver must have removed all its ports via the
+ uart_remove_one_port() if it registered them with uart_add_one_port().
+
+ Locking: none
+ Interrupts: enabled
+
+uart_suspend_port()
+
+uart_resume_port()
+
+uart_add_one_port()
+
+uart_remove_one_port()
+
+Other notes
+-----------
+
+It is intended some day to drop the 'unused' entries from uart_port, and
+allow low level drivers to register their own individual uart_port's with
+the core. This will allow drivers to use uart_port as a pointer to a
+structure containing both the uart_port entry with their own extensions,
+thus:
+
+ struct my_port {
+ struct uart_port port;
+ int my_stuff;
+ };
+
+Modem control lines via GPIO
+----------------------------
+
+Some helpers are provided in order to set/get modem control lines via GPIO.
+
+mctrl_gpio_init(dev, idx):
+ This will get the {cts,rts,...}-gpios from device tree if they are
+ present and request them, set direction etc, and return an
+ allocated structure. devm_* functions are used, so there's no need
+ to call mctrl_gpio_free().
+
+mctrl_gpio_free(dev, gpios):
+ This will free the requested gpios in mctrl_gpio_init().
+ As devm_* function are used, there's generally no need to call
+ this function.
+
+mctrl_gpio_to_gpiod(gpios, gidx)
+ This returns the gpio structure associated to the modem line index.
+
+mctrl_gpio_set(gpios, mctrl):
+ This will sets the gpios according to the mctrl state.
+
+mctrl_gpio_get(gpios, mctrl):
+ This will update mctrl with the gpios values.
diff --git a/Documentation/serial/moxa-smartio b/Documentation/serial/moxa-smartio
new file mode 100644
index 000000000..5d2a33be0
--- /dev/null
+++ b/Documentation/serial/moxa-smartio
@@ -0,0 +1,523 @@
+=============================================================================
+ MOXA Smartio/Industio Family Device Driver Installation Guide
+ for Linux Kernel 2.4.x, 2.6.x
+ Copyright (C) 2008, Moxa Inc.
+=============================================================================
+Date: 01/21/2008
+
+Content
+
+1. Introduction
+2. System Requirement
+3. Installation
+ 3.1 Hardware installation
+ 3.2 Driver files
+ 3.3 Device naming convention
+ 3.4 Module driver configuration
+ 3.5 Static driver configuration for Linux kernel 2.4.x and 2.6.x.
+ 3.6 Custom configuration
+ 3.7 Verify driver installation
+4. Utilities
+5. Setserial
+6. Troubleshooting
+
+-----------------------------------------------------------------------------
+1. Introduction
+
+ The Smartio/Industio/UPCI family Linux driver supports following multiport
+ boards.
+
+ - 2 ports multiport board
+ CP-102U, CP-102UL, CP-102UF
+ CP-132U-I, CP-132UL,
+ CP-132, CP-132I, CP132S, CP-132IS,
+ CI-132, CI-132I, CI-132IS,
+ (C102H, C102HI, C102HIS, C102P, CP-102, CP-102S)
+
+ - 4 ports multiport board
+ CP-104EL,
+ CP-104UL, CP-104JU,
+ CP-134U, CP-134U-I,
+ C104H/PCI, C104HS/PCI,
+ CP-114, CP-114I, CP-114S, CP-114IS, CP-114UL,
+ C104H, C104HS,
+ CI-104J, CI-104JS,
+ CI-134, CI-134I, CI-134IS,
+ (C114HI, CT-114I, C104P)
+ POS-104UL,
+ CB-114,
+ CB-134I
+
+ - 8 ports multiport board
+ CP-118EL, CP-168EL,
+ CP-118U, CP-168U,
+ C168H/PCI,
+ C168H, C168HS,
+ (C168P),
+ CB-108
+
+ This driver and installation procedure have been developed upon Linux Kernel
+ 2.4.x and 2.6.x. This driver supports Intel x86 hardware platform. In order
+ to maintain compatibility, this version has also been properly tested with
+ RedHat, Mandrake, Fedora and S.u.S.E Linux. However, if compatibility problem
+ occurs, please contact Moxa at support@moxa.com.tw.
+
+ In addition to device driver, useful utilities are also provided in this
+ version. They are
+ - msdiag Diagnostic program for displaying installed Moxa
+ Smartio/Industio boards.
+ - msmon Monitor program to observe data count and line status signals.
+ - msterm A simple terminal program which is useful in testing serial
+ ports.
+ - io-irq.exe Configuration program to setup ISA boards. Please note that
+ this program can only be executed under DOS.
+
+ All the drivers and utilities are published in form of source code under
+ GNU General Public License in this version. Please refer to GNU General
+ Public License announcement in each source code file for more detail.
+
+ In Moxa's Web sites, you may always find latest driver at http://www.moxa.com/.
+
+ This version of driver can be installed as Loadable Module (Module driver)
+ or built-in into kernel (Static driver). You may refer to following
+ installation procedure for suitable one. Before you install the driver,
+ please refer to hardware installation procedure in the User's Manual.
+
+ We assume the user should be familiar with following documents.
+ - Serial-HOWTO
+ - Kernel-HOWTO
+
+-----------------------------------------------------------------------------
+2. System Requirement
+ - Hardware platform: Intel x86 machine
+ - Kernel version: 2.4.x or 2.6.x
+ - gcc version 2.72 or later
+ - Maximum 4 boards can be installed in combination
+
+-----------------------------------------------------------------------------
+3. Installation
+
+ 3.1 Hardware installation
+ 3.2 Driver files
+ 3.3 Device naming convention
+ 3.4 Module driver configuration
+ 3.5 Static driver configuration for Linux kernel 2.4.x, 2.6.x.
+ 3.6 Custom configuration
+ 3.7 Verify driver installation
+
+
+ 3.1 Hardware installation
+
+ There are two types of buses, ISA and PCI, for Smartio/Industio
+ family multiport board.
+
+ ISA board
+ ---------
+ You'll have to configure CAP address, I/O address, Interrupt Vector
+ as well as IRQ before installing this driver. Please refer to hardware
+ installation procedure in User's Manual before proceed any further.
+ Please make sure the JP1 is open after the ISA board is set properly.
+
+ PCI/UPCI board
+ --------------
+ You may need to adjust IRQ usage in BIOS to avoid from IRQ conflict
+ with other ISA devices. Please refer to hardware installation
+ procedure in User's Manual in advance.
+
+ PCI IRQ Sharing
+ -----------
+ Each port within the same multiport board shares the same IRQ. Up to
+ 4 Moxa Smartio/Industio PCI Family multiport boards can be installed
+ together on one system and they can share the same IRQ.
+
+
+ 3.2 Driver files
+
+ The driver file may be obtained from ftp, CD-ROM or floppy disk. The
+ first step, anyway, is to copy driver file "mxser.tgz" into specified
+ directory. e.g. /moxa. The execute commands as below.
+
+ # cd /
+ # mkdir moxa
+ # cd /moxa
+ # tar xvf /dev/fd0
+
+ or
+
+ # cd /
+ # mkdir moxa
+ # cd /moxa
+ # cp /mnt/cdrom/<driver directory>/mxser.tgz .
+ # tar xvfz mxser.tgz
+
+
+ 3.3 Device naming convention
+
+ You may find all the driver and utilities files in /moxa/mxser.
+ Following installation procedure depends on the model you'd like to
+ run the driver. If you prefer module driver, please refer to 3.4.
+ If static driver is required, please refer to 3.5.
+
+ Dialin and callout port
+ -----------------------
+ This driver remains traditional serial device properties. There are
+ two special file name for each serial port. One is dial-in port
+ which is named "ttyMxx". For callout port, the naming convention
+ is "cumxx".
+
+ Device naming when more than 2 boards installed
+ -----------------------------------------------
+ Naming convention for each Smartio/Industio multiport board is
+ pre-defined as below.
+
+ Board Num. Dial-in Port Callout port
+ 1st board ttyM0 - ttyM7 cum0 - cum7
+ 2nd board ttyM8 - ttyM15 cum8 - cum15
+ 3rd board ttyM16 - ttyM23 cum16 - cum23
+ 4th board ttyM24 - ttym31 cum24 - cum31
+
+
+ !!!!!!!!!!!!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ Under Kernel 2.6 the cum Device is Obsolete. So use ttyM*
+ device instead.
+ !!!!!!!!!!!!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ Board sequence
+ --------------
+ This driver will activate ISA boards according to the parameter set
+ in the driver. After all specified ISA board activated, PCI board
+ will be installed in the system automatically driven.
+ Therefore the board number is sorted by the CAP address of ISA boards.
+ For PCI boards, their sequence will be after ISA boards and C168H/PCI
+ has higher priority than C104H/PCI boards.
+
+ 3.4 Module driver configuration
+ Module driver is easiest way to install. If you prefer static driver
+ installation, please skip this paragraph.
+
+
+ ------------- Prepare to use the MOXA driver--------------------
+ 3.4.1 Create tty device with correct major number
+ Before using MOXA driver, your system must have the tty devices
+ which are created with driver's major number. We offer one shell
+ script "msmknod" to simplify the procedure.
+ This step is only needed to be executed once. But you still
+ need to do this procedure when:
+ a. You change the driver's major number. Please refer the "3.7"
+ section.
+ b. Your total installed MOXA boards number is changed. Maybe you
+ add/delete one MOXA board.
+ c. You want to change the tty name. This needs to modify the
+ shell script "msmknod"
+
+ The procedure is:
+ # cd /moxa/mxser/driver
+ # ./msmknod
+
+ This shell script will require the major number for dial-in
+ device and callout device to create tty device. You also need
+ to specify the total installed MOXA board number. Default major
+ numbers for dial-in device and callout device are 30, 35. If
+ you need to change to other number, please refer section "3.7"
+ for more detailed procedure.
+ Msmknod will delete any special files occupying the same device
+ naming.
+
+ 3.4.2 Build the MOXA driver and utilities
+ Before using the MOXA driver and utilities, you need compile the
+ all the source code. This step is only need to be executed once.
+ But you still re-compile the source code if you modify the source
+ code. For example, if you change the driver's major number (see
+ "3.7" section), then you need to do this step again.
+
+ Find "Makefile" in /moxa/mxser, then run
+
+ # make clean; make install
+
+ !!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!
+ For Red Hat 9, Red Hat Enterprise Linux AS3/ES3/WS3 & Fedora Core1:
+ # make clean; make installsp1
+
+ For Red Hat Enterprise Linux AS4/ES4/WS4:
+ # make clean; make installsp2
+ !!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!
+
+ The driver files "mxser.o" and utilities will be properly compiled
+ and copied to system directories respectively.
+
+ ------------- Load MOXA driver--------------------
+ 3.4.3 Load the MOXA driver
+
+ # modprobe mxser <argument>
+
+ will activate the module driver. You may run "lsmod" to check
+ if "mxser" is activated. If the MOXA board is ISA board, the
+ <argument> is needed. Please refer to section "3.4.5" for more
+ information.
+
+
+ ------------- Load MOXA driver on boot --------------------
+ 3.4.4 For the above description, you may manually execute
+ "modprobe mxser" to activate this driver and run
+ "rmmod mxser" to remove it.
+ However, it's better to have a boot time configuration to
+ eliminate manual operation. Boot time configuration can be
+ achieved by rc file. We offer one "rc.mxser" file to simplify
+ the procedure under "moxa/mxser/driver".
+
+ But if you use ISA board, please modify the "modprobe ..." command
+ to add the argument (see "3.4.5" section). After modifying the
+ rc.mxser, please try to execute "/moxa/mxser/driver/rc.mxser"
+ manually to make sure the modification is ok. If any error
+ encountered, please try to modify again. If the modification is
+ completed, follow the below step.
+
+ Run following command for setting rc files.
+
+ # cd /moxa/mxser/driver
+ # cp ./rc.mxser /etc/rc.d
+ # cd /etc/rc.d
+
+ Check "rc.serial" is existed or not. If "rc.serial" doesn't exist,
+ create it by vi, run "chmod 755 rc.serial" to change the permission.
+ Add "/etc/rc.d/rc.mxser" in last line,
+
+ Reboot and check if moxa.o activated by "lsmod" command.
+
+ 3.4.5. If you'd like to drive Smartio/Industio ISA boards in the system,
+ you'll have to add parameter to specify CAP address of given
+ board while activating "mxser.o". The format for parameters are
+ as follows.
+
+ modprobe mxser ioaddr=0x???,0x???,0x???,0x???
+ | | | |
+ | | | +- 4th ISA board
+ | | +------ 3rd ISA board
+ | +------------ 2nd ISA board
+ +------------------- 1st ISA board
+
+ 3.5 Static driver configuration for Linux kernel 2.4.x and 2.6.x
+
+ Note: To use static driver, you must install the linux kernel
+ source package.
+
+ 3.5.1 Backup the built-in driver in the kernel.
+ # cd /usr/src/linux/drivers/char
+ # mv mxser.c mxser.c.old
+
+ For Red Hat 7.x user, you need to create link:
+ # cd /usr/src
+ # ln -s linux-2.4 linux
+
+ 3.5.2 Create link
+ # cd /usr/src/linux/drivers/char
+ # ln -s /moxa/mxser/driver/mxser.c mxser.c
+
+ 3.5.3 Add CAP address list for ISA boards. For PCI boards user,
+ please skip this step.
+
+ In module mode, the CAP address for ISA board is given by
+ parameter. In static driver configuration, you'll have to
+ assign it within driver's source code. If you will not
+ install any ISA boards, you may skip to next portion.
+ The instructions to modify driver source code are as
+ below.
+ a. # cd /moxa/mxser/driver
+ # vi mxser.c
+ b. Find the array mxserBoardCAP[] as below.
+
+ static int mxserBoardCAP[]
+ = {0x00, 0x00, 0x00, 0x00};
+
+ c. Change the address within this array using vi. For
+ example, to driver 2 ISA boards with CAP address
+ 0x280 and 0x180 as 1st and 2nd board. Just to change
+ the source code as follows.
+
+ static int mxserBoardCAP[]
+ = {0x280, 0x180, 0x00, 0x00};
+
+ 3.5.4 Setup kernel configuration
+
+ Configure the kernel:
+
+ # cd /usr/src/linux
+ # make menuconfig
+
+ You will go into a menu-driven system. Please select [Character
+ devices][Non-standard serial port support], enable the [Moxa
+ SmartIO support] driver with "[*]" for built-in (not "[M]"), then
+ select [Exit] to exit this program.
+
+ 3.5.5 Rebuild kernel
+ The following are for Linux kernel rebuilding, for your
+ reference only.
+ For appropriate details, please refer to the Linux document.
+
+ a. cd /usr/src/linux
+ b. make clean /* take a few minutes */
+ c. make dep /* take a few minutes */
+ d. make bzImage /* take probably 10-20 minutes */
+ e. make install /* copy boot image to correct position */
+ f. Please make sure the boot kernel (vmlinuz) is in the
+ correct position.
+ g. If you use 'lilo' utility, you should check /etc/lilo.conf
+ 'image' item specified the path which is the 'vmlinuz' path,
+ or you will load wrong (or old) boot kernel image (vmlinuz).
+ After checking /etc/lilo.conf, please run "lilo".
+
+ Note that if the result of "make bzImage" is ERROR, then you have to
+ go back to Linux configuration Setup. Type "make menuconfig" in
+ directory /usr/src/linux.
+
+
+ 3.5.6 Make tty device and special file
+ # cd /moxa/mxser/driver
+ # ./msmknod
+
+ 3.5.7 Make utility
+ # cd /moxa/mxser/utility
+ # make clean; make install
+
+ 3.5.8 Reboot
+
+
+
+ 3.6 Custom configuration
+ Although this driver already provides you default configuration, you
+ still can change the device name and major number. The instruction to
+ change these parameters are shown as below.
+
+ Change Device name
+ ------------------
+ If you'd like to use other device names instead of default naming
+ convention, all you have to do is to modify the internal code
+ within the shell script "msmknod". First, you have to open "msmknod"
+ by vi. Locate each line contains "ttyM" and "cum" and change them
+ to the device name you desired. "msmknod" creates the device names
+ you need next time executed.
+
+ Change Major number
+ -------------------
+ If major number 30 and 35 had been occupied, you may have to select
+ 2 free major numbers for this driver. There are 3 steps to change
+ major numbers.
+
+ 3.6.1 Find free major numbers
+ In /proc/devices, you may find all the major numbers occupied
+ in the system. Please select 2 major numbers that are available.
+ e.g. 40, 45.
+ 3.6.2 Create special files
+ Run /moxa/mxser/driver/msmknod to create special files with
+ specified major numbers.
+ 3.6.3 Modify driver with new major number
+ Run vi to open /moxa/mxser/driver/mxser.c. Locate the line
+ contains "MXSERMAJOR". Change the content as below.
+ #define MXSERMAJOR 40
+ #define MXSERCUMAJOR 45
+ 3.6.4 Run "make clean; make install" in /moxa/mxser/driver.
+
+ 3.7 Verify driver installation
+ You may refer to /var/log/messages to check the latest status
+ log reported by this driver whenever it's activated.
+
+-----------------------------------------------------------------------------
+4. Utilities
+ There are 3 utilities contained in this driver. They are msdiag, msmon and
+ msterm. These 3 utilities are released in form of source code. They should
+ be compiled into executable file and copied into /usr/bin.
+
+ Before using these utilities, please load driver (refer 3.4 & 3.5) and
+ make sure you had run the "msmknod" utility.
+
+ msdiag - Diagnostic
+ --------------------
+ This utility provides the function to display what Moxa Smartio/Industio
+ board found by driver in the system.
+
+ msmon - Port Monitoring
+ -----------------------
+ This utility gives the user a quick view about all the MOXA ports'
+ activities. One can easily learn each port's total received/transmitted
+ (Rx/Tx) character count since the time when the monitoring is started.
+ Rx/Tx throughputs per second are also reported in interval basis (e.g.
+ the last 5 seconds) and in average basis (since the time the monitoring
+ is started). You can reset all ports' count by <HOME> key. <+> <->
+ (plus/minus) keys to change the displaying time interval. Press <ENTER>
+ on the port, that cursor stay, to view the port's communication
+ parameters, signal status, and input/output queue.
+
+ msterm - Terminal Emulation
+ ---------------------------
+ This utility provides data sending and receiving ability of all tty ports,
+ especially for MOXA ports. It is quite useful for testing simple
+ application, for example, sending AT command to a modem connected to the
+ port or used as a terminal for login purpose. Note that this is only a
+ dumb terminal emulation without handling full screen operation.
+
+-----------------------------------------------------------------------------
+5. Setserial
+
+ Supported Setserial parameters are listed as below.
+
+ uart set UART type(16450-->disable FIFO, 16550A-->enable FIFO)
+ close_delay set the amount of time(in 1/100 of a second) that DTR
+ should be kept low while being closed.
+ closing_wait set the amount of time(in 1/100 of a second) that the
+ serial port should wait for data to be drained while
+ being closed, before the receiver is disable.
+ spd_hi Use 57.6kb when the application requests 38.4kb.
+ spd_vhi Use 115.2kb when the application requests 38.4kb.
+ spd_shi Use 230.4kb when the application requests 38.4kb.
+ spd_warp Use 460.8kb when the application requests 38.4kb.
+ spd_normal Use 38.4kb when the application requests 38.4kb.
+ spd_cust Use the custom divisor to set the speed when the
+ application requests 38.4kb.
+ divisor This option set the custom division.
+ baud_base This option set the base baud rate.
+
+-----------------------------------------------------------------------------
+6. Troubleshooting
+
+ The boot time error messages and solutions are stated as clearly as
+ possible. If all the possible solutions fail, please contact our technical
+ support team to get more help.
+
+
+ Error msg: More than 4 Moxa Smartio/Industio family boards found. Fifth board
+ and after are ignored.
+ Solution:
+ To avoid this problem, please unplug fifth and after board, because Moxa
+ driver supports up to 4 boards.
+
+ Error msg: Request_irq fail, IRQ(?) may be conflict with another device.
+ Solution:
+ Other PCI or ISA devices occupy the assigned IRQ. If you are not sure
+ which device causes the situation, please check /proc/interrupts to find
+ free IRQ and simply change another free IRQ for Moxa board.
+
+ Error msg: Board #: C1xx Series(CAP=xxx) interrupt number invalid.
+ Solution:
+ Each port within the same multiport board shares the same IRQ. Please set
+ one IRQ (IRQ doesn't equal to zero) for one Moxa board.
+
+ Error msg: No interrupt vector be set for Moxa ISA board(CAP=xxx).
+ Solution:
+ Moxa ISA board needs an interrupt vector.Please refer to user's manual
+ "Hardware Installation" chapter to set interrupt vector.
+
+ Error msg: Couldn't install MOXA Smartio/Industio family driver!
+ Solution:
+ Load Moxa driver fail, the major number may conflict with other devices.
+ Please refer to previous section 3.7 to change a free major number for
+ Moxa driver.
+
+ Error msg: Couldn't install MOXA Smartio/Industio family callout driver!
+ Solution:
+ Load Moxa callout driver fail, the callout device major number may
+ conflict with other devices. Please refer to previous section 3.7 to
+ change a free callout device major number for Moxa driver.
+
+
+-----------------------------------------------------------------------------
+
diff --git a/Documentation/serial/n_gsm.txt b/Documentation/serial/n_gsm.txt
new file mode 100644
index 000000000..a5d91126a
--- /dev/null
+++ b/Documentation/serial/n_gsm.txt
@@ -0,0 +1,89 @@
+n_gsm.c GSM 0710 tty multiplexor HOWTO
+===================================================
+
+This line discipline implements the GSM 07.10 multiplexing protocol
+detailed in the following 3GPP document :
+http://www.3gpp.org/ftp/Specs/archive/07_series/07.10/0710-720.zip
+
+This document give some hints on how to use this driver with GPRS and 3G
+modems connected to a physical serial port.
+
+How to use it
+-------------
+1- initialize the modem in 0710 mux mode (usually AT+CMUX= command) through
+its serial port. Depending on the modem used, you can pass more or less
+parameters to this command,
+2- switch the serial line to using the n_gsm line discipline by using
+TIOCSETD ioctl,
+3- configure the mux using GSMIOC_GETCONF / GSMIOC_SETCONF ioctl,
+
+Major parts of the initialization program :
+(a good starting point is util-linux-ng/sys-utils/ldattach.c)
+#include <linux/gsmmux.h>
+#define N_GSM0710 21 /* GSM 0710 Mux */
+#define DEFAULT_SPEED B115200
+#define SERIAL_PORT /dev/ttyS0
+
+ int ldisc = N_GSM0710;
+ struct gsm_config c;
+ struct termios configuration;
+
+ /* open the serial port connected to the modem */
+ fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY);
+
+ /* configure the serial port : speed, flow control ... */
+
+ /* send the AT commands to switch the modem to CMUX mode
+ and check that it's successful (should return OK) */
+ write(fd, "AT+CMUX=0\r", 10);
+
+ /* experience showed that some modems need some time before
+ being able to answer to the first MUX packet so a delay
+ may be needed here in some case */
+ sleep(3);
+
+ /* use n_gsm line discipline */
+ ioctl(fd, TIOCSETD, &ldisc);
+
+ /* get n_gsm configuration */
+ ioctl(fd, GSMIOC_GETCONF, &c);
+ /* we are initiator and need encoding 0 (basic) */
+ c.initiator = 1;
+ c.encapsulation = 0;
+ /* our modem defaults to a maximum size of 127 bytes */
+ c.mru = 127;
+ c.mtu = 127;
+ /* set the new configuration */
+ ioctl(fd, GSMIOC_SETCONF, &c);
+
+ /* and wait for ever to keep the line discipline enabled */
+ daemon(0,0);
+ pause();
+
+4- create the devices corresponding to the "virtual" serial ports (take care,
+each modem has its configuration and some DLC have dedicated functions,
+for example GPS), starting with minor 1 (DLC0 is reserved for the management
+of the mux)
+
+MAJOR=`cat /proc/devices |grep gsmtty | awk '{print $1}`
+for i in `seq 1 4`; do
+ mknod /dev/ttygsm$i c $MAJOR $i
+done
+
+5- use these devices as plain serial ports.
+for example, it's possible :
+- and to use gnokii to send / receive SMS on ttygsm1
+- to use ppp to establish a datalink on ttygsm2
+
+6- first close all virtual ports before closing the physical port.
+
+Additional Documentation
+------------------------
+More practical details on the protocol and how it's supported by industrial
+modems can be found in the following documents :
+http://www.telit.com/module/infopool/download.php?id=616
+http://www.u-blox.com/images/downloads/Product_Docs/LEON-G100-G200-MuxImplementation_ApplicationNote_%28GSM%20G1-CS-10002%29.pdf
+http://www.sierrawireless.com/Support/Downloads/AirPrime/WMP_Series/~/media/Support_Downloads/AirPrime/Application_notes/CMUX_Feature_Application_Note-Rev004.ashx
+http://wm.sim.com/sim/News/photo/2010721161442.pdf
+
+11-03-08 - Eric Bénard - <eric@eukrea.com>
diff --git a/Documentation/serial/rocket.txt b/Documentation/serial/rocket.txt
new file mode 100644
index 000000000..60b039891
--- /dev/null
+++ b/Documentation/serial/rocket.txt
@@ -0,0 +1,189 @@
+Comtrol(tm) RocketPort(R)/RocketModem(TM) Series
+Device Driver for the Linux Operating System
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+PRODUCT OVERVIEW
+----------------
+
+This driver provides a loadable kernel driver for the Comtrol RocketPort
+and RocketModem PCI boards. These boards provide, 2, 4, 8, 16, or 32
+high-speed serial ports or modems. This driver supports up to a combination
+of four RocketPort or RocketModems boards in one machine simultaneously.
+This file assumes that you are using the RocketPort driver which is
+integrated into the kernel sources.
+
+The driver can also be installed as an external module using the usual
+"make;make install" routine. This external module driver, obtainable
+from the Comtrol website listed below, is useful for updating the driver
+or installing it into kernels which do not have the driver configured
+into them. Installations instructions for the external module
+are in the included README and HW_INSTALL files.
+
+RocketPort ISA and RocketModem II PCI boards currently are only supported by
+this driver in module form.
+
+The RocketPort ISA board requires I/O ports to be configured by the DIP
+switches on the board. See the section "ISA Rocketport Boards" below for
+information on how to set the DIP switches.
+
+You pass the I/O port to the driver using the following module parameters:
+
+board1 : I/O port for the first ISA board
+board2 : I/O port for the second ISA board
+board3 : I/O port for the third ISA board
+board4 : I/O port for the fourth ISA board
+
+There is a set of utilities and scripts provided with the external driver
+( downloadable from http://www.comtrol.com ) that ease the configuration and
+setup of the ISA cards.
+
+The RocketModem II PCI boards require firmware to be loaded into the card
+before it will function. The driver has only been tested as a module for this
+board.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+INSTALLATION PROCEDURES
+-----------------------
+
+RocketPort/RocketModem PCI cards require no driver configuration, they are
+automatically detected and configured.
+
+The RocketPort driver can be installed as a module (recommended) or built
+into the kernel. This is selected, as for other drivers, through the `make config`
+command from the root of the Linux source tree during the kernel build process.
+
+The RocketPort/RocketModem serial ports installed by this driver are assigned
+device major number 46, and will be named /dev/ttyRx, where x is the port number
+starting at zero (ex. /dev/ttyR0, /devttyR1, ...). If you have multiple cards
+installed in the system, the mapping of port names to serial ports is displayed
+in the system log at /var/log/messages.
+
+If installed as a module, the module must be loaded. This can be done
+manually by entering "modprobe rocket". To have the module loaded automatically
+upon system boot, edit a /etc/modprobe.d/*.conf file and add the line
+"alias char-major-46 rocket".
+
+In order to use the ports, their device names (nodes) must be created with mknod.
+This is only required once, the system will retain the names once created. To
+create the RocketPort/RocketModem device names, use the command
+"mknod /dev/ttyRx c 46 x" where x is the port number starting at zero. For example:
+
+>mknod /dev/ttyR0 c 46 0
+>mknod /dev/ttyR1 c 46 1
+>mknod /dev/ttyR2 c 46 2
+
+The Linux script MAKEDEV will create the first 16 ttyRx device names (nodes)
+for you:
+
+>/dev/MAKEDEV ttyR
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+ISA Rocketport Boards
+---------------------
+
+You must assign and configure the I/O addresses used by the ISA Rocketport
+card before installing and using it. This is done by setting a set of DIP
+switches on the Rocketport board.
+
+
+SETTING THE I/O ADDRESS
+-----------------------
+
+Before installing RocketPort(R) or RocketPort RA boards, you must find
+a range of I/O addresses for it to use. The first RocketPort card
+requires a 68-byte contiguous block of I/O addresses, starting at one
+of the following: 0x100h, 0x140h, 0x180h, 0x200h, 0x240h, 0x280h,
+0x300h, 0x340h, 0x380h. This I/O address must be reflected in the DIP
+switches of *all* of the Rocketport cards.
+
+The second, third, and fourth RocketPort cards require a 64-byte
+contiguous block of I/O addresses, starting at one of the following
+I/O addresses: 0x100h, 0x140h, 0x180h, 0x1C0h, 0x200h, 0x240h, 0x280h,
+0x2C0h, 0x300h, 0x340h, 0x380h, 0x3C0h. The I/O address used by the
+second, third, and fourth Rocketport cards (if present) are set via
+software control. The DIP switch settings for the I/O address must be
+set to the value of the first Rocketport cards.
+
+In order to distinguish each of the card from the others, each card
+must have a unique board ID set on the dip switches. The first
+Rocketport board must be set with the DIP switches corresponding to
+the first board, the second board must be set with the DIP switches
+corresponding to the second board, etc. IMPORTANT: The board ID is
+the only place where the DIP switch settings should differ between the
+various Rocketport boards in a system.
+
+The I/O address range used by any of the RocketPort cards must not
+conflict with any other cards in the system, including other
+RocketPort cards. Below, you will find a list of commonly used I/O
+address ranges which may be in use by other devices in your system.
+On a Linux system, "cat /proc/ioports" will also be helpful in
+identifying what I/O addresses are being used by devices on your
+system.
+
+Remember, the FIRST RocketPort uses 68 I/O addresses. So, if you set it
+for 0x100, it will occupy 0x100 to 0x143. This would mean that you
+CAN NOT set the second, third or fourth board for address 0x140 since
+the first 4 bytes of that range are used by the first board. You would
+need to set the second, third, or fourth board to one of the next available
+blocks such as 0x180.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+RocketPort and RocketPort RA SW1 Settings:
+
+ +-------------------------------+
+ | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
+ +-------+-------+---------------+
+ | Unused| Card | I/O Port Block|
+ +-------------------------------+
+
+DIP Switches DIP Switches
+7 8 6 5
+=================== ===================
+On On UNUSED, MUST BE ON. On On First Card <==== Default
+ On Off Second Card
+ Off On Third Card
+ Off Off Fourth Card
+
+DIP Switches I/O Address Range
+4 3 2 1 Used by the First Card
+=====================================
+On Off On Off 100-143
+On Off Off On 140-183
+On Off Off Off 180-1C3 <==== Default
+Off On On Off 200-243
+Off On Off On 240-283
+Off On Off Off 280-2C3
+Off Off On Off 300-343
+Off Off Off On 340-383
+Off Off Off Off 380-3C3
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+REPORTING BUGS
+--------------
+
+For technical support, please provide the following
+information: Driver version, kernel release, distribution of
+kernel, and type of board you are using. Error messages and log
+printouts port configuration details are especially helpful.
+
+USA
+ Phone: (612) 494-4100
+ FAX: (612) 494-4199
+ email: support@comtrol.com
+
+Comtrol Europe
+ Phone: +44 (0) 1 869 323-220
+ FAX: +44 (0) 1 869 323-211
+ email: support@comtrol.co.uk
+
+Web: http://www.comtrol.com
+FTP: ftp.comtrol.com
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+
diff --git a/Documentation/serial/serial-rs485.txt b/Documentation/serial/serial-rs485.txt
new file mode 100644
index 000000000..39dac9542
--- /dev/null
+++ b/Documentation/serial/serial-rs485.txt
@@ -0,0 +1,136 @@
+ RS485 SERIAL COMMUNICATIONS
+
+1. INTRODUCTION
+
+ EIA-485, also known as TIA/EIA-485 or RS-485, is a standard defining the
+ electrical characteristics of drivers and receivers for use in balanced
+ digital multipoint systems.
+ This standard is widely used for communications in industrial automation
+ because it can be used effectively over long distances and in electrically
+ noisy environments.
+
+2. HARDWARE-RELATED CONSIDERATIONS
+
+ Some CPUs/UARTs (e.g., Atmel AT91 or 16C950 UART) contain a built-in
+ half-duplex mode capable of automatically controlling line direction by
+ toggling RTS or DTR signals. That can be used to control external
+ half-duplex hardware like an RS485 transceiver or any RS232-connected
+ half-duplex devices like some modems.
+
+ For these microcontrollers, the Linux driver should be made capable of
+ working in both modes, and proper ioctls (see later) should be made
+ available at user-level to allow switching from one mode to the other, and
+ vice versa.
+
+3. DATA STRUCTURES ALREADY AVAILABLE IN THE KERNEL
+
+ The Linux kernel provides the serial_rs485 structure (see [1]) to handle
+ RS485 communications. This data structure is used to set and configure RS485
+ parameters in the platform data and in ioctls.
+
+ The device tree can also provide RS485 boot time parameters (see [2]
+ for bindings). The driver is in charge of filling this data structure from
+ the values given by the device tree.
+
+ Any driver for devices capable of working both as RS232 and RS485 should
+ provide at least the following ioctls:
+
+ - TIOCSRS485 (typically associated with number 0x542F). This ioctl is used
+ to enable/disable RS485 mode from user-space
+
+ - TIOCGRS485 (typically associated with number 0x542E). This ioctl is used
+ to get RS485 mode from kernel-space (i.e., driver) to user-space.
+
+ In other words, the serial driver should contain a code similar to the next
+ one:
+
+ static struct uart_ops atmel_pops = {
+ /* ... */
+ .ioctl = handle_ioctl,
+ };
+
+ static int handle_ioctl(struct uart_port *port,
+ unsigned int cmd,
+ unsigned long arg)
+ {
+ struct serial_rs485 rs485conf;
+
+ switch (cmd) {
+ case TIOCSRS485:
+ if (copy_from_user(&rs485conf,
+ (struct serial_rs485 *) arg,
+ sizeof(rs485conf)))
+ return -EFAULT;
+
+ /* ... */
+ break;
+
+ case TIOCGRS485:
+ if (copy_to_user((struct serial_rs485 *) arg,
+ ...,
+ sizeof(rs485conf)))
+ return -EFAULT;
+ /* ... */
+ break;
+
+ /* ... */
+ }
+ }
+
+
+4. USAGE FROM USER-LEVEL
+
+ From user-level, RS485 configuration can be get/set using the previous
+ ioctls. For instance, to set RS485 you can use the following code:
+
+ #include <linux/serial.h>
+
+ /* Driver-specific ioctls: */
+ #define TIOCGRS485 0x542E
+ #define TIOCSRS485 0x542F
+
+ /* Open your specific device (e.g., /dev/mydevice): */
+ int fd = open ("/dev/mydevice", O_RDWR);
+ if (fd < 0) {
+ /* Error handling. See errno. */
+ }
+
+ struct serial_rs485 rs485conf;
+
+ /* Enable RS485 mode: */
+ rs485conf.flags |= SER_RS485_ENABLED;
+
+ /* Set logical level for RTS pin equal to 1 when sending: */
+ rs485conf.flags |= SER_RS485_RTS_ON_SEND;
+ /* or, set logical level for RTS pin equal to 0 when sending: */
+ rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);
+
+ /* Set logical level for RTS pin equal to 1 after sending: */
+ rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
+ /* or, set logical level for RTS pin equal to 0 after sending: */
+ rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
+
+ /* Set rts delay before send, if needed: */
+ rs485conf.delay_rts_before_send = ...;
+
+ /* Set rts delay after send, if needed: */
+ rs485conf.delay_rts_after_send = ...;
+
+ /* Set this flag if you want to receive data even whilst sending data */
+ rs485conf.flags |= SER_RS485_RX_DURING_TX;
+
+ if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
+ /* Error handling. See errno. */
+ }
+
+ /* Use read() and write() syscalls here... */
+
+ /* Close the device when finished: */
+ if (close (fd) < 0) {
+ /* Error handling. See errno. */
+ }
+
+5. REFERENCES
+
+ [1] include/uapi/linux/serial.h
+ [2] Documentation/devicetree/bindings/serial/rs485.txt
diff --git a/Documentation/serial/tty.txt b/Documentation/serial/tty.txt
new file mode 100644
index 000000000..dbe6623fe
--- /dev/null
+++ b/Documentation/serial/tty.txt
@@ -0,0 +1,304 @@
+
+ The Lockronomicon
+
+Your guide to the ancient and twisted locking policies of the tty layer and
+the warped logic behind them. Beware all ye who read on.
+
+FIXME: still need to work out the full set of BKL assumptions and document
+them so they can eventually be killed off.
+
+
+Line Discipline
+---------------
+
+Line disciplines are registered with tty_register_ldisc() passing the
+discipline number and the ldisc structure. At the point of registration the
+discipline must be ready to use and it is possible it will get used before
+the call returns success. If the call returns an error then it won't get
+called. Do not re-use ldisc numbers as they are part of the userspace ABI
+and writing over an existing ldisc will cause demons to eat your computer.
+After the return the ldisc data has been copied so you may free your own
+copy of the structure. You must not re-register over the top of the line
+discipline even with the same data or your computer again will be eaten by
+demons.
+
+In order to remove a line discipline call tty_unregister_ldisc().
+In ancient times this always worked. In modern times the function will
+return -EBUSY if the ldisc is currently in use. Since the ldisc referencing
+code manages the module counts this should not usually be a concern.
+
+Heed this warning: the reference count field of the registered copies of the
+tty_ldisc structure in the ldisc table counts the number of lines using this
+discipline. The reference count of the tty_ldisc structure within a tty
+counts the number of active users of the ldisc at this instant. In effect it
+counts the number of threads of execution within an ldisc method (plus those
+about to enter and exit although this detail matters not).
+
+Line Discipline Methods
+-----------------------
+
+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. 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
+ execution no further users will enter the
+ ldisc code for this tty. Can sleep.
+
+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.
+ The return value is ignored. Can sleep.
+
+write() - A process is writing data through the line
+ discipline. Multiple write calls are serialized
+ by the tty layer for the ldisc. May sleep.
+
+flush_buffer() - (optional) May be called at any point between
+ open and close, and instructs the line discipline
+ to empty its input buffer.
+
+chars_in_buffer() - (optional) Report the number of bytes in the input
+ buffer.
+
+set_termios() - (optional) Called on termios structure changes.
+ The caller passes the old termios data and the
+ current data is in the tty. Called under the
+ termios semaphore so allowed to sleep. Serialized
+ against itself only.
+
+read() - Move data from the line discipline to the user.
+ Multiple read calls may occur in parallel and the
+ ldisc must deal with serialization issues. May
+ sleep.
+
+poll() - Check the status for the poll/select calls. Multiple
+ poll calls may occur in parallel. May sleep.
+
+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
+ for processing. Semantics currently rather
+ mysterious 8(
+
+write_wakeup() - May be called at any point between open and close.
+ The TTY_DO_WRITE_WAKEUP flag indicates if a call
+ is needed but always races versus calls. Thus the
+ ldisc must be careful about setting order and to
+ handle unexpected calls. Must not sleep.
+
+ The driver is forbidden from calling this directly
+ from the ->write call from the ldisc as the ldisc
+ is permitted to call the driver write method from
+ this function. In such a situation defer it.
+
+dcd_change() - Report to the tty line the current DCD pin status
+ changes and the relative timestamp. The timestamp
+ cannot be NULL.
+
+
+Driver Access
+
+Line discipline methods can call the following methods of the underlying
+hardware driver through the function pointers within the tty->driver
+structure:
+
+write() Write a block of characters to the tty device.
+ Returns the number of characters accepted. The
+ character buffer passed to this method is already
+ in kernel space.
+
+put_char() Queues a character for writing to the tty device.
+ If there is no room in the queue, the character is
+ ignored.
+
+flush_chars() (Optional) If defined, must be called after
+ queueing characters with put_char() in order to
+ start transmission.
+
+write_room() Returns the numbers of characters the tty driver
+ will accept for queueing to be written.
+
+ioctl() Invoke device specific ioctl.
+ Expects data pointers to refer to userspace.
+ Returns ENOIOCTLCMD for unrecognized ioctl numbers.
+
+set_termios() Notify the tty driver that the device's termios
+ settings have changed. New settings are in
+ tty->termios. Previous settings should be passed in
+ the "old" argument.
+
+ The API is defined such that the driver should return
+ the actual modes selected. This means that the
+ driver function is responsible for modifying any
+ bits in the request it cannot fulfill to indicate
+ the actual modes being used. A device with no
+ hardware capability for change (e.g. a USB dongle or
+ virtual port) can provide NULL for this method.
+
+throttle() Notify the tty driver that input buffers for the
+ line discipline are close to full, and it should
+ somehow signal that no more characters should be
+ sent to the tty.
+
+unthrottle() Notify the tty driver that characters can now be
+ sent to the tty without fear of overrunning the
+ input buffers of the line disciplines.
+
+stop() Ask the tty driver to stop outputting characters
+ to the tty device.
+
+start() Ask the tty driver to resume sending characters
+ to the tty device.
+
+hangup() Ask the tty driver to hang up the tty device.
+
+break_ctl() (Optional) Ask the tty driver to turn on or off
+ BREAK status on the RS-232 port. If state is -1,
+ then the BREAK status should be turned on; if
+ state is 0, then BREAK should be turned off.
+ If this routine is not implemented, use ioctls
+ TIOCSBRK / TIOCCBRK instead.
+
+wait_until_sent() Waits until the device has written out all of the
+ characters in its transmitter FIFO.
+
+send_xchar() Send a high-priority XON/XOFF character to the device.
+
+
+Flags
+
+Line discipline methods have access to tty->flags field containing the
+following interesting flags:
+
+TTY_THROTTLED Driver input is throttled. The ldisc should call
+ tty->driver->unthrottle() in order to resume
+ reception when it is ready to process more data.
+
+TTY_DO_WRITE_WAKEUP If set, causes the driver to call the ldisc's
+ write_wakeup() method in order to resume
+ transmission when it can accept more data
+ to transmit.
+
+TTY_IO_ERROR If set, causes all subsequent userspace read/write
+ calls on the tty to fail, returning -EIO.
+
+TTY_OTHER_CLOSED Device is a pty and the other side has closed.
+
+TTY_OTHER_DONE Device is a pty and the other side has closed and
+ all pending input processing has been completed.
+
+TTY_NO_WRITE_SPLIT Prevent driver from splitting up writes into
+ smaller chunks.
+
+
+Locking
+
+Callers to the line discipline functions from the tty layer are required to
+take line discipline locks. The same is true of calls from the driver side
+but not yet enforced.
+
+Three calls are now provided
+
+ ldisc = tty_ldisc_ref(tty);
+
+takes a handle to the line discipline in the tty and returns it. If no ldisc
+is currently attached or the ldisc is being closed and re-opened at this
+point then NULL is returned. While this handle is held the ldisc will not
+change or go away.
+
+ tty_ldisc_deref(ldisc)
+
+Returns the ldisc reference and allows the ldisc to be closed. Returning the
+reference takes away your right to call the ldisc functions until you take
+a new reference.
+
+ ldisc = tty_ldisc_ref_wait(tty);
+
+Performs the same function as tty_ldisc_ref except that it will wait for an
+ldisc change to complete and then return a reference to the new ldisc.
+
+While these functions are slightly slower than the old code they should have
+minimal impact as most receive logic uses the flip buffers and they only
+need to take a reference when they push bits up through the driver.
+
+A caution: The ldisc->open(), ldisc->close() and driver->set_ldisc
+functions are called with the ldisc unavailable. Thus tty_ldisc_ref will
+fail in this situation if used within these functions. Ldisc and driver
+code calling its own functions must be careful in this case.
+
+
+Driver Interface
+----------------
+
+open() - Called when a device is opened. May sleep
+
+close() - Called when a device is closed. At the point of
+ return from this call the driver must make no
+ further ldisc calls of any kind. May sleep
+
+write() - Called to write bytes to the device. May not
+ sleep. May occur in parallel in special cases.
+ Because this includes panic paths drivers generally
+ shouldn't try and do clever locking here.
+
+put_char() - Stuff a single character onto the queue. The
+ driver is guaranteed following up calls to
+ flush_chars.
+
+flush_chars() - Ask the kernel to write put_char queue
+
+write_room() - Return the number of characters that can be stuffed
+ into the port buffers without overflow (or less).
+ The ldisc is responsible for being intelligent
+ about multi-threading of write_room/write calls
+
+ioctl() - Called when an ioctl may be for the driver
+
+set_termios() - Called on termios change, serialized against
+ itself by a semaphore. May sleep.
+
+set_ldisc() - Notifier for discipline change. At the point this
+ is done the discipline is not yet usable. Can now
+ sleep (I think)
+
+throttle() - Called by the ldisc to ask the driver to do flow
+ control. Serialization including with unthrottle
+ is the job of the ldisc layer.
+
+unthrottle() - Called by the ldisc to ask the driver to stop flow
+ control.
+
+stop() - Ldisc notifier to the driver to stop output. As with
+ throttle the serializations with start() are down
+ to the ldisc layer.
+
+start() - Ldisc notifier to the driver to start output.
+
+hangup() - Ask the tty driver to cause a hangup initiated
+ from the host side. [Can sleep ??]
+
+break_ctl() - Send RS232 break. Can sleep. Can get called in
+ parallel, driver must serialize (for now), and
+ with write calls.
+
+wait_until_sent() - Wait for characters to exit the hardware queue
+ of the driver. Can sleep
+
+send_xchar() - Send XON/XOFF and if possible jump the queue with
+ it in order to get fast flow control responses.
+ Cannot sleep ??
+