moxa.c revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*****************************************************************************/ 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * moxa.c -- MOXA Intellio family multiport serial driver. 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5b9705b603d1d29471aa2977e6310f4f9a4e85925Jiri Slaby * Copyright (C) 1999-2000 Moxa Technologies (support@moxa.com.tw). 6b9705b603d1d29471aa2977e6310f4f9a4e85925Jiri Slaby * 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This code is loosely based on the Linux serial driver, written by 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Linus Torvalds, Theodore T'so and others. 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * it under the terms of the GNU General Public License as published by 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the Free Software Foundation; either version 2 of the License, or 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (at your option) any later version. 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is distributed in the hope that it will be useful, 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License for more details. 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You should have received a copy of the GNU General Public License 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * along with this program; if not, write to the Free Software 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MOXA Intellio Series Driver 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for : LINUX 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * date : 1999/1/7 29037182346f0991683cc7320a257c3f6089432ceeJiri Slaby * version : 5.1 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/config.h> 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h> 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ioport.h> 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/signal.h> 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sched.h> 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/timer.h> 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/interrupt.h> 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/tty.h> 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/tty_flip.h> 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/major.h> 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h> 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fcntl.h> 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ptrace.h> 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/serial.h> 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/tty_driver.h> 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 51037182346f0991683cc7320a257c3f6089432ceeJiri Slaby#include <linux/pci.h> 52037182346f0991683cc7320a257c3f6089432ceeJiri Slaby#include <linux/init.h> 53b9705b603d1d29471aa2977e6310f4f9a4e85925Jiri Slaby#include <linux/bitops.h> 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 55037182346f0991683cc7320a257c3f6089432ceeJiri Slaby#include <asm/system.h> 56037182346f0991683cc7320a257c3f6089432ceeJiri Slaby#include <asm/io.h> 5711324edd4ad34981764b25bed44d46a1507b62e1Jiri Slaby#include <asm/uaccess.h> 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5911324edd4ad34981764b25bed44d46a1507b62e1Jiri Slaby#define MOXA_VERSION "5.1k" 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6111324edd4ad34981764b25bed44d46a1507b62e1Jiri Slaby#define MOXAMAJOR 172 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXACUMAJOR 173 6308d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby 6408d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby#define put_to_user(arg1, arg2) put_user(arg1, (unsigned long *)arg2) 6508d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby#define get_from_user(arg1, arg2) get_user(arg1, (unsigned int *)arg2) 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MAX_BOARDS 4 /* Don't change this value */ 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MAX_PORTS_PER_BOARD 32 /* Don't change this value */ 6911324edd4ad34981764b25bed44d46a1507b62e1Jiri Slaby#define MAX_PORTS 128 /* Don't change this value */ 7011324edd4ad34981764b25bed44d46a1507b62e1Jiri Slaby 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Define the Moxa PCI vendor and device IDs. 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_BUS_TYPE_ISA 0 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_BUS_TYPE_PCI 1 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef PCI_VENDOR_ID_MOXA 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PCI_VENDOR_ID_MOXA 0x1393 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef PCI_DEVICE_ID_CP204J 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PCI_DEVICE_ID_CP204J 0x2040 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef PCI_DEVICE_ID_C218 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PCI_DEVICE_ID_C218 0x2180 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef PCI_DEVICE_ID_C320 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PCI_DEVICE_ID_C320 0x3200 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenum { 915ebb4078af0dab866fdf57f84f72b9e9a7e8c6b8Jiri Slaby MOXA_BOARD_C218_PCI = 1, 925ebb4078af0dab866fdf57f84f72b9e9a7e8c6b8Jiri Slaby MOXA_BOARD_C218_ISA, 935ebb4078af0dab866fdf57f84f72b9e9a7e8c6b8Jiri Slaby MOXA_BOARD_C320_PCI, 945ebb4078af0dab866fdf57f84f72b9e9a7e8c6b8Jiri Slaby MOXA_BOARD_C320_ISA, 955ebb4078af0dab866fdf57f84f72b9e9a7e8c6b8Jiri Slaby MOXA_BOARD_CP204J, 965ebb4078af0dab866fdf57f84f72b9e9a7e8c6b8Jiri Slaby}; 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *moxa_brdname[] = 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "C218 Turbo PCI series", 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "C218 Turbo ISA series", 102037182346f0991683cc7320a257c3f6089432ceeJiri Slaby "C320 Turbo PCI series", 103037182346f0991683cc7320a257c3f6089432ceeJiri Slaby "C320 Turbo ISA series", 1048f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby "CP-204J series", 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PCI 1088f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slabystatic struct pci_device_id moxa_pcibrds[] = { 109810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C218, PCI_ANY_ID, PCI_ANY_ID, 1108f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby 0, 0, MOXA_BOARD_C218_PCI }, 111037182346f0991683cc7320a257c3f6089432ceeJiri Slaby { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C320, PCI_ANY_ID, PCI_ANY_ID, 112037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 0, 0, MOXA_BOARD_C320_PCI }, 1138f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_CP204J, PCI_ANY_ID, PCI_ANY_ID, 1148f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby 0, 0, MOXA_BOARD_CP204J }, 1158f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby { 0 } 1168f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby}; 1178f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri SlabyMODULE_DEVICE_TABLE(pci, moxa_pcibrds); 1188f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby#endif /* CONFIG_PCI */ 1198f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby 1208f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slabytypedef struct _moxa_isa_board_conf { 1218f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby int boardType; 1228f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby int numPorts; 1238f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby unsigned long baseAddr; 1248f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby} moxa_isa_board_conf; 1259dff89cd82af7bccc706fed288b1c33a51c3b937Jiri Slaby 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic moxa_isa_board_conf moxa_isa_boards[] = 1278f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby{ 1288f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby/* {MOXA_BOARD_C218_ISA,8,0xDC000}, */ 1298f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby}; 1308f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef struct _moxa_pci_devinfo { 1328f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby ushort busNum; 1339de6a51fee08f9e7020074738150441305e83af2Alan Cox ushort devNum; 134b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby} moxa_pci_devinfo; 1357bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 1367bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabytypedef struct _moxa_board_conf { 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int boardType; 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int numPorts; 1397bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby unsigned long baseAddr; 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int busType; 1417bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby moxa_pci_devinfo pciInfo; 1427bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby} moxa_board_conf; 1437bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 1448f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slabystatic moxa_board_conf moxa_boards[MAX_BOARDS]; 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __iomem *moxaBaseAddr[MAX_BOARDS]; 14674d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby 14774d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystruct moxa_str { 14874d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby int type; 14974d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby int port; 15074d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby int close_delay; 15174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby unsigned short closing_wait; 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int count; 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int blocked_open; 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long event; /* long req'd for set_bit --RR */ 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int asyncflags; 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long statusflags; 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct tty_struct *tty; 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cflag; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wait_queue_head_t open_wait; 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wait_queue_head_t close_wait; 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct work_struct tqueue; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 16374d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby 16474d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystruct mxser_mstatus { 1657bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby tcflag_t cflag; 166a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby int cts; 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int dsr; 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ri; 169d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby int dcd; 170d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby}; 171d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mxser_mstatus GMStatus[MAX_PORTS]; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* statusflags */ 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TXSTOPPED 0x1 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LOWWAIT 0x2 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define EMPTYWAIT 0x4 178d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby#define THROTTLE 0x8 179d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby 180d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby/* event */ 181d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby#define MOXA_EVENT_HANGUP 1 182d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby 183d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby#define SERIAL_DO_RESTART 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SERIAL_TYPE_NORMAL 1 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WAKEUP_CHARS 256 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PORTNO(x) ((x)->index) 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int verbose = 0; 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int ttymajor = MOXAMAJOR; 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Variables for insmod */ 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef MODULE 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int baseaddr[] = {0, 0, 0, 0}; 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int type[] = {0, 0, 0, 0}; 198606d099cdd1080bbb50ea50dc52d98252f8f10a1Alan Coxstatic int numports[] = {0, 0, 0, 0}; 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("William Chen"); 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver"); 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef MODULE 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param_array(type, int, NULL, 0); 206db1acaa632870ec87b65e062bc72ca375837a1f6Alan Coxmodule_param_array(baseaddr, int, NULL, 0); 2076f56b658b4e5c4486641ce62f331150954c4de37Jiri Slabymodule_param_array(numports, int, NULL, 0); 2086f56b658b4e5c4486641ce62f331150954c4de37Jiri Slaby#endif 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(ttymajor, int, 0); 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(verbose, bool, 0644); 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 212b4173f45758a5b5185acb302c507289e661d9419Jiri Slabystatic struct tty_driver *moxaDriver; 213b4173f45758a5b5185acb302c507289e661d9419Jiri Slabystatic struct moxa_str moxaChannels[MAX_PORTS]; 214b4173f45758a5b5185acb302c507289e661d9419Jiri Slabystatic unsigned char *moxaXmitBuff; 215b4173f45758a5b5185acb302c507289e661d9419Jiri Slabystatic int moxaTimer_on; 216b4173f45758a5b5185acb302c507289e661d9419Jiri Slabystatic struct timer_list moxaTimer; 217b4173f45758a5b5185acb302c507289e661d9419Jiri Slabystatic int moxaEmptyTimer_on[MAX_PORTS]; 218b4173f45758a5b5185acb302c507289e661d9419Jiri Slabystatic struct timer_list moxaEmptyTimer[MAX_PORTS]; 219b4173f45758a5b5185acb302c507289e661d9419Jiri Slabystatic struct semaphore moxaBuffSem; 2202108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby 2217bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby/* 222b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * static functions: 223b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby */ 224b4173f45758a5b5185acb302c507289e661d9419Jiri Slabystatic void do_moxa_softint(void *); 225b4173f45758a5b5185acb302c507289e661d9419Jiri Slabystatic int moxa_open(struct tty_struct *, struct file *); 226b4173f45758a5b5185acb302c507289e661d9419Jiri Slabystatic void moxa_close(struct tty_struct *, struct file *); 2278f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slabystatic int moxa_write(struct tty_struct *, const unsigned char *, int); 2288f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slabystatic int moxa_write_room(struct tty_struct *); 229b4173f45758a5b5185acb302c507289e661d9419Jiri Slabystatic void moxa_flush_buffer(struct tty_struct *); 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_chars_in_buffer(struct tty_struct *); 23174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void moxa_flush_chars(struct tty_struct *); 23274d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void moxa_put_char(struct tty_struct *, unsigned char); 23374d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int moxa_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long); 23474d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void moxa_throttle(struct tty_struct *); 23574d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void moxa_unthrottle(struct tty_struct *); 23674d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void moxa_set_termios(struct tty_struct *, struct termios *); 23774d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void moxa_stop(struct tty_struct *); 23874d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void moxa_start(struct tty_struct *); 23974d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void moxa_hangup(struct tty_struct *); 24074d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int moxa_tiocmget(struct tty_struct *tty, struct file *file); 24174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int moxa_tiocmset(struct tty_struct *tty, struct file *file, 24274d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby unsigned int set, unsigned int clear); 24374d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void moxa_poll(unsigned long); 24474d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void set_tty_param(struct tty_struct *); 24574d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int block_till_ready(struct tty_struct *, struct file *, 246eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby struct moxa_str *); 24774d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void setup_empty_event(struct tty_struct *); 24874d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void check_xmit_empty(unsigned long); 24974d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void shut_down(struct moxa_str *); 25074d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void receive_data(struct moxa_str *); 25174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby/* 25274d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby * moxa board interface functions: 2537bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby */ 2547bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic void MoxaDriverInit(void); 2557bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic int MoxaDriverIoctl(unsigned int, unsigned long, int); 2567bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic int MoxaDriverPoll(void); 2577bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic int MoxaPortsOfCard(int); 2587bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic int MoxaPortIsValid(int); 2597bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic void MoxaPortEnable(int); 2607bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic void MoxaPortDisable(int); 2617bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic long MoxaPortGetMaxBaud(int); 2627bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic long MoxaPortSetBaud(int, long); 2637bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic int MoxaPortSetTermio(int, struct termios *); 2647bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic int MoxaPortGetLineOut(int, int *, int *); 2657bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic void MoxaPortLineCtrl(int, int, int); 2667bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic void MoxaPortFlowCtrl(int, int, int, int, int, int); 26774d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int MoxaPortLineStatus(int); 26874d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int MoxaPortDCDChange(int); 26974d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int MoxaPortDCDON(int); 27074d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void MoxaPortFlushData(int, int); 27174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int MoxaPortWriteData(int, unsigned char *, int); 27274d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int MoxaPortReadData(int, unsigned char *, int); 27374d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int MoxaPortTxQueue(int); 27474d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int MoxaPortRxQueue(int); 27574d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int MoxaPortTxFree(int); 276a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slabystatic void MoxaPortTxDisable(int); 27774d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void MoxaPortTxEnable(int); 27874d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int MoxaPortResetBrkCnt(int); 27974d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void MoxaPortSendBreak(int, int); 28074d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int moxa_get_serial_info(struct moxa_str *, struct serial_struct __user *); 28174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int moxa_set_serial_info(struct moxa_str *, struct serial_struct __user *); 28274d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic void MoxaSetFifo(int port, int enable); 28374d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby 28474d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic struct tty_operations moxa_ops = { 28574d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby .open = moxa_open, 28674d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby .close = moxa_close, 28774d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby .write = moxa_write, 288a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby .write_room = moxa_write_room, 289a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby .flush_buffer = moxa_flush_buffer, 290a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby .chars_in_buffer = moxa_chars_in_buffer, 29174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby .flush_chars = moxa_flush_chars, 29274d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby .put_char = moxa_put_char, 293a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby .ioctl = moxa_ioctl, 29474d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby .throttle = moxa_throttle, 29574d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby .unthrottle = moxa_unthrottle, 29674d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby .set_termios = moxa_set_termios, 29774d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby .stop = moxa_stop, 29874d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby .start = moxa_start, 29974d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby .hangup = moxa_hangup, 300a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby .tiocmget = moxa_tiocmget, 30174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby .tiocmset = moxa_tiocmset, 30274d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby}; 30374d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby 30474d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby#ifdef CONFIG_PCI 30574d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board) 30674d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby{ 30774d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby board->baseAddr = pci_resource_start (p, 2); 30874d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby board->boardType = board_type; 309a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby switch (board_type) { 310a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby case MOXA_BOARD_C218_ISA: 31174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby case MOXA_BOARD_C218_PCI: 312a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby board->numPorts = 8; 31374d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby break; 31474d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby 315a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby case MOXA_BOARD_CP204J: 316a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby board->numPorts = 4; 31774d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby break; 31874d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby default: 319a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby board->numPorts = 0; 320a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby break; 32174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby } 32274d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby board->busType = MOXA_BUS_TYPE_PCI; 323a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby board->pciInfo.busNum = p->bus->number; 324a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby board->pciInfo.devNum = p->devfn >> 3; 32574d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby 32674d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby return (0); 32774d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby} 32874d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby#endif /* CONFIG_PCI */ 32974d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby 33074d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slabystatic int __init moxa_init(void) 331a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby{ 33274d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby int i, numBoards; 33374d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby struct moxa_str *ch; 33474d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby 33574d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION); 33674d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxaDriver = alloc_tty_driver(MAX_PORTS + 1); 33774d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby if (!moxaDriver) 33874d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby return -ENOMEM; 33974d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby 34074d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby init_MUTEX(&moxaBuffSem); 34174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxaDriver->owner = THIS_MODULE; 34274d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxaDriver->name = "ttya"; 34374d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxaDriver->devfs_name = "tts/a"; 34474d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxaDriver->major = ttymajor; 34574d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxaDriver->minor_start = 0; 34674d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxaDriver->type = TTY_DRIVER_TYPE_SERIAL; 3479de6a51fee08f9e7020074738150441305e83af2Alan Cox moxaDriver->subtype = SERIAL_TYPE_NORMAL; 34874d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxaDriver->init_termios = tty_std_termios; 34974d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxaDriver->init_termios.c_iflag = 0; 3509de6a51fee08f9e7020074738150441305e83af2Alan Cox moxaDriver->init_termios.c_oflag = 0; 35174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; 352a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby moxaDriver->init_termios.c_lflag = 0; 353a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby moxaDriver->flags = TTY_DRIVER_REAL_RAW; 35474d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby tty_set_operations(moxaDriver, &moxa_ops); 355a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 35674d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxaXmitBuff = NULL; 35774d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby 358a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby for (i = 0, ch = moxaChannels; i < MAX_PORTS; i++, ch++) { 359a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby ch->type = PORT_16550A; 36074d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby ch->port = i; 36174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby INIT_WORK(&ch->tqueue, do_moxa_softint, ch); 362a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby ch->tty = NULL; 363a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby ch->close_delay = 5 * HZ / 10; 364a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby ch->closing_wait = 30 * HZ; 365a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby ch->count = 0; 36674d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby ch->blocked_open = 0; 367a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; 368a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby init_waitqueue_head(&ch->open_wait); 369a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby init_waitqueue_head(&ch->close_wait); 370a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby } 371a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 372a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby for (i = 0; i < MAX_BOARDS; i++) { 37374d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxa_boards[i].boardType = 0; 374a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby moxa_boards[i].numPorts = 0; 37574d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxa_boards[i].baseAddr = 0; 37674d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxa_boards[i].busType = 0; 37774d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxa_boards[i].pciInfo.busNum = 0; 37874d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxa_boards[i].pciInfo.devNum = 0; 37974d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby } 38074d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby MoxaDriverInit(); 38174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby printk("Tty devices major number = %d\n", ttymajor); 38274d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby 38374d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby if (tty_register_driver(moxaDriver)) { 38474d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n"); 385b68e31d0ebbcc909d1941f9f230c9d062a3a13d3Jeff Dike put_tty_driver(moxaDriver); 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_PORTS; i++) { 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_timer(&moxaEmptyTimer[i]); 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaEmptyTimer[i].function = check_xmit_empty; 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaEmptyTimer[i].data = (unsigned long) & moxaChannels[i]; 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaEmptyTimer_on[i] = 0; 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_timer(&moxaTimer); 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaTimer.function = moxa_poll; 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaTimer.expires = jiffies + (HZ / 50); 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaTimer_on = 1; 39974d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby add_timer(&moxaTimer); 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Find the boards defined in source code */ 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds numBoards = 0; 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_BOARDS; i++) { 404aa7e5221fb47badbea618cc62704d6e4a4bcce15Jiri Slaby if ((moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA) || 405aa7e5221fb47badbea618cc62704d6e4a4bcce15Jiri Slaby (moxa_isa_boards[i].boardType == MOXA_BOARD_C320_ISA)) { 40634af946a22724c4e2b204957f2b24b22a0fb121cIngo Molnar moxa_boards[numBoards].boardType = moxa_isa_boards[i].boardType; 40733f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA) 40874d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxa_boards[numBoards].numPorts = 8; 40974d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby else 41074d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts; 41174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA; 412037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr; 413037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (verbose) 414037182346f0991683cc7320a257c3f6089432ceeJiri Slaby printk("Board %2d: %s board(baseAddr=%lx)\n", 415037182346f0991683cc7320a257c3f6089432ceeJiri Slaby numBoards + 1, 416037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxa_brdname[moxa_boards[numBoards].boardType - 1], 417037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxa_boards[numBoards].baseAddr); 418037182346f0991683cc7320a257c3f6089432ceeJiri Slaby numBoards++; 419037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 420037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 421037182346f0991683cc7320a257c3f6089432ceeJiri Slaby /* Find the boards defined form module args. */ 422037182346f0991683cc7320a257c3f6089432ceeJiri Slaby#ifdef MODULE 423037182346f0991683cc7320a257c3f6089432ceeJiri Slaby for (i = 0; i < MAX_BOARDS; i++) { 424037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if ((type[i] == MOXA_BOARD_C218_ISA) || 425037182346f0991683cc7320a257c3f6089432ceeJiri Slaby (type[i] == MOXA_BOARD_C320_ISA)) { 426037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (verbose) 427037182346f0991683cc7320a257c3f6089432ceeJiri Slaby printk("Board %2d: %s board(baseAddr=%lx)\n", 428037182346f0991683cc7320a257c3f6089432ceeJiri Slaby numBoards + 1, 429037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxa_brdname[type[i] - 1], 430037182346f0991683cc7320a257c3f6089432ceeJiri Slaby (unsigned long) baseaddr[i]); 431037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (numBoards >= MAX_BOARDS) { 432037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (verbose) 433037182346f0991683cc7320a257c3f6089432ceeJiri Slaby printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS); 434037182346f0991683cc7320a257c3f6089432ceeJiri Slaby continue; 435037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 436037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxa_boards[numBoards].boardType = type[i]; 437037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA) 438037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxa_boards[numBoards].numPorts = 8; 439037182346f0991683cc7320a257c3f6089432ceeJiri Slaby else 440037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxa_boards[numBoards].numPorts = numports[i]; 441037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA; 442037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxa_boards[numBoards].baseAddr = baseaddr[i]; 443037182346f0991683cc7320a257c3f6089432ceeJiri Slaby numBoards++; 444037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 445037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 446037182346f0991683cc7320a257c3f6089432ceeJiri Slaby#endif 447037182346f0991683cc7320a257c3f6089432ceeJiri Slaby /* Find PCI boards here */ 448037182346f0991683cc7320a257c3f6089432ceeJiri Slaby#ifdef CONFIG_PCI 449037182346f0991683cc7320a257c3f6089432ceeJiri Slaby { 450037182346f0991683cc7320a257c3f6089432ceeJiri Slaby struct pci_dev *p = NULL; 451037182346f0991683cc7320a257c3f6089432ceeJiri Slaby int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1; 452037182346f0991683cc7320a257c3f6089432ceeJiri Slaby i = 0; 453037182346f0991683cc7320a257c3f6089432ceeJiri Slaby while (i < n) { 454037182346f0991683cc7320a257c3f6089432ceeJiri Slaby while ((p = pci_find_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL) 455037182346f0991683cc7320a257c3f6089432ceeJiri Slaby { 456037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (pci_enable_device(p)) 457037182346f0991683cc7320a257c3f6089432ceeJiri Slaby continue; 458037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (numBoards >= MAX_BOARDS) { 459037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (verbose) 460037182346f0991683cc7320a257c3f6089432ceeJiri Slaby printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS); 461037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } else { 462037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxa_get_PCI_conf(p, moxa_pcibrds[i].driver_data, 463037182346f0991683cc7320a257c3f6089432ceeJiri Slaby &moxa_boards[numBoards]); 464037182346f0991683cc7320a257c3f6089432ceeJiri Slaby numBoards++; 465037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 466037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 467037182346f0991683cc7320a257c3f6089432ceeJiri Slaby i++; 468037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 469037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 470037182346f0991683cc7320a257c3f6089432ceeJiri Slaby#endif 471037182346f0991683cc7320a257c3f6089432ceeJiri Slaby for (i = 0; i < numBoards; i++) { 472037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxaBaseAddr[i] = ioremap((unsigned long) moxa_boards[i].baseAddr, 0x4000); 473037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 474037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 475037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return (0); 476eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby} 477037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 478037182346f0991683cc7320a257c3f6089432ceeJiri Slabystatic void __exit moxa_exit(void) 479037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 480037182346f0991683cc7320a257c3f6089432ceeJiri Slaby int i; 481037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 482037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (verbose) 483037182346f0991683cc7320a257c3f6089432ceeJiri Slaby printk("Unloading module moxa ...\n"); 484037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 485eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby if (moxaTimer_on) 486037182346f0991683cc7320a257c3f6089432ceeJiri Slaby del_timer(&moxaTimer); 487037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 488037182346f0991683cc7320a257c3f6089432ceeJiri Slaby for (i = 0; i < MAX_PORTS; i++) 489037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (moxaEmptyTimer_on[i]) 490037182346f0991683cc7320a257c3f6089432ceeJiri Slaby del_timer(&moxaEmptyTimer[i]); 491037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 492037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (tty_unregister_driver(moxaDriver)) 493037182346f0991683cc7320a257c3f6089432ceeJiri Slaby printk("Couldn't unregister MOXA Intellio family serial driver\n"); 494037182346f0991683cc7320a257c3f6089432ceeJiri Slaby put_tty_driver(moxaDriver); 495eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby if (verbose) 496037182346f0991683cc7320a257c3f6089432ceeJiri Slaby printk("Done\n"); 497037182346f0991683cc7320a257c3f6089432ceeJiri Slaby} 498037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 499037182346f0991683cc7320a257c3f6089432ceeJiri Slabymodule_init(moxa_init); 500037182346f0991683cc7320a257c3f6089432ceeJiri Slabymodule_exit(moxa_exit); 501037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 502037182346f0991683cc7320a257c3f6089432ceeJiri Slabystatic void do_moxa_softint(void *private_) 503037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 504037182346f0991683cc7320a257c3f6089432ceeJiri Slaby struct moxa_str *ch = (struct moxa_str *) private_; 505037182346f0991683cc7320a257c3f6089432ceeJiri Slaby struct tty_struct *tty; 506037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 507037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (ch && (tty = ch->tty)) { 5085292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby if (test_and_clear_bit(MOXA_EVENT_HANGUP, &ch->event)) { 509037182346f0991683cc7320a257c3f6089432ceeJiri Slaby tty_hangup(tty); /* FIXME: module removal race here - AKPM */ 510037182346f0991683cc7320a257c3f6089432ceeJiri Slaby wake_up_interruptible(&ch->open_wait); 511037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; 512037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 513037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 5145292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby} 51508d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby 516037182346f0991683cc7320a257c3f6089432ceeJiri Slabystatic int moxa_open(struct tty_struct *tty, struct file *filp) 517037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 5185292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby struct moxa_str *ch; 5195292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby int port; 520037182346f0991683cc7320a257c3f6089432ceeJiri Slaby int retval; 5215292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby unsigned long page; 5225292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby 5235292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby port = PORTNO(tty); 5245292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby if (port == MAX_PORTS) { 5255292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby return (0); 5265292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby } 5275292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby if (!MoxaPortIsValid(port)) { 5285292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby tty->driver_data = NULL; 5295292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby return (-ENODEV); 5305292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby } 5315292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby down(&moxaBuffSem); 5325292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby if (!moxaXmitBuff) { 5335292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby page = get_zeroed_page(GFP_KERNEL); 5345292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby if (!page) { 5355292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby up(&moxaBuffSem); 5365292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby return (-ENOMEM); 5375292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby } 5385292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby /* This test is guarded by the BuffSem so no longer needed 539037182346f0991683cc7320a257c3f6089432ceeJiri Slaby delete me in 2.5 */ 540037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (moxaXmitBuff) 541037182346f0991683cc7320a257c3f6089432ceeJiri Slaby free_page(page); 542037182346f0991683cc7320a257c3f6089432ceeJiri Slaby else 543037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxaXmitBuff = (unsigned char *) page; 544037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 545037182346f0991683cc7320a257c3f6089432ceeJiri Slaby up(&moxaBuffSem); 546037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 547037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ch = &moxaChannels[port]; 548037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ch->count++; 549037182346f0991683cc7320a257c3f6089432ceeJiri Slaby tty->driver_data = ch; 550037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ch->tty = tty; 551037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (!(ch->asyncflags & ASYNC_INITIALIZED)) { 5525292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby ch->statusflags = 0; 553037182346f0991683cc7320a257c3f6089432ceeJiri Slaby set_tty_param(tty); 5545292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby MoxaPortLineCtrl(ch->port, 1, 1); 5555292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby MoxaPortEnable(ch->port); 5565292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby ch->asyncflags |= ASYNC_INITIALIZED; 5575292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby } 5585292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby retval = block_till_ready(tty, filp, ch); 559037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 560037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxa_unthrottle(tty); 561037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 5625292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby if (ch->type == PORT_16550A) { 563037182346f0991683cc7320a257c3f6089432ceeJiri Slaby MoxaSetFifo(ch->port, 1); 564037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } else { 5655292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby MoxaSetFifo(ch->port, 0); 5665292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby } 5675292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby 5685292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby return (retval); 5695292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby} 570037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 571037182346f0991683cc7320a257c3f6089432ceeJiri Slabystatic void moxa_close(struct tty_struct *tty, struct file *filp) 572037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 573037182346f0991683cc7320a257c3f6089432ceeJiri Slaby struct moxa_str *ch; 5745292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby int port; 5755292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby 576037182346f0991683cc7320a257c3f6089432ceeJiri Slaby port = PORTNO(tty); 577037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (port == MAX_PORTS) { 5785292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby return; 579037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 580037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (!MoxaPortIsValid(port)) { 581037182346f0991683cc7320a257c3f6089432ceeJiri Slaby#ifdef SERIAL_DEBUG_CLOSE 582037182346f0991683cc7320a257c3f6089432ceeJiri Slaby printk("Invalid portno in moxa_close\n"); 583037182346f0991683cc7320a257c3f6089432ceeJiri Slaby#endif 584037182346f0991683cc7320a257c3f6089432ceeJiri Slaby tty->driver_data = NULL; 585037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return; 586037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 58708d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby if (tty->driver_data == NULL) { 5885292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby return; 5895292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby } 5905292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby if (tty_hung_up_p(filp)) { 5915292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby return; 5925292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby } 5935292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby ch = (struct moxa_str *) tty->driver_data; 5945292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby 5955292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby if ((tty->count == 1) && (ch->count != 1)) { 5965292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby printk("moxa_close: bad serial port count; tty->count is 1, " 597037182346f0991683cc7320a257c3f6089432ceeJiri Slaby "ch->count is %d\n", ch->count); 598037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ch->count = 1; 599037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 600037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (--ch->count < 0) { 601037182346f0991683cc7320a257c3f6089432ceeJiri Slaby printk("moxa_close: bad serial port count, device=%s\n", 602037182346f0991683cc7320a257c3f6089432ceeJiri Slaby tty->name); 603037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ch->count = 0; 604037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 605037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (ch->count) { 606037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return; 607037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 60808d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby ch->asyncflags |= ASYNC_CLOSING; 6095292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby 6105292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby ch->cflag = tty->termios->c_cflag; 6115292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby if (ch->asyncflags & ASYNC_INITIALIZED) { 6125292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby setup_empty_event(tty); 6135292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ 6145292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby moxaEmptyTimer_on[ch->port] = 0; 6155292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby del_timer(&moxaEmptyTimer[ch->port]); 6165292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby } 6175292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby shut_down(ch); 6185292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby MoxaPortFlushData(port, 2); 6195292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby 6205292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby if (tty->driver->flush_buffer) 6215292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby tty->driver->flush_buffer(tty); 622037182346f0991683cc7320a257c3f6089432ceeJiri Slaby tty_ldisc_flush(tty); 623037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 624037182346f0991683cc7320a257c3f6089432ceeJiri Slaby tty->closing = 0; 625037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ch->event = 0; 626037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ch->tty = NULL; 627037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (ch->blocked_open) { 628037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (ch->close_delay) { 629037182346f0991683cc7320a257c3f6089432ceeJiri Slaby msleep_interruptible(jiffies_to_msecs(ch->close_delay)); 630037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 631037182346f0991683cc7320a257c3f6089432ceeJiri Slaby wake_up_interruptible(&ch->open_wait); 632037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 633037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); 634037182346f0991683cc7320a257c3f6089432ceeJiri Slaby wake_up_interruptible(&ch->close_wait); 635037182346f0991683cc7320a257c3f6089432ceeJiri Slaby} 636037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 637037182346f0991683cc7320a257c3f6089432ceeJiri Slabystatic int moxa_write(struct tty_struct *tty, 638eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby const unsigned char *buf, int count) 639037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 640037182346f0991683cc7320a257c3f6089432ceeJiri Slaby struct moxa_str *ch; 641037182346f0991683cc7320a257c3f6089432ceeJiri Slaby int len, port; 6425292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby unsigned long flags; 6435292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby 6445292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby ch = (struct moxa_str *) tty->driver_data; 6455292bcd38e4bcd147905941b5e37b5b0da1a5577Jiri Slaby if (ch == NULL) 646037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return (0); 647037182346f0991683cc7320a257c3f6089432ceeJiri Slaby port = ch->port; 648037182346f0991683cc7320a257c3f6089432ceeJiri Slaby save_flags(flags); 649037182346f0991683cc7320a257c3f6089432ceeJiri Slaby cli(); 650037182346f0991683cc7320a257c3f6089432ceeJiri Slaby len = MoxaPortWriteData(port, (unsigned char *) buf, count); 651037182346f0991683cc7320a257c3f6089432ceeJiri Slaby restore_flags(flags); 652b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby 653037182346f0991683cc7320a257c3f6089432ceeJiri Slaby /********************************************* 654037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if ( !(ch->statusflags & LOWWAIT) && 655037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ((len != count) || (MoxaPortTxFree(port) <= 100)) ) 656037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ************************************************/ 657037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ch->statusflags |= LOWWAIT; 658037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return (len); 659037182346f0991683cc7320a257c3f6089432ceeJiri Slaby} 660037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 661037182346f0991683cc7320a257c3f6089432ceeJiri Slabystatic int moxa_write_room(struct tty_struct *tty) 662037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 663037182346f0991683cc7320a257c3f6089432ceeJiri Slaby struct moxa_str *ch; 664037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 665037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (tty->stopped) 666037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return (0); 667037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ch = (struct moxa_str *) tty->driver_data; 668037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (ch == NULL) 669037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return (0); 670b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby return (MoxaPortTxFree(ch->port)); 671037182346f0991683cc7320a257c3f6089432ceeJiri Slaby} 672037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 673037182346f0991683cc7320a257c3f6089432ceeJiri Slabystatic void moxa_flush_buffer(struct tty_struct *tty) 674037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 675037182346f0991683cc7320a257c3f6089432ceeJiri Slaby struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 676037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 677037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (ch == NULL) 678037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return; 679037182346f0991683cc7320a257c3f6089432ceeJiri Slaby MoxaPortFlushData(ch->port, 1); 680037182346f0991683cc7320a257c3f6089432ceeJiri Slaby tty_wakeup(tty); 681037182346f0991683cc7320a257c3f6089432ceeJiri Slaby} 682037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 683037182346f0991683cc7320a257c3f6089432ceeJiri Slabystatic int moxa_chars_in_buffer(struct tty_struct *tty) 684037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 685037182346f0991683cc7320a257c3f6089432ceeJiri Slaby int chars; 686037182346f0991683cc7320a257c3f6089432ceeJiri Slaby struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 687037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 688037182346f0991683cc7320a257c3f6089432ceeJiri Slaby /* 689037182346f0991683cc7320a257c3f6089432ceeJiri Slaby * Sigh...I have to check if driver_data is NULL here, because 690037182346f0991683cc7320a257c3f6089432ceeJiri Slaby * if an open() fails, the TTY subsystem eventually calls 691037182346f0991683cc7320a257c3f6089432ceeJiri Slaby * tty_wait_until_sent(), which calls the driver's chars_in_buffer() 692037182346f0991683cc7320a257c3f6089432ceeJiri Slaby * routine. And since the open() failed, we return 0 here. TDJ 693037182346f0991683cc7320a257c3f6089432ceeJiri Slaby */ 694037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (ch == NULL) 695037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return (0); 696037182346f0991683cc7320a257c3f6089432ceeJiri Slaby chars = MoxaPortTxQueue(ch->port); 697037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (chars) { 698037182346f0991683cc7320a257c3f6089432ceeJiri Slaby /* 699037182346f0991683cc7320a257c3f6089432ceeJiri Slaby * Make it possible to wakeup anything waiting for output 700037182346f0991683cc7320a257c3f6089432ceeJiri Slaby * in tty_ioctl.c, etc. 701037182346f0991683cc7320a257c3f6089432ceeJiri Slaby */ 702037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (!(ch->statusflags & EMPTYWAIT)) 703037182346f0991683cc7320a257c3f6089432ceeJiri Slaby setup_empty_event(tty); 704037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 705037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return (chars); 706037182346f0991683cc7320a257c3f6089432ceeJiri Slaby} 707037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 708037182346f0991683cc7320a257c3f6089432ceeJiri Slabystatic void moxa_flush_chars(struct tty_struct *tty) 709037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 710037182346f0991683cc7320a257c3f6089432ceeJiri Slaby /* 711037182346f0991683cc7320a257c3f6089432ceeJiri Slaby * Don't think I need this, because this is called to empty the TX 712037182346f0991683cc7320a257c3f6089432ceeJiri Slaby * buffer for the 16450, 16550, etc. 713037182346f0991683cc7320a257c3f6089432ceeJiri Slaby */ 714037182346f0991683cc7320a257c3f6089432ceeJiri Slaby} 715037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 716037182346f0991683cc7320a257c3f6089432ceeJiri Slabystatic void moxa_put_char(struct tty_struct *tty, unsigned char c) 717037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 718037182346f0991683cc7320a257c3f6089432ceeJiri Slaby struct moxa_str *ch; 719037182346f0991683cc7320a257c3f6089432ceeJiri Slaby int port; 7202bca76e89bc43f86136080536858048ebffab3e3David Howells unsigned long flags; 721037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 722037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ch = (struct moxa_str *) tty->driver_data; 723037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (ch == NULL) 724037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return; 725037182346f0991683cc7320a257c3f6089432ceeJiri Slaby port = ch->port; 726037182346f0991683cc7320a257c3f6089432ceeJiri Slaby save_flags(flags); 727037182346f0991683cc7320a257c3f6089432ceeJiri Slaby cli(); 728037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxaXmitBuff[0] = c; 729037182346f0991683cc7320a257c3f6089432ceeJiri Slaby MoxaPortWriteData(port, moxaXmitBuff, 1); 730037182346f0991683cc7320a257c3f6089432ceeJiri Slaby restore_flags(flags); 731037182346f0991683cc7320a257c3f6089432ceeJiri Slaby /************************************************ 732037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) ) 7332bca76e89bc43f86136080536858048ebffab3e3David Howells *************************************************/ 734037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ch->statusflags |= LOWWAIT; 735037182346f0991683cc7320a257c3f6089432ceeJiri Slaby} 736037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 737037182346f0991683cc7320a257c3f6089432ceeJiri Slabystatic int moxa_tiocmget(struct tty_struct *tty, struct file *file) 738037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 739037182346f0991683cc7320a257c3f6089432ceeJiri Slaby struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 740037182346f0991683cc7320a257c3f6089432ceeJiri Slaby int port; 741037182346f0991683cc7320a257c3f6089432ceeJiri Slaby int flag = 0, dtr, rts; 742037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 743037182346f0991683cc7320a257c3f6089432ceeJiri Slaby port = PORTNO(tty); 744037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if ((port != MAX_PORTS) && (!ch)) 745037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return (-EINVAL); 746037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 747037182346f0991683cc7320a257c3f6089432ceeJiri Slaby MoxaPortGetLineOut(ch->port, &dtr, &rts); 748037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (dtr) 749037182346f0991683cc7320a257c3f6089432ceeJiri Slaby flag |= TIOCM_DTR; 750037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (rts) 751037182346f0991683cc7320a257c3f6089432ceeJiri Slaby flag |= TIOCM_RTS; 752037182346f0991683cc7320a257c3f6089432ceeJiri Slaby dtr = MoxaPortLineStatus(ch->port); 753037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (dtr & 1) 754037182346f0991683cc7320a257c3f6089432ceeJiri Slaby flag |= TIOCM_CTS; 755037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (dtr & 2) 756037182346f0991683cc7320a257c3f6089432ceeJiri Slaby flag |= TIOCM_DSR; 757037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (dtr & 4) 758037182346f0991683cc7320a257c3f6089432ceeJiri Slaby flag |= TIOCM_CD; 759037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return flag; 760eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby} 761037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 762037182346f0991683cc7320a257c3f6089432ceeJiri Slabystatic int moxa_tiocmset(struct tty_struct *tty, struct file *file, 763037182346f0991683cc7320a257c3f6089432ceeJiri Slaby unsigned int set, unsigned int clear) 764037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 765037182346f0991683cc7320a257c3f6089432ceeJiri Slaby struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 766037182346f0991683cc7320a257c3f6089432ceeJiri Slaby int port; 767037182346f0991683cc7320a257c3f6089432ceeJiri Slaby int dtr, rts; 768037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 769037182346f0991683cc7320a257c3f6089432ceeJiri Slaby port = PORTNO(tty); 770037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if ((port != MAX_PORTS) && (!ch)) 771037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return (-EINVAL); 772037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 773037182346f0991683cc7320a257c3f6089432ceeJiri Slaby MoxaPortGetLineOut(ch->port, &dtr, &rts); 774037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (set & TIOCM_RTS) 775037182346f0991683cc7320a257c3f6089432ceeJiri Slaby rts = 1; 776037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (set & TIOCM_DTR) 777037182346f0991683cc7320a257c3f6089432ceeJiri Slaby dtr = 1; 778037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (clear & TIOCM_RTS) 779037182346f0991683cc7320a257c3f6089432ceeJiri Slaby rts = 0; 780037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (clear & TIOCM_DTR) 781037182346f0991683cc7320a257c3f6089432ceeJiri Slaby dtr = 0; 782037182346f0991683cc7320a257c3f6089432ceeJiri Slaby MoxaPortLineCtrl(ch->port, dtr, rts); 783037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return 0; 784037182346f0991683cc7320a257c3f6089432ceeJiri Slaby} 785037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 786037182346f0991683cc7320a257c3f6089432ceeJiri Slabystatic int moxa_ioctl(struct tty_struct *tty, struct file *file, 787037182346f0991683cc7320a257c3f6089432ceeJiri Slaby unsigned int cmd, unsigned long arg) 788037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 789037182346f0991683cc7320a257c3f6089432ceeJiri Slaby struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 790037182346f0991683cc7320a257c3f6089432ceeJiri Slaby register int port; 791037182346f0991683cc7320a257c3f6089432ceeJiri Slaby void __user *argp = (void __user *)arg; 792037182346f0991683cc7320a257c3f6089432ceeJiri Slaby int retval; 793037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 794037182346f0991683cc7320a257c3f6089432ceeJiri Slaby port = PORTNO(tty); 795037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if ((port != MAX_PORTS) && (!ch)) 796037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return (-EINVAL); 797037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 798037182346f0991683cc7320a257c3f6089432ceeJiri Slaby switch (cmd) { 799037182346f0991683cc7320a257c3f6089432ceeJiri Slaby case TCSBRK: /* SVID version: non-zero arg --> no break */ 800037182346f0991683cc7320a257c3f6089432ceeJiri Slaby retval = tty_check_change(tty); 801037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (retval) 802037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return (retval); 803037182346f0991683cc7320a257c3f6089432ceeJiri Slaby setup_empty_event(tty); 804037182346f0991683cc7320a257c3f6089432ceeJiri Slaby tty_wait_until_sent(tty, 0); 805037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (!arg) 806037182346f0991683cc7320a257c3f6089432ceeJiri Slaby MoxaPortSendBreak(ch->port, 0); 807037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return (0); 808037182346f0991683cc7320a257c3f6089432ceeJiri Slaby case TCSBRKP: /* support for POSIX tcsendbreak() */ 809037182346f0991683cc7320a257c3f6089432ceeJiri Slaby retval = tty_check_change(tty); 810037182346f0991683cc7320a257c3f6089432ceeJiri Slaby if (retval) 811810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby return (retval); 812810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby setup_empty_event(tty); 813037182346f0991683cc7320a257c3f6089432ceeJiri Slaby tty_wait_until_sent(tty, 0); 814037182346f0991683cc7320a257c3f6089432ceeJiri Slaby MoxaPortSendBreak(ch->port, arg); 815810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby return (0); 816810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby case TIOCGSOFTCAR: 817810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp); 818810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby case TIOCSSOFTCAR: 819810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby if(get_user(retval, (unsigned long __user *) argp)) 820810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby return -EFAULT; 821810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby arg = retval; 822810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | 823810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby (arg ? CLOCAL : 0)); 82444b7d1b37f786c61d0e382b6f72f605f73de284bAlan Cox if (C_CLOCAL(tty)) 825810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby ch->asyncflags &= ~ASYNC_CHECK_CD; 826810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby else 827810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby ch->asyncflags |= ASYNC_CHECK_CD; 828810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby return (0); 829037182346f0991683cc7320a257c3f6089432ceeJiri Slaby case TIOCGSERIAL: 830037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return moxa_get_serial_info(ch, argp); 831037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 832037182346f0991683cc7320a257c3f6089432ceeJiri Slaby case TIOCSSERIAL: 833037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return moxa_set_serial_info(ch, argp); 834037182346f0991683cc7320a257c3f6089432ceeJiri Slaby default: 835037182346f0991683cc7320a257c3f6089432ceeJiri Slaby retval = MoxaDriverIoctl(cmd, arg, port); 836037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 837037182346f0991683cc7320a257c3f6089432ceeJiri Slaby return (retval); 838037182346f0991683cc7320a257c3f6089432ceeJiri Slaby} 839037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 840037182346f0991683cc7320a257c3f6089432ceeJiri Slabystatic void moxa_throttle(struct tty_struct *tty) 841037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 842037182346f0991683cc7320a257c3f6089432ceeJiri Slaby struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 843037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 844ec09cd562135158dcb8a6c08e5a9efa36febedb1Jiri Slaby ch->statusflags |= THROTTLE; 845ec09cd562135158dcb8a6c08e5a9efa36febedb1Jiri Slaby} 846ec09cd562135158dcb8a6c08e5a9efa36febedb1Jiri Slaby 847ec09cd562135158dcb8a6c08e5a9efa36febedb1Jiri Slabystatic void moxa_unthrottle(struct tty_struct *tty) 848810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby{ 849037182346f0991683cc7320a257c3f6089432ceeJiri Slaby struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 850037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 851037182346f0991683cc7320a257c3f6089432ceeJiri Slaby ch->statusflags &= ~THROTTLE; 852037182346f0991683cc7320a257c3f6089432ceeJiri Slaby} 853037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 854810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slabystatic void moxa_set_termios(struct tty_struct *tty, 855810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby struct termios *old_termios) 856810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby{ 857810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 8582a5413416b6b2fd8a5a38601a4fe3b56a52cfb86Jiri Slaby 859810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby if (ch == NULL) 8600bcc4caadc8f5396b52950ee03c67b76875602dfJiri Slaby return; 8610bcc4caadc8f5396b52950ee03c67b76875602dfJiri Slaby set_tty_param(tty); 8622a5413416b6b2fd8a5a38601a4fe3b56a52cfb86Jiri Slaby if (!(old_termios->c_cflag & CLOCAL) && 8630bcc4caadc8f5396b52950ee03c67b76875602dfJiri Slaby (tty->termios->c_cflag & CLOCAL)) 864810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby wake_up_interruptible(&ch->open_wait); 865810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby} 866810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby 867810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slabystatic void moxa_stop(struct tty_struct *tty) 868037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 869037182346f0991683cc7320a257c3f6089432ceeJiri Slaby struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 870037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 871810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby if (ch == NULL) 872810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby return; 873a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby MoxaPortTxDisable(ch->port); 874a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby ch->statusflags |= TXSTOPPED; 875a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby} 8767bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 877810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby 8787bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic void moxa_start(struct tty_struct *tty) 879a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby{ 880a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 881a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 8829de6a51fee08f9e7020074738150441305e83af2Alan Cox if (ch == NULL) 8839de6a51fee08f9e7020074738150441305e83af2Alan Cox return; 884a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 885a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby if (!(ch->statusflags & TXSTOPPED)) 886a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby return; 8879de6a51fee08f9e7020074738150441305e83af2Alan Cox 888a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby MoxaPortTxEnable(ch->port); 889a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby ch->statusflags &= ~TXSTOPPED; 890a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby} 891a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 892a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slabystatic void moxa_hangup(struct tty_struct *tty) 893a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby{ 894a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 895a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 896810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby moxa_flush_buffer(tty); 897810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby shut_down(ch); 898810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby ch->event = 0; 899810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby ch->count = 0; 900810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->tty = NULL; 9029cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby wake_up_interruptible(&ch->open_wait); 9039cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby} 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9059cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slabystatic void moxa_poll(unsigned long ignored) 9069cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby{ 9079cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby register int card; 9089cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby struct moxa_str *ch; 9099cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby struct tty_struct *tp; 9109cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby int i, ports; 9117aeb95daf37dbd72f63cdd52d86a8b5d89e59394Jiri Slaby 9127aeb95daf37dbd72f63cdd52d86a8b5d89e59394Jiri Slaby moxaTimer_on = 0; 9139cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby del_timer(&moxaTimer); 9147aeb95daf37dbd72f63cdd52d86a8b5d89e59394Jiri Slaby 9159cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby if (MoxaDriverPoll() < 0) { 9169cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby moxaTimer.function = moxa_poll; 9179cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby moxaTimer.expires = jiffies + (HZ / 50); 9189cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby moxaTimer_on = 1; 9199cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby add_timer(&moxaTimer); 9209cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby return; 9219cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby } 9227aeb95daf37dbd72f63cdd52d86a8b5d89e59394Jiri Slaby for (card = 0; card < MAX_BOARDS; card++) { 9239cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby if ((ports = MoxaPortsOfCard(card)) <= 0) 9249cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby continue; 9259cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby ch = &moxaChannels[card * MAX_PORTS_PER_BOARD]; 9269cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby for (i = 0; i < ports; i++, ch++) { 9279cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby if ((ch->asyncflags & ASYNC_INITIALIZED) == 0) 928e46a5e3ff06b70690d567bdc81faf6c1c32e742fJiri Slaby continue; 929e46a5e3ff06b70690d567bdc81faf6c1c32e742fJiri Slaby if (!(ch->statusflags & THROTTLE) && 930e46a5e3ff06b70690d567bdc81faf6c1c32e742fJiri Slaby (MoxaPortRxQueue(ch->port) > 0)) 931e46a5e3ff06b70690d567bdc81faf6c1c32e742fJiri Slaby receive_data(ch); 932e46a5e3ff06b70690d567bdc81faf6c1c32e742fJiri Slaby if ((tp = ch->tty) == 0) 933e46a5e3ff06b70690d567bdc81faf6c1c32e742fJiri Slaby continue; 934e46a5e3ff06b70690d567bdc81faf6c1c32e742fJiri Slaby if (ch->statusflags & LOWWAIT) { 93524cb233520f01971d6d873cb52c64bbbb0665ac0Alan Cox if (MoxaPortTxQueue(ch->port) <= WAKEUP_CHARS) { 9367aeb95daf37dbd72f63cdd52d86a8b5d89e59394Jiri Slaby if (!tp->stopped) { 9377aeb95daf37dbd72f63cdd52d86a8b5d89e59394Jiri Slaby ch->statusflags &= ~LOWWAIT; 938e46a5e3ff06b70690d567bdc81faf6c1c32e742fJiri Slaby tty_wakeup(tp); 9397aeb95daf37dbd72f63cdd52d86a8b5d89e59394Jiri Slaby } 9409cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby } 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!I_IGNBRK(tp) && (MoxaPortResetBrkCnt(ch->port) > 0)) { 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty_insert_flip_char(tp, 0, TTY_BREAK); 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty_schedule_flip(tp); 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (MoxaPortDCDChange(ch->port)) { 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch->asyncflags & ASYNC_CHECK_CD) { 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (MoxaPortDCDON(ch->port)) 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up_interruptible(&ch->open_wait); 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_bit(MOXA_EVENT_HANGUP, &ch->event); 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds schedule_work(&ch->tqueue); 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 956a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby } 957037182346f0991683cc7320a257c3f6089432ceeJiri Slaby } 958037182346f0991683cc7320a257c3f6089432ceeJiri Slaby 959037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxaTimer.function = moxa_poll; 960037182346f0991683cc7320a257c3f6089432ceeJiri Slaby moxaTimer.expires = jiffies + (HZ / 50); 9619cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby moxaTimer_on = 1; 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add_timer(&moxaTimer); 963bb9f910a1153101a2f92620f1e7d0fda786c9812Jiri Slaby} 964bb9f910a1153101a2f92620f1e7d0fda786c9812Jiri Slaby 965bb9f910a1153101a2f92620f1e7d0fda786c9812Jiri Slaby/******************************************************************************/ 966eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby 967037182346f0991683cc7320a257c3f6089432ceeJiri Slabystatic void set_tty_param(struct tty_struct *tty) 968037182346f0991683cc7320a257c3f6089432ceeJiri Slaby{ 969037182346f0991683cc7320a257c3f6089432ceeJiri Slaby register struct termios *ts; 970e46a5e3ff06b70690d567bdc81faf6c1c32e742fJiri Slaby struct moxa_str *ch; 971e46a5e3ff06b70690d567bdc81faf6c1c32e742fJiri Slaby int rts, cts, txflow, rxflow, xany; 9729cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby 9739cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby ch = (struct moxa_str *) tty->driver_data; 9749cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby ts = tty->termios; 9759cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby if (ts->c_cflag & CLOCAL) 9769cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby ch->asyncflags &= ~ASYNC_CHECK_CD; 9779cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby else 9789cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby ch->asyncflags |= ASYNC_CHECK_CD; 9799cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby rts = cts = txflow = rxflow = xany = 0; 980810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby if (ts->c_cflag & CRTSCTS) 981810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby rts = cts = 1; 982e46a5e3ff06b70690d567bdc81faf6c1c32e742fJiri Slaby if (ts->c_iflag & IXON) 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds txflow = 1; 984a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby if (ts->c_iflag & IXOFF) 985a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby rxflow = 1; 986a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby if (ts->c_iflag & IXANY) 987a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby xany = 1; 988a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby MoxaPortFlowCtrl(ch->port, rts, cts, txflow, rxflow, xany); 989a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby MoxaPortSetTermio(ch->port, ts); 990a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby} 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int block_till_ready(struct tty_struct *tty, struct file *filp, 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch) 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 995810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby DECLARE_WAITQUEUE(wait,current); 996d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby unsigned long flags; 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retval; 9987aeb95daf37dbd72f63cdd52d86a8b5d89e59394Jiri Slaby int do_clocal = C_CLOCAL(tty); 9997aeb95daf37dbd72f63cdd52d86a8b5d89e59394Jiri Slaby 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If the device is in the middle of being closed, then block 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * until it's done, and then try again. 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) { 10059b4e3b13b147e9b737de63188a9ae740eaa8c36dSergey Vlasov if (ch->asyncflags & ASYNC_CLOSING) 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds interruptible_sleep_on(&ch->close_wait); 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef SERIAL_DO_RESTART 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch->asyncflags & ASYNC_HUP_NOTIFY) 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-EAGAIN); 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-ERESTARTSYS); 1012606d099cdd1080bbb50ea50dc52d98252f8f10a1Alan Cox#else 1013606d099cdd1080bbb50ea50dc52d98252f8f10a1Alan Cox return (-EAGAIN); 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If non-blocking mode is set, then make the check up front 1018eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby * and then exit. 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (filp->f_flags & O_NONBLOCK) { 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->asyncflags |= ASYNC_NORMAL_ACTIVE; 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 1023d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby } 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 1025d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby * Block waiting for the carrier detect and the line to become free 1026d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby */ 1027810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby retval = 0; 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add_wait_queue(&ch->open_wait, &wait); 1029d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby#ifdef SERIAL_DEBUG_OPEN 1030d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby printk("block_til_ready before block: ttys%d, count = %d\n", 1031d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby ch->line, ch->count); 1032d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby#endif 10337aeb95daf37dbd72f63cdd52d86a8b5d89e59394Jiri Slaby save_flags(flags); 1034d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby cli(); 1035d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby if (!tty_hung_up_p(filp)) 1036d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby ch->count--; 1037d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby restore_flags(flags); 1038d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby ch->blocked_open++; 1039d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby while (1) { 104024cb233520f01971d6d873cb52c64bbbb0665ac0Alan Cox set_current_state(TASK_INTERRUPTIBLE); 1041d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby if (tty_hung_up_p(filp) || 1042eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby !(ch->asyncflags & ASYNC_INITIALIZED)) { 1043d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby#ifdef SERIAL_DO_RESTART 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch->asyncflags & ASYNC_HUP_NOTIFY) 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -EAGAIN; 1046037182346f0991683cc7320a257c3f6089432ceeJiri Slaby else 1047037182346f0991683cc7320a257c3f6089432ceeJiri Slaby retval = -ERESTARTSYS; 1048037182346f0991683cc7320a257c3f6089432ceeJiri Slaby#else 1049037182346f0991683cc7320a257c3f6089432ceeJiri Slaby retval = -EAGAIN; 1050037182346f0991683cc7320a257c3f6089432ceeJiri Slaby#endif 1051d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby break; 1052bb9f910a1153101a2f92620f1e7d0fda786c9812Jiri Slaby } 1053bb9f910a1153101a2f92620f1e7d0fda786c9812Jiri Slaby if (!(ch->asyncflags & ASYNC_CLOSING) && (do_clocal || 1054bb9f910a1153101a2f92620f1e7d0fda786c9812Jiri Slaby MoxaPortDCDON(ch->port))) 1055bb9f910a1153101a2f92620f1e7d0fda786c9812Jiri Slaby break; 1056d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby 1057d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby if (signal_pending(current)) { 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -ERESTARTSYS; 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1060d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby } 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds schedule(); 1062a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby } 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_current_state(TASK_RUNNING); 1064a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby remove_wait_queue(&ch->open_wait, &wait); 1065a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby if (!tty_hung_up_p(filp)) 1066eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby ch->count++; 1067d353eca4e0480fddcb088c4692e1edba0a82eac9Jiri Slaby ch->blocked_open--; 1068a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby#ifdef SERIAL_DEBUG_OPEN 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("block_til_ready after blocking: ttys%d, count = %d\n", 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->line, ch->count); 1071a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby#endif 1072a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby if (retval) 10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (retval); 10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->asyncflags |= ASYNC_NORMAL_ACTIVE; 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1077eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void setup_empty_event(struct tty_struct *tty) 10799cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby{ 1080a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby struct moxa_str *ch = tty->driver_data; 10819cde5bf027556bd1e58caa14bfe8cdba64192eddJiri Slaby unsigned long flags; 1082a784bf7c195f9eca1188562c54952e4bf9791437Jiri Slaby 1083810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby save_flags(flags); 1084810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby cli(); 1085810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby ch->statusflags |= EMPTYWAIT; 10862a5413416b6b2fd8a5a38601a4fe3b56a52cfb86Jiri Slaby moxaEmptyTimer_on[ch->port] = 0; 10872a5413416b6b2fd8a5a38601a4fe3b56a52cfb86Jiri Slaby del_timer(&moxaEmptyTimer[ch->port]); 10882a5413416b6b2fd8a5a38601a4fe3b56a52cfb86Jiri Slaby moxaEmptyTimer[ch->port].expires = jiffies + HZ; 10892a5413416b6b2fd8a5a38601a4fe3b56a52cfb86Jiri Slaby moxaEmptyTimer_on[ch->port] = 1; 10902a5413416b6b2fd8a5a38601a4fe3b56a52cfb86Jiri Slaby add_timer(&moxaEmptyTimer[ch->port]); 10912a5413416b6b2fd8a5a38601a4fe3b56a52cfb86Jiri Slaby restore_flags(flags); 10922a5413416b6b2fd8a5a38601a4fe3b56a52cfb86Jiri Slaby} 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void check_xmit_empty(unsigned long data) 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch; 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1098a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby ch = (struct moxa_str *) data; 1099a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby moxaEmptyTimer_on[ch->port] = 0; 1100a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby del_timer(&moxaEmptyTimer[ch->port]); 1101a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby if (ch->tty && (ch->statusflags & EMPTYWAIT)) { 11029de6a51fee08f9e7020074738150441305e83af2Alan Cox if (MoxaPortTxQueue(ch->port) == 0) { 11039de6a51fee08f9e7020074738150441305e83af2Alan Cox ch->statusflags &= ~EMPTYWAIT; 11049de6a51fee08f9e7020074738150441305e83af2Alan Cox tty_wakeup(ch->tty); 1105a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby return; 1106a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby } 1107a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby moxaEmptyTimer[ch->port].expires = jiffies + HZ; 1108a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby moxaEmptyTimer_on[ch->port] = 1; 1109a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby add_timer(&moxaEmptyTimer[ch->port]); 1110a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby } else 1111a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby ch->statusflags &= ~EMPTYWAIT; 1112a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby} 1113a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 1114a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slabystatic void shut_down(struct moxa_str *ch) 11159de6a51fee08f9e7020074738150441305e83af2Alan Cox{ 1116a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby struct tty_struct *tp; 1117a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 1118a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby if (!(ch->asyncflags & ASYNC_INITIALIZED)) 1119a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby return; 1120a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 1121a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby tp = ch->tty; 1122a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 1123a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby MoxaPortDisable(ch->port); 1124a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 1125a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby /* 1126a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby * If we're a modem control device and HUPCL is on, drop RTS & DTR. 1127a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby */ 1128a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby if (tp->termios->c_cflag & HUPCL) 1129a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby MoxaPortLineCtrl(ch->port, 0, 0); 1130a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 1131a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby ch->asyncflags &= ~ASYNC_INITIALIZED; 1132a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby} 1133a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 1134a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slabystatic void receive_data(struct moxa_str *ch) 1135a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby{ 11369de6a51fee08f9e7020074738150441305e83af2Alan Cox struct tty_struct *tp; 1137a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby struct termios *ts; 1138a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby int i, count, rc, space; 1139a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby unsigned char *charptr, *flagptr; 1140a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby unsigned long flags; 11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ts = NULL; 1143810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby tp = ch->tty; 11448f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby if (tp) 11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ts = tp->termios; 11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /************************************************** 11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( !tp || !ts || !(ts->c_cflag & CREAD) ) { 114811324edd4ad34981764b25bed44d46a1507b62e1Jiri Slaby *****************************************************/ 11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!tp || !ts) { 115074d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby MoxaPortFlushData(ch->port, 0); 11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1152a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby } 1153a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby space = TTY_FLIPBUF_SIZE - tp->flip.count; 1154810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby if (space <= 0) 1155a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby return; 1156a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby charptr = tp->flip.char_buf_ptr; 1157810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby flagptr = tp->flip.flag_buf_ptr; 1158a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby rc = tp->flip.count; 11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds save_flags(flags); 1160810ab09b2f3a4e9a6f553e3d1e84a27f4074de9cJiri Slaby cli(); 11619de6a51fee08f9e7020074738150441305e83af2Alan Cox count = MoxaPortReadData(ch->port, charptr, space); 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds restore_flags(flags); 11639de6a51fee08f9e7020074738150441305e83af2Alan Cox for (i = 0; i < count; i++) 11649de6a51fee08f9e7020074738150441305e83af2Alan Cox *flagptr++ = 0; 11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds charptr += count; 1166db1acaa632870ec87b65e062bc72ca375837a1f6Alan Cox rc += count; 1167b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby tp->flip.count = rc; 1168b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby tp->flip.char_buf_ptr = charptr; 1169a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby tp->flip.flag_buf_ptr = flagptr; 11709de6a51fee08f9e7020074738150441305e83af2Alan Cox tty_schedule_flip(ch->tty); 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1172a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Magic_code 0x404 1174a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 1175a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby/* 1176a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby * System Configuration 1177a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby */ 1178a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby/* 11799de6a51fee08f9e7020074738150441305e83af2Alan Cox * for C218 BIOS initialization 11809de6a51fee08f9e7020074738150441305e83af2Alan Cox */ 1181a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define C218_ConfBase 0x800 1182a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define C218_status (C218_ConfBase + 0) /* BIOS running status */ 11839de6a51fee08f9e7020074738150441305e83af2Alan Cox#define C218_diag (C218_ConfBase + 2) /* diagnostic status */ 1184a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define C218_key (C218_ConfBase + 4) /* WORD (0x218 for C218) */ 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218DLoad_len (C218_ConfBase + 6) /* WORD */ 1186a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define C218check_sum (C218_ConfBase + 8) /* BYTE */ 11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218chksum_ok (C218_ConfBase + 0x0a) /* BYTE (1:ok) */ 11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218_TestRx (C218_ConfBase + 0x10) /* 8 bytes for 8 ports */ 11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218_TestTx (C218_ConfBase + 0x18) /* 8 bytes for 8 ports */ 11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218_RXerr (C218_ConfBase + 0x20) /* 8 bytes for 8 ports */ 11918f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby#define C218_ErrFlag (C218_ConfBase + 0x28) /* 8 bytes for 8 ports */ 11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218_LoadBuf 0x0F00 119411324edd4ad34981764b25bed44d46a1507b62e1Jiri Slaby#define C218_KeyCode 0x218 1195a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define CP204J_KeyCode 0x204 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1198a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby * for C320 BIOS initialization 1199a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby */ 1200a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define C320_ConfBase 0x800 1201a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define C320_LoadBuf 0x0f00 12029de6a51fee08f9e7020074738150441305e83af2Alan Cox#define STS_init 0x05 /* for C320_status */ 12037aeb95daf37dbd72f63cdd52d86a8b5d89e59394Jiri Slaby 12049de6a51fee08f9e7020074738150441305e83af2Alan Cox#define C320_status C320_ConfBase + 0 /* BIOS running status */ 12059de6a51fee08f9e7020074738150441305e83af2Alan Cox#define C320_diag C320_ConfBase + 2 /* diagnostic status */ 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320_key C320_ConfBase + 4 /* WORD (0320H for C320) */ 12079de6a51fee08f9e7020074738150441305e83af2Alan Cox#define C320DLoad_len C320_ConfBase + 6 /* WORD */ 12087aeb95daf37dbd72f63cdd52d86a8b5d89e59394Jiri Slaby#define C320check_sum C320_ConfBase + 8 /* WORD */ 12097aeb95daf37dbd72f63cdd52d86a8b5d89e59394Jiri Slaby#define C320chksum_ok C320_ConfBase + 0x0a /* WORD (1:ok) */ 12109de6a51fee08f9e7020074738150441305e83af2Alan Cox#define C320bapi_len C320_ConfBase + 0x0c /* WORD */ 12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320UART_no C320_ConfBase + 0x0e /* WORD */ 12129de6a51fee08f9e7020074738150441305e83af2Alan Cox 1213a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define C320_KeyCode 0x320 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FixPage_addr 0x0000 /* starting addr of static page */ 12169de6a51fee08f9e7020074738150441305e83af2Alan Cox#define DynPage_addr 0x2000 /* starting addr of dynamic page */ 12176f56b658b4e5c4486641ce62f331150954c4de37Jiri Slaby#define C218_start 0x3000 /* starting addr of C218 BIOS prg */ 12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Control_reg 0x1ff0 /* select page and reset control */ 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HW_reset 0x80 12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1221a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby/* 1222a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby * Function Codes 1223a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby */ 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_CardReset 0x80 12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_ChannelReset 1 /* C320 firmware not supported */ 12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_EnableCH 2 12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_DisableCH 3 12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetParam 4 1229b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define FC_SetMode 5 1230b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define FC_SetRate 6 12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_LineControl 7 12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_LineStatus 8 1233b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define FC_XmitControl 9 123433f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox#define FC_FlushQueue 10 12357bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define FC_SendBreak 11 12362108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby#define FC_StopBreak 12 12377bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define FC_LoopbackON 13 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_LoopbackOFF 14 12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_ClrIrqTable 15 1240eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby#define FC_SendXon 16 12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetTermIrq 17 /* C320 firmware not supported */ 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetCntIrq 18 /* C320 firmware not supported */ 12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetBreakIrq 19 12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetLineIrq 20 12458f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby#define FC_SetFlowCtl 21 12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_GenIrq 22 12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_InCD180 23 1248eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby#define FC_OutCD180 24 1249b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define FC_InUARTreg 23 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_OutUARTreg 24 1251eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby#define FC_SetXonXoff 25 1252b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define FC_OutCD180CCR 26 12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_ExtIQueue 27 12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_ExtOQueue 28 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_ClrLineIrq 29 12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_HWFlowCtl 30 1257b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define FC_GetClockRate 35 12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetBaud 36 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetDataMode 41 12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_GetCCSR 43 1261b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define FC_GetDataError 45 12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_RxControl 50 12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_ImmSend 51 12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetXonState 52 12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetXoffState 53 12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetRxFIFOTrig 54 1267b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define FC_SetTxFIFOCnt 55 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_UnixRate 56 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_UnixResetTimer 57 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RxFIFOTrig1 0 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RxFIFOTrig4 1 12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RxFIFOTrig8 2 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RxFIFOTrig14 3 12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1277eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby * Dual-Ported RAM 1278978e595f88a1fba5869aa42a4af4fba36f33ecacAlan Cox */ 1279b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define DRAM_global 0 12801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define INT_data (DRAM_global + 0) 12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Config_base (DRAM_global + 0x108) 12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IRQindex (INT_data + 0) 12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IRQpending (INT_data + 4) 12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IRQtable (INT_data + 8) 12866f56b658b4e5c4486641ce62f331150954c4de37Jiri Slaby 12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1288978e595f88a1fba5869aa42a4af4fba36f33ecacAlan Cox * Interrupt Status 1289eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby */ 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IntrRx 0x01 /* receiver data O.K. */ 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IntrTx 0x02 /* transmit buffer empty */ 12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IntrFunc 0x04 /* function complete */ 12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IntrBreak 0x08 /* received break */ 1294a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define IntrLine 0x10 /* line status change 12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for transmitter */ 12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IntrIntr 0x20 /* received INTR code */ 1297a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define IntrQuit 0x40 /* received QUIT code */ 1298a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define IntrEOF 0x80 /* received EOF code */ 1299a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 1300a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define IntrRxTrigger 0x100 /* rx data count reach tigger value */ 130174d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby#define IntrTxTrigger 0x200 /* tx data count below trigger value */ 1302a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Magic_no (Config_base + 0) 1304b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define Card_model_no (Config_base + 2) 13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Total_ports (Config_base + 4) 13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Module_cnt (Config_base + 8) 13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Module_no (Config_base + 10) 13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Timer_10ms (Config_base + 14) 1309b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define Disable_IRQ (Config_base + 20) 13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TMS320_PORT1 (Config_base + 22) 13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TMS320_PORT2 (Config_base + 24) 13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TMS320_CLOCK (Config_base + 26) 13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DATA BUFFER in DRAM 1316a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby */ 13171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Extern_table 0x400 /* Base address of the external table 13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (24 words * 64) total 3K bytes 13191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (24 words * 128) total 6K bytes */ 13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Extern_size 0x60 /* 96 bytes */ 13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RXrptr 0x00 /* read pointer for RX buffer */ 13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RXwptr 0x02 /* write pointer for RX buffer */ 1323a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define TXrptr 0x04 /* read pointer for TX buffer */ 13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TXwptr 0x06 /* write pointer for TX buffer */ 13251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HostStat 0x08 /* IRQ flag and general flag */ 13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FlagStat 0x0A 132711324edd4ad34981764b25bed44d46a1507b62e1Jiri Slaby#define FlowControl 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */ 1328a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby /* x x x x | | | | */ 1329a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby /* | | | + CTS flow */ 1330a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby /* | | +--- RTS flow */ 1331a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby /* | +------ TX Xon/Xoff */ 133274d7d97b9e2a090a4b1812b5074ac6c539234ebbJiri Slaby /* +--------- RX Xon/Xoff */ 1333a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define Break_cnt 0x0E /* received break count */ 13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CD180TXirq 0x10 /* if non-0: enable TX irq */ 1335b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define RX_mask 0x12 13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TX_mask 0x14 13371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Ofs_rxb 0x16 13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Ofs_txb 0x18 13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Page_rxb 0x1A 13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Page_txb 0x1C 13411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define EndPage_rxb 0x1E 13421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define EndPage_txb 0x20 13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Data_error 0x22 1344b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define RxTrigger 0x28 1345a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define TxTrigger 0x2a 13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define rRXwptr 0x34 13481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Low_water 0x36 13491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FuncCode 0x40 1351eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby#define FuncArg 0x42 13521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FuncArg1 0x44 13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218rx_size 0x2000 /* 8K bytes */ 13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218tx_size 0x8000 /* 32K bytes */ 13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218rx_mask (C218rx_size - 1) 1358eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby#define C218tx_mask (C218tx_size - 1) 13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8rx_size 0x2000 13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8tx_size 0x8000 13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8rx_mask (C320p8rx_size - 1) 13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8tx_mask (C320p8tx_size - 1) 1364eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby 13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16rx_size 0x2000 1366eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby#define C320p16tx_size 0x4000 13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16rx_mask (C320p16rx_size - 1) 13681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16tx_mask (C320p16tx_size - 1) 13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1370db1acaa632870ec87b65e062bc72ca375837a1f6Alan Cox#define C320p24rx_size 0x2000 1371eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby#define C320p24tx_size 0x2000 13729de6a51fee08f9e7020074738150441305e83af2Alan Cox#define C320p24rx_mask (C320p24rx_size - 1) 13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p24tx_mask (C320p24tx_size - 1) 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p32rx_size 0x1000 13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p32tx_size 0x1000 1377eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby#define C320p32rx_mask (C320p32rx_size - 1) 13781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p32tx_mask (C320p32tx_size - 1) 13791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Page_size 0x2000 1381b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define Page_mask (Page_size - 1) 13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218rx_spage 3 13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218tx_spage 4 13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218rx_pageno 1 13851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218tx_pageno 4 13861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218buf_pageno 5 13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1388eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby#define C320p8rx_spage 3 13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8tx_spage 4 13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8rx_pgno 1 13911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8tx_pgno 4 13921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8buf_pgno 5 13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16rx_spage 3 13951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16tx_spage 4 1396b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define C320p16rx_pgno 1 13971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16tx_pgno 2 13981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16buf_pgno 3 13991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p24rx_spage 3 14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p24tx_spage 4 1402a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define C320p24rx_pgno 1 14031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p24tx_pgno 1 1404a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define C320p24buf_pgno 2 1405a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 1406a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define C320p32rx_spage 3 1407a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define C320p32tx_ofs C320p32rx_size 1408a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define C320p32tx_spage 3 1409a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define C320p32buf_pgno 1 14109de6a51fee08f9e7020074738150441305e83af2Alan Cox 1411a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby/* 1412a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby * Host Status 1413a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby */ 14149de6a51fee08f9e7020074738150441305e83af2Alan Cox#define WakeupRx 0x01 14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WakeupTx 0x02 14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WakeupBreak 0x08 14177bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define WakeupLine 0x10 14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WakeupIntr 0x20 14197bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define WakeupQuit 0x40 14201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WakeupEOF 0x80 /* used in VTIME control */ 14219de6a51fee08f9e7020074738150441305e83af2Alan Cox#define WakeupRxTrigger 0x100 1422a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby#define WakeupTxTrigger 0x200 14239de6a51fee08f9e7020074738150441305e83af2Alan Cox/* 14247bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby * Flag status 14257bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby */ 14267bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define Rx_over 0x01 14271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Xoff_state 0x02 14287bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define Tx_flowOff 0x04 14297bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define Tx_enable 0x08 14307bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define CTS_state 0x10 14319de6a51fee08f9e7020074738150441305e83af2Alan Cox#define DSR_state 0x20 14327bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define DCD_state 0x80 14339de6a51fee08f9e7020074738150441305e83af2Alan Cox/* 14347bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby * FlowControl 14357bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby */ 14367bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define CTS_FlowCtl 1 14377bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define RTS_FlowCtl 2 14387bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define Tx_FlowCtl 4 14397bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define Rx_FlowCtl 8 14407bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define IXM_IXANY 0x10 14417bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 14427bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define LowWater 128 14437bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 14447bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define DTR_ON 1 14457bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define RTS_ON 2 14467bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define CTS_ON 1 14477bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define DSR_ON 2 14487bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define DCD_ON 8 14497bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 14507bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby/* mode definition */ 14517bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define MX_CS8 0x03 14527bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define MX_CS7 0x02 14537bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define MX_CS6 0x01 14547bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define MX_CS5 0x00 14557bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 14561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MX_STOP1 0x00 14570bcc4caadc8f5396b52950ee03c67b76875602dfJiri Slaby#define MX_STOP15 0x04 14587bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define MX_STOP2 0x08 14597bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 14607bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define MX_PARNONE 0x00 14617bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define MX_PAREVEN 0x40 14627bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define MX_PARODD 0xC0 14637bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 14647bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby/* 14657bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby * Query 14667bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby */ 14677bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define QueryPort MAX_PORTS 14687bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 14697bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 14707bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 14717bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystruct mon_str { 14727bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby int tick; 14737bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby int rxcnt[MAX_PORTS]; 14747bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby int txcnt[MAX_PORTS]; 14757bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby}; 14767bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabytypedef struct mon_str mon_st; 14777bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 14787bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define DCD_changed 0x01 14797bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby#define DCD_oldstate 0x80 14807bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 14817bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic unsigned char moxaBuff[10240]; 14827bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic void __iomem *moxaIntNdx[MAX_BOARDS]; 14837bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic void __iomem *moxaIntPend[MAX_BOARDS]; 14847bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic void __iomem *moxaIntTable[MAX_BOARDS]; 14857bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic char moxaChkPort[MAX_PORTS]; 14867bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic char moxaLineCtrl[MAX_PORTS]; 14877bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic void __iomem *moxaTableAddr[MAX_PORTS]; 14887bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic long moxaCurBaud[MAX_PORTS]; 14892a5413416b6b2fd8a5a38601a4fe3b56a52cfb86Jiri Slabystatic char moxaDCDState[MAX_PORTS]; 14907bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic char moxaLowChkFlag[MAX_PORTS]; 14917bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic int moxaLowWaterChk; 14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaCard; 14937bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic mon_st moxaLog; 14947bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic int moxaFuncTout; 14951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ushort moxaBreakCnt[MAX_PORTS]; 14967bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 14972a5413416b6b2fd8a5a38601a4fe3b56a52cfb86Jiri Slabystatic void moxadelay(int); 14982a5413416b6b2fd8a5a38601a4fe3b56a52cfb86Jiri Slabystatic void moxafunc(void __iomem *, int, ushort); 14997bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic void wait_finish(void __iomem *); 15007bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic void low_water_check(void __iomem *); 15017bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic int moxaloadbios(int, unsigned char __user *, int); 15027bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic int moxafindcard(int); 15037bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic int moxaload320b(int, unsigned char __user *, int); 15047bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic int moxaloadcode(int, unsigned char __user *, int); 15057bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic int moxaloadc218(int, void __iomem *, int); 15067bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic int moxaloadc320(int, void __iomem *, int, int *); 15077bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby 15087bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby/***************************************************************************** 15097bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby * Driver level functions: * 15107bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby * 1. MoxaDriverInit(void); * 15117bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby * 2. MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port); * 15127bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby * 3. MoxaDriverPoll(void); * 15137bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby *****************************************************************************/ 15147bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabyvoid MoxaDriverInit(void) 15151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 15171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15187bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby moxaFuncTout = HZ / 2; /* 500 mini-seconds */ 15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaCard = 0; 15202a5413416b6b2fd8a5a38601a4fe3b56a52cfb86Jiri Slaby moxaLog.tick = 0; 15212a5413416b6b2fd8a5a38601a4fe3b56a52cfb86Jiri Slaby moxaLowWaterChk = 0; 15222a5413416b6b2fd8a5a38601a4fe3b56a52cfb86Jiri Slaby for (i = 0; i < MAX_PORTS; i++) { 15231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaChkPort[i] = 0; 15241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLowChkFlag[i] = 0; 15251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLineCtrl[i] = 0; 15261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLog.rxcnt[i] = 0; 1527db1acaa632870ec87b65e062bc72ca375837a1f6Alan Cox moxaLog.txcnt[i] = 0; 15281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1529eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby} 1530eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby 1531db1acaa632870ec87b65e062bc72ca375837a1f6Alan Cox#define MOXA 0x400 15321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_GET_IQUEUE (MOXA + 1) /* get input buffered count */ 15331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_GET_OQUEUE (MOXA + 2) /* get output buffered count */ 15341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_INIT_DRIVER (MOXA + 6) /* moxaCard=0 */ 15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_LOAD_BIOS (MOXA + 9) /* download BIOS */ 15361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_FIND_BOARD (MOXA + 10) /* Check if MOXA card exist? */ 15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_LOAD_C320B (MOXA + 11) /* download 320B firmware */ 15381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_LOAD_CODE (MOXA + 12) /* download firmware */ 15391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_GETDATACOUNT (MOXA + 23) 15401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_GET_IOQUEUE (MOXA + 27) 15411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_FLUSH_QUEUE (MOXA + 28) 1542db1acaa632870ec87b65e062bc72ca375837a1f6Alan Cox#define MOXA_GET_CONF (MOXA + 35) /* configuration */ 1543db1acaa632870ec87b65e062bc72ca375837a1f6Alan Cox#define MOXA_GET_MAJOR (MOXA + 63) 1544db1acaa632870ec87b65e062bc72ca375837a1f6Alan Cox#define MOXA_GET_CUMAJOR (MOXA + 64) 1545b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby#define MOXA_GETMSTATUS (MOXA + 65) 1546b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby 1547db1acaa632870ec87b65e062bc72ca375837a1f6Alan Cox 1548db1acaa632870ec87b65e062bc72ca375837a1f6Alan Coxstruct moxaq_str { 1549db1acaa632870ec87b65e062bc72ca375837a1f6Alan Cox int inq; 1550db1acaa632870ec87b65e062bc72ca375837a1f6Alan Cox int outq; 15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 15521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15536f56b658b4e5c4486641ce62f331150954c4de37Jiri Slabystruct dl_str { 15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char __user *buf; 15558f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby int len; 15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cardno; 15577bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby}; 15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15597bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slabystatic struct moxaq_str temp_queue[MAX_PORTS]; 15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct dl_str dltmp; 15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15626f56b658b4e5c4486641ce62f331150954c4de37Jiri Slabyvoid MoxaPortFlushData(int port, int mode) 15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15649de6a51fee08f9e7020074738150441305e83af2Alan Cox void __iomem *ofsAddr; 15651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((mode < 0) || (mode > 2)) 15669de6a51fee08f9e7020074738150441305e83af2Alan Cox return; 15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_FlushQueue, mode); 1569b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby if (mode != 1) { 15701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLowChkFlag[port] = 0; 15711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds low_water_check(ofsAddr); 15721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1574a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby 1575b4173f45758a5b5185acb302c507289e661d9419Jiri Slabyint MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port) 15761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1577a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby int i; 15789de6a51fee08f9e7020074738150441305e83af2Alan Cox int status; 1579a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby int MoxaPortTxQueue(int), MoxaPortRxQueue(int); 15801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __user *argp = (void __user *)arg; 15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (port == QueryPort) { 15831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((cmd != MOXA_GET_CONF) && (cmd != MOXA_INIT_DRIVER) && 15841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (cmd != MOXA_LOAD_BIOS) && (cmd != MOXA_FIND_BOARD) && (cmd != MOXA_LOAD_C320B) && 15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (cmd != MOXA_LOAD_CODE) && (cmd != MOXA_GETDATACOUNT) && 1586b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby (cmd != MOXA_GET_IOQUEUE) && (cmd != MOXA_GET_MAJOR) && 15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (cmd != MOXA_GET_CUMAJOR) && (cmd != MOXA_GETMSTATUS)) 15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-EINVAL); 1589eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby } 15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 1591b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby case MOXA_GET_CONF: 15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_to_user(argp, &moxa_boards, MAX_BOARDS * sizeof(moxa_board_conf))) 15931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 1594b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby return (0); 15956f56b658b4e5c4486641ce62f331150954c4de37Jiri Slaby case MOXA_INIT_DRIVER: 15961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((int) arg == 0x404) 15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaDriverInit(); 15981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_GETDATACOUNT: 16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLog.tick = jiffies; 16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_to_user(argp, &moxaLog, sizeof(mon_st))) 16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 16031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 16041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_FLUSH_QUEUE: 16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortFlushData(port, arg); 16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 16071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_GET_IOQUEUE: 16081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_PORTS; i++) { 16091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaChkPort[i]) { 16101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds temp_queue[i].inq = MoxaPortRxQueue(i); 16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds temp_queue[i].outq = MoxaPortTxQueue(i); 16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_to_user(argp, temp_queue, sizeof(struct moxaq_str) * MAX_PORTS)) 16151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 16161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_GET_OQUEUE: 16181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = MoxaPortTxQueue(port); 16191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return put_user(i, (unsigned long __user *)argp); 16201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_GET_IQUEUE: 16211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = MoxaPortRxQueue(port); 16221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return put_user(i, (unsigned long __user *)argp); 16231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_GET_MAJOR: 16241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_to_user(argp, &ttymajor, sizeof(int))) 16251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 16261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 16271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_GET_CUMAJOR: 16281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = 0; 16291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_to_user(argp, &i, sizeof(int))) 16301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 16311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 16321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_GETMSTATUS: 16331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_PORTS; i++) { 16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].ri = 0; 16351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].dcd = 0; 16361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].dsr = 0; 16371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].cts = 0; 16381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!moxaChkPort[i]) { 16391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 16401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 16411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = MoxaPortLineStatus(moxaChannels[i].port); 16421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status & 1) 16431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].cts = 1; 16441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status & 2) 16451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].dsr = 1; 16461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status & 4) 16471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].dcd = 1; 16481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 164908d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby 16501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!moxaChannels[i].tty || !moxaChannels[i].tty->termios) 16511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].cflag = moxaChannels[i].cflag; 16521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 16531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].cflag = moxaChannels[i].tty->termios->c_cflag; 16541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_to_user(argp, GMStatus, sizeof(struct mxser_mstatus) * MAX_PORTS)) 16561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 16571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 16581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 16591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-ENOIOCTLCMD); 16601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_LOAD_BIOS: 16611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_FIND_BOARD: 1662606d099cdd1080bbb50ea50dc52d98252f8f10a1Alan Cox case MOXA_LOAD_C320B: 16631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_LOAD_CODE: 1664606d099cdd1080bbb50ea50dc52d98252f8f10a1Alan Cox break; 1665c7bce3097c0f9bbed76ee6fd03742f2624031a45Alan Cox } 16661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_from_user(&dltmp, argp, sizeof(struct dl_str))) 16681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 16691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS) 16701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 16711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(cmd) 16731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 16741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_LOAD_BIOS: 16751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = moxaloadbios(dltmp.cardno, dltmp.buf, dltmp.len); 16761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (i); 16771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_FIND_BOARD: 16781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return moxafindcard(dltmp.cardno); 16791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_LOAD_C320B: 16801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaload320b(dltmp.cardno, dltmp.buf, dltmp.len); 16811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: /* to keep gcc happy */ 16821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 16831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_LOAD_CODE: 16841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = moxaloadcode(dltmp.cardno, dltmp.buf, dltmp.len); 16851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i == -1) 16861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-EFAULT); 16871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (i); 16881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaDriverPoll(void) 16931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register ushort temp; 16951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register int card; 16961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 16971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ip; 16981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int port, p, ports; 16991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaCard == 0) 17011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 17021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (card = 0; card < MAX_BOARDS; card++) { 17031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ports = moxa_boards[card].numPorts) == 0) 17041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 17051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readb(moxaIntPend[card]) == 0xff) { 17061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ip = moxaIntTable[card] + readb(moxaIntNdx[card]); 17071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = card * MAX_PORTS_PER_BOARD; 17081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ports <<= 1; 17091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (port = 0; port < ports; port += 2, p++) { 17101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((temp = readw(ip + port)) != 0) { 17111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0, ip + port); 17121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[p]; 17131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (temp & IntrTx) 17141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(readw(ofsAddr + HostStat) & ~WakeupTx, ofsAddr + HostStat); 17151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (temp & IntrBreak) { 17161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaBreakCnt[p]++; 17171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (temp & IntrLine) { 17191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readb(ofsAddr + FlagStat) & DCD_state) { 17201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((moxaDCDState[p] & DCD_oldstate) == 0) 17211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDCDState[p] = (DCD_oldstate | 17221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DCD_changed); 17231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 17241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaDCDState[p] & DCD_oldstate) 17251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDCDState[p] = DCD_changed; 17261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(0, moxaIntPend[card]); 17311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaLowWaterChk) { 17331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = card * MAX_PORTS_PER_BOARD; 17341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (port = 0; port < ports; port++, p++) { 17351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaLowChkFlag[p]) { 17361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLowChkFlag[p] = 0; 17371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[p]; 173833f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox low_water_check(ofsAddr); 17391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 174033f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox } 17411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLowWaterChk = 0; 17441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 17451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************************************************************** 17481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Card level function: * 17491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. MoxaPortsOfCard(int cardno); * 17501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/ 17511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortsOfCard(int cardno) 17521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxa_boards[cardno].boardType == 0) 17551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 17561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (moxa_boards[cardno].numPorts); 17571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************************************************************** 17601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Port level functions: * 17611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. MoxaPortIsValid(int port); * 17621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. MoxaPortEnable(int port); * 17631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. MoxaPortDisable(int port); * 17641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4. MoxaPortGetMaxBaud(int port); * 17651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5. MoxaPortGetCurBaud(int port); * 17661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6. MoxaPortSetBaud(int port, long baud); * 17671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7. MoxaPortSetMode(int port, int databit, int stopbit, int parity); * 17681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8. MoxaPortSetTermio(int port, unsigned char *termio); * 17691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9. MoxaPortGetLineOut(int port, int *dtrState, int *rtsState); * 17701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 10. MoxaPortLineCtrl(int port, int dtrState, int rtsState); * 17711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 11. MoxaPortFlowCtrl(int port, int rts, int cts, int rx, int tx,int xany); * 17721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 12. MoxaPortLineStatus(int port); * 17731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 13. MoxaPortDCDChange(int port); * 17741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 14. MoxaPortDCDON(int port); * 17751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 15. MoxaPortFlushData(int port, int mode); * 17761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); * 17771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 17. MoxaPortReadData(int port, unsigned char * buffer, int length); * 17781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18. MoxaPortTxBufSize(int port); * 17791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19. MoxaPortRxBufSize(int port); * 17801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20. MoxaPortTxQueue(int port); * 17811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 21. MoxaPortTxFree(int port); * 17821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 22. MoxaPortRxQueue(int port); * 17831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 23. MoxaPortRxFree(int port); * 17841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 24. MoxaPortTxDisable(int port); * 17851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 25. MoxaPortTxEnable(int port); * 17861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 26. MoxaPortGetBrkCnt(int port); * 17871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 27. MoxaPortResetBrkCnt(int port); * 17881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 28. MoxaPortSetXonXoff(int port, int xonValue, int xoffValue); * 17891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 29. MoxaPortIsTxHold(int port); * 17901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 30. MoxaPortSendBreak(int port, int ticks); * 1791b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby *****************************************************************************/ 17921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 17931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Moxa Port Number Description: 1794eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby * 17951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MOXA serial driver supports up to 4 MOXA-C218/C320 boards. And, 1796b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * the port number using in MOXA driver functions will be 0 to 31 for 17971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * first MOXA board, 32 to 63 for second, 64 to 95 for third and 96 179808d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby * to 127 for fourth. For example, if you setup three MOXA boards, 17991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * first board is C218, second board is C320-16 and third board is 1800eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby * C320-32. The port number of first board (C218 - 8 ports) is from 1801eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby * 0 to 7. The port number of second board (C320 - 16 ports) is form 1802eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby * 32 to 47. The port number of third board (C320 - 32 ports) is from 18031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 64 to 95. And those port numbers form 8 to 31, 48 to 63 and 96 to 18041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 127 will be invalid. 18051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Moxa Functions Description: 18081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 1: Driver initialization routine, this routine must be 18101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * called when initialized driver. 1811b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * Syntax: 18121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaDriverInit(); 1813b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * 18141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 2: Moxa driver private IOCTL command processing. 18161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port); 18181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * unsigned int cmd : IOCTL command 18201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * unsigned long arg : IOCTL argument 182108d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby * int port : port number (0 - 127) 18221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 182308d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby * return: 0 (OK) 182408d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby * -EINVAL 182508d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby * -ENOIOCTLCMD 18261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 182708d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby * 182808d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby * Function 3: Moxa driver polling process routine. 1829eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby * Syntax: 18301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaDriverPoll(void); 18311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 183208d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby * return: 0 ; polling O.K. 18331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * -1 : no any Moxa card. 18341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1836eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby * Function 4: Get the ports of this card. 18371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortsOfCard(int cardno); 1839b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * 1840b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * int cardno : card number (0 - 3) 18411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : this card is invalid 18431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8/16/24/32 18441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1846b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * Function 5: Check this port is valid or invalid 18471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortIsValid(int port); 18491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127, ref port description) 18501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : this port is invalid 18521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1 : this port is valid 18531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 6: Enable this port to start Tx/Rx data. 18561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaPortEnable(int port); 18581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 18591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 7: Disable this port 18621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaPortDisable(int port); 18641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 18651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 8: Get the maximun available baud rate of this port. 18681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * long MoxaPortGetMaxBaud(int port); 18701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 18711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : this port is invalid 18731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 38400/57600/115200 bps 18741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1875eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby * 18761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 9: Get the current baud rate of this port. 187708d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby * Syntax: 187808d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby * long MoxaPortGetCurBaud(int port); 187908d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby * int port : port number (0 - 127) 1880db1acaa632870ec87b65e062bc72ca375837a1f6Alan Cox * 18811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : this port is invalid 18821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 50 - 115200 bps 18831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 10: Setting baud rate of this port. 18866f56b658b4e5c4486641ce62f331150954c4de37Jiri Slaby * Syntax: 18871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * long MoxaPortSetBaud(int port, long baud); 18881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 1889eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby * long baud : baud rate (50 - 115200) 18901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : this port is invalid or baud < 50 1892b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * 50 - 115200 : the real baud rate set to the port, if 1893b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * the argument baud is large than maximun 18941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * available baud rate, the real setting 1895b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * baud rate will be the maximun baud rate. 1896b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * 1897b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * 1898b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * Function 11: Setting the data-bits/stop-bits/parity of this port 1899b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * Syntax: 1900eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby * int MoxaPortSetMode(int port, int databits, int stopbits, int parity); 19011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int databits : data bits (8/7/6/5) 1903b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * int stopbits : stop bits (2/1/0, 0 show 1.5 stop bits) 19041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int parity : parity (0:None,1:Odd,2:Even,3:Mark,4:Space) 1905eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby * 19061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: -1 : invalid parameter 19071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 : setting O.K. 19081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 12: Configure the port. 1911b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * Syntax: 1912b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * int MoxaPortSetTermio(int port, struct termios *termio); 19131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * struct termios * termio : termio structure pointer 1915b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * 1916b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * return: -1 : this port is invalid or termio == NULL 19171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 : setting O.K. 1918b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * 19191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 13: Get the DTR/RTS state of this port. 19211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 19221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortGetLineOut(int port, int *dtrState, int *rtsState); 19231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int * dtrState : pointer to INT to receive the current DTR 19251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * state. (if NULL, this function will not 19261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * write to this address) 19271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int * rtsState : pointer to INT to receive the current RTS 19281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * state. (if NULL, this function will not 19291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * write to this address) 1930b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * 19311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: -1 : this port is invalid 19321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 : O.K. 1933b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * 19341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 14: Setting the DTR/RTS output state of this port. 19361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 19371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaPortLineCtrl(int port, int dtrState, int rtsState); 1938b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * int port : port number (0 - 127) 193908d01c792568ba07d2bcf5202dbc8484dbff6747Jiri Slaby * int dtrState : DTR output state (0: off, 1: on) 19401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int rtsState : RTS output state (0: off, 1: on) 19411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 15: Setting the flow control of this port. 19441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 19451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaPortFlowCtrl(int port, int rtsFlow, int ctsFlow, int rxFlow, 19467bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby * int txFlow,int xany); 19471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 1948a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby * int rtsFlow : H/W RTS flow control (0: no, 1: yes) 19497bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby * int ctsFlow : H/W CTS flow control (0: no, 1: yes) 1950a8f5cda067e2eeefe49fe386caf0f61fc5c825e0Jiri Slaby * int rxFlow : S/W Rx XON/XOFF flow control (0: no, 1: yes) 19511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int txFlow : S/W Tx XON/XOFF flow control (0: no, 1: yes) 19527bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby * int xany : S/W XANY flow control (0: no, 1: yes) 19531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19552108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * Function 16: Get ths line status of this port 19562108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * Syntax: 19571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortLineStatus(int port); 19581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19592108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * 19602108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * return: Bit 0 - CTS state (0: off, 1: on) 19612108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * Bit 1 - DSR state (0: off, 1: on) 19621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 2 - DCD state (0: off, 1: on) 1963b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * 1964b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * 19651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 17: Check the DCD state has changed since the last read 19661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of this function. 19671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 19681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortDCDChange(int port); 19691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19702108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * 19711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : no changed 19721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1 : DCD has changed 19739de6a51fee08f9e7020074738150441305e83af2Alan Cox * 19741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 18: Check ths current DCD state is ON or not. 19761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 19771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortDCDON(int port); 19781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : DCD off 19811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1 : DCD on 19821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 19: Flush the Rx/Tx buffer data of this port. 19852108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * Syntax: 19862108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * void MoxaPortFlushData(int port, int mode); 19871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int mode 19891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 : flush the Rx buffer 19901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1 : flush the Tx buffer 19911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2 : flush the Rx and Tx buffer 19921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19932108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * 19942108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * Function 20: Write data. 19952108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * Syntax: 19962108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * int MoxaPortWriteData(int port, unsigned char * buffer, int length); 19971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * unsigned char * buffer : pointer to write data buffer. 19992108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * int length : write data length 20002108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * 20011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 - length : real write data length 20021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20042108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * Function 21: Read data. 20052108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * Syntax: 20062108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * int MoxaPortReadData(int port, unsigned char * buffer, int length); 20071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20082108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * unsigned char * buffer : pointer to read data buffer. 20091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int length : read data buffer length 20102108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * 20111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 - length : real read data length 20121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20137bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby * 20141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 22: Get the Tx buffer size of this port 20159de6a51fee08f9e7020074738150441305e83af2Alan Cox * Syntax: 20162108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * int MoxaPortTxBufSize(int port); 20171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20182108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * 20192108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * return: .. : Tx buffer size 20202108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * 20211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2022b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * Function 23: Get the Rx buffer size of this port 2023b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * Syntax: 20241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortRxBufSize(int port); 20251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: .. : Rx buffer size 20281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20292108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * 20301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 24: Get the Tx buffer current queued data bytes 203133f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox * Syntax: 20321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortTxQueue(int port); 203333f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox * int port : port number (0 - 127) 20347bcf97d1dd88135b58c7adb7c3bfebab55b21a20Jiri Slaby * 20351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: .. : Tx buffer current queued data bytes 20361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 25: Get the Tx buffer current free space 20391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20402108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * int MoxaPortTxFree(int port); 20412108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * int port : port number (0 - 127) 20422108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * 20432108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * return: .. : Tx buffer current free space 20442108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * 20451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 26: Get the Rx buffer current queued data bytes 20471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortRxQueue(int port); 20491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20512108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * return: .. : Rx buffer current queued data bytes 20521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20542108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * Function 27: Get the Rx buffer current free space 20552108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * Syntax: 20562108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * int MoxaPortRxFree(int port); 20572108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * int port : port number (0 - 127) 20582108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * 20592108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * return: .. : Rx buffer current free space 20602108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * 20611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20622108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * Function 28: Disable port data transmission. 20632108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * Syntax: 20641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaPortTxDisable(int port); 20652108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * int port : port number (0 - 127) 20662108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * 20671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2068b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * Function 29: Enable port data transmission. 20691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20702108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * void MoxaPortTxEnable(int port); 20711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2074b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * Function 30: Get the received BREAK signal count. 20751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 2076b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * int MoxaPortGetBrkCnt(int port); 20772108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * int port : port number (0 - 127) 20781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 - .. : BREAK signal count 20801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20822108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * Function 31: Get the received BREAK signal count and reset it. 20831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortResetBrkCnt(int port); 2085b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * int port : port number (0 - 127) 20861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2087b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * return: 0 - .. : BREAK signal count 20882108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * 20891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 32: Set the S/W flow control new XON/XOFF value, default 20911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * XON is 0x11 & XOFF is 0x13. 20921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20932108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * void MoxaPortSetXonXoff(int port, int xonValue, int xoffValue); 20941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int xonValue : new XON value (0 - 255) 2096b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * int xoffValue : new XOFF value (0 - 255) 20971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2098b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * 20992108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * Function 33: Check this port's transmission is hold by remote site 21001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * because the flow control. 21011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 21021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortIsTxHold(int port); 21031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 21042108eba5c531c12f5ae2ed2ef4cee7bf4246897bJiri Slaby * 21051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : normal 21061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1 : hold by remote site 2107b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * 21081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2109b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * Function 34: Send out a BREAK signal. 21101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 21111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaPortSendBreak(int port, int ms100); 2112b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * int port : port number (0 - 127) 21131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int ms100 : break signal time interval. 2114b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby * unit: 100 mini-second. if ms100 == 0, it will 21151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * send out a about 250 ms BREAK signal. 21161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 21178f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby */ 2118eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slabyint MoxaPortIsValid(int port) 21191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2120eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby 2121eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby if (moxaCard == 0) 21229de6a51fee08f9e7020074738150441305e83af2Alan Cox return (0); 21239de6a51fee08f9e7020074738150441305e83af2Alan Cox if (moxaChkPort[port] == 0) 2124eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby return (0); 212544b7d1b37f786c61d0e382b6f72f605f73de284bAlan Cox return (1); 2126eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby} 2127eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby 21281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid MoxaPortEnable(int port) 21291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 21301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 21318f8ecbad09b48e5fe44a8d7f5344e802e9c231c8Jiri Slaby int MoxaPortLineStatus(int); 2132eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby short lowwater = 512; 21331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 21351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(lowwater, ofsAddr + Low_water); 2136eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby moxaBreakCnt[port] = 0; 21371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || 21381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) { 2139eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby moxafunc(ofsAddr, FC_SetBreakIrq, 0); 2140eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby } else { 2141eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby writew(readw(ofsAddr + HostStat) | WakeupBreak, ofsAddr + HostStat); 2142eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby } 21431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SetLineIrq, Magic_code); 21451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_FlushQueue, 2); 21469de6a51fee08f9e7020074738150441305e83af2Alan Cox 2147eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby moxafunc(ofsAddr, FC_EnableCH, Magic_code); 2148eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby MoxaPortLineStatus(port); 214944b7d1b37f786c61d0e382b6f72f605f73de284bAlan Cox} 21501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid MoxaPortDisable(int port) 21529de6a51fee08f9e7020074738150441305e83af2Alan Cox{ 21531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr = moxaTableAddr[port]; 2154eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby 21551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SetFlowCtl, 0); /* disable flow control */ 21561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_ClrLineIrq, Magic_code); 2157eaa95a8da6366c34d3a61e93109e5f8f8a4e72a0Jiri Slaby writew(0, ofsAddr + HostStat); 21581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_DisableCH, Magic_code); 21591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 21601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldslong MoxaPortGetMaxBaud(int port) 21621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 21631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || 21641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) 21651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (460800L); 2166b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby else 21671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (921600L); 2168b4173f45758a5b5185acb302c507289e661d9419Jiri Slaby} 21691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldslong MoxaPortSetBaud(int port, long baud) 21721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 21731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 21741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long max, clock; 21751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int val; 21761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((baud < 50L) || ((max = MoxaPortGetMaxBaud(port)) == 0)) 2178 return (0); 2179 ofsAddr = moxaTableAddr[port]; 2180 if (baud > max) 2181 baud = max; 2182 if (max == 38400L) 2183 clock = 614400L; /* for 9.8304 Mhz : max. 38400 bps */ 2184 else if (max == 57600L) 2185 clock = 691200L; /* for 11.0592 Mhz : max. 57600 bps */ 2186 else 2187 clock = 921600L; /* for 14.7456 Mhz : max. 115200 bps */ 2188 val = clock / baud; 2189 moxafunc(ofsAddr, FC_SetBaud, val); 2190 baud = clock / val; 2191 moxaCurBaud[port] = baud; 2192 return (baud); 2193} 2194 2195int MoxaPortSetTermio(int port, struct termios *termio) 2196{ 2197 void __iomem *ofsAddr; 2198 tcflag_t cflag; 2199 long baud; 2200 tcflag_t mode = 0; 2201 2202 if (moxaChkPort[port] == 0 || termio == 0) 2203 return (-1); 2204 ofsAddr = moxaTableAddr[port]; 2205 cflag = termio->c_cflag; /* termio->c_cflag */ 2206 2207 mode = termio->c_cflag & CSIZE; 2208 if (mode == CS5) 2209 mode = MX_CS5; 2210 else if (mode == CS6) 2211 mode = MX_CS6; 2212 else if (mode == CS7) 2213 mode = MX_CS7; 2214 else if (mode == CS8) 2215 mode = MX_CS8; 2216 2217 if (termio->c_cflag & CSTOPB) { 2218 if (mode == MX_CS5) 2219 mode |= MX_STOP15; 2220 else 2221 mode |= MX_STOP2; 2222 } else 2223 mode |= MX_STOP1; 2224 2225 if (termio->c_cflag & PARENB) { 2226 if (termio->c_cflag & PARODD) 2227 mode |= MX_PARODD; 2228 else 2229 mode |= MX_PAREVEN; 2230 } else 2231 mode |= MX_PARNONE; 2232 2233 moxafunc(ofsAddr, FC_SetDataMode, (ushort) mode); 2234 2235 cflag &= (CBAUD | CBAUDEX); 2236#ifndef B921600 2237#define B921600 (B460800+1) 2238#endif 2239 switch (cflag) { 2240 case B921600: 2241 baud = 921600L; 2242 break; 2243 case B460800: 2244 baud = 460800L; 2245 break; 2246 case B230400: 2247 baud = 230400L; 2248 break; 2249 case B115200: 2250 baud = 115200L; 2251 break; 2252 case B57600: 2253 baud = 57600L; 2254 break; 2255 case B38400: 2256 baud = 38400L; 2257 break; 2258 case B19200: 2259 baud = 19200L; 2260 break; 2261 case B9600: 2262 baud = 9600L; 2263 break; 2264 case B4800: 2265 baud = 4800L; 2266 break; 2267 case B2400: 2268 baud = 2400L; 2269 break; 2270 case B1800: 2271 baud = 1800L; 2272 break; 2273 case B1200: 2274 baud = 1200L; 2275 break; 2276 case B600: 2277 baud = 600L; 2278 break; 2279 case B300: 2280 baud = 300L; 2281 break; 2282 case B200: 2283 baud = 200L; 2284 break; 2285 case B150: 2286 baud = 150L; 2287 break; 2288 case B134: 2289 baud = 134L; 2290 break; 2291 case B110: 2292 baud = 110L; 2293 break; 2294 case B75: 2295 baud = 75L; 2296 break; 2297 case B50: 2298 baud = 50L; 2299 break; 2300 default: 2301 baud = 0; 2302 } 2303 if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || 2304 (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) { 2305 if (baud == 921600L) 2306 return (-1); 2307 } 2308 MoxaPortSetBaud(port, baud); 2309 2310 if (termio->c_iflag & (IXON | IXOFF | IXANY)) { 2311 writeb(termio->c_cc[VSTART], ofsAddr + FuncArg); 2312 writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1); 2313 writeb(FC_SetXonXoff, ofsAddr + FuncCode); 2314 wait_finish(ofsAddr); 2315 2316 } 2317 return (0); 2318} 2319 2320int MoxaPortGetLineOut(int port, int *dtrState, int *rtsState) 2321{ 2322 2323 if (!MoxaPortIsValid(port)) 2324 return (-1); 2325 if (dtrState) { 2326 if (moxaLineCtrl[port] & DTR_ON) 2327 *dtrState = 1; 2328 else 2329 *dtrState = 0; 2330 } 2331 if (rtsState) { 2332 if (moxaLineCtrl[port] & RTS_ON) 2333 *rtsState = 1; 2334 else 2335 *rtsState = 0; 2336 } 2337 return (0); 2338} 2339 2340void MoxaPortLineCtrl(int port, int dtr, int rts) 2341{ 2342 void __iomem *ofsAddr; 2343 int mode; 2344 2345 ofsAddr = moxaTableAddr[port]; 2346 mode = 0; 2347 if (dtr) 2348 mode |= DTR_ON; 2349 if (rts) 2350 mode |= RTS_ON; 2351 moxaLineCtrl[port] = mode; 2352 moxafunc(ofsAddr, FC_LineControl, mode); 2353} 2354 2355void MoxaPortFlowCtrl(int port, int rts, int cts, int txflow, int rxflow, int txany) 2356{ 2357 void __iomem *ofsAddr; 2358 int mode; 2359 2360 ofsAddr = moxaTableAddr[port]; 2361 mode = 0; 2362 if (rts) 2363 mode |= RTS_FlowCtl; 2364 if (cts) 2365 mode |= CTS_FlowCtl; 2366 if (txflow) 2367 mode |= Tx_FlowCtl; 2368 if (rxflow) 2369 mode |= Rx_FlowCtl; 2370 if (txany) 2371 mode |= IXM_IXANY; 2372 moxafunc(ofsAddr, FC_SetFlowCtl, mode); 2373} 2374 2375int MoxaPortLineStatus(int port) 2376{ 2377 void __iomem *ofsAddr; 2378 int val; 2379 2380 ofsAddr = moxaTableAddr[port]; 2381 if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || 2382 (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) { 2383 moxafunc(ofsAddr, FC_LineStatus, 0); 2384 val = readw(ofsAddr + FuncArg); 2385 } else { 2386 val = readw(ofsAddr + FlagStat) >> 4; 2387 } 2388 val &= 0x0B; 2389 if (val & 8) { 2390 val |= 4; 2391 if ((moxaDCDState[port] & DCD_oldstate) == 0) 2392 moxaDCDState[port] = (DCD_oldstate | DCD_changed); 2393 } else { 2394 if (moxaDCDState[port] & DCD_oldstate) 2395 moxaDCDState[port] = DCD_changed; 2396 } 2397 val &= 7; 2398 return (val); 2399} 2400 2401int MoxaPortDCDChange(int port) 2402{ 2403 int n; 2404 2405 if (moxaChkPort[port] == 0) 2406 return (0); 2407 n = moxaDCDState[port]; 2408 moxaDCDState[port] &= ~DCD_changed; 2409 n &= DCD_changed; 2410 return (n); 2411} 2412 2413int MoxaPortDCDON(int port) 2414{ 2415 int n; 2416 2417 if (moxaChkPort[port] == 0) 2418 return (0); 2419 if (moxaDCDState[port] & DCD_oldstate) 2420 n = 1; 2421 else 2422 n = 0; 2423 return (n); 2424} 2425 2426 2427/* 2428 int MoxaDumpMem(int port, unsigned char * buffer, int len) 2429 { 2430 int i; 2431 unsigned long baseAddr,ofsAddr,ofs; 2432 2433 baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD]; 2434 ofs = baseAddr + DynPage_addr + pageofs; 2435 if (len > 0x2000L) 2436 len = 0x2000L; 2437 for (i = 0; i < len; i++) 2438 buffer[i] = readb(ofs+i); 2439 } 2440 */ 2441 2442 2443int MoxaPortWriteData(int port, unsigned char * buffer, int len) 2444{ 2445 int c, total, i; 2446 ushort tail; 2447 int cnt; 2448 ushort head, tx_mask, spage, epage; 2449 ushort pageno, pageofs, bufhead; 2450 void __iomem *baseAddr, *ofsAddr, *ofs; 2451 2452 ofsAddr = moxaTableAddr[port]; 2453 baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD]; 2454 tx_mask = readw(ofsAddr + TX_mask); 2455 spage = readw(ofsAddr + Page_txb); 2456 epage = readw(ofsAddr + EndPage_txb); 2457 tail = readw(ofsAddr + TXwptr); 2458 head = readw(ofsAddr + TXrptr); 2459 c = (head > tail) ? (head - tail - 1) 2460 : (head - tail + tx_mask); 2461 if (c > len) 2462 c = len; 2463 moxaLog.txcnt[port] += c; 2464 total = c; 2465 if (spage == epage) { 2466 bufhead = readw(ofsAddr + Ofs_txb); 2467 writew(spage, baseAddr + Control_reg); 2468 while (c > 0) { 2469 if (head > tail) 2470 len = head - tail - 1; 2471 else 2472 len = tx_mask + 1 - tail; 2473 len = (c > len) ? len : c; 2474 ofs = baseAddr + DynPage_addr + bufhead + tail; 2475 for (i = 0; i < len; i++) 2476 writeb(*buffer++, ofs + i); 2477 tail = (tail + len) & tx_mask; 2478 c -= len; 2479 } 2480 writew(tail, ofsAddr + TXwptr); 2481 } else { 2482 len = c; 2483 pageno = spage + (tail >> 13); 2484 pageofs = tail & Page_mask; 2485 do { 2486 cnt = Page_size - pageofs; 2487 if (cnt > c) 2488 cnt = c; 2489 c -= cnt; 2490 writeb(pageno, baseAddr + Control_reg); 2491 ofs = baseAddr + DynPage_addr + pageofs; 2492 for (i = 0; i < cnt; i++) 2493 writeb(*buffer++, ofs + i); 2494 if (c == 0) { 2495 writew((tail + len) & tx_mask, ofsAddr + TXwptr); 2496 break; 2497 } 2498 if (++pageno == epage) 2499 pageno = spage; 2500 pageofs = 0; 2501 } while (1); 2502 } 2503 writeb(1, ofsAddr + CD180TXirq); /* start to send */ 2504 return (total); 2505} 2506 2507int MoxaPortReadData(int port, unsigned char * buffer, int space) 2508{ 2509 register ushort head, pageofs; 2510 int i, count, cnt, len, total, remain; 2511 ushort tail, rx_mask, spage, epage; 2512 ushort pageno, bufhead; 2513 void __iomem *baseAddr, *ofsAddr, *ofs; 2514 2515 ofsAddr = moxaTableAddr[port]; 2516 baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD]; 2517 head = readw(ofsAddr + RXrptr); 2518 tail = readw(ofsAddr + RXwptr); 2519 rx_mask = readw(ofsAddr + RX_mask); 2520 spage = readw(ofsAddr + Page_rxb); 2521 epage = readw(ofsAddr + EndPage_rxb); 2522 count = (tail >= head) ? (tail - head) 2523 : (tail - head + rx_mask + 1); 2524 if (count == 0) 2525 return (0); 2526 2527 total = (space > count) ? count : space; 2528 remain = count - total; 2529 moxaLog.rxcnt[port] += total; 2530 count = total; 2531 if (spage == epage) { 2532 bufhead = readw(ofsAddr + Ofs_rxb); 2533 writew(spage, baseAddr + Control_reg); 2534 while (count > 0) { 2535 if (tail >= head) 2536 len = tail - head; 2537 else 2538 len = rx_mask + 1 - head; 2539 len = (count > len) ? len : count; 2540 ofs = baseAddr + DynPage_addr + bufhead + head; 2541 for (i = 0; i < len; i++) 2542 *buffer++ = readb(ofs + i); 2543 head = (head + len) & rx_mask; 2544 count -= len; 2545 } 2546 writew(head, ofsAddr + RXrptr); 2547 } else { 2548 len = count; 2549 pageno = spage + (head >> 13); 2550 pageofs = head & Page_mask; 2551 do { 2552 cnt = Page_size - pageofs; 2553 if (cnt > count) 2554 cnt = count; 2555 count -= cnt; 2556 writew(pageno, baseAddr + Control_reg); 2557 ofs = baseAddr + DynPage_addr + pageofs; 2558 for (i = 0; i < cnt; i++) 2559 *buffer++ = readb(ofs + i); 2560 if (count == 0) { 2561 writew((head + len) & rx_mask, ofsAddr + RXrptr); 2562 break; 2563 } 2564 if (++pageno == epage) 2565 pageno = spage; 2566 pageofs = 0; 2567 } while (1); 2568 } 2569 if ((readb(ofsAddr + FlagStat) & Xoff_state) && (remain < LowWater)) { 2570 moxaLowWaterChk = 1; 2571 moxaLowChkFlag[port] = 1; 2572 } 2573 return (total); 2574} 2575 2576 2577int MoxaPortTxQueue(int port) 2578{ 2579 void __iomem *ofsAddr; 2580 ushort rptr, wptr, mask; 2581 int len; 2582 2583 ofsAddr = moxaTableAddr[port]; 2584 rptr = readw(ofsAddr + TXrptr); 2585 wptr = readw(ofsAddr + TXwptr); 2586 mask = readw(ofsAddr + TX_mask); 2587 len = (wptr - rptr) & mask; 2588 return (len); 2589} 2590 2591int MoxaPortTxFree(int port) 2592{ 2593 void __iomem *ofsAddr; 2594 ushort rptr, wptr, mask; 2595 int len; 2596 2597 ofsAddr = moxaTableAddr[port]; 2598 rptr = readw(ofsAddr + TXrptr); 2599 wptr = readw(ofsAddr + TXwptr); 2600 mask = readw(ofsAddr + TX_mask); 2601 len = mask - ((wptr - rptr) & mask); 2602 return (len); 2603} 2604 2605int MoxaPortRxQueue(int port) 2606{ 2607 void __iomem *ofsAddr; 2608 ushort rptr, wptr, mask; 2609 int len; 2610 2611 ofsAddr = moxaTableAddr[port]; 2612 rptr = readw(ofsAddr + RXrptr); 2613 wptr = readw(ofsAddr + RXwptr); 2614 mask = readw(ofsAddr + RX_mask); 2615 len = (wptr - rptr) & mask; 2616 return (len); 2617} 2618 2619 2620void MoxaPortTxDisable(int port) 2621{ 2622 void __iomem *ofsAddr; 2623 2624 ofsAddr = moxaTableAddr[port]; 2625 moxafunc(ofsAddr, FC_SetXoffState, Magic_code); 2626} 2627 2628void MoxaPortTxEnable(int port) 2629{ 2630 void __iomem *ofsAddr; 2631 2632 ofsAddr = moxaTableAddr[port]; 2633 moxafunc(ofsAddr, FC_SetXonState, Magic_code); 2634} 2635 2636 2637int MoxaPortResetBrkCnt(int port) 2638{ 2639 ushort cnt; 2640 cnt = moxaBreakCnt[port]; 2641 moxaBreakCnt[port] = 0; 2642 return (cnt); 2643} 2644 2645 2646void MoxaPortSendBreak(int port, int ms100) 2647{ 2648 void __iomem *ofsAddr; 2649 2650 ofsAddr = moxaTableAddr[port]; 2651 if (ms100) { 2652 moxafunc(ofsAddr, FC_SendBreak, Magic_code); 2653 moxadelay(ms100 * (HZ / 10)); 2654 } else { 2655 moxafunc(ofsAddr, FC_SendBreak, Magic_code); 2656 moxadelay(HZ / 4); /* 250 ms */ 2657 } 2658 moxafunc(ofsAddr, FC_StopBreak, Magic_code); 2659} 2660 2661static int moxa_get_serial_info(struct moxa_str *info, 2662 struct serial_struct __user *retinfo) 2663{ 2664 struct serial_struct tmp; 2665 2666 memset(&tmp, 0, sizeof(tmp)); 2667 tmp.type = info->type; 2668 tmp.line = info->port; 2669 tmp.port = 0; 2670 tmp.irq = 0; 2671 tmp.flags = info->asyncflags; 2672 tmp.baud_base = 921600; 2673 tmp.close_delay = info->close_delay; 2674 tmp.closing_wait = info->closing_wait; 2675 tmp.custom_divisor = 0; 2676 tmp.hub6 = 0; 2677 if(copy_to_user(retinfo, &tmp, sizeof(*retinfo))) 2678 return -EFAULT; 2679 return (0); 2680} 2681 2682 2683static int moxa_set_serial_info(struct moxa_str *info, 2684 struct serial_struct __user *new_info) 2685{ 2686 struct serial_struct new_serial; 2687 2688 if(copy_from_user(&new_serial, new_info, sizeof(new_serial))) 2689 return -EFAULT; 2690 2691 if ((new_serial.irq != 0) || 2692 (new_serial.port != 0) || 2693// (new_serial.type != info->type) || 2694 (new_serial.custom_divisor != 0) || 2695 (new_serial.baud_base != 921600)) 2696 return (-EPERM); 2697 2698 if (!capable(CAP_SYS_ADMIN)) { 2699 if (((new_serial.flags & ~ASYNC_USR_MASK) != 2700 (info->asyncflags & ~ASYNC_USR_MASK))) 2701 return (-EPERM); 2702 } else { 2703 info->close_delay = new_serial.close_delay * HZ / 100; 2704 info->closing_wait = new_serial.closing_wait * HZ / 100; 2705 } 2706 2707 new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS); 2708 new_serial.flags |= (info->asyncflags & ASYNC_FLAGS); 2709 2710 if (new_serial.type == PORT_16550A) { 2711 MoxaSetFifo(info->port, 1); 2712 } else { 2713 MoxaSetFifo(info->port, 0); 2714 } 2715 2716 info->type = new_serial.type; 2717 return (0); 2718} 2719 2720 2721 2722/***************************************************************************** 2723 * Static local functions: * 2724 *****************************************************************************/ 2725/* 2726 * moxadelay - delays a specified number ticks 2727 */ 2728static void moxadelay(int tick) 2729{ 2730 unsigned long st, et; 2731 2732 st = jiffies; 2733 et = st + tick; 2734 while (time_before(jiffies, et)); 2735} 2736 2737static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg) 2738{ 2739 2740 writew(arg, ofsAddr + FuncArg); 2741 writew(cmd, ofsAddr + FuncCode); 2742 wait_finish(ofsAddr); 2743} 2744 2745static void wait_finish(void __iomem *ofsAddr) 2746{ 2747 unsigned long i, j; 2748 2749 i = jiffies; 2750 while (readw(ofsAddr + FuncCode) != 0) { 2751 j = jiffies; 2752 if ((j - i) > moxaFuncTout) { 2753 return; 2754 } 2755 } 2756} 2757 2758static void low_water_check(void __iomem *ofsAddr) 2759{ 2760 int len; 2761 ushort rptr, wptr, mask; 2762 2763 if (readb(ofsAddr + FlagStat) & Xoff_state) { 2764 rptr = readw(ofsAddr + RXrptr); 2765 wptr = readw(ofsAddr + RXwptr); 2766 mask = readw(ofsAddr + RX_mask); 2767 len = (wptr - rptr) & mask; 2768 if (len <= Low_water) 2769 moxafunc(ofsAddr, FC_SendXon, 0); 2770 } 2771} 2772 2773static int moxaloadbios(int cardno, unsigned char __user *tmp, int len) 2774{ 2775 void __iomem *baseAddr; 2776 int i; 2777 2778 if(copy_from_user(moxaBuff, tmp, len)) 2779 return -EFAULT; 2780 baseAddr = moxaBaseAddr[cardno]; 2781 writeb(HW_reset, baseAddr + Control_reg); /* reset */ 2782 moxadelay(1); /* delay 10 ms */ 2783 for (i = 0; i < 4096; i++) 2784 writeb(0, baseAddr + i); /* clear fix page */ 2785 for (i = 0; i < len; i++) 2786 writeb(moxaBuff[i], baseAddr + i); /* download BIOS */ 2787 writeb(0, baseAddr + Control_reg); /* restart */ 2788 return (0); 2789} 2790 2791static int moxafindcard(int cardno) 2792{ 2793 void __iomem *baseAddr; 2794 ushort tmp; 2795 2796 baseAddr = moxaBaseAddr[cardno]; 2797 switch (moxa_boards[cardno].boardType) { 2798 case MOXA_BOARD_C218_ISA: 2799 case MOXA_BOARD_C218_PCI: 2800 if ((tmp = readw(baseAddr + C218_key)) != C218_KeyCode) { 2801 return (-1); 2802 } 2803 break; 2804 case MOXA_BOARD_CP204J: 2805 if ((tmp = readw(baseAddr + C218_key)) != CP204J_KeyCode) { 2806 return (-1); 2807 } 2808 break; 2809 default: 2810 if ((tmp = readw(baseAddr + C320_key)) != C320_KeyCode) { 2811 return (-1); 2812 } 2813 if ((tmp = readw(baseAddr + C320_status)) != STS_init) { 2814 return (-2); 2815 } 2816 } 2817 return (0); 2818} 2819 2820static int moxaload320b(int cardno, unsigned char __user *tmp, int len) 2821{ 2822 void __iomem *baseAddr; 2823 int i; 2824 2825 if(len > sizeof(moxaBuff)) 2826 return -EINVAL; 2827 if(copy_from_user(moxaBuff, tmp, len)) 2828 return -EFAULT; 2829 baseAddr = moxaBaseAddr[cardno]; 2830 writew(len - 7168 - 2, baseAddr + C320bapi_len); 2831 writeb(1, baseAddr + Control_reg); /* Select Page 1 */ 2832 for (i = 0; i < 7168; i++) 2833 writeb(moxaBuff[i], baseAddr + DynPage_addr + i); 2834 writeb(2, baseAddr + Control_reg); /* Select Page 2 */ 2835 for (i = 0; i < (len - 7168); i++) 2836 writeb(moxaBuff[i + 7168], baseAddr + DynPage_addr + i); 2837 return (0); 2838} 2839 2840static int moxaloadcode(int cardno, unsigned char __user *tmp, int len) 2841{ 2842 void __iomem *baseAddr, *ofsAddr; 2843 int retval, port, i; 2844 2845 if(copy_from_user(moxaBuff, tmp, len)) 2846 return -EFAULT; 2847 baseAddr = moxaBaseAddr[cardno]; 2848 switch (moxa_boards[cardno].boardType) { 2849 case MOXA_BOARD_C218_ISA: 2850 case MOXA_BOARD_C218_PCI: 2851 case MOXA_BOARD_CP204J: 2852 retval = moxaloadc218(cardno, baseAddr, len); 2853 if (retval) 2854 return (retval); 2855 port = cardno * MAX_PORTS_PER_BOARD; 2856 for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) { 2857 moxaChkPort[port] = 1; 2858 moxaCurBaud[port] = 9600L; 2859 moxaDCDState[port] = 0; 2860 moxaTableAddr[port] = baseAddr + Extern_table + Extern_size * i; 2861 ofsAddr = moxaTableAddr[port]; 2862 writew(C218rx_mask, ofsAddr + RX_mask); 2863 writew(C218tx_mask, ofsAddr + TX_mask); 2864 writew(C218rx_spage + i * C218buf_pageno, ofsAddr + Page_rxb); 2865 writew(readw(ofsAddr + Page_rxb) + C218rx_pageno, ofsAddr + EndPage_rxb); 2866 2867 writew(C218tx_spage + i * C218buf_pageno, ofsAddr + Page_txb); 2868 writew(readw(ofsAddr + Page_txb) + C218tx_pageno, ofsAddr + EndPage_txb); 2869 2870 } 2871 break; 2872 default: 2873 retval = moxaloadc320(cardno, baseAddr, len, 2874 &moxa_boards[cardno].numPorts); 2875 if (retval) 2876 return (retval); 2877 port = cardno * MAX_PORTS_PER_BOARD; 2878 for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) { 2879 moxaChkPort[port] = 1; 2880 moxaCurBaud[port] = 9600L; 2881 moxaDCDState[port] = 0; 2882 moxaTableAddr[port] = baseAddr + Extern_table + Extern_size * i; 2883 ofsAddr = moxaTableAddr[port]; 2884 if (moxa_boards[cardno].numPorts == 8) { 2885 writew(C320p8rx_mask, ofsAddr + RX_mask); 2886 writew(C320p8tx_mask, ofsAddr + TX_mask); 2887 writew(C320p8rx_spage + i * C320p8buf_pgno, ofsAddr + Page_rxb); 2888 writew(readw(ofsAddr + Page_rxb) + C320p8rx_pgno, ofsAddr + EndPage_rxb); 2889 writew(C320p8tx_spage + i * C320p8buf_pgno, ofsAddr + Page_txb); 2890 writew(readw(ofsAddr + Page_txb) + C320p8tx_pgno, ofsAddr + EndPage_txb); 2891 2892 } else if (moxa_boards[cardno].numPorts == 16) { 2893 writew(C320p16rx_mask, ofsAddr + RX_mask); 2894 writew(C320p16tx_mask, ofsAddr + TX_mask); 2895 writew(C320p16rx_spage + i * C320p16buf_pgno, ofsAddr + Page_rxb); 2896 writew(readw(ofsAddr + Page_rxb) + C320p16rx_pgno, ofsAddr + EndPage_rxb); 2897 writew(C320p16tx_spage + i * C320p16buf_pgno, ofsAddr + Page_txb); 2898 writew(readw(ofsAddr + Page_txb) + C320p16tx_pgno, ofsAddr + EndPage_txb); 2899 2900 } else if (moxa_boards[cardno].numPorts == 24) { 2901 writew(C320p24rx_mask, ofsAddr + RX_mask); 2902 writew(C320p24tx_mask, ofsAddr + TX_mask); 2903 writew(C320p24rx_spage + i * C320p24buf_pgno, ofsAddr + Page_rxb); 2904 writew(readw(ofsAddr + Page_rxb) + C320p24rx_pgno, ofsAddr + EndPage_rxb); 2905 writew(C320p24tx_spage + i * C320p24buf_pgno, ofsAddr + Page_txb); 2906 writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb); 2907 } else if (moxa_boards[cardno].numPorts == 32) { 2908 writew(C320p32rx_mask, ofsAddr + RX_mask); 2909 writew(C320p32tx_mask, ofsAddr + TX_mask); 2910 writew(C320p32tx_ofs, ofsAddr + Ofs_txb); 2911 writew(C320p32rx_spage + i * C320p32buf_pgno, ofsAddr + Page_rxb); 2912 writew(readb(ofsAddr + Page_rxb), ofsAddr + EndPage_rxb); 2913 writew(C320p32tx_spage + i * C320p32buf_pgno, ofsAddr + Page_txb); 2914 writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb); 2915 } 2916 } 2917 break; 2918 } 2919 return (0); 2920} 2921 2922static int moxaloadc218(int cardno, void __iomem *baseAddr, int len) 2923{ 2924 char retry; 2925 int i, j, len1, len2; 2926 ushort usum, *ptr, keycode; 2927 2928 if (moxa_boards[cardno].boardType == MOXA_BOARD_CP204J) 2929 keycode = CP204J_KeyCode; 2930 else 2931 keycode = C218_KeyCode; 2932 usum = 0; 2933 len1 = len >> 1; 2934 ptr = (ushort *) moxaBuff; 2935 for (i = 0; i < len1; i++) 2936 usum += *(ptr + i); 2937 retry = 0; 2938 do { 2939 len1 = len >> 1; 2940 j = 0; 2941 while (len1) { 2942 len2 = (len1 > 2048) ? 2048 : len1; 2943 len1 -= len2; 2944 for (i = 0; i < len2 << 1; i++) 2945 writeb(moxaBuff[i + j], baseAddr + C218_LoadBuf + i); 2946 j += i; 2947 2948 writew(len2, baseAddr + C218DLoad_len); 2949 writew(0, baseAddr + C218_key); 2950 for (i = 0; i < 100; i++) { 2951 if (readw(baseAddr + C218_key) == keycode) 2952 break; 2953 moxadelay(1); /* delay 10 ms */ 2954 } 2955 if (readw(baseAddr + C218_key) != keycode) { 2956 return (-1); 2957 } 2958 } 2959 writew(0, baseAddr + C218DLoad_len); 2960 writew(usum, baseAddr + C218check_sum); 2961 writew(0, baseAddr + C218_key); 2962 for (i = 0; i < 100; i++) { 2963 if (readw(baseAddr + C218_key) == keycode) 2964 break; 2965 moxadelay(1); /* delay 10 ms */ 2966 } 2967 retry++; 2968 } while ((readb(baseAddr + C218chksum_ok) != 1) && (retry < 3)); 2969 if (readb(baseAddr + C218chksum_ok) != 1) { 2970 return (-1); 2971 } 2972 writew(0, baseAddr + C218_key); 2973 for (i = 0; i < 100; i++) { 2974 if (readw(baseAddr + Magic_no) == Magic_code) 2975 break; 2976 moxadelay(1); /* delay 10 ms */ 2977 } 2978 if (readw(baseAddr + Magic_no) != Magic_code) { 2979 return (-1); 2980 } 2981 writew(1, baseAddr + Disable_IRQ); 2982 writew(0, baseAddr + Magic_no); 2983 for (i = 0; i < 100; i++) { 2984 if (readw(baseAddr + Magic_no) == Magic_code) 2985 break; 2986 moxadelay(1); /* delay 10 ms */ 2987 } 2988 if (readw(baseAddr + Magic_no) != Magic_code) { 2989 return (-1); 2990 } 2991 moxaCard = 1; 2992 moxaIntNdx[cardno] = baseAddr + IRQindex; 2993 moxaIntPend[cardno] = baseAddr + IRQpending; 2994 moxaIntTable[cardno] = baseAddr + IRQtable; 2995 return (0); 2996} 2997 2998static int moxaloadc320(int cardno, void __iomem *baseAddr, int len, int *numPorts) 2999{ 3000 ushort usum; 3001 int i, j, wlen, len2, retry; 3002 ushort *uptr; 3003 3004 usum = 0; 3005 wlen = len >> 1; 3006 uptr = (ushort *) moxaBuff; 3007 for (i = 0; i < wlen; i++) 3008 usum += uptr[i]; 3009 retry = 0; 3010 j = 0; 3011 do { 3012 while (wlen) { 3013 if (wlen > 2048) 3014 len2 = 2048; 3015 else 3016 len2 = wlen; 3017 wlen -= len2; 3018 len2 <<= 1; 3019 for (i = 0; i < len2; i++) 3020 writeb(moxaBuff[j + i], baseAddr + C320_LoadBuf + i); 3021 len2 >>= 1; 3022 j += i; 3023 writew(len2, baseAddr + C320DLoad_len); 3024 writew(0, baseAddr + C320_key); 3025 for (i = 0; i < 10; i++) { 3026 if (readw(baseAddr + C320_key) == C320_KeyCode) 3027 break; 3028 moxadelay(1); 3029 } 3030 if (readw(baseAddr + C320_key) != C320_KeyCode) 3031 return (-1); 3032 } 3033 writew(0, baseAddr + C320DLoad_len); 3034 writew(usum, baseAddr + C320check_sum); 3035 writew(0, baseAddr + C320_key); 3036 for (i = 0; i < 10; i++) { 3037 if (readw(baseAddr + C320_key) == C320_KeyCode) 3038 break; 3039 moxadelay(1); 3040 } 3041 retry++; 3042 } while ((readb(baseAddr + C320chksum_ok) != 1) && (retry < 3)); 3043 if (readb(baseAddr + C320chksum_ok) != 1) 3044 return (-1); 3045 writew(0, baseAddr + C320_key); 3046 for (i = 0; i < 600; i++) { 3047 if (readw(baseAddr + Magic_no) == Magic_code) 3048 break; 3049 moxadelay(1); 3050 } 3051 if (readw(baseAddr + Magic_no) != Magic_code) 3052 return (-100); 3053 3054 if (moxa_boards[cardno].busType == MOXA_BUS_TYPE_PCI) { /* ASIC board */ 3055 writew(0x3800, baseAddr + TMS320_PORT1); 3056 writew(0x3900, baseAddr + TMS320_PORT2); 3057 writew(28499, baseAddr + TMS320_CLOCK); 3058 } else { 3059 writew(0x3200, baseAddr + TMS320_PORT1); 3060 writew(0x3400, baseAddr + TMS320_PORT2); 3061 writew(19999, baseAddr + TMS320_CLOCK); 3062 } 3063 writew(1, baseAddr + Disable_IRQ); 3064 writew(0, baseAddr + Magic_no); 3065 for (i = 0; i < 500; i++) { 3066 if (readw(baseAddr + Magic_no) == Magic_code) 3067 break; 3068 moxadelay(1); 3069 } 3070 if (readw(baseAddr + Magic_no) != Magic_code) 3071 return (-102); 3072 3073 j = readw(baseAddr + Module_cnt); 3074 if (j <= 0) 3075 return (-101); 3076 *numPorts = j * 8; 3077 writew(j, baseAddr + Module_no); 3078 writew(0, baseAddr + Magic_no); 3079 for (i = 0; i < 600; i++) { 3080 if (readw(baseAddr + Magic_no) == Magic_code) 3081 break; 3082 moxadelay(1); 3083 } 3084 if (readw(baseAddr + Magic_no) != Magic_code) 3085 return (-102); 3086 moxaCard = 1; 3087 moxaIntNdx[cardno] = baseAddr + IRQindex; 3088 moxaIntPend[cardno] = baseAddr + IRQpending; 3089 moxaIntTable[cardno] = baseAddr + IRQtable; 3090 return (0); 3091} 3092 3093#if 0 3094long MoxaPortGetCurBaud(int port) 3095{ 3096 3097 if (moxaChkPort[port] == 0) 3098 return (0); 3099 return (moxaCurBaud[port]); 3100} 3101#endif /* 0 */ 3102 3103static void MoxaSetFifo(int port, int enable) 3104{ 3105 void __iomem *ofsAddr = moxaTableAddr[port]; 3106 3107 if (!enable) { 3108 moxafunc(ofsAddr, FC_SetRxFIFOTrig, 0); 3109 moxafunc(ofsAddr, FC_SetTxFIFOCnt, 1); 3110 } else { 3111 moxafunc(ofsAddr, FC_SetRxFIFOTrig, 3); 3112 moxafunc(ofsAddr, FC_SetTxFIFOCnt, 16); 3113 } 3114} 3115 3116#if 0 3117int MoxaPortSetMode(int port, int databits, int stopbits, int parity) 3118{ 3119 void __iomem *ofsAddr; 3120 int val; 3121 3122 val = 0; 3123 switch (databits) { 3124 case 5: 3125 val |= 0; 3126 break; 3127 case 6: 3128 val |= 1; 3129 break; 3130 case 7: 3131 val |= 2; 3132 break; 3133 case 8: 3134 val |= 3; 3135 break; 3136 default: 3137 return (-1); 3138 } 3139 switch (stopbits) { 3140 case 0: 3141 val |= 0; 3142 break; /* stop bits 1.5 */ 3143 case 1: 3144 val |= 0; 3145 break; 3146 case 2: 3147 val |= 4; 3148 break; 3149 default: 3150 return (-1); 3151 } 3152 switch (parity) { 3153 case 0: 3154 val |= 0x00; 3155 break; /* None */ 3156 case 1: 3157 val |= 0x08; 3158 break; /* Odd */ 3159 case 2: 3160 val |= 0x18; 3161 break; /* Even */ 3162 case 3: 3163 val |= 0x28; 3164 break; /* Mark */ 3165 case 4: 3166 val |= 0x38; 3167 break; /* Space */ 3168 default: 3169 return (-1); 3170 } 3171 ofsAddr = moxaTableAddr[port]; 3172 moxafunc(ofsAddr, FC_SetMode, val); 3173 return (0); 3174} 3175 3176int MoxaPortTxBufSize(int port) 3177{ 3178 void __iomem *ofsAddr; 3179 int size; 3180 3181 ofsAddr = moxaTableAddr[port]; 3182 size = readw(ofsAddr + TX_mask); 3183 return (size); 3184} 3185 3186int MoxaPortRxBufSize(int port) 3187{ 3188 void __iomem *ofsAddr; 3189 int size; 3190 3191 ofsAddr = moxaTableAddr[port]; 3192 size = readw(ofsAddr + RX_mask); 3193 return (size); 3194} 3195 3196int MoxaPortRxFree(int port) 3197{ 3198 void __iomem *ofsAddr; 3199 ushort rptr, wptr, mask; 3200 int len; 3201 3202 ofsAddr = moxaTableAddr[port]; 3203 rptr = readw(ofsAddr + RXrptr); 3204 wptr = readw(ofsAddr + RXwptr); 3205 mask = readw(ofsAddr + RX_mask); 3206 len = mask - ((wptr - rptr) & mask); 3207 return (len); 3208} 3209int MoxaPortGetBrkCnt(int port) 3210{ 3211 return (moxaBreakCnt[port]); 3212} 3213 3214void MoxaPortSetXonXoff(int port, int xonValue, int xoffValue) 3215{ 3216 void __iomem *ofsAddr; 3217 3218 ofsAddr = moxaTableAddr[port]; 3219 writew(xonValue, ofsAddr + FuncArg); 3220 writew(xoffValue, ofsAddr + FuncArg1); 3221 writew(FC_SetXonXoff, ofsAddr + FuncCode); 3222 wait_finish(ofsAddr); 3223} 3224 3225int MoxaPortIsTxHold(int port) 3226{ 3227 void __iomem *ofsAddr; 3228 int val; 3229 3230 ofsAddr = moxaTableAddr[port]; 3231 if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || 3232 (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) { 3233 moxafunc(ofsAddr, FC_GetCCSR, 0); 3234 val = readw(ofsAddr + FuncArg); 3235 if (val & 0x04) 3236 return (1); 3237 } else { 3238 if (readw(ofsAddr + FlagStat) & Tx_flowOff) 3239 return (1); 3240 } 3241 return (0); 3242} 3243#endif 3244