linux/drivers/tty/moxa.c

// SPDX-License-Identifier: GPL-2.0+
/*****************************************************************************/
/*
 *           moxa.c  -- MOXA Intellio family multiport serial driver.
 *
 *      Copyright (C) 1999-2000  Moxa Technologies ([email protected]).
 *      Copyright (c) 2007 Jiri Slaby <[email protected]>
 *
 *      This code is loosely based on the Linux serial driver, written by
 *      Linus Torvalds, Theodore T'so and others.
 */

/*
 *    MOXA Intellio Series Driver
 *      for             : LINUX
 *      date            : 1999/1/7
 *      version         : 5.1
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/firmware.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/serial.h>
#include <linux/tty_driver.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/ratelimit.h>

#include <asm/io.h>
#include <linux/uaccess.h>

#define MOXA
#define MOXA_GET_IQUEUE
#define MOXA_GET_OQUEUE
#define MOXA_GETDATACOUNT
#define MOXA_GET_IOQUEUE
#define MOXA_FLUSH_QUEUE
#define MOXA_GETMSTATUS

/*
 *    System Configuration
 */

#define Magic_code

/*
 *    for C218 BIOS initialization
 */
#define C218_ConfBase
#define C218_status
#define C218_diag
#define C218_key
#define C218DLoad_len
#define C218check_sum
#define C218chksum_ok
#define C218_TestRx
#define C218_TestTx
#define C218_RXerr
#define C218_ErrFlag

#define C218_LoadBuf
#define C218_KeyCode
#define CP204J_KeyCode

/*
 *    for C320 BIOS initialization
 */
#define C320_ConfBase
#define C320_LoadBuf
#define STS_init

#define C320_status
#define C320_diag
#define C320_key
#define C320DLoad_len
#define C320check_sum
#define C320chksum_ok
#define C320bapi_len
#define C320UART_no

#define C320_KeyCode

#define FixPage_addr
#define DynPage_addr
#define C218_start
#define Control_reg
#define HW_reset

/*
 *    Function Codes
 */
#define FC_CardReset
#define FC_ChannelReset
#define FC_EnableCH
#define FC_DisableCH
#define FC_SetParam
#define FC_SetMode
#define FC_SetRate
#define FC_LineControl
#define FC_LineStatus
#define FC_XmitControl
#define FC_FlushQueue
#define FC_SendBreak
#define FC_StopBreak
#define FC_LoopbackON
#define FC_LoopbackOFF
#define FC_ClrIrqTable
#define FC_SendXon
#define FC_SetTermIrq
#define FC_SetCntIrq
#define FC_SetBreakIrq
#define FC_SetLineIrq
#define FC_SetFlowCtl
#define FC_GenIrq
#define FC_InCD180
#define FC_OutCD180
#define FC_InUARTreg
#define FC_OutUARTreg
#define FC_SetXonXoff
#define FC_OutCD180CCR
#define FC_ExtIQueue
#define FC_ExtOQueue
#define FC_ClrLineIrq
#define FC_HWFlowCtl
#define FC_GetClockRate
#define FC_SetBaud
#define FC_SetDataMode
#define FC_GetCCSR
#define FC_GetDataError
#define FC_RxControl
#define FC_ImmSend
#define FC_SetXonState
#define FC_SetXoffState
#define FC_SetRxFIFOTrig
#define FC_SetTxFIFOCnt
#define FC_UnixRate
#define FC_UnixResetTimer

#define RxFIFOTrig1
#define RxFIFOTrig4
#define RxFIFOTrig8
#define RxFIFOTrig14

/*
 *    Dual-Ported RAM
 */
#define DRAM_global
#define INT_data
#define Config_base

#define IRQindex
#define IRQpending
#define IRQtable

/*
 *    Interrupt Status
 */
#define IntrRx
#define IntrTx
#define IntrFunc
#define IntrBreak
#define IntrLine
#define IntrIntr
#define IntrQuit
#define IntrEOF

#define IntrRxTrigger
#define IntrTxTrigger

#define Magic_no
#define Card_model_no
#define Total_ports
#define Module_cnt
#define Module_no
#define Timer_10ms
#define Disable_IRQ
#define TMS320_PORT1
#define TMS320_PORT2
#define TMS320_CLOCK

/*
 *    DATA BUFFER in DRAM
 */
#define Extern_table
#define Extern_size
#define RXrptr
#define RXwptr
#define TXrptr
#define TXwptr
#define HostStat
#define FlagStat
#define FlowControl
				/*  x  x  x  x  |  |  |  |            */
				/*              |  |  |  + CTS flow   */
				/*              |  |  +--- RTS flow   */
				/*              |  +------ TX Xon/Xoff */
				/*              +--------- RX Xon/Xoff */
#define Break_cnt
#define CD180TXirq
#define RX_mask
#define TX_mask
#define Ofs_rxb
#define Ofs_txb
#define Page_rxb
#define Page_txb
#define EndPage_rxb
#define EndPage_txb
#define Data_error
#define RxTrigger
#define TxTrigger

#define rRXwptr
#define Low_water

#define FuncCode
#define FuncArg
#define FuncArg1

#define C218rx_size
#define C218tx_size

#define C218rx_mask
#define C218tx_mask

#define C320p8rx_size
#define C320p8tx_size
#define C320p8rx_mask
#define C320p8tx_mask

#define C320p16rx_size
#define C320p16tx_size
#define C320p16rx_mask
#define C320p16tx_mask

#define C320p24rx_size
#define C320p24tx_size
#define C320p24rx_mask
#define C320p24tx_mask

#define C320p32rx_size
#define C320p32tx_size
#define C320p32rx_mask
#define C320p32tx_mask

#define Page_size
#define Page_mask
#define C218rx_spage
#define C218tx_spage
#define C218rx_pageno
#define C218tx_pageno
#define C218buf_pageno

#define C320p8rx_spage
#define C320p8tx_spage
#define C320p8rx_pgno
#define C320p8tx_pgno
#define C320p8buf_pgno

#define C320p16rx_spage
#define C320p16tx_spage
#define C320p16rx_pgno
#define C320p16tx_pgno
#define C320p16buf_pgno

#define C320p24rx_spage
#define C320p24tx_spage
#define C320p24rx_pgno
#define C320p24tx_pgno
#define C320p24buf_pgno

#define C320p32rx_spage
#define C320p32tx_ofs
#define C320p32tx_spage
#define C320p32buf_pgno

/*
 *    Host Status
 */
#define WakeupRx
#define WakeupTx
#define WakeupBreak
#define WakeupLine
#define WakeupIntr
#define WakeupQuit
#define WakeupEOF
#define WakeupRxTrigger
#define WakeupTxTrigger
/*
 *    Flag status
 */
#define Rx_over
#define Xoff_state
#define Tx_flowOff
#define Tx_enable
#define CTS_state
#define DSR_state
#define DCD_state
/*
 *    FlowControl
 */
#define CTS_FlowCtl
#define RTS_FlowCtl
#define Tx_FlowCtl
#define Rx_FlowCtl
#define IXM_IXANY

#define LowWater

#define DTR_ON
#define RTS_ON
#define CTS_ON
#define DSR_ON
#define DCD_ON

/* mode definition */
#define MX_CS8
#define MX_CS7
#define MX_CS6
#define MX_CS5

#define MX_STOP1
#define MX_STOP15
#define MX_STOP2

#define MX_PARNONE
#define MX_PAREVEN
#define MX_PARODD
#define MX_PARMARK
#define MX_PARSPACE

#define MOXA_VERSION

#define MOXA_FW_HDRLEN

#define MOXAMAJOR

#define MAX_BOARDS
#define MAX_PORTS_PER_BOARD
#define MAX_PORTS

#define MOXA_IS_320(brd)

/*
 *    Define the Moxa PCI vendor and device IDs.
 */
#define MOXA_BUS_TYPE_ISA
#define MOXA_BUS_TYPE_PCI

enum {};

static char *moxa_brdname[] =;

#ifdef CONFIG_PCI
static const struct pci_device_id moxa_pcibrds[] =;
MODULE_DEVICE_TABLE(pci, moxa_pcibrds);
#endif /* CONFIG_PCI */

struct moxa_port;

static struct moxa_board_conf {} moxa_boards[MAX_BOARDS];

struct mxser_mstatus {};

struct moxaq_str {};

struct moxa_port {};

struct mon_str {};

/* statusflags */
#define TXSTOPPED
#define LOWWAIT
#define EMPTYWAIT


#define WAKEUP_CHARS

static int ttymajor =;
static struct mon_str moxaLog;
static unsigned int moxaFuncTout =;
static unsigned int moxaLowWaterChk;
static DEFINE_MUTEX(moxa_openlock);
static DEFINE_SPINLOCK(moxa_lock);

static unsigned long baseaddr[MAX_BOARDS];
static unsigned int type[MAX_BOARDS];
static unsigned int numports[MAX_BOARDS];
static struct tty_port moxa_service_port;

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();
MODULE_FIRMWARE();

module_param_array();
MODULE_PARM_DESC();
module_param_hw_array(baseaddr, ulong, ioport, NULL, 0);
MODULE_PARM_DESC();
module_param_array();
MODULE_PARM_DESC();

module_param(ttymajor, int, 0);

/*
 * static functions:
 */
static int moxa_open(struct tty_struct *, struct file *);
static void moxa_close(struct tty_struct *, struct file *);
static ssize_t moxa_write(struct tty_struct *, const u8 *, size_t);
static unsigned int moxa_write_room(struct tty_struct *);
static void moxa_flush_buffer(struct tty_struct *);
static unsigned int moxa_chars_in_buffer(struct tty_struct *);
static void moxa_set_termios(struct tty_struct *, const struct ktermios *);
static void moxa_stop(struct tty_struct *);
static void moxa_start(struct tty_struct *);
static void moxa_hangup(struct tty_struct *);
static int moxa_tiocmget(struct tty_struct *tty);
static int moxa_tiocmset(struct tty_struct *tty,
			 unsigned int set, unsigned int clear);
static void moxa_poll(struct timer_list *);
static void moxa_set_tty_param(struct tty_struct *, const struct ktermios *);
static void moxa_shutdown(struct tty_port *);
static bool moxa_carrier_raised(struct tty_port *);
static void moxa_dtr_rts(struct tty_port *, bool);
/*
 * moxa board interface functions:
 */
static void MoxaPortEnable(struct moxa_port *);
static void MoxaPortDisable(struct moxa_port *);
static int MoxaPortSetTermio(struct moxa_port *, struct ktermios *, speed_t);
static int MoxaPortGetLineOut(struct moxa_port *, bool *, bool *);
static void MoxaPortLineCtrl(struct moxa_port *, bool, bool);
static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int);
static int MoxaPortLineStatus(struct moxa_port *);
static void MoxaPortFlushData(struct moxa_port *, int);
static ssize_t MoxaPortWriteData(struct tty_struct *, const u8 *, size_t);
static int MoxaPortReadData(struct moxa_port *);
static unsigned int MoxaPortTxQueue(struct moxa_port *);
static int MoxaPortRxQueue(struct moxa_port *);
static unsigned int MoxaPortTxFree(struct moxa_port *);
static void MoxaPortTxDisable(struct moxa_port *);
static void MoxaPortTxEnable(struct moxa_port *);
static int moxa_get_serial_info(struct tty_struct *, struct serial_struct *);
static int moxa_set_serial_info(struct tty_struct *, struct serial_struct *);
static void MoxaSetFifo(struct moxa_port *port, int enable);

/*
 * I/O functions
 */

static DEFINE_SPINLOCK(moxafunc_lock);

static void moxa_wait_finish(void __iomem *ofsAddr)
{}

static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg)
{}

static int moxafuncret(void __iomem *ofsAddr, u16 cmd, u16 arg)
{}

static void moxa_low_water_check(void __iomem *ofsAddr)
{}

/*
 * TTY operations
 */

static int moxa_ioctl(struct tty_struct *tty,
		      unsigned int cmd, unsigned long arg)
{}

static int moxa_break_ctl(struct tty_struct *tty, int state)
{}

static const struct tty_operations moxa_ops =;

static const struct tty_port_operations moxa_port_ops =;

static struct tty_driver *moxaDriver;
static DEFINE_TIMER(moxaTimer, moxa_poll);

/*
 * HW init
 */

static int moxa_check_fw_model(struct moxa_board_conf *brd, u8 model)
{}

static int moxa_check_fw(const void *ptr)
{}

static int moxa_load_bios(struct moxa_board_conf *brd, const u8 *buf,
		size_t len)
{}

static int moxa_load_320b(struct moxa_board_conf *brd, const u8 *ptr,
		size_t len)
{}

static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr,
		size_t len)
{}

static int moxa_load_code(struct moxa_board_conf *brd, const void *ptr,
		size_t len)
{}

static int moxa_load_fw(struct moxa_board_conf *brd, const struct firmware *fw)
{}

static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)
{}

static void moxa_board_deinit(struct moxa_board_conf *brd)
{}

#ifdef CONFIG_PCI
static int moxa_pci_probe(struct pci_dev *pdev,
		const struct pci_device_id *ent)
{}

static void moxa_pci_remove(struct pci_dev *pdev)
{}

static struct pci_driver moxa_pci_driver =;
#endif /* CONFIG_PCI */

static int __init moxa_init(void)
{}

static void __exit moxa_exit(void)
{}

module_init();
module_exit(moxa_exit);

static void moxa_shutdown(struct tty_port *port)
{}

static bool moxa_carrier_raised(struct tty_port *port)
{}

static void moxa_dtr_rts(struct tty_port *port, bool active)
{}


static int moxa_open(struct tty_struct *tty, struct file *filp)
{}

static void moxa_close(struct tty_struct *tty, struct file *filp)
{}

static ssize_t moxa_write(struct tty_struct *tty, const u8 *buf, size_t count)
{}

static unsigned int moxa_write_room(struct tty_struct *tty)
{}

static void moxa_flush_buffer(struct tty_struct *tty)
{}

static unsigned int moxa_chars_in_buffer(struct tty_struct *tty)
{}

static int moxa_tiocmget(struct tty_struct *tty)
{}

static int moxa_tiocmset(struct tty_struct *tty,
			 unsigned int set, unsigned int clear)
{}

static void moxa_set_termios(struct tty_struct *tty,
		             const struct ktermios *old_termios)
{}

static void moxa_stop(struct tty_struct *tty)
{}


static void moxa_start(struct tty_struct *tty)
{}

static void moxa_hangup(struct tty_struct *tty)
{}

static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
{}

static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
		u16 __iomem *ip)
{}

static void moxa_poll(struct timer_list *unused)
{}

/******************************************************************************/

static void moxa_set_tty_param(struct tty_struct *tty,
			       const struct ktermios *old_termios)
{}

/*****************************************************************************
 *	Driver level functions: 					     *
 *****************************************************************************/

static void MoxaPortFlushData(struct moxa_port *port, int mode)
{}

/*
 *    Moxa Port Number Description:
 *
 *      MOXA serial driver supports up to 4 MOXA-C218/C320 boards. And,
 *      the port number using in MOXA driver functions will be 0 to 31 for
 *      first MOXA board, 32 to 63 for second, 64 to 95 for third and 96
 *      to 127 for fourth. For example, if you setup three MOXA boards,
 *      first board is C218, second board is C320-16 and third board is
 *      C320-32. The port number of first board (C218 - 8 ports) is from
 *      0 to 7. The port number of second board (C320 - 16 ports) is form
 *      32 to 47. The port number of third board (C320 - 32 ports) is from
 *      64 to 95. And those port numbers form 8 to 31, 48 to 63 and 96 to
 *      127 will be invalid.
 *
 *
 *      Moxa Functions Description:
 *
 *      Function 1:     Driver initialization routine, this routine must be
 *                      called when initialized driver.
 *      Syntax:
 *      void MoxaDriverInit();
 *
 *
 *      Function 2:     Moxa driver private IOCTL command processing.
 *      Syntax:
 *      int  MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port);
 *
 *           unsigned int cmd   : IOCTL command
 *           unsigned long arg  : IOCTL argument
 *           int port           : port number (0 - 127)
 *
 *           return:    0  (OK)
 *                      -EINVAL
 *                      -ENOIOCTLCMD
 *
 *
 *      Function 6:     Enable this port to start Tx/Rx data.
 *      Syntax:
 *      void MoxaPortEnable(int port);
 *           int port           : port number (0 - 127)
 *
 *
 *      Function 7:     Disable this port
 *      Syntax:
 *      void MoxaPortDisable(int port);
 *           int port           : port number (0 - 127)
 *
 *
 *      Function 10:    Setting baud rate of this port.
 *      Syntax:
 *      speed_t MoxaPortSetBaud(int port, speed_t baud);
 *           int port           : port number (0 - 127)
 *           long baud          : baud rate (50 - 115200)
 *
 *           return:    0       : this port is invalid or baud < 50
 *                      50 - 115200 : the real baud rate set to the port, if
 *                                    the argument baud is large than maximun
 *                                    available baud rate, the real setting
 *                                    baud rate will be the maximun baud rate.
 *
 *
 *      Function 12:    Configure the port.
 *      Syntax:
 *      int  MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud);
 *           int port           : port number (0 - 127)
 *           struct ktermios * termio : termio structure pointer
 *	     speed_t baud	: baud rate
 *
 *           return:    -1      : this port is invalid or termio == NULL
 *                      0       : setting O.K.
 *
 *
 *      Function 13:    Get the DTR/RTS state of this port.
 *      Syntax:
 *      int  MoxaPortGetLineOut(int port, bool *dtrState, bool *rtsState);
 *           int port           : port number (0 - 127)
 *           bool * dtr_active  : pointer to bool to receive the current DTR
 *                                state. (if NULL, this function will not
 *                                write to this address)
 *           bool * rts_active  : pointer to bool to receive the current RTS
 *                                state. (if NULL, this function will not
 *                                write to this address)
 *
 *           return:    -1      : this port is invalid
 *                      0       : O.K.
 *
 *
 *      Function 14:    Setting the DTR/RTS output state of this port.
 *      Syntax:
 *      void MoxaPortLineCtrl(int port, bool dtrState, bool rtsState);
 *           int port           : port number (0 - 127)
 *           bool dtr_active    : DTR output state
 *           bool rts_active    : RTS output state
 *
 *
 *      Function 15:    Setting the flow control of this port.
 *      Syntax:
 *      void MoxaPortFlowCtrl(int port, int rtsFlow, int ctsFlow, int rxFlow,
 *                            int txFlow,int xany);
 *           int port           : port number (0 - 127)
 *           int rtsFlow        : H/W RTS flow control (0: no, 1: yes)
 *           int ctsFlow        : H/W CTS flow control (0: no, 1: yes)
 *           int rxFlow         : S/W Rx XON/XOFF flow control (0: no, 1: yes)
 *           int txFlow         : S/W Tx XON/XOFF flow control (0: no, 1: yes)
 *           int xany           : S/W XANY flow control (0: no, 1: yes)
 *
 *
 *      Function 16:    Get ths line status of this port
 *      Syntax:
 *      int  MoxaPortLineStatus(int port);
 *           int port           : port number (0 - 127)
 *
 *           return:    Bit 0 - CTS state (0: off, 1: on)
 *                      Bit 1 - DSR state (0: off, 1: on)
 *                      Bit 2 - DCD state (0: off, 1: on)
 *
 *
 *      Function 19:    Flush the Rx/Tx buffer data of this port.
 *      Syntax:
 *      void MoxaPortFlushData(int port, int mode);
 *           int port           : port number (0 - 127)
 *           int mode    
 *                      0       : flush the Rx buffer 
 *                      1       : flush the Tx buffer 
 *                      2       : flush the Rx and Tx buffer 
 *
 *
 *      Function 20:    Write data.
 *      Syntax:
 *      ssize_t  MoxaPortWriteData(int port, u8 *buffer, size_t length);
 *           int port           : port number (0 - 127)
 *           u8 *buffer         : pointer to write data buffer.
 *           size_t length      : write data length
 *
 *           return:    0 - length      : real write data length
 *
 *
 *      Function 21:    Read data.
 *      Syntax:
 *      int  MoxaPortReadData(int port, struct tty_struct *tty);
 *           int port           : port number (0 - 127)
 *	     struct tty_struct *tty : tty for data
 *
 *           return:    0 - length      : real read data length
 *
 *
 *      Function 24:    Get the Tx buffer current queued data bytes
 *      Syntax:
 *      int  MoxaPortTxQueue(int port);
 *           int port           : port number (0 - 127)
 *
 *           return:    ..      : Tx buffer current queued data bytes
 *
 *
 *      Function 25:    Get the Tx buffer current free space
 *      Syntax:
 *      int  MoxaPortTxFree(int port);
 *           int port           : port number (0 - 127)
 *
 *           return:    ..      : Tx buffer current free space
 *
 *
 *      Function 26:    Get the Rx buffer current queued data bytes
 *      Syntax:
 *      int  MoxaPortRxQueue(int port);
 *           int port           : port number (0 - 127)
 *
 *           return:    ..      : Rx buffer current queued data bytes
 *
 *
 *      Function 28:    Disable port data transmission.
 *      Syntax:
 *      void MoxaPortTxDisable(int port);
 *           int port           : port number (0 - 127)
 *
 *
 *      Function 29:    Enable port data transmission.
 *      Syntax:
 *      void MoxaPortTxEnable(int port);
 *           int port           : port number (0 - 127)
 *
 *
 *      Function 31:    Get the received BREAK signal count and reset it.
 *      Syntax:
 *      int  MoxaPortResetBrkCnt(int port);
 *           int port           : port number (0 - 127)
 *
 *           return:    0 - ..  : BREAK signal count
 *
 *
 */

static void MoxaPortEnable(struct moxa_port *port)
{}

static void MoxaPortDisable(struct moxa_port *port)
{}

static speed_t MoxaPortSetBaud(struct moxa_port *port, speed_t baud)
{}

static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
		speed_t baud)
{}

static int MoxaPortGetLineOut(struct moxa_port *port, bool *dtr_active,
		bool *rts_active)
{}

static void MoxaPortLineCtrl(struct moxa_port *port, bool dtr_active, bool rts_active)
{}

static void MoxaPortFlowCtrl(struct moxa_port *port, int rts, int cts,
		int txflow, int rxflow, int txany)
{}

static int MoxaPortLineStatus(struct moxa_port *port)
{}

static ssize_t MoxaPortWriteData(struct tty_struct *tty, const u8 *buffer,
				 size_t len)
{}

static int MoxaPortReadData(struct moxa_port *port)
{}


static unsigned int MoxaPortTxQueue(struct moxa_port *port)
{}

static unsigned int MoxaPortTxFree(struct moxa_port *port)
{}

static int MoxaPortRxQueue(struct moxa_port *port)
{}

static void MoxaPortTxDisable(struct moxa_port *port)
{}

static void MoxaPortTxEnable(struct moxa_port *port)
{}

static int moxa_get_serial_info(struct tty_struct *tty,
		struct serial_struct *ss)
{}


static int moxa_set_serial_info(struct tty_struct *tty,
		struct serial_struct *ss)
{}



/*****************************************************************************
 *	Static local functions: 					     *
 *****************************************************************************/

static void MoxaSetFifo(struct moxa_port *port, int enable)
{}