2400 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*****************************************************************************/3/*4 * moxa.c -- MOXA Intellio family multiport serial driver.5 *6 * Copyright (C) 1999-2000 Moxa Technologies (support@moxa.com).7 * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>8 *9 * This code is loosely based on the Linux serial driver, written by10 * Linus Torvalds, Theodore T'so and others.11 */12 13/*14 * MOXA Intellio Series Driver15 * for : LINUX16 * date : 1999/1/717 * version : 5.118 */19 20#include <linux/module.h>21#include <linux/types.h>22#include <linux/mm.h>23#include <linux/ioport.h>24#include <linux/errno.h>25#include <linux/firmware.h>26#include <linux/signal.h>27#include <linux/sched.h>28#include <linux/timer.h>29#include <linux/interrupt.h>30#include <linux/tty.h>31#include <linux/tty_flip.h>32#include <linux/major.h>33#include <linux/string.h>34#include <linux/fcntl.h>35#include <linux/ptrace.h>36#include <linux/serial.h>37#include <linux/tty_driver.h>38#include <linux/delay.h>39#include <linux/pci.h>40#include <linux/init.h>41#include <linux/bitops.h>42#include <linux/slab.h>43#include <linux/ratelimit.h>44 45#include <asm/io.h>46#include <linux/uaccess.h>47 48#define MOXA 0x40049#define MOXA_GET_IQUEUE (MOXA + 1) /* get input buffered count */50#define MOXA_GET_OQUEUE (MOXA + 2) /* get output buffered count */51#define MOXA_GETDATACOUNT (MOXA + 23)52#define MOXA_GET_IOQUEUE (MOXA + 27)53#define MOXA_FLUSH_QUEUE (MOXA + 28)54#define MOXA_GETMSTATUS (MOXA + 65)55 56/*57 * System Configuration58 */59 60#define Magic_code 0x40461 62/*63 * for C218 BIOS initialization64 */65#define C218_ConfBase 0x80066#define C218_status (C218_ConfBase + 0) /* BIOS running status */67#define C218_diag (C218_ConfBase + 2) /* diagnostic status */68#define C218_key (C218_ConfBase + 4) /* WORD (0x218 for C218) */69#define C218DLoad_len (C218_ConfBase + 6) /* WORD */70#define C218check_sum (C218_ConfBase + 8) /* BYTE */71#define C218chksum_ok (C218_ConfBase + 0x0a) /* BYTE (1:ok) */72#define C218_TestRx (C218_ConfBase + 0x10) /* 8 bytes for 8 ports */73#define C218_TestTx (C218_ConfBase + 0x18) /* 8 bytes for 8 ports */74#define C218_RXerr (C218_ConfBase + 0x20) /* 8 bytes for 8 ports */75#define C218_ErrFlag (C218_ConfBase + 0x28) /* 8 bytes for 8 ports */76 77#define C218_LoadBuf 0x0F0078#define C218_KeyCode 0x21879#define CP204J_KeyCode 0x20480 81/*82 * for C320 BIOS initialization83 */84#define C320_ConfBase 0x80085#define C320_LoadBuf 0x0f0086#define STS_init 0x05 /* for C320_status */87 88#define C320_status C320_ConfBase + 0 /* BIOS running status */89#define C320_diag C320_ConfBase + 2 /* diagnostic status */90#define C320_key C320_ConfBase + 4 /* WORD (0320H for C320) */91#define C320DLoad_len C320_ConfBase + 6 /* WORD */92#define C320check_sum C320_ConfBase + 8 /* WORD */93#define C320chksum_ok C320_ConfBase + 0x0a /* WORD (1:ok) */94#define C320bapi_len C320_ConfBase + 0x0c /* WORD */95#define C320UART_no C320_ConfBase + 0x0e /* WORD */96 97#define C320_KeyCode 0x32098 99#define FixPage_addr 0x0000 /* starting addr of static page */100#define DynPage_addr 0x2000 /* starting addr of dynamic page */101#define C218_start 0x3000 /* starting addr of C218 BIOS prg */102#define Control_reg 0x1ff0 /* select page and reset control */103#define HW_reset 0x80104 105/*106 * Function Codes107 */108#define FC_CardReset 0x80109#define FC_ChannelReset 1 /* C320 firmware not supported */110#define FC_EnableCH 2111#define FC_DisableCH 3112#define FC_SetParam 4113#define FC_SetMode 5114#define FC_SetRate 6115#define FC_LineControl 7116#define FC_LineStatus 8117#define FC_XmitControl 9118#define FC_FlushQueue 10119#define FC_SendBreak 11120#define FC_StopBreak 12121#define FC_LoopbackON 13122#define FC_LoopbackOFF 14123#define FC_ClrIrqTable 15124#define FC_SendXon 16125#define FC_SetTermIrq 17 /* C320 firmware not supported */126#define FC_SetCntIrq 18 /* C320 firmware not supported */127#define FC_SetBreakIrq 19128#define FC_SetLineIrq 20129#define FC_SetFlowCtl 21130#define FC_GenIrq 22131#define FC_InCD180 23132#define FC_OutCD180 24133#define FC_InUARTreg 23134#define FC_OutUARTreg 24135#define FC_SetXonXoff 25136#define FC_OutCD180CCR 26137#define FC_ExtIQueue 27138#define FC_ExtOQueue 28139#define FC_ClrLineIrq 29140#define FC_HWFlowCtl 30141#define FC_GetClockRate 35142#define FC_SetBaud 36143#define FC_SetDataMode 41144#define FC_GetCCSR 43145#define FC_GetDataError 45146#define FC_RxControl 50147#define FC_ImmSend 51148#define FC_SetXonState 52149#define FC_SetXoffState 53150#define FC_SetRxFIFOTrig 54151#define FC_SetTxFIFOCnt 55152#define FC_UnixRate 56153#define FC_UnixResetTimer 57154 155#define RxFIFOTrig1 0156#define RxFIFOTrig4 1157#define RxFIFOTrig8 2158#define RxFIFOTrig14 3159 160/*161 * Dual-Ported RAM162 */163#define DRAM_global 0164#define INT_data (DRAM_global + 0)165#define Config_base (DRAM_global + 0x108)166 167#define IRQindex (INT_data + 0)168#define IRQpending (INT_data + 4)169#define IRQtable (INT_data + 8)170 171/*172 * Interrupt Status173 */174#define IntrRx 0x01 /* receiver data O.K. */175#define IntrTx 0x02 /* transmit buffer empty */176#define IntrFunc 0x04 /* function complete */177#define IntrBreak 0x08 /* received break */178#define IntrLine 0x10 /* line status change179 for transmitter */180#define IntrIntr 0x20 /* received INTR code */181#define IntrQuit 0x40 /* received QUIT code */182#define IntrEOF 0x80 /* received EOF code */183 184#define IntrRxTrigger 0x100 /* rx data count reach trigger value */185#define IntrTxTrigger 0x200 /* tx data count below trigger value */186 187#define Magic_no (Config_base + 0)188#define Card_model_no (Config_base + 2)189#define Total_ports (Config_base + 4)190#define Module_cnt (Config_base + 8)191#define Module_no (Config_base + 10)192#define Timer_10ms (Config_base + 14)193#define Disable_IRQ (Config_base + 20)194#define TMS320_PORT1 (Config_base + 22)195#define TMS320_PORT2 (Config_base + 24)196#define TMS320_CLOCK (Config_base + 26)197 198/*199 * DATA BUFFER in DRAM200 */201#define Extern_table 0x400 /* Base address of the external table202 (24 words * 64) total 3K bytes203 (24 words * 128) total 6K bytes */204#define Extern_size 0x60 /* 96 bytes */205#define RXrptr 0x00 /* read pointer for RX buffer */206#define RXwptr 0x02 /* write pointer for RX buffer */207#define TXrptr 0x04 /* read pointer for TX buffer */208#define TXwptr 0x06 /* write pointer for TX buffer */209#define HostStat 0x08 /* IRQ flag and general flag */210#define FlagStat 0x0A211#define FlowControl 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */212 /* x x x x | | | | */213 /* | | | + CTS flow */214 /* | | +--- RTS flow */215 /* | +------ TX Xon/Xoff */216 /* +--------- RX Xon/Xoff */217#define Break_cnt 0x0E /* received break count */218#define CD180TXirq 0x10 /* if non-0: enable TX irq */219#define RX_mask 0x12220#define TX_mask 0x14221#define Ofs_rxb 0x16222#define Ofs_txb 0x18223#define Page_rxb 0x1A224#define Page_txb 0x1C225#define EndPage_rxb 0x1E226#define EndPage_txb 0x20227#define Data_error 0x22228#define RxTrigger 0x28229#define TxTrigger 0x2a230 231#define rRXwptr 0x34232#define Low_water 0x36233 234#define FuncCode 0x40235#define FuncArg 0x42236#define FuncArg1 0x44237 238#define C218rx_size 0x2000 /* 8K bytes */239#define C218tx_size 0x8000 /* 32K bytes */240 241#define C218rx_mask (C218rx_size - 1)242#define C218tx_mask (C218tx_size - 1)243 244#define C320p8rx_size 0x2000245#define C320p8tx_size 0x8000246#define C320p8rx_mask (C320p8rx_size - 1)247#define C320p8tx_mask (C320p8tx_size - 1)248 249#define C320p16rx_size 0x2000250#define C320p16tx_size 0x4000251#define C320p16rx_mask (C320p16rx_size - 1)252#define C320p16tx_mask (C320p16tx_size - 1)253 254#define C320p24rx_size 0x2000255#define C320p24tx_size 0x2000256#define C320p24rx_mask (C320p24rx_size - 1)257#define C320p24tx_mask (C320p24tx_size - 1)258 259#define C320p32rx_size 0x1000260#define C320p32tx_size 0x1000261#define C320p32rx_mask (C320p32rx_size - 1)262#define C320p32tx_mask (C320p32tx_size - 1)263 264#define Page_size 0x2000U265#define Page_mask (Page_size - 1)266#define C218rx_spage 3267#define C218tx_spage 4268#define C218rx_pageno 1269#define C218tx_pageno 4270#define C218buf_pageno 5271 272#define C320p8rx_spage 3273#define C320p8tx_spage 4274#define C320p8rx_pgno 1275#define C320p8tx_pgno 4276#define C320p8buf_pgno 5277 278#define C320p16rx_spage 3279#define C320p16tx_spage 4280#define C320p16rx_pgno 1281#define C320p16tx_pgno 2282#define C320p16buf_pgno 3283 284#define C320p24rx_spage 3285#define C320p24tx_spage 4286#define C320p24rx_pgno 1287#define C320p24tx_pgno 1288#define C320p24buf_pgno 2289 290#define C320p32rx_spage 3291#define C320p32tx_ofs C320p32rx_size292#define C320p32tx_spage 3293#define C320p32buf_pgno 1294 295/*296 * Host Status297 */298#define WakeupRx 0x01299#define WakeupTx 0x02300#define WakeupBreak 0x08301#define WakeupLine 0x10302#define WakeupIntr 0x20303#define WakeupQuit 0x40304#define WakeupEOF 0x80 /* used in VTIME control */305#define WakeupRxTrigger 0x100306#define WakeupTxTrigger 0x200307/*308 * Flag status309 */310#define Rx_over 0x01311#define Xoff_state 0x02312#define Tx_flowOff 0x04313#define Tx_enable 0x08314#define CTS_state 0x10315#define DSR_state 0x20316#define DCD_state 0x80317/*318 * FlowControl319 */320#define CTS_FlowCtl 1321#define RTS_FlowCtl 2322#define Tx_FlowCtl 4323#define Rx_FlowCtl 8324#define IXM_IXANY 0x10325 326#define LowWater 128327 328#define DTR_ON 1329#define RTS_ON 2330#define CTS_ON 1331#define DSR_ON 2332#define DCD_ON 8333 334/* mode definition */335#define MX_CS8 0x03336#define MX_CS7 0x02337#define MX_CS6 0x01338#define MX_CS5 0x00339 340#define MX_STOP1 0x00341#define MX_STOP15 0x04342#define MX_STOP2 0x08343 344#define MX_PARNONE 0x00345#define MX_PAREVEN 0x40346#define MX_PARODD 0xC0347#define MX_PARMARK 0xA0348#define MX_PARSPACE 0x20349 350#define MOXA_VERSION "6.0k"351 352#define MOXA_FW_HDRLEN 32353 354#define MOXAMAJOR 172355 356#define MAX_BOARDS 4 /* Don't change this value */357#define MAX_PORTS_PER_BOARD 32 /* Don't change this value */358#define MAX_PORTS (MAX_BOARDS * MAX_PORTS_PER_BOARD)359 360#define MOXA_IS_320(brd) ((brd)->boardType == MOXA_BOARD_C320_ISA || \361 (brd)->boardType == MOXA_BOARD_C320_PCI)362 363/*364 * Define the Moxa PCI vendor and device IDs.365 */366#define MOXA_BUS_TYPE_ISA 0367#define MOXA_BUS_TYPE_PCI 1368 369enum {370 MOXA_BOARD_C218_PCI = 1,371 MOXA_BOARD_C218_ISA,372 MOXA_BOARD_C320_PCI,373 MOXA_BOARD_C320_ISA,374 MOXA_BOARD_CP204J,375};376 377static char *moxa_brdname[] =378{379 "C218 Turbo PCI series",380 "C218 Turbo ISA series",381 "C320 Turbo PCI series",382 "C320 Turbo ISA series",383 "CP-204J series",384};385 386#ifdef CONFIG_PCI387static const struct pci_device_id moxa_pcibrds[] = {388 { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C218),389 .driver_data = MOXA_BOARD_C218_PCI },390 { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C320),391 .driver_data = MOXA_BOARD_C320_PCI },392 { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP204J),393 .driver_data = MOXA_BOARD_CP204J },394 { 0 }395};396MODULE_DEVICE_TABLE(pci, moxa_pcibrds);397#endif /* CONFIG_PCI */398 399struct moxa_port;400 401static struct moxa_board_conf {402 int boardType;403 int numPorts;404 int busType;405 406 unsigned int ready;407 408 struct moxa_port *ports;409 410 void __iomem *basemem;411 void __iomem *intNdx;412 void __iomem *intPend;413 void __iomem *intTable;414} moxa_boards[MAX_BOARDS];415 416struct mxser_mstatus {417 tcflag_t cflag;418 int cts;419 int dsr;420 int ri;421 int dcd;422};423 424struct moxaq_str {425 int inq;426 int outq;427};428 429struct moxa_port {430 struct tty_port port;431 struct moxa_board_conf *board;432 void __iomem *tableAddr;433 434 int type;435 int cflag;436 unsigned long statusflags;437 438 u8 DCDState; /* Protected by the port lock */439 u8 lineCtrl;440 u8 lowChkFlag;441};442 443struct mon_str {444 int tick;445 int rxcnt[MAX_PORTS];446 int txcnt[MAX_PORTS];447};448 449/* statusflags */450#define TXSTOPPED 1451#define LOWWAIT 2452#define EMPTYWAIT 3453 454 455#define WAKEUP_CHARS 256456 457static int ttymajor = MOXAMAJOR;458static struct mon_str moxaLog;459static unsigned int moxaFuncTout = HZ / 2;460static unsigned int moxaLowWaterChk;461static DEFINE_MUTEX(moxa_openlock);462static DEFINE_SPINLOCK(moxa_lock);463 464static unsigned long baseaddr[MAX_BOARDS];465static unsigned int type[MAX_BOARDS];466static unsigned int numports[MAX_BOARDS];467static struct tty_port moxa_service_port;468 469MODULE_AUTHOR("William Chen");470MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver");471MODULE_LICENSE("GPL");472MODULE_FIRMWARE("c218tunx.cod");473MODULE_FIRMWARE("cp204unx.cod");474MODULE_FIRMWARE("c320tunx.cod");475 476module_param_array(type, uint, NULL, 0);477MODULE_PARM_DESC(type, "card type: C218=2, C320=4");478module_param_hw_array(baseaddr, ulong, ioport, NULL, 0);479MODULE_PARM_DESC(baseaddr, "base address");480module_param_array(numports, uint, NULL, 0);481MODULE_PARM_DESC(numports, "numports (ignored for C218)");482 483module_param(ttymajor, int, 0);484 485/*486 * static functions:487 */488static int moxa_open(struct tty_struct *, struct file *);489static void moxa_close(struct tty_struct *, struct file *);490static ssize_t moxa_write(struct tty_struct *, const u8 *, size_t);491static unsigned int moxa_write_room(struct tty_struct *);492static void moxa_flush_buffer(struct tty_struct *);493static unsigned int moxa_chars_in_buffer(struct tty_struct *);494static void moxa_set_termios(struct tty_struct *, const struct ktermios *);495static void moxa_stop(struct tty_struct *);496static void moxa_start(struct tty_struct *);497static void moxa_hangup(struct tty_struct *);498static int moxa_tiocmget(struct tty_struct *tty);499static int moxa_tiocmset(struct tty_struct *tty,500 unsigned int set, unsigned int clear);501static void moxa_poll(struct timer_list *);502static void moxa_set_tty_param(struct tty_struct *, const struct ktermios *);503static void moxa_shutdown(struct tty_port *);504static bool moxa_carrier_raised(struct tty_port *);505static void moxa_dtr_rts(struct tty_port *, bool);506/*507 * moxa board interface functions:508 */509static void MoxaPortEnable(struct moxa_port *);510static void MoxaPortDisable(struct moxa_port *);511static int MoxaPortSetTermio(struct moxa_port *, struct ktermios *, speed_t);512static int MoxaPortGetLineOut(struct moxa_port *, bool *, bool *);513static void MoxaPortLineCtrl(struct moxa_port *, bool, bool);514static void MoxaPortFlowCtrl(struct moxa_port *, int, int, int, int, int);515static int MoxaPortLineStatus(struct moxa_port *);516static void MoxaPortFlushData(struct moxa_port *, int);517static ssize_t MoxaPortWriteData(struct tty_struct *, const u8 *, size_t);518static int MoxaPortReadData(struct moxa_port *);519static unsigned int MoxaPortTxQueue(struct moxa_port *);520static int MoxaPortRxQueue(struct moxa_port *);521static unsigned int MoxaPortTxFree(struct moxa_port *);522static void MoxaPortTxDisable(struct moxa_port *);523static void MoxaPortTxEnable(struct moxa_port *);524static int moxa_get_serial_info(struct tty_struct *, struct serial_struct *);525static int moxa_set_serial_info(struct tty_struct *, struct serial_struct *);526static void MoxaSetFifo(struct moxa_port *port, int enable);527 528/*529 * I/O functions530 */531 532static DEFINE_SPINLOCK(moxafunc_lock);533 534static void moxa_wait_finish(void __iomem *ofsAddr)535{536 unsigned long end = jiffies + moxaFuncTout;537 538 while (readw(ofsAddr + FuncCode) != 0)539 if (time_after(jiffies, end))540 return;541 if (readw(ofsAddr + FuncCode) != 0)542 printk_ratelimited(KERN_WARNING "moxa function expired\n");543}544 545static void moxafunc(void __iomem *ofsAddr, u16 cmd, u16 arg)546{547 unsigned long flags;548 spin_lock_irqsave(&moxafunc_lock, flags);549 writew(arg, ofsAddr + FuncArg);550 writew(cmd, ofsAddr + FuncCode);551 moxa_wait_finish(ofsAddr);552 spin_unlock_irqrestore(&moxafunc_lock, flags);553}554 555static int moxafuncret(void __iomem *ofsAddr, u16 cmd, u16 arg)556{557 unsigned long flags;558 u16 ret;559 spin_lock_irqsave(&moxafunc_lock, flags);560 writew(arg, ofsAddr + FuncArg);561 writew(cmd, ofsAddr + FuncCode);562 moxa_wait_finish(ofsAddr);563 ret = readw(ofsAddr + FuncArg);564 spin_unlock_irqrestore(&moxafunc_lock, flags);565 return ret;566}567 568static void moxa_low_water_check(void __iomem *ofsAddr)569{570 u16 rptr, wptr, mask, len;571 572 if (readb(ofsAddr + FlagStat) & Xoff_state) {573 rptr = readw(ofsAddr + RXrptr);574 wptr = readw(ofsAddr + RXwptr);575 mask = readw(ofsAddr + RX_mask);576 len = (wptr - rptr) & mask;577 if (len <= Low_water)578 moxafunc(ofsAddr, FC_SendXon, 0);579 }580}581 582/*583 * TTY operations584 */585 586static int moxa_ioctl(struct tty_struct *tty,587 unsigned int cmd, unsigned long arg)588{589 struct moxa_port *ch = tty->driver_data;590 void __user *argp = (void __user *)arg;591 int status, ret = 0;592 593 if (tty->index == MAX_PORTS) {594 if (cmd != MOXA_GETDATACOUNT && cmd != MOXA_GET_IOQUEUE &&595 cmd != MOXA_GETMSTATUS)596 return -EINVAL;597 } else if (!ch)598 return -ENODEV;599 600 switch (cmd) {601 case MOXA_GETDATACOUNT:602 moxaLog.tick = jiffies;603 if (copy_to_user(argp, &moxaLog, sizeof(moxaLog)))604 ret = -EFAULT;605 break;606 case MOXA_FLUSH_QUEUE:607 MoxaPortFlushData(ch, arg);608 break;609 case MOXA_GET_IOQUEUE: {610 struct moxaq_str __user *argm = argp;611 struct moxaq_str tmp;612 struct moxa_port *p;613 unsigned int i, j;614 615 for (i = 0; i < MAX_BOARDS; i++) {616 p = moxa_boards[i].ports;617 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {618 memset(&tmp, 0, sizeof(tmp));619 spin_lock_bh(&moxa_lock);620 if (moxa_boards[i].ready) {621 tmp.inq = MoxaPortRxQueue(p);622 tmp.outq = MoxaPortTxQueue(p);623 }624 spin_unlock_bh(&moxa_lock);625 if (copy_to_user(argm, &tmp, sizeof(tmp)))626 return -EFAULT;627 }628 }629 break;630 } case MOXA_GET_OQUEUE:631 status = MoxaPortTxQueue(ch);632 ret = put_user(status, (unsigned long __user *)argp);633 break;634 case MOXA_GET_IQUEUE:635 status = MoxaPortRxQueue(ch);636 ret = put_user(status, (unsigned long __user *)argp);637 break;638 case MOXA_GETMSTATUS: {639 struct mxser_mstatus __user *argm = argp;640 struct mxser_mstatus tmp;641 struct moxa_port *p;642 unsigned int i, j;643 644 for (i = 0; i < MAX_BOARDS; i++) {645 p = moxa_boards[i].ports;646 for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {647 struct tty_struct *ttyp;648 memset(&tmp, 0, sizeof(tmp));649 spin_lock_bh(&moxa_lock);650 if (!moxa_boards[i].ready) {651 spin_unlock_bh(&moxa_lock);652 goto copy;653 }654 655 status = MoxaPortLineStatus(p);656 spin_unlock_bh(&moxa_lock);657 658 if (status & 1)659 tmp.cts = 1;660 if (status & 2)661 tmp.dsr = 1;662 if (status & 4)663 tmp.dcd = 1;664 665 ttyp = tty_port_tty_get(&p->port);666 if (!ttyp)667 tmp.cflag = p->cflag;668 else669 tmp.cflag = ttyp->termios.c_cflag;670 tty_kref_put(ttyp);671copy:672 if (copy_to_user(argm, &tmp, sizeof(tmp)))673 return -EFAULT;674 }675 }676 break;677 }678 default:679 ret = -ENOIOCTLCMD;680 }681 return ret;682}683 684static int moxa_break_ctl(struct tty_struct *tty, int state)685{686 struct moxa_port *port = tty->driver_data;687 688 moxafunc(port->tableAddr, state ? FC_SendBreak : FC_StopBreak,689 Magic_code);690 return 0;691}692 693static const struct tty_operations moxa_ops = {694 .open = moxa_open,695 .close = moxa_close,696 .write = moxa_write,697 .write_room = moxa_write_room,698 .flush_buffer = moxa_flush_buffer,699 .chars_in_buffer = moxa_chars_in_buffer,700 .ioctl = moxa_ioctl,701 .set_termios = moxa_set_termios,702 .stop = moxa_stop,703 .start = moxa_start,704 .hangup = moxa_hangup,705 .break_ctl = moxa_break_ctl,706 .tiocmget = moxa_tiocmget,707 .tiocmset = moxa_tiocmset,708 .set_serial = moxa_set_serial_info,709 .get_serial = moxa_get_serial_info,710};711 712static const struct tty_port_operations moxa_port_ops = {713 .carrier_raised = moxa_carrier_raised,714 .dtr_rts = moxa_dtr_rts,715 .shutdown = moxa_shutdown,716};717 718static struct tty_driver *moxaDriver;719static DEFINE_TIMER(moxaTimer, moxa_poll);720 721/*722 * HW init723 */724 725static int moxa_check_fw_model(struct moxa_board_conf *brd, u8 model)726{727 switch (brd->boardType) {728 case MOXA_BOARD_C218_ISA:729 case MOXA_BOARD_C218_PCI:730 if (model != 1)731 goto err;732 break;733 case MOXA_BOARD_CP204J:734 if (model != 3)735 goto err;736 break;737 default:738 if (model != 2)739 goto err;740 break;741 }742 return 0;743err:744 return -EINVAL;745}746 747static int moxa_check_fw(const void *ptr)748{749 const __le16 *lptr = ptr;750 751 if (*lptr != cpu_to_le16(0x7980))752 return -EINVAL;753 754 return 0;755}756 757static int moxa_load_bios(struct moxa_board_conf *brd, const u8 *buf,758 size_t len)759{760 void __iomem *baseAddr = brd->basemem;761 u16 tmp;762 763 writeb(HW_reset, baseAddr + Control_reg); /* reset */764 msleep(10);765 memset_io(baseAddr, 0, 4096);766 memcpy_toio(baseAddr, buf, len); /* download BIOS */767 writeb(0, baseAddr + Control_reg); /* restart */768 769 msleep(2000);770 771 switch (brd->boardType) {772 case MOXA_BOARD_C218_ISA:773 case MOXA_BOARD_C218_PCI:774 tmp = readw(baseAddr + C218_key);775 if (tmp != C218_KeyCode)776 goto err;777 break;778 case MOXA_BOARD_CP204J:779 tmp = readw(baseAddr + C218_key);780 if (tmp != CP204J_KeyCode)781 goto err;782 break;783 default:784 tmp = readw(baseAddr + C320_key);785 if (tmp != C320_KeyCode)786 goto err;787 tmp = readw(baseAddr + C320_status);788 if (tmp != STS_init) {789 printk(KERN_ERR "MOXA: bios upload failed -- CPU/Basic "790 "module not found\n");791 return -EIO;792 }793 break;794 }795 796 return 0;797err:798 printk(KERN_ERR "MOXA: bios upload failed -- board not found\n");799 return -EIO;800}801 802static int moxa_load_320b(struct moxa_board_conf *brd, const u8 *ptr,803 size_t len)804{805 void __iomem *baseAddr = brd->basemem;806 807 if (len < 7168) {808 printk(KERN_ERR "MOXA: invalid 320 bios -- too short\n");809 return -EINVAL;810 }811 812 writew(len - 7168 - 2, baseAddr + C320bapi_len);813 writeb(1, baseAddr + Control_reg); /* Select Page 1 */814 memcpy_toio(baseAddr + DynPage_addr, ptr, 7168);815 writeb(2, baseAddr + Control_reg); /* Select Page 2 */816 memcpy_toio(baseAddr + DynPage_addr, ptr + 7168, len - 7168);817 818 return 0;819}820 821static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr,822 size_t len)823{824 void __iomem *baseAddr = brd->basemem;825 const __le16 *uptr = ptr;826 size_t wlen, len2, j;827 unsigned long key, loadbuf, loadlen, checksum, checksum_ok;828 unsigned int i, retry;829 u16 usum, keycode;830 831 keycode = (brd->boardType == MOXA_BOARD_CP204J) ? CP204J_KeyCode :832 C218_KeyCode;833 834 switch (brd->boardType) {835 case MOXA_BOARD_CP204J:836 case MOXA_BOARD_C218_ISA:837 case MOXA_BOARD_C218_PCI:838 key = C218_key;839 loadbuf = C218_LoadBuf;840 loadlen = C218DLoad_len;841 checksum = C218check_sum;842 checksum_ok = C218chksum_ok;843 break;844 default:845 key = C320_key;846 keycode = C320_KeyCode;847 loadbuf = C320_LoadBuf;848 loadlen = C320DLoad_len;849 checksum = C320check_sum;850 checksum_ok = C320chksum_ok;851 break;852 }853 854 usum = 0;855 wlen = len >> 1;856 for (i = 0; i < wlen; i++)857 usum += le16_to_cpu(uptr[i]);858 retry = 0;859 do {860 wlen = len >> 1;861 j = 0;862 while (wlen) {863 len2 = (wlen > 2048) ? 2048 : wlen;864 wlen -= len2;865 memcpy_toio(baseAddr + loadbuf, ptr + j, len2 << 1);866 j += len2 << 1;867 868 writew(len2, baseAddr + loadlen);869 writew(0, baseAddr + key);870 for (i = 0; i < 100; i++) {871 if (readw(baseAddr + key) == keycode)872 break;873 msleep(10);874 }875 if (readw(baseAddr + key) != keycode)876 return -EIO;877 }878 writew(0, baseAddr + loadlen);879 writew(usum, baseAddr + checksum);880 writew(0, baseAddr + key);881 for (i = 0; i < 100; i++) {882 if (readw(baseAddr + key) == keycode)883 break;884 msleep(10);885 }886 retry++;887 } while ((readb(baseAddr + checksum_ok) != 1) && (retry < 3));888 if (readb(baseAddr + checksum_ok) != 1)889 return -EIO;890 891 writew(0, baseAddr + key);892 for (i = 0; i < 600; i++) {893 if (readw(baseAddr + Magic_no) == Magic_code)894 break;895 msleep(10);896 }897 if (readw(baseAddr + Magic_no) != Magic_code)898 return -EIO;899 900 if (MOXA_IS_320(brd)) {901 if (brd->busType == MOXA_BUS_TYPE_PCI) { /* ASIC board */902 writew(0x3800, baseAddr + TMS320_PORT1);903 writew(0x3900, baseAddr + TMS320_PORT2);904 writew(28499, baseAddr + TMS320_CLOCK);905 } else {906 writew(0x3200, baseAddr + TMS320_PORT1);907 writew(0x3400, baseAddr + TMS320_PORT2);908 writew(19999, baseAddr + TMS320_CLOCK);909 }910 }911 writew(1, baseAddr + Disable_IRQ);912 writew(0, baseAddr + Magic_no);913 for (i = 0; i < 500; i++) {914 if (readw(baseAddr + Magic_no) == Magic_code)915 break;916 msleep(10);917 }918 if (readw(baseAddr + Magic_no) != Magic_code)919 return -EIO;920 921 if (MOXA_IS_320(brd)) {922 j = readw(baseAddr + Module_cnt);923 if (j <= 0)924 return -EIO;925 brd->numPorts = j * 8;926 writew(j, baseAddr + Module_no);927 writew(0, baseAddr + Magic_no);928 for (i = 0; i < 600; i++) {929 if (readw(baseAddr + Magic_no) == Magic_code)930 break;931 msleep(10);932 }933 if (readw(baseAddr + Magic_no) != Magic_code)934 return -EIO;935 }936 brd->intNdx = baseAddr + IRQindex;937 brd->intPend = baseAddr + IRQpending;938 brd->intTable = baseAddr + IRQtable;939 940 return 0;941}942 943static int moxa_load_code(struct moxa_board_conf *brd, const void *ptr,944 size_t len)945{946 void __iomem *ofsAddr, *baseAddr = brd->basemem;947 struct moxa_port *port;948 int retval, i;949 950 if (len % 2) {951 printk(KERN_ERR "MOXA: bios length is not even\n");952 return -EINVAL;953 }954 955 retval = moxa_real_load_code(brd, ptr, len); /* may change numPorts */956 if (retval)957 return retval;958 959 switch (brd->boardType) {960 case MOXA_BOARD_C218_ISA:961 case MOXA_BOARD_C218_PCI:962 case MOXA_BOARD_CP204J:963 port = brd->ports;964 for (i = 0; i < brd->numPorts; i++, port++) {965 port->board = brd;966 port->DCDState = 0;967 port->tableAddr = baseAddr + Extern_table +968 Extern_size * i;969 ofsAddr = port->tableAddr;970 writew(C218rx_mask, ofsAddr + RX_mask);971 writew(C218tx_mask, ofsAddr + TX_mask);972 writew(C218rx_spage + i * C218buf_pageno, ofsAddr + Page_rxb);973 writew(readw(ofsAddr + Page_rxb) + C218rx_pageno, ofsAddr + EndPage_rxb);974 975 writew(C218tx_spage + i * C218buf_pageno, ofsAddr + Page_txb);976 writew(readw(ofsAddr + Page_txb) + C218tx_pageno, ofsAddr + EndPage_txb);977 978 }979 break;980 default:981 port = brd->ports;982 for (i = 0; i < brd->numPorts; i++, port++) {983 port->board = brd;984 port->DCDState = 0;985 port->tableAddr = baseAddr + Extern_table +986 Extern_size * i;987 ofsAddr = port->tableAddr;988 switch (brd->numPorts) {989 case 8:990 writew(C320p8rx_mask, ofsAddr + RX_mask);991 writew(C320p8tx_mask, ofsAddr + TX_mask);992 writew(C320p8rx_spage + i * C320p8buf_pgno, ofsAddr + Page_rxb);993 writew(readw(ofsAddr + Page_rxb) + C320p8rx_pgno, ofsAddr + EndPage_rxb);994 writew(C320p8tx_spage + i * C320p8buf_pgno, ofsAddr + Page_txb);995 writew(readw(ofsAddr + Page_txb) + C320p8tx_pgno, ofsAddr + EndPage_txb);996 997 break;998 case 16:999 writew(C320p16rx_mask, ofsAddr + RX_mask);1000 writew(C320p16tx_mask, ofsAddr + TX_mask);1001 writew(C320p16rx_spage + i * C320p16buf_pgno, ofsAddr + Page_rxb);1002 writew(readw(ofsAddr + Page_rxb) + C320p16rx_pgno, ofsAddr + EndPage_rxb);1003 writew(C320p16tx_spage + i * C320p16buf_pgno, ofsAddr + Page_txb);1004 writew(readw(ofsAddr + Page_txb) + C320p16tx_pgno, ofsAddr + EndPage_txb);1005 break;1006 1007 case 24:1008 writew(C320p24rx_mask, ofsAddr + RX_mask);1009 writew(C320p24tx_mask, ofsAddr + TX_mask);1010 writew(C320p24rx_spage + i * C320p24buf_pgno, ofsAddr + Page_rxb);1011 writew(readw(ofsAddr + Page_rxb) + C320p24rx_pgno, ofsAddr + EndPage_rxb);1012 writew(C320p24tx_spage + i * C320p24buf_pgno, ofsAddr + Page_txb);1013 writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);1014 break;1015 case 32:1016 writew(C320p32rx_mask, ofsAddr + RX_mask);1017 writew(C320p32tx_mask, ofsAddr + TX_mask);1018 writew(C320p32tx_ofs, ofsAddr + Ofs_txb);1019 writew(C320p32rx_spage + i * C320p32buf_pgno, ofsAddr + Page_rxb);1020 writew(readb(ofsAddr + Page_rxb), ofsAddr + EndPage_rxb);1021 writew(C320p32tx_spage + i * C320p32buf_pgno, ofsAddr + Page_txb);1022 writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);1023 break;1024 }1025 }1026 break;1027 }1028 return 0;1029}1030 1031static int moxa_load_fw(struct moxa_board_conf *brd, const struct firmware *fw)1032{1033 const void *ptr = fw->data;1034 char rsn[64];1035 u16 lens[5];1036 size_t len;1037 unsigned int a, lenp, lencnt;1038 int ret = -EINVAL;1039 struct {1040 __le32 magic; /* 0x34303430 */1041 u8 reserved1[2];1042 u8 type; /* UNIX = 3 */1043 u8 model; /* C218T=1, C320T=2, CP204=3 */1044 u8 reserved2[8];1045 __le16 len[5];1046 } const *hdr = ptr;1047 1048 BUILD_BUG_ON(ARRAY_SIZE(hdr->len) != ARRAY_SIZE(lens));1049 1050 if (fw->size < MOXA_FW_HDRLEN) {1051 strcpy(rsn, "too short (even header won't fit)");1052 goto err;1053 }1054 if (hdr->magic != cpu_to_le32(0x30343034)) {1055 sprintf(rsn, "bad magic: %.8x", le32_to_cpu(hdr->magic));1056 goto err;1057 }1058 if (hdr->type != 3) {1059 sprintf(rsn, "not for linux, type is %u", hdr->type);1060 goto err;1061 }1062 if (moxa_check_fw_model(brd, hdr->model)) {1063 sprintf(rsn, "not for this card, model is %u", hdr->model);1064 goto err;1065 }1066 1067 len = MOXA_FW_HDRLEN;1068 lencnt = hdr->model == 2 ? 5 : 3;1069 for (a = 0; a < ARRAY_SIZE(lens); a++) {1070 lens[a] = le16_to_cpu(hdr->len[a]);1071 if (lens[a] && len + lens[a] <= fw->size &&1072 moxa_check_fw(&fw->data[len]))1073 printk(KERN_WARNING "MOXA firmware: unexpected input "1074 "at offset %u, but going on\n", (u32)len);1075 if (!lens[a] && a < lencnt) {1076 sprintf(rsn, "too few entries in fw file");1077 goto err;1078 }1079 len += lens[a];1080 }1081 1082 if (len != fw->size) {1083 sprintf(rsn, "bad length: %u (should be %u)", (u32)fw->size,1084 (u32)len);1085 goto err;1086 }1087 1088 ptr += MOXA_FW_HDRLEN;1089 lenp = 0; /* bios */1090 1091 strcpy(rsn, "read above");1092 1093 ret = moxa_load_bios(brd, ptr, lens[lenp]);1094 if (ret)1095 goto err;1096 1097 /* we skip the tty section (lens[1]), since we don't need it */1098 ptr += lens[lenp] + lens[lenp + 1];1099 lenp += 2; /* comm */1100 1101 if (hdr->model == 2) {1102 ret = moxa_load_320b(brd, ptr, lens[lenp]);1103 if (ret)1104 goto err;1105 /* skip another tty */1106 ptr += lens[lenp] + lens[lenp + 1];1107 lenp += 2;1108 }1109 1110 ret = moxa_load_code(brd, ptr, lens[lenp]);1111 if (ret)1112 goto err;1113 1114 return 0;1115err:1116 printk(KERN_ERR "firmware failed to load, reason: %s\n", rsn);1117 return ret;1118}1119 1120static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)1121{1122 const struct firmware *fw;1123 const char *file;1124 struct moxa_port *p;1125 unsigned int i, first_idx;1126 int ret;1127 1128 brd->ports = kcalloc(MAX_PORTS_PER_BOARD, sizeof(*brd->ports),1129 GFP_KERNEL);1130 if (brd->ports == NULL) {1131 printk(KERN_ERR "cannot allocate memory for ports\n");1132 ret = -ENOMEM;1133 goto err;1134 }1135 1136 for (i = 0, p = brd->ports; i < MAX_PORTS_PER_BOARD; i++, p++) {1137 tty_port_init(&p->port);1138 p->port.ops = &moxa_port_ops;1139 p->type = PORT_16550A;1140 p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;1141 }1142 1143 switch (brd->boardType) {1144 case MOXA_BOARD_C218_ISA:1145 case MOXA_BOARD_C218_PCI:1146 file = "c218tunx.cod";1147 break;1148 case MOXA_BOARD_CP204J:1149 file = "cp204unx.cod";1150 break;1151 default:1152 file = "c320tunx.cod";1153 break;1154 }1155 1156 ret = request_firmware(&fw, file, dev);1157 if (ret) {1158 printk(KERN_ERR "MOXA: request_firmware failed. Make sure "1159 "you've placed '%s' file into your firmware "1160 "loader directory (e.g. /lib/firmware)\n",1161 file);1162 goto err_free;1163 }1164 1165 ret = moxa_load_fw(brd, fw);1166 1167 release_firmware(fw);1168 1169 if (ret)1170 goto err_free;1171 1172 spin_lock_bh(&moxa_lock);1173 brd->ready = 1;1174 if (!timer_pending(&moxaTimer))1175 mod_timer(&moxaTimer, jiffies + HZ / 50);1176 spin_unlock_bh(&moxa_lock);1177 1178 first_idx = (brd - moxa_boards) * MAX_PORTS_PER_BOARD;1179 for (i = 0; i < brd->numPorts; i++)1180 tty_port_register_device(&brd->ports[i].port, moxaDriver,1181 first_idx + i, dev);1182 1183 return 0;1184err_free:1185 for (i = 0; i < MAX_PORTS_PER_BOARD; i++)1186 tty_port_destroy(&brd->ports[i].port);1187 kfree(brd->ports);1188err:1189 return ret;1190}1191 1192static void moxa_board_deinit(struct moxa_board_conf *brd)1193{1194 unsigned int a, opened, first_idx;1195 1196 mutex_lock(&moxa_openlock);1197 spin_lock_bh(&moxa_lock);1198 brd->ready = 0;1199 spin_unlock_bh(&moxa_lock);1200 1201 /* pci hot-un-plug support */1202 for (a = 0; a < brd->numPorts; a++)1203 if (tty_port_initialized(&brd->ports[a].port))1204 tty_port_tty_hangup(&brd->ports[a].port, false);1205 1206 for (a = 0; a < MAX_PORTS_PER_BOARD; a++)1207 tty_port_destroy(&brd->ports[a].port);1208 1209 while (1) {1210 opened = 0;1211 for (a = 0; a < brd->numPorts; a++)1212 if (tty_port_initialized(&brd->ports[a].port))1213 opened++;1214 mutex_unlock(&moxa_openlock);1215 if (!opened)1216 break;1217 msleep(50);1218 mutex_lock(&moxa_openlock);1219 }1220 1221 first_idx = (brd - moxa_boards) * MAX_PORTS_PER_BOARD;1222 for (a = 0; a < brd->numPorts; a++)1223 tty_unregister_device(moxaDriver, first_idx + a);1224 1225 iounmap(brd->basemem);1226 brd->basemem = NULL;1227 kfree(brd->ports);1228}1229 1230#ifdef CONFIG_PCI1231static int moxa_pci_probe(struct pci_dev *pdev,1232 const struct pci_device_id *ent)1233{1234 struct moxa_board_conf *board;1235 unsigned int i;1236 int board_type = ent->driver_data;1237 int retval;1238 1239 retval = pci_enable_device(pdev);1240 if (retval) {1241 dev_err(&pdev->dev, "can't enable pci device\n");1242 goto err;1243 }1244 1245 for (i = 0; i < MAX_BOARDS; i++)1246 if (moxa_boards[i].basemem == NULL)1247 break;1248 1249 retval = -ENODEV;1250 if (i >= MAX_BOARDS) {1251 dev_warn(&pdev->dev, "more than %u MOXA Intellio family boards "1252 "found. Board is ignored.\n", MAX_BOARDS);1253 goto err;1254 }1255 1256 board = &moxa_boards[i];1257 1258 retval = pci_request_region(pdev, 2, "moxa-base");1259 if (retval) {1260 dev_err(&pdev->dev, "can't request pci region 2\n");1261 goto err;1262 }1263 1264 board->basemem = ioremap(pci_resource_start(pdev, 2), 0x4000);1265 if (board->basemem == NULL) {1266 dev_err(&pdev->dev, "can't remap io space 2\n");1267 retval = -ENOMEM;1268 goto err_reg;1269 }1270 1271 board->boardType = board_type;1272 switch (board_type) {1273 case MOXA_BOARD_C218_ISA:1274 case MOXA_BOARD_C218_PCI:1275 board->numPorts = 8;1276 break;1277 1278 case MOXA_BOARD_CP204J:1279 board->numPorts = 4;1280 break;1281 default:1282 board->numPorts = 0;1283 break;1284 }1285 board->busType = MOXA_BUS_TYPE_PCI;1286 1287 retval = moxa_init_board(board, &pdev->dev);1288 if (retval)1289 goto err_base;1290 1291 pci_set_drvdata(pdev, board);1292 1293 dev_info(&pdev->dev, "board '%s' ready (%u ports, firmware loaded)\n",1294 moxa_brdname[board_type - 1], board->numPorts);1295 1296 return 0;1297err_base:1298 iounmap(board->basemem);1299 board->basemem = NULL;1300err_reg:1301 pci_release_region(pdev, 2);1302err:1303 return retval;1304}1305 1306static void moxa_pci_remove(struct pci_dev *pdev)1307{1308 struct moxa_board_conf *brd = pci_get_drvdata(pdev);1309 1310 moxa_board_deinit(brd);1311 1312 pci_release_region(pdev, 2);1313}1314 1315static struct pci_driver moxa_pci_driver = {1316 .name = "moxa",1317 .id_table = moxa_pcibrds,1318 .probe = moxa_pci_probe,1319 .remove = moxa_pci_remove1320};1321#endif /* CONFIG_PCI */1322 1323static int __init moxa_init(void)1324{1325 unsigned int isabrds = 0;1326 int retval = 0;1327 struct moxa_board_conf *brd = moxa_boards;1328 unsigned int i;1329 1330 printk(KERN_INFO "MOXA Intellio family driver version %s\n",1331 MOXA_VERSION);1332 1333 tty_port_init(&moxa_service_port);1334 1335 moxaDriver = tty_alloc_driver(MAX_PORTS + 1,1336 TTY_DRIVER_REAL_RAW |1337 TTY_DRIVER_DYNAMIC_DEV);1338 if (IS_ERR(moxaDriver))1339 return PTR_ERR(moxaDriver);1340 1341 moxaDriver->name = "ttyMX";1342 moxaDriver->major = ttymajor;1343 moxaDriver->minor_start = 0;1344 moxaDriver->type = TTY_DRIVER_TYPE_SERIAL;1345 moxaDriver->subtype = SERIAL_TYPE_NORMAL;1346 moxaDriver->init_termios = tty_std_termios;1347 moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;1348 moxaDriver->init_termios.c_ispeed = 9600;1349 moxaDriver->init_termios.c_ospeed = 9600;1350 tty_set_operations(moxaDriver, &moxa_ops);1351 /* Having one more port only for ioctls is ugly */1352 tty_port_link_device(&moxa_service_port, moxaDriver, MAX_PORTS);1353 1354 if (tty_register_driver(moxaDriver)) {1355 printk(KERN_ERR "can't register MOXA Smartio tty driver!\n");1356 tty_driver_kref_put(moxaDriver);1357 return -1;1358 }1359 1360 /* Find the boards defined from module args. */1361 1362 for (i = 0; i < MAX_BOARDS; i++) {1363 if (!baseaddr[i])1364 break;1365 if (type[i] == MOXA_BOARD_C218_ISA ||1366 type[i] == MOXA_BOARD_C320_ISA) {1367 pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n",1368 isabrds + 1, moxa_brdname[type[i] - 1],1369 baseaddr[i]);1370 brd->boardType = type[i];1371 brd->numPorts = type[i] == MOXA_BOARD_C218_ISA ? 8 :1372 numports[i];1373 brd->busType = MOXA_BUS_TYPE_ISA;1374 brd->basemem = ioremap(baseaddr[i], 0x4000);1375 if (!brd->basemem) {1376 printk(KERN_ERR "MOXA: can't remap %lx\n",1377 baseaddr[i]);1378 continue;1379 }1380 if (moxa_init_board(brd, NULL)) {1381 iounmap(brd->basemem);1382 brd->basemem = NULL;1383 continue;1384 }1385 1386 printk(KERN_INFO "MOXA isa board found at 0x%.8lx and "1387 "ready (%u ports, firmware loaded)\n",1388 baseaddr[i], brd->numPorts);1389 1390 brd++;1391 isabrds++;1392 }1393 }1394 1395#ifdef CONFIG_PCI1396 retval = pci_register_driver(&moxa_pci_driver);1397 if (retval) {1398 printk(KERN_ERR "Can't register MOXA pci driver!\n");1399 if (isabrds)1400 retval = 0;1401 }1402#endif1403 1404 return retval;1405}1406 1407static void __exit moxa_exit(void)1408{1409 unsigned int i;1410 1411#ifdef CONFIG_PCI1412 pci_unregister_driver(&moxa_pci_driver);1413#endif1414 1415 for (i = 0; i < MAX_BOARDS; i++) /* ISA boards */1416 if (moxa_boards[i].ready)1417 moxa_board_deinit(&moxa_boards[i]);1418 1419 del_timer_sync(&moxaTimer);1420 1421 tty_unregister_driver(moxaDriver);1422 tty_driver_kref_put(moxaDriver);1423}1424 1425module_init(moxa_init);1426module_exit(moxa_exit);1427 1428static void moxa_shutdown(struct tty_port *port)1429{1430 struct moxa_port *ch = container_of(port, struct moxa_port, port);1431 MoxaPortDisable(ch);1432 MoxaPortFlushData(ch, 2);1433}1434 1435static bool moxa_carrier_raised(struct tty_port *port)1436{1437 struct moxa_port *ch = container_of(port, struct moxa_port, port);1438 int dcd;1439 1440 spin_lock_irq(&port->lock);1441 dcd = ch->DCDState;1442 spin_unlock_irq(&port->lock);1443 return dcd;1444}1445 1446static void moxa_dtr_rts(struct tty_port *port, bool active)1447{1448 struct moxa_port *ch = container_of(port, struct moxa_port, port);1449 MoxaPortLineCtrl(ch, active, active);1450}1451 1452 1453static int moxa_open(struct tty_struct *tty, struct file *filp)1454{1455 struct moxa_board_conf *brd;1456 struct moxa_port *ch;1457 int port;1458 1459 port = tty->index;1460 if (port == MAX_PORTS) {1461 return capable(CAP_SYS_ADMIN) ? 0 : -EPERM;1462 }1463 if (mutex_lock_interruptible(&moxa_openlock))1464 return -ERESTARTSYS;1465 brd = &moxa_boards[port / MAX_PORTS_PER_BOARD];1466 if (!brd->ready) {1467 mutex_unlock(&moxa_openlock);1468 return -ENODEV;1469 }1470 1471 if (port % MAX_PORTS_PER_BOARD >= brd->numPorts) {1472 mutex_unlock(&moxa_openlock);1473 return -ENODEV;1474 }1475 1476 ch = &brd->ports[port % MAX_PORTS_PER_BOARD];1477 ch->port.count++;1478 tty->driver_data = ch;1479 tty_port_tty_set(&ch->port, tty);1480 mutex_lock(&ch->port.mutex);1481 if (!tty_port_initialized(&ch->port)) {1482 ch->statusflags = 0;1483 moxa_set_tty_param(tty, &tty->termios);1484 MoxaPortLineCtrl(ch, true, true);1485 MoxaPortEnable(ch);1486 MoxaSetFifo(ch, ch->type == PORT_16550A);1487 tty_port_set_initialized(&ch->port, true);1488 }1489 mutex_unlock(&ch->port.mutex);1490 mutex_unlock(&moxa_openlock);1491 1492 return tty_port_block_til_ready(&ch->port, tty, filp);1493}1494 1495static void moxa_close(struct tty_struct *tty, struct file *filp)1496{1497 struct moxa_port *ch = tty->driver_data;1498 ch->cflag = tty->termios.c_cflag;1499 tty_port_close(&ch->port, tty, filp);1500}1501 1502static ssize_t moxa_write(struct tty_struct *tty, const u8 *buf, size_t count)1503{1504 struct moxa_port *ch = tty->driver_data;1505 unsigned long flags;1506 int len;1507 1508 if (ch == NULL)1509 return 0;1510 1511 spin_lock_irqsave(&moxa_lock, flags);1512 len = MoxaPortWriteData(tty, buf, count);1513 spin_unlock_irqrestore(&moxa_lock, flags);1514 1515 set_bit(LOWWAIT, &ch->statusflags);1516 return len;1517}1518 1519static unsigned int moxa_write_room(struct tty_struct *tty)1520{1521 struct moxa_port *ch;1522 1523 if (tty->flow.stopped)1524 return 0;1525 ch = tty->driver_data;1526 if (ch == NULL)1527 return 0;1528 return MoxaPortTxFree(ch);1529}1530 1531static void moxa_flush_buffer(struct tty_struct *tty)1532{1533 struct moxa_port *ch = tty->driver_data;1534 1535 if (ch == NULL)1536 return;1537 MoxaPortFlushData(ch, 1);1538 tty_wakeup(tty);1539}1540 1541static unsigned int moxa_chars_in_buffer(struct tty_struct *tty)1542{1543 struct moxa_port *ch = tty->driver_data;1544 unsigned int chars;1545 1546 chars = MoxaPortTxQueue(ch);1547 if (chars)1548 /*1549 * Make it possible to wakeup anything waiting for output1550 * in tty_ioctl.c, etc.1551 */1552 set_bit(EMPTYWAIT, &ch->statusflags);1553 return chars;1554}1555 1556static int moxa_tiocmget(struct tty_struct *tty)1557{1558 struct moxa_port *ch = tty->driver_data;1559 bool dtr_active, rts_active;1560 int flag = 0;1561 int status;1562 1563 MoxaPortGetLineOut(ch, &dtr_active, &rts_active);1564 if (dtr_active)1565 flag |= TIOCM_DTR;1566 if (rts_active)1567 flag |= TIOCM_RTS;1568 status = MoxaPortLineStatus(ch);1569 if (status & 1)1570 flag |= TIOCM_CTS;1571 if (status & 2)1572 flag |= TIOCM_DSR;1573 if (status & 4)1574 flag |= TIOCM_CD;1575 return flag;1576}1577 1578static int moxa_tiocmset(struct tty_struct *tty,1579 unsigned int set, unsigned int clear)1580{1581 bool dtr_active, rts_active;1582 struct moxa_port *ch;1583 1584 mutex_lock(&moxa_openlock);1585 ch = tty->driver_data;1586 if (!ch) {1587 mutex_unlock(&moxa_openlock);1588 return -EINVAL;1589 }1590 1591 MoxaPortGetLineOut(ch, &dtr_active, &rts_active);1592 if (set & TIOCM_RTS)1593 rts_active = true;1594 if (set & TIOCM_DTR)1595 dtr_active = true;1596 if (clear & TIOCM_RTS)1597 rts_active = false;1598 if (clear & TIOCM_DTR)1599 dtr_active = false;1600 MoxaPortLineCtrl(ch, dtr_active, rts_active);1601 mutex_unlock(&moxa_openlock);1602 return 0;1603}1604 1605static void moxa_set_termios(struct tty_struct *tty,1606 const struct ktermios *old_termios)1607{1608 struct moxa_port *ch = tty->driver_data;1609 1610 if (ch == NULL)1611 return;1612 moxa_set_tty_param(tty, old_termios);1613 if (!(old_termios->c_cflag & CLOCAL) && C_CLOCAL(tty))1614 wake_up_interruptible(&ch->port.open_wait);1615}1616 1617static void moxa_stop(struct tty_struct *tty)1618{1619 struct moxa_port *ch = tty->driver_data;1620 1621 if (ch == NULL)1622 return;1623 MoxaPortTxDisable(ch);1624 set_bit(TXSTOPPED, &ch->statusflags);1625}1626 1627 1628static void moxa_start(struct tty_struct *tty)1629{1630 struct moxa_port *ch = tty->driver_data;1631 1632 if (ch == NULL)1633 return;1634 1635 if (!test_bit(TXSTOPPED, &ch->statusflags))1636 return;1637 1638 MoxaPortTxEnable(ch);1639 clear_bit(TXSTOPPED, &ch->statusflags);1640}1641 1642static void moxa_hangup(struct tty_struct *tty)1643{1644 struct moxa_port *ch = tty->driver_data;1645 tty_port_hangup(&ch->port);1646}1647 1648static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)1649{1650 unsigned long flags;1651 dcd = !!dcd;1652 1653 spin_lock_irqsave(&p->port.lock, flags);1654 if (dcd != p->DCDState) {1655 p->DCDState = dcd;1656 spin_unlock_irqrestore(&p->port.lock, flags);1657 if (!dcd)1658 tty_port_tty_hangup(&p->port, true);1659 }1660 else1661 spin_unlock_irqrestore(&p->port.lock, flags);1662}1663 1664static int moxa_poll_port(struct moxa_port *p, unsigned int handle,1665 u16 __iomem *ip)1666{1667 struct tty_struct *tty = tty_port_tty_get(&p->port);1668 bool inited = tty_port_initialized(&p->port);1669 void __iomem *ofsAddr;1670 u16 intr;1671 1672 if (tty) {1673 if (test_bit(EMPTYWAIT, &p->statusflags) &&1674 MoxaPortTxQueue(p) == 0) {1675 clear_bit(EMPTYWAIT, &p->statusflags);1676 tty_wakeup(tty);1677 }1678 if (test_bit(LOWWAIT, &p->statusflags) && !tty->flow.stopped &&1679 MoxaPortTxQueue(p) <= WAKEUP_CHARS) {1680 clear_bit(LOWWAIT, &p->statusflags);1681 tty_wakeup(tty);1682 }1683 1684 if (inited && !tty_throttled(tty) &&1685 MoxaPortRxQueue(p) > 0) { /* RX */1686 MoxaPortReadData(p);1687 tty_flip_buffer_push(&p->port);1688 }1689 } else {1690 clear_bit(EMPTYWAIT, &p->statusflags);1691 MoxaPortFlushData(p, 0); /* flush RX */1692 }1693 1694 if (!handle) /* nothing else to do */1695 goto put;1696 1697 intr = readw(ip); /* port irq status */1698 if (intr == 0)1699 goto put;1700 1701 writew(0, ip); /* ACK port */1702 ofsAddr = p->tableAddr;1703 if (intr & IntrTx) /* disable tx intr */1704 writew(readw(ofsAddr + HostStat) & ~WakeupTx,1705 ofsAddr + HostStat);1706 1707 if (!inited)1708 goto put;1709 1710 if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */1711 tty_insert_flip_char(&p->port, 0, TTY_BREAK);1712 tty_flip_buffer_push(&p->port);1713 }1714 1715 if (intr & IntrLine)1716 moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state);1717put:1718 tty_kref_put(tty);1719 1720 return 0;1721}1722 1723static void moxa_poll(struct timer_list *unused)1724{1725 struct moxa_board_conf *brd;1726 u16 __iomem *ip;1727 unsigned int card, port, served = 0;1728 1729 spin_lock(&moxa_lock);1730 for (card = 0; card < MAX_BOARDS; card++) {1731 brd = &moxa_boards[card];1732 if (!brd->ready)1733 continue;1734 1735 served++;1736 1737 ip = NULL;1738 if (readb(brd->intPend) == 0xff)1739 ip = brd->intTable + readb(brd->intNdx);1740 1741 for (port = 0; port < brd->numPorts; port++)1742 moxa_poll_port(&brd->ports[port], !!ip, ip + port);1743 1744 if (ip)1745 writeb(0, brd->intPend); /* ACK */1746 1747 if (moxaLowWaterChk) {1748 struct moxa_port *p = brd->ports;1749 for (port = 0; port < brd->numPorts; port++, p++)1750 if (p->lowChkFlag) {1751 p->lowChkFlag = 0;1752 moxa_low_water_check(p->tableAddr);1753 }1754 }1755 }1756 moxaLowWaterChk = 0;1757 1758 if (served)1759 mod_timer(&moxaTimer, jiffies + HZ / 50);1760 spin_unlock(&moxa_lock);1761}1762 1763/******************************************************************************/1764 1765static void moxa_set_tty_param(struct tty_struct *tty,1766 const struct ktermios *old_termios)1767{1768 register struct ktermios *ts = &tty->termios;1769 struct moxa_port *ch = tty->driver_data;1770 int rts, cts, txflow, rxflow, xany, baud;1771 1772 rts = cts = txflow = rxflow = xany = 0;1773 if (ts->c_cflag & CRTSCTS)1774 rts = cts = 1;1775 if (ts->c_iflag & IXON)1776 txflow = 1;1777 if (ts->c_iflag & IXOFF)1778 rxflow = 1;1779 if (ts->c_iflag & IXANY)1780 xany = 1;1781 1782 MoxaPortFlowCtrl(ch, rts, cts, txflow, rxflow, xany);1783 baud = MoxaPortSetTermio(ch, ts, tty_get_baud_rate(tty));1784 if (baud == -1)1785 baud = tty_termios_baud_rate(old_termios);1786 /* Not put the baud rate into the termios data */1787 tty_encode_baud_rate(tty, baud, baud);1788}1789 1790/*****************************************************************************1791 * Driver level functions: *1792 *****************************************************************************/1793 1794static void MoxaPortFlushData(struct moxa_port *port, int mode)1795{1796 void __iomem *ofsAddr;1797 if (mode < 0 || mode > 2)1798 return;1799 ofsAddr = port->tableAddr;1800 moxafunc(ofsAddr, FC_FlushQueue, mode);1801 if (mode != 1) {1802 port->lowChkFlag = 0;1803 moxa_low_water_check(ofsAddr);1804 }1805}1806 1807/*1808 * Moxa Port Number Description:1809 *1810 * MOXA serial driver supports up to 4 MOXA-C218/C320 boards. And,1811 * the port number using in MOXA driver functions will be 0 to 31 for1812 * first MOXA board, 32 to 63 for second, 64 to 95 for third and 961813 * to 127 for fourth. For example, if you setup three MOXA boards,1814 * first board is C218, second board is C320-16 and third board is1815 * C320-32. The port number of first board (C218 - 8 ports) is from1816 * 0 to 7. The port number of second board (C320 - 16 ports) is form1817 * 32 to 47. The port number of third board (C320 - 32 ports) is from1818 * 64 to 95. And those port numbers form 8 to 31, 48 to 63 and 96 to1819 * 127 will be invalid.1820 *1821 *1822 * Moxa Functions Description:1823 *1824 * Function 1: Driver initialization routine, this routine must be1825 * called when initialized driver.1826 * Syntax:1827 * void MoxaDriverInit();1828 *1829 *1830 * Function 2: Moxa driver private IOCTL command processing.1831 * Syntax:1832 * int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port);1833 *1834 * unsigned int cmd : IOCTL command1835 * unsigned long arg : IOCTL argument1836 * int port : port number (0 - 127)1837 *1838 * return: 0 (OK)1839 * -EINVAL1840 * -ENOIOCTLCMD1841 *1842 *1843 * Function 6: Enable this port to start Tx/Rx data.1844 * Syntax:1845 * void MoxaPortEnable(int port);1846 * int port : port number (0 - 127)1847 *1848 *1849 * Function 7: Disable this port1850 * Syntax:1851 * void MoxaPortDisable(int port);1852 * int port : port number (0 - 127)1853 *1854 *1855 * Function 10: Setting baud rate of this port.1856 * Syntax:1857 * speed_t MoxaPortSetBaud(int port, speed_t baud);1858 * int port : port number (0 - 127)1859 * long baud : baud rate (50 - 115200)1860 *1861 * return: 0 : this port is invalid or baud < 501862 * 50 - 115200 : the real baud rate set to the port, if1863 * the argument baud is large than maximun1864 * available baud rate, the real setting1865 * baud rate will be the maximun baud rate.1866 *1867 *1868 * Function 12: Configure the port.1869 * Syntax:1870 * int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud);1871 * int port : port number (0 - 127)1872 * struct ktermios * termio : termio structure pointer1873 * speed_t baud : baud rate1874 *1875 * return: -1 : this port is invalid or termio == NULL1876 * 0 : setting O.K.1877 *1878 *1879 * Function 13: Get the DTR/RTS state of this port.1880 * Syntax:1881 * int MoxaPortGetLineOut(int port, bool *dtrState, bool *rtsState);1882 * int port : port number (0 - 127)1883 * bool * dtr_active : pointer to bool to receive the current DTR1884 * state. (if NULL, this function will not1885 * write to this address)1886 * bool * rts_active : pointer to bool to receive the current RTS1887 * state. (if NULL, this function will not1888 * write to this address)1889 *1890 * return: -1 : this port is invalid1891 * 0 : O.K.1892 *1893 *1894 * Function 14: Setting the DTR/RTS output state of this port.1895 * Syntax:1896 * void MoxaPortLineCtrl(int port, bool dtrState, bool rtsState);1897 * int port : port number (0 - 127)1898 * bool dtr_active : DTR output state1899 * bool rts_active : RTS output state1900 *1901 *1902 * Function 15: Setting the flow control of this port.1903 * Syntax:1904 * void MoxaPortFlowCtrl(int port, int rtsFlow, int ctsFlow, int rxFlow,1905 * int txFlow,int xany);1906 * int port : port number (0 - 127)1907 * int rtsFlow : H/W RTS flow control (0: no, 1: yes)1908 * int ctsFlow : H/W CTS flow control (0: no, 1: yes)1909 * int rxFlow : S/W Rx XON/XOFF flow control (0: no, 1: yes)1910 * int txFlow : S/W Tx XON/XOFF flow control (0: no, 1: yes)1911 * int xany : S/W XANY flow control (0: no, 1: yes)1912 *1913 *1914 * Function 16: Get ths line status of this port1915 * Syntax:1916 * int MoxaPortLineStatus(int port);1917 * int port : port number (0 - 127)1918 *1919 * return: Bit 0 - CTS state (0: off, 1: on)1920 * Bit 1 - DSR state (0: off, 1: on)1921 * Bit 2 - DCD state (0: off, 1: on)1922 *1923 *1924 * Function 19: Flush the Rx/Tx buffer data of this port.1925 * Syntax:1926 * void MoxaPortFlushData(int port, int mode);1927 * int port : port number (0 - 127)1928 * int mode 1929 * 0 : flush the Rx buffer 1930 * 1 : flush the Tx buffer 1931 * 2 : flush the Rx and Tx buffer 1932 *1933 *1934 * Function 20: Write data.1935 * Syntax:1936 * ssize_t MoxaPortWriteData(int port, u8 *buffer, size_t length);1937 * int port : port number (0 - 127)1938 * u8 *buffer : pointer to write data buffer.1939 * size_t length : write data length1940 *1941 * return: 0 - length : real write data length1942 *1943 *1944 * Function 21: Read data.1945 * Syntax:1946 * int MoxaPortReadData(int port, struct tty_struct *tty);1947 * int port : port number (0 - 127)1948 * struct tty_struct *tty : tty for data1949 *1950 * return: 0 - length : real read data length1951 *1952 *1953 * Function 24: Get the Tx buffer current queued data bytes1954 * Syntax:1955 * int MoxaPortTxQueue(int port);1956 * int port : port number (0 - 127)1957 *1958 * return: .. : Tx buffer current queued data bytes1959 *1960 *1961 * Function 25: Get the Tx buffer current free space1962 * Syntax:1963 * int MoxaPortTxFree(int port);1964 * int port : port number (0 - 127)1965 *1966 * return: .. : Tx buffer current free space1967 *1968 *1969 * Function 26: Get the Rx buffer current queued data bytes1970 * Syntax:1971 * int MoxaPortRxQueue(int port);1972 * int port : port number (0 - 127)1973 *1974 * return: .. : Rx buffer current queued data bytes1975 *1976 *1977 * Function 28: Disable port data transmission.1978 * Syntax:1979 * void MoxaPortTxDisable(int port);1980 * int port : port number (0 - 127)1981 *1982 *1983 * Function 29: Enable port data transmission.1984 * Syntax:1985 * void MoxaPortTxEnable(int port);1986 * int port : port number (0 - 127)1987 *1988 *1989 * Function 31: Get the received BREAK signal count and reset it.1990 * Syntax:1991 * int MoxaPortResetBrkCnt(int port);1992 * int port : port number (0 - 127)1993 *1994 * return: 0 - .. : BREAK signal count1995 *1996 *1997 */1998 1999static void MoxaPortEnable(struct moxa_port *port)2000{2001 void __iomem *ofsAddr;2002 u16 lowwater = 512;2003 2004 ofsAddr = port->tableAddr;2005 writew(lowwater, ofsAddr + Low_water);2006 if (MOXA_IS_320(port->board))2007 moxafunc(ofsAddr, FC_SetBreakIrq, 0);2008 else2009 writew(readw(ofsAddr + HostStat) | WakeupBreak,2010 ofsAddr + HostStat);2011 2012 moxafunc(ofsAddr, FC_SetLineIrq, Magic_code);2013 moxafunc(ofsAddr, FC_FlushQueue, 2);2014 2015 moxafunc(ofsAddr, FC_EnableCH, Magic_code);2016 MoxaPortLineStatus(port);2017}2018 2019static void MoxaPortDisable(struct moxa_port *port)2020{2021 void __iomem *ofsAddr = port->tableAddr;2022 2023 moxafunc(ofsAddr, FC_SetFlowCtl, 0); /* disable flow control */2024 moxafunc(ofsAddr, FC_ClrLineIrq, Magic_code);2025 writew(0, ofsAddr + HostStat);2026 moxafunc(ofsAddr, FC_DisableCH, Magic_code);2027}2028 2029static speed_t MoxaPortSetBaud(struct moxa_port *port, speed_t baud)2030{2031 void __iomem *ofsAddr = port->tableAddr;2032 unsigned int clock, val;2033 speed_t max;2034 2035 max = MOXA_IS_320(port->board) ? 460800 : 921600;2036 if (baud < 50)2037 return 0;2038 if (baud > max)2039 baud = max;2040 clock = 921600;2041 val = clock / baud;2042 moxafunc(ofsAddr, FC_SetBaud, val);2043 baud = clock / val;2044 return baud;2045}2046 2047static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,2048 speed_t baud)2049{2050 void __iomem *ofsAddr;2051 tcflag_t mode = 0;2052 2053 ofsAddr = port->tableAddr;2054 2055 mode = termio->c_cflag & CSIZE;2056 if (mode == CS5)2057 mode = MX_CS5;2058 else if (mode == CS6)2059 mode = MX_CS6;2060 else if (mode == CS7)2061 mode = MX_CS7;2062 else if (mode == CS8)2063 mode = MX_CS8;2064 2065 if (termio->c_cflag & CSTOPB) {2066 if (mode == MX_CS5)2067 mode |= MX_STOP15;2068 else2069 mode |= MX_STOP2;2070 } else2071 mode |= MX_STOP1;2072 2073 if (termio->c_cflag & PARENB) {2074 if (termio->c_cflag & PARODD) {2075 if (termio->c_cflag & CMSPAR)2076 mode |= MX_PARMARK;2077 else2078 mode |= MX_PARODD;2079 } else {2080 if (termio->c_cflag & CMSPAR)2081 mode |= MX_PARSPACE;2082 else2083 mode |= MX_PAREVEN;2084 }2085 } else2086 mode |= MX_PARNONE;2087 2088 moxafunc(ofsAddr, FC_SetDataMode, (u16)mode);2089 2090 if (MOXA_IS_320(port->board) && baud >= 921600)2091 return -1;2092 2093 baud = MoxaPortSetBaud(port, baud);2094 2095 if (termio->c_iflag & (IXON | IXOFF | IXANY)) {2096 spin_lock_irq(&moxafunc_lock);2097 writeb(termio->c_cc[VSTART], ofsAddr + FuncArg);2098 writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);2099 writeb(FC_SetXonXoff, ofsAddr + FuncCode);2100 moxa_wait_finish(ofsAddr);2101 spin_unlock_irq(&moxafunc_lock);2102 2103 }2104 return baud;2105}2106 2107static int MoxaPortGetLineOut(struct moxa_port *port, bool *dtr_active,2108 bool *rts_active)2109{2110 if (dtr_active)2111 *dtr_active = port->lineCtrl & DTR_ON;2112 if (rts_active)2113 *rts_active = port->lineCtrl & RTS_ON;2114 2115 return 0;2116}2117 2118static void MoxaPortLineCtrl(struct moxa_port *port, bool dtr_active, bool rts_active)2119{2120 u8 mode = 0;2121 2122 if (dtr_active)2123 mode |= DTR_ON;2124 if (rts_active)2125 mode |= RTS_ON;2126 port->lineCtrl = mode;2127 moxafunc(port->tableAddr, FC_LineControl, mode);2128}2129 2130static void MoxaPortFlowCtrl(struct moxa_port *port, int rts, int cts,2131 int txflow, int rxflow, int txany)2132{2133 int mode = 0;2134 2135 if (rts)2136 mode |= RTS_FlowCtl;2137 if (cts)2138 mode |= CTS_FlowCtl;2139 if (txflow)2140 mode |= Tx_FlowCtl;2141 if (rxflow)2142 mode |= Rx_FlowCtl;2143 if (txany)2144 mode |= IXM_IXANY;2145 moxafunc(port->tableAddr, FC_SetFlowCtl, mode);2146}2147 2148static int MoxaPortLineStatus(struct moxa_port *port)2149{2150 void __iomem *ofsAddr;2151 int val;2152 2153 ofsAddr = port->tableAddr;2154 if (MOXA_IS_320(port->board))2155 val = moxafuncret(ofsAddr, FC_LineStatus, 0);2156 else2157 val = readw(ofsAddr + FlagStat) >> 4;2158 val &= 0x0B;2159 if (val & 8)2160 val |= 4;2161 moxa_new_dcdstate(port, val & 8);2162 val &= 7;2163 return val;2164}2165 2166static ssize_t MoxaPortWriteData(struct tty_struct *tty, const u8 *buffer,2167 size_t len)2168{2169 struct moxa_port *port = tty->driver_data;2170 void __iomem *baseAddr, *ofsAddr, *ofs;2171 size_t c, total;2172 u16 head, tail, tx_mask, spage, epage;2173 u16 pageno, pageofs, bufhead;2174 2175 ofsAddr = port->tableAddr;2176 baseAddr = port->board->basemem;2177 tx_mask = readw(ofsAddr + TX_mask);2178 spage = readw(ofsAddr + Page_txb);2179 epage = readw(ofsAddr + EndPage_txb);2180 tail = readw(ofsAddr + TXwptr);2181 head = readw(ofsAddr + TXrptr);2182 c = (head > tail) ? (head - tail - 1) : (head - tail + tx_mask);2183 if (c > len)2184 c = len;2185 moxaLog.txcnt[port->port.tty->index] += c;2186 total = c;2187 if (spage == epage) {2188 bufhead = readw(ofsAddr + Ofs_txb);2189 writew(spage, baseAddr + Control_reg);2190 while (c > 0) {2191 if (head > tail)2192 len = head - tail - 1;2193 else2194 len = tx_mask + 1 - tail;2195 len = (c > len) ? len : c;2196 ofs = baseAddr + DynPage_addr + bufhead + tail;2197 memcpy_toio(ofs, buffer, len);2198 buffer += len;2199 tail = (tail + len) & tx_mask;2200 c -= len;2201 }2202 } else {2203 pageno = spage + (tail >> 13);2204 pageofs = tail & Page_mask;2205 while (c > 0) {2206 len = Page_size - pageofs;2207 if (len > c)2208 len = c;2209 writeb(pageno, baseAddr + Control_reg);2210 ofs = baseAddr + DynPage_addr + pageofs;2211 memcpy_toio(ofs, buffer, len);2212 buffer += len;2213 if (++pageno == epage)2214 pageno = spage;2215 pageofs = 0;2216 c -= len;2217 }2218 tail = (tail + total) & tx_mask;2219 }2220 writew(tail, ofsAddr + TXwptr);2221 writeb(1, ofsAddr + CD180TXirq); /* start to send */2222 return total;2223}2224 2225static int MoxaPortReadData(struct moxa_port *port)2226{2227 struct tty_struct *tty = port->port.tty;2228 void __iomem *baseAddr, *ofsAddr, *ofs;2229 u8 *dst;2230 unsigned int count, len, total;2231 u16 tail, rx_mask, spage, epage;2232 u16 pageno, pageofs, bufhead, head;2233 2234 ofsAddr = port->tableAddr;2235 baseAddr = port->board->basemem;2236 head = readw(ofsAddr + RXrptr);2237 tail = readw(ofsAddr + RXwptr);2238 rx_mask = readw(ofsAddr + RX_mask);2239 spage = readw(ofsAddr + Page_rxb);2240 epage = readw(ofsAddr + EndPage_rxb);2241 count = (tail >= head) ? (tail - head) : (tail - head + rx_mask + 1);2242 if (count == 0)2243 return 0;2244 2245 total = count;2246 moxaLog.rxcnt[tty->index] += total;2247 if (spage == epage) {2248 bufhead = readw(ofsAddr + Ofs_rxb);2249 writew(spage, baseAddr + Control_reg);2250 while (count > 0) {2251 ofs = baseAddr + DynPage_addr + bufhead + head;2252 len = (tail >= head) ? (tail - head) :2253 (rx_mask + 1 - head);2254 len = tty_prepare_flip_string(&port->port, &dst,2255 min(len, count));2256 memcpy_fromio(dst, ofs, len);2257 head = (head + len) & rx_mask;2258 count -= len;2259 }2260 } else {2261 pageno = spage + (head >> 13);2262 pageofs = head & Page_mask;2263 while (count > 0) {2264 writew(pageno, baseAddr + Control_reg);2265 ofs = baseAddr + DynPage_addr + pageofs;2266 len = tty_prepare_flip_string(&port->port, &dst,2267 min(Page_size - pageofs, count));2268 memcpy_fromio(dst, ofs, len);2269 2270 count -= len;2271 pageofs = (pageofs + len) & Page_mask;2272 if (pageofs == 0 && ++pageno == epage)2273 pageno = spage;2274 }2275 head = (head + total) & rx_mask;2276 }2277 writew(head, ofsAddr + RXrptr);2278 if (readb(ofsAddr + FlagStat) & Xoff_state) {2279 moxaLowWaterChk = 1;2280 port->lowChkFlag = 1;2281 }2282 return total;2283}2284 2285 2286static unsigned int MoxaPortTxQueue(struct moxa_port *port)2287{2288 void __iomem *ofsAddr = port->tableAddr;2289 u16 rptr, wptr, mask;2290 2291 rptr = readw(ofsAddr + TXrptr);2292 wptr = readw(ofsAddr + TXwptr);2293 mask = readw(ofsAddr + TX_mask);2294 return (wptr - rptr) & mask;2295}2296 2297static unsigned int MoxaPortTxFree(struct moxa_port *port)2298{2299 void __iomem *ofsAddr = port->tableAddr;2300 u16 rptr, wptr, mask;2301 2302 rptr = readw(ofsAddr + TXrptr);2303 wptr = readw(ofsAddr + TXwptr);2304 mask = readw(ofsAddr + TX_mask);2305 return mask - ((wptr - rptr) & mask);2306}2307 2308static int MoxaPortRxQueue(struct moxa_port *port)2309{2310 void __iomem *ofsAddr = port->tableAddr;2311 u16 rptr, wptr, mask;2312 2313 rptr = readw(ofsAddr + RXrptr);2314 wptr = readw(ofsAddr + RXwptr);2315 mask = readw(ofsAddr + RX_mask);2316 return (wptr - rptr) & mask;2317}2318 2319static void MoxaPortTxDisable(struct moxa_port *port)2320{2321 moxafunc(port->tableAddr, FC_SetXoffState, Magic_code);2322}2323 2324static void MoxaPortTxEnable(struct moxa_port *port)2325{2326 moxafunc(port->tableAddr, FC_SetXonState, Magic_code);2327}2328 2329static int moxa_get_serial_info(struct tty_struct *tty,2330 struct serial_struct *ss)2331{2332 struct moxa_port *info = tty->driver_data;2333 2334 if (tty->index == MAX_PORTS)2335 return -EINVAL;2336 if (!info)2337 return -ENODEV;2338 mutex_lock(&info->port.mutex);2339 ss->type = info->type;2340 ss->line = info->port.tty->index;2341 ss->flags = info->port.flags;2342 ss->baud_base = 921600;2343 ss->close_delay = jiffies_to_msecs(info->port.close_delay) / 10;2344 mutex_unlock(&info->port.mutex);2345 return 0;2346}2347 2348 2349static int moxa_set_serial_info(struct tty_struct *tty,2350 struct serial_struct *ss)2351{2352 struct moxa_port *info = tty->driver_data;2353 unsigned int close_delay;2354 2355 if (tty->index == MAX_PORTS)2356 return -EINVAL;2357 if (!info)2358 return -ENODEV;2359 2360 close_delay = msecs_to_jiffies(ss->close_delay * 10);2361 2362 mutex_lock(&info->port.mutex);2363 if (!capable(CAP_SYS_ADMIN)) {2364 if (close_delay != info->port.close_delay ||2365 ss->type != info->type ||2366 ((ss->flags & ~ASYNC_USR_MASK) !=2367 (info->port.flags & ~ASYNC_USR_MASK))) {2368 mutex_unlock(&info->port.mutex);2369 return -EPERM;2370 }2371 } else {2372 info->port.close_delay = close_delay;2373 2374 MoxaSetFifo(info, ss->type == PORT_16550A);2375 2376 info->type = ss->type;2377 }2378 mutex_unlock(&info->port.mutex);2379 return 0;2380}2381 2382 2383 2384/*****************************************************************************2385 * Static local functions: *2386 *****************************************************************************/2387 2388static void MoxaSetFifo(struct moxa_port *port, int enable)2389{2390 void __iomem *ofsAddr = port->tableAddr;2391 2392 if (!enable) {2393 moxafunc(ofsAddr, FC_SetRxFIFOTrig, 0);2394 moxafunc(ofsAddr, FC_SetTxFIFOCnt, 1);2395 } else {2396 moxafunc(ofsAddr, FC_SetRxFIFOTrig, 3);2397 moxafunc(ofsAddr, FC_SetTxFIFOCnt, 16);2398 }2399}2400