moxa.c revision 33f0f88f1c51ae5c2d593d26960c760ea154c2e2
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*****************************************************************************/ 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * moxa.c -- MOXA Intellio family multiport serial driver. 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1999-2000 Moxa Technologies (support@moxa.com.tw). 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 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 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 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> 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h> 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/bitops.h> 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/system.h> 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h> 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_VERSION "5.1k" 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXAMAJOR 172 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXACUMAJOR 173 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define put_to_user(arg1, arg2) put_user(arg1, (unsigned long *)arg2) 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#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 */ 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MAX_PORTS 128 /* Don't change this value */ 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 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 { 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MOXA_BOARD_C218_PCI = 1, 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MOXA_BOARD_C218_ISA, 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MOXA_BOARD_C320_PCI, 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MOXA_BOARD_C320_ISA, 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MOXA_BOARD_CP204J, 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *moxa_brdname[] = 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "C218 Turbo PCI series", 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "C218 Turbo ISA series", 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "C320 Turbo PCI series", 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "C320 Turbo ISA series", 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "CP-204J series", 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PCI 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pci_device_id moxa_pcibrds[] = { 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C218, PCI_ANY_ID, PCI_ANY_ID, 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0, 0, MOXA_BOARD_C218_PCI }, 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C320, PCI_ANY_ID, PCI_ANY_ID, 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0, 0, MOXA_BOARD_C320_PCI }, 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_CP204J, PCI_ANY_ID, PCI_ANY_ID, 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0, 0, MOXA_BOARD_CP204J }, 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 0 } 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DEVICE_TABLE(pci, moxa_pcibrds); 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_PCI */ 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef struct _moxa_isa_board_conf { 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int boardType; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int numPorts; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long baseAddr; 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} moxa_isa_board_conf; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic moxa_isa_board_conf moxa_isa_boards[] = 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* {MOXA_BOARD_C218_ISA,8,0xDC000}, */ 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef struct _moxa_pci_devinfo { 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort busNum; 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort devNum; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} moxa_pci_devinfo; 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef struct _moxa_board_conf { 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int boardType; 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int numPorts; 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long baseAddr; 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int busType; 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_pci_devinfo pciInfo; 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} moxa_board_conf; 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic moxa_board_conf moxa_boards[MAX_BOARDS]; 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __iomem *moxaBaseAddr[MAX_BOARDS]; 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct moxa_str { 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int type; 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int port; 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int close_delay; 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 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}; 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct mxser_mstatus { 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tcflag_t cflag; 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cts; 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int dsr; 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ri; 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int dcd; 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 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 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define THROTTLE 0x8 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* event */ 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_EVENT_HANGUP 1 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#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}; 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic 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); 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param_array(baseaddr, int, NULL, 0); 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param_array(numports, int, NULL, 0); 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(ttymajor, int, 0); 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(verbose, bool, 0644); 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct tty_driver *moxaDriver; 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct moxa_str moxaChannels[MAX_PORTS]; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned char *moxaXmitBuff; 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaTimer_on; 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct timer_list moxaTimer; 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaEmptyTimer_on[MAX_PORTS]; 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct timer_list moxaEmptyTimer[MAX_PORTS]; 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct semaphore moxaBuffSem; 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * static functions: 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void do_moxa_softint(void *); 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_open(struct tty_struct *, struct file *); 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_close(struct tty_struct *, struct file *); 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_write(struct tty_struct *, const unsigned char *, int); 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_write_room(struct tty_struct *); 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_flush_buffer(struct tty_struct *); 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_chars_in_buffer(struct tty_struct *); 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_flush_chars(struct tty_struct *); 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_put_char(struct tty_struct *, unsigned char); 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long); 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_throttle(struct tty_struct *); 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_unthrottle(struct tty_struct *); 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_set_termios(struct tty_struct *, struct termios *); 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_stop(struct tty_struct *); 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_start(struct tty_struct *); 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_hangup(struct tty_struct *); 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_tiocmget(struct tty_struct *tty, struct file *file); 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_tiocmset(struct tty_struct *tty, struct file *file, 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int set, unsigned int clear); 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_poll(unsigned long); 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void set_tty_param(struct tty_struct *); 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int block_till_ready(struct tty_struct *, struct file *, 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *); 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void setup_empty_event(struct tty_struct *); 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void check_xmit_empty(unsigned long); 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void shut_down(struct moxa_str *); 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void receive_data(struct moxa_str *); 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * moxa board interface functions: 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void MoxaDriverInit(void); 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int MoxaDriverIoctl(unsigned int, unsigned long, int); 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int MoxaDriverPoll(void); 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int MoxaPortsOfCard(int); 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int MoxaPortIsValid(int); 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void MoxaPortEnable(int); 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void MoxaPortDisable(int); 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic long MoxaPortGetMaxBaud(int); 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic long MoxaPortSetBaud(int, long); 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int MoxaPortSetTermio(int, struct termios *); 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int MoxaPortGetLineOut(int, int *, int *); 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void MoxaPortLineCtrl(int, int, int); 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void MoxaPortFlowCtrl(int, int, int, int, int, int); 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int MoxaPortLineStatus(int); 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int MoxaPortDCDChange(int); 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int MoxaPortDCDON(int); 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void MoxaPortFlushData(int, int); 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int MoxaPortWriteData(int, unsigned char *, int); 27233f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Coxstatic int MoxaPortReadData(int, struct tty_struct *tty); 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int MoxaPortTxQueue(int); 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int MoxaPortRxQueue(int); 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int MoxaPortTxFree(int); 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void MoxaPortTxDisable(int); 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void MoxaPortTxEnable(int); 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int MoxaPortResetBrkCnt(int); 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void MoxaPortSendBreak(int, int); 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_get_serial_info(struct moxa_str *, struct serial_struct __user *); 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_set_serial_info(struct moxa_str *, struct serial_struct __user *); 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void MoxaSetFifo(int port, int enable); 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct tty_operations moxa_ops = { 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .open = moxa_open, 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .close = moxa_close, 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write = moxa_write, 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write_room = moxa_write_room, 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .flush_buffer = moxa_flush_buffer, 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .chars_in_buffer = moxa_chars_in_buffer, 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .flush_chars = moxa_flush_chars, 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .put_char = moxa_put_char, 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ioctl = moxa_ioctl, 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .throttle = moxa_throttle, 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .unthrottle = moxa_unthrottle, 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .set_termios = moxa_set_termios, 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .stop = moxa_stop, 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .start = moxa_start, 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .hangup = moxa_hangup, 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .tiocmget = moxa_tiocmget, 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .tiocmset = moxa_tiocmset, 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30433f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Coxstatic spinlock_t moxa_lock = SPIN_LOCK_UNLOCKED; 30533f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PCI 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board) 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds board->baseAddr = pci_resource_start (p, 2); 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds board->boardType = board_type; 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (board_type) { 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_BOARD_C218_ISA: 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_BOARD_C218_PCI: 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds board->numPorts = 8; 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_BOARD_CP204J: 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds board->numPorts = 4; 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds board->numPorts = 0; 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds board->busType = MOXA_BUS_TYPE_PCI; 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds board->pciInfo.busNum = p->bus->number; 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds board->pciInfo.devNum = p->devfn >> 3; 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_PCI */ 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init moxa_init(void) 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, numBoards; 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch; 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION); 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDriver = alloc_tty_driver(MAX_PORTS + 1); 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!moxaDriver) 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_MUTEX(&moxaBuffSem); 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDriver->owner = THIS_MODULE; 3449b4e3b13b147e9b737de63188a9ae740eaa8c36dSergey Vlasov moxaDriver->name = "ttyMX"; 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDriver->devfs_name = "tts/a"; 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDriver->major = ttymajor; 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDriver->minor_start = 0; 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDriver->type = TTY_DRIVER_TYPE_SERIAL; 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDriver->subtype = SERIAL_TYPE_NORMAL; 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDriver->init_termios = tty_std_termios; 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDriver->init_termios.c_iflag = 0; 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDriver->init_termios.c_oflag = 0; 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDriver->init_termios.c_lflag = 0; 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDriver->flags = TTY_DRIVER_REAL_RAW; 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty_set_operations(moxaDriver, &moxa_ops); 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaXmitBuff = NULL; 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0, ch = moxaChannels; i < MAX_PORTS; i++, ch++) { 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->type = PORT_16550A; 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->port = i; 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds INIT_WORK(&ch->tqueue, do_moxa_softint, ch); 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->tty = NULL; 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->close_delay = 5 * HZ / 10; 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->closing_wait = 30 * HZ; 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->count = 0; 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->blocked_open = 0; 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_waitqueue_head(&ch->open_wait); 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_waitqueue_head(&ch->close_wait); 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_BOARDS; i++) { 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[i].boardType = 0; 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[i].numPorts = 0; 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[i].baseAddr = 0; 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[i].busType = 0; 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[i].pciInfo.busNum = 0; 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[i].pciInfo.devNum = 0; 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaDriverInit(); 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Tty devices major number = %d\n", ttymajor); 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tty_register_driver(moxaDriver)) { 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n"); 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds put_tty_driver(moxaDriver); 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_PORTS; i++) { 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_timer(&moxaEmptyTimer[i]); 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaEmptyTimer[i].function = check_xmit_empty; 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaEmptyTimer[i].data = (unsigned long) & moxaChannels[i]; 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaEmptyTimer_on[i] = 0; 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_timer(&moxaTimer); 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaTimer.function = moxa_poll; 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaTimer.expires = jiffies + (HZ / 50); 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaTimer_on = 1; 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add_timer(&moxaTimer); 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Find the boards defined in source code */ 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds numBoards = 0; 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_BOARDS; i++) { 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA) || 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (moxa_isa_boards[i].boardType == MOXA_BOARD_C320_ISA)) { 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[numBoards].boardType = moxa_isa_boards[i].boardType; 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA) 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[numBoards].numPorts = 8; 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts; 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA; 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr; 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (verbose) 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Board %2d: %s board(baseAddr=%lx)\n", 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds numBoards + 1, 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_brdname[moxa_boards[numBoards].boardType - 1], 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[numBoards].baseAddr); 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds numBoards++; 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Find the boards defined form module args. */ 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef MODULE 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_BOARDS; i++) { 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((type[i] == MOXA_BOARD_C218_ISA) || 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (type[i] == MOXA_BOARD_C320_ISA)) { 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (verbose) 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Board %2d: %s board(baseAddr=%lx)\n", 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds numBoards + 1, 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_brdname[type[i] - 1], 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (unsigned long) baseaddr[i]); 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (numBoards >= MAX_BOARDS) { 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (verbose) 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS); 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[numBoards].boardType = type[i]; 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA) 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[numBoards].numPorts = 8; 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[numBoards].numPorts = numports[i]; 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA; 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_boards[numBoards].baseAddr = baseaddr[i]; 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds numBoards++; 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Find PCI boards here */ 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PCI 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *p = NULL; 453fe971071a89c5c5184fc9f3482c7a8e997cf0520Tobias Klauser int n = ARRAY_SIZE(moxa_pcibrds) - 1; 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = 0; 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (i < n) { 456881a8c120acf7ec09c90289e2996b7c70f51e996Amit Gud while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL) 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (pci_enable_device(p)) 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (numBoards >= MAX_BOARDS) { 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (verbose) 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS); 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_get_PCI_conf(p, moxa_pcibrds[i].driver_data, 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &moxa_boards[numBoards]); 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds numBoards++; 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i++; 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < numBoards; i++) { 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaBaseAddr[i] = ioremap((unsigned long) moxa_boards[i].baseAddr, 0x4000); 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit moxa_exit(void) 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (verbose) 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Unloading module moxa ...\n"); 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaTimer_on) 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer(&moxaTimer); 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_PORTS; i++) 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaEmptyTimer_on[i]) 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer(&moxaEmptyTimer[i]); 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tty_unregister_driver(moxaDriver)) 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Couldn't unregister MOXA Intellio family serial driver\n"); 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds put_tty_driver(moxaDriver); 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (verbose) 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Done\n"); 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(moxa_init); 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(moxa_exit); 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void do_moxa_softint(void *private_) 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch = (struct moxa_str *) private_; 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct tty_struct *tty; 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch && (tty = ch->tty)) { 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (test_and_clear_bit(MOXA_EVENT_HANGUP, &ch->event)) { 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty_hangup(tty); /* FIXME: module removal race here - AKPM */ 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up_interruptible(&ch->open_wait); 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_open(struct tty_struct *tty, struct file *filp) 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch; 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int port; 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retval; 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long page; 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds port = PORTNO(tty); 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (port == MAX_PORTS) { 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!MoxaPortIsValid(port)) { 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty->driver_data = NULL; 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-ENODEV); 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds down(&moxaBuffSem); 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!moxaXmitBuff) { 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds page = get_zeroed_page(GFP_KERNEL); 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!page) { 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds up(&moxaBuffSem); 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-ENOMEM); 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* This test is guarded by the BuffSem so no longer needed 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds delete me in 2.5 */ 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaXmitBuff) 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_page(page); 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaXmitBuff = (unsigned char *) page; 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds up(&moxaBuffSem); 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch = &moxaChannels[port]; 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->count++; 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty->driver_data = ch; 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->tty = tty; 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(ch->asyncflags & ASYNC_INITIALIZED)) { 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->statusflags = 0; 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_tty_param(tty); 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortLineCtrl(ch->port, 1, 1); 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortEnable(ch->port); 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->asyncflags |= ASYNC_INITIALIZED; 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = block_till_ready(tty, filp, ch); 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_unthrottle(tty); 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch->type == PORT_16550A) { 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaSetFifo(ch->port, 1); 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaSetFifo(ch->port, 0); 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (retval); 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_close(struct tty_struct *tty, struct file *filp) 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch; 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int port; 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds port = PORTNO(tty); 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (port == MAX_PORTS) { 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!MoxaPortIsValid(port)) { 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef SERIAL_DEBUG_CLOSE 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Invalid portno in moxa_close\n"); 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty->driver_data = NULL; 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tty->driver_data == NULL) { 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tty_hung_up_p(filp)) { 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch = (struct moxa_str *) tty->driver_data; 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((tty->count == 1) && (ch->count != 1)) { 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("moxa_close: bad serial port count; tty->count is 1, " 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ch->count is %d\n", ch->count); 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->count = 1; 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (--ch->count < 0) { 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("moxa_close: bad serial port count, device=%s\n", 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty->name); 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->count = 0; 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch->count) { 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->asyncflags |= ASYNC_CLOSING; 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->cflag = tty->termios->c_cflag; 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch->asyncflags & ASYNC_INITIALIZED) { 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setup_empty_event(tty); 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaEmptyTimer_on[ch->port] = 0; 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer(&moxaEmptyTimer[ch->port]); 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds shut_down(ch); 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortFlushData(port, 2); 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tty->driver->flush_buffer) 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty->driver->flush_buffer(tty); 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty_ldisc_flush(tty); 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty->closing = 0; 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->event = 0; 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->tty = NULL; 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch->blocked_open) { 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch->close_delay) { 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep_interruptible(jiffies_to_msecs(ch->close_delay)); 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up_interruptible(&ch->open_wait); 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up_interruptible(&ch->close_wait); 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_write(struct tty_struct *tty, 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const unsigned char *buf, int count) 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch; 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len, port; 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch = (struct moxa_str *) tty->driver_data; 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch == NULL) 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds port = ch->port; 65033f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox 65133f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox spin_lock_irqsave(&moxa_lock, flags); 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = MoxaPortWriteData(port, (unsigned char *) buf, count); 65333f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox spin_unlock_irqrestore(&moxa_lock, flags); 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /********************************************* 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( !(ch->statusflags & LOWWAIT) && 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((len != count) || (MoxaPortTxFree(port) <= 100)) ) 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ************************************************/ 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->statusflags |= LOWWAIT; 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (len); 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_write_room(struct tty_struct *tty) 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch; 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tty->stopped) 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch = (struct moxa_str *) tty->driver_data; 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch == NULL) 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (MoxaPortTxFree(ch->port)); 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_flush_buffer(struct tty_struct *tty) 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch == NULL) 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortFlushData(ch->port, 1); 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty_wakeup(tty); 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_chars_in_buffer(struct tty_struct *tty) 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int chars; 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Sigh...I have to check if driver_data is NULL here, because 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * if an open() fails, the TTY subsystem eventually calls 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * tty_wait_until_sent(), which calls the driver's chars_in_buffer() 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * routine. And since the open() failed, we return 0 here. TDJ 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch == NULL) 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chars = MoxaPortTxQueue(ch->port); 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chars) { 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Make it possible to wakeup anything waiting for output 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * in tty_ioctl.c, etc. 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(ch->statusflags & EMPTYWAIT)) 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setup_empty_event(tty); 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (chars); 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_flush_chars(struct tty_struct *tty) 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Don't think I need this, because this is called to empty the TX 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * buffer for the 16450, 16550, etc. 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_put_char(struct tty_struct *tty, unsigned char c) 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch; 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int port; 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch = (struct moxa_str *) tty->driver_data; 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch == NULL) 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds port = ch->port; 72833f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox spin_lock_irqsave(&moxa_lock, flags); 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaXmitBuff[0] = c; 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortWriteData(port, moxaXmitBuff, 1); 73133f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox spin_unlock_irqrestore(&moxa_lock, flags); 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /************************************************ 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) ) 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *************************************************/ 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->statusflags |= LOWWAIT; 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_tiocmget(struct tty_struct *tty, struct file *file) 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int port; 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int flag = 0, dtr, rts; 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds port = PORTNO(tty); 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((port != MAX_PORTS) && (!ch)) 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-EINVAL); 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortGetLineOut(ch->port, &dtr, &rts); 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dtr) 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flag |= TIOCM_DTR; 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rts) 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flag |= TIOCM_RTS; 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dtr = MoxaPortLineStatus(ch->port); 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dtr & 1) 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flag |= TIOCM_CTS; 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dtr & 2) 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flag |= TIOCM_DSR; 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dtr & 4) 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flag |= TIOCM_CD; 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return flag; 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_tiocmset(struct tty_struct *tty, struct file *file, 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int set, unsigned int clear) 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int port; 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int dtr, rts; 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds port = PORTNO(tty); 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((port != MAX_PORTS) && (!ch)) 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-EINVAL); 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortGetLineOut(ch->port, &dtr, &rts); 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (set & TIOCM_RTS) 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rts = 1; 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (set & TIOCM_DTR) 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dtr = 1; 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (clear & TIOCM_RTS) 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rts = 0; 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (clear & TIOCM_DTR) 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dtr = 0; 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortLineCtrl(ch->port, dtr, rts); 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_ioctl(struct tty_struct *tty, struct file *file, 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int cmd, unsigned long arg) 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register int port; 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __user *argp = (void __user *)arg; 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retval; 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds port = PORTNO(tty); 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((port != MAX_PORTS) && (!ch)) 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-EINVAL); 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case TCSBRK: /* SVID version: non-zero arg --> no break */ 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = tty_check_change(tty); 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (retval) 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (retval); 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setup_empty_event(tty); 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty_wait_until_sent(tty, 0); 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!arg) 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortSendBreak(ch->port, 0); 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case TCSBRKP: /* support for POSIX tcsendbreak() */ 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = tty_check_change(tty); 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (retval) 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (retval); 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds setup_empty_event(tty); 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty_wait_until_sent(tty, 0); 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortSendBreak(ch->port, arg); 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case TIOCGSOFTCAR: 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp); 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case TIOCSSOFTCAR: 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(get_user(retval, (unsigned long __user *) argp)) 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds arg = retval; 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (arg ? CLOCAL : 0)); 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (C_CLOCAL(tty)) 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->asyncflags &= ~ASYNC_CHECK_CD; 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->asyncflags |= ASYNC_CHECK_CD; 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case TIOCGSERIAL: 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return moxa_get_serial_info(ch, argp); 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case TIOCSSERIAL: 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return moxa_set_serial_info(ch, argp); 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = MoxaDriverIoctl(cmd, arg, port); 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (retval); 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_throttle(struct tty_struct *tty) 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->statusflags |= THROTTLE; 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_unthrottle(struct tty_struct *tty) 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->statusflags &= ~THROTTLE; 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_set_termios(struct tty_struct *tty, 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct termios *old_termios) 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch == NULL) 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_tty_param(tty); 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(old_termios->c_cflag & CLOCAL) && 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (tty->termios->c_cflag & CLOCAL)) 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up_interruptible(&ch->open_wait); 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_stop(struct tty_struct *tty) 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch == NULL) 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortTxDisable(ch->port); 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->statusflags |= TXSTOPPED; 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_start(struct tty_struct *tty) 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch == NULL) 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(ch->statusflags & TXSTOPPED)) 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortTxEnable(ch->port); 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->statusflags &= ~TXSTOPPED; 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_hangup(struct tty_struct *tty) 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch = (struct moxa_str *) tty->driver_data; 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxa_flush_buffer(tty); 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds shut_down(ch); 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->event = 0; 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->count = 0; 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->tty = NULL; 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up_interruptible(&ch->open_wait); 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxa_poll(unsigned long ignored) 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register int card; 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch; 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct tty_struct *tp; 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, ports; 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaTimer_on = 0; 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer(&moxaTimer); 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (MoxaDriverPoll() < 0) { 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaTimer.function = moxa_poll; 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaTimer.expires = jiffies + (HZ / 50); 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaTimer_on = 1; 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add_timer(&moxaTimer); 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (card = 0; card < MAX_BOARDS; card++) { 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ports = MoxaPortsOfCard(card)) <= 0) 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch = &moxaChannels[card * MAX_PORTS_PER_BOARD]; 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < ports; i++, ch++) { 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ch->asyncflags & ASYNC_INITIALIZED) == 0) 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(ch->statusflags & THROTTLE) && 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (MoxaPortRxQueue(ch->port) > 0)) 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds receive_data(ch); 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((tp = ch->tty) == 0) 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch->statusflags & LOWWAIT) { 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (MoxaPortTxQueue(ch->port) <= WAKEUP_CHARS) { 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!tp->stopped) { 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->statusflags &= ~LOWWAIT; 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty_wakeup(tp); 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!I_IGNBRK(tp) && (MoxaPortResetBrkCnt(ch->port) > 0)) { 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty_insert_flip_char(tp, 0, TTY_BREAK); 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty_schedule_flip(tp); 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (MoxaPortDCDChange(ch->port)) { 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch->asyncflags & ASYNC_CHECK_CD) { 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (MoxaPortDCDON(ch->port)) 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wake_up_interruptible(&ch->open_wait); 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_bit(MOXA_EVENT_HANGUP, &ch->event); 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds schedule_work(&ch->tqueue); 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaTimer.function = moxa_poll; 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaTimer.expires = jiffies + (HZ / 50); 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaTimer_on = 1; 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add_timer(&moxaTimer); 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/******************************************************************************/ 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void set_tty_param(struct tty_struct *tty) 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register struct termios *ts; 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch; 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rts, cts, txflow, rxflow, xany; 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch = (struct moxa_str *) tty->driver_data; 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ts = tty->termios; 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ts->c_cflag & CLOCAL) 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->asyncflags &= ~ASYNC_CHECK_CD; 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->asyncflags |= ASYNC_CHECK_CD; 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rts = cts = txflow = rxflow = xany = 0; 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ts->c_cflag & CRTSCTS) 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rts = cts = 1; 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ts->c_iflag & IXON) 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds txflow = 1; 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ts->c_iflag & IXOFF) 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rxflow = 1; 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ts->c_iflag & IXANY) 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds xany = 1; 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortFlowCtrl(ch->port, rts, cts, txflow, rxflow, xany); 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortSetTermio(ch->port, ts); 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int block_till_ready(struct tty_struct *tty, struct file *filp, 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch) 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DECLARE_WAITQUEUE(wait,current); 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retval; 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int do_clocal = C_CLOCAL(tty); 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If the device is in the middle of being closed, then block 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * until it's done, and then try again. 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) { 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch->asyncflags & ASYNC_CLOSING) 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds interruptible_sleep_on(&ch->close_wait); 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef SERIAL_DO_RESTART 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch->asyncflags & ASYNC_HUP_NOTIFY) 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-EAGAIN); 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-ERESTARTSYS); 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-EAGAIN); 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If non-blocking mode is set, then make the check up front 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and then exit. 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (filp->f_flags & O_NONBLOCK) { 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->asyncflags |= ASYNC_NORMAL_ACTIVE; 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Block waiting for the carrier detect and the line to become free 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = 0; 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add_wait_queue(&ch->open_wait, &wait); 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef SERIAL_DEBUG_OPEN 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("block_til_ready before block: ttys%d, count = %d\n", 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->line, ch->count); 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 103433f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox spin_lock_irqsave(&moxa_lock, flags); 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!tty_hung_up_p(filp)) 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->count--; 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->blocked_open++; 103833f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox spin_unlock_irqrestore(&moxa_lock, flags); 103933f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (1) { 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_current_state(TASK_INTERRUPTIBLE); 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tty_hung_up_p(filp) || 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds !(ch->asyncflags & ASYNC_INITIALIZED)) { 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef SERIAL_DO_RESTART 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch->asyncflags & ASYNC_HUP_NOTIFY) 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -EAGAIN; 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -ERESTARTSYS; 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -EAGAIN; 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(ch->asyncflags & ASYNC_CLOSING) && (do_clocal || 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortDCDON(ch->port))) 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (signal_pending(current)) { 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = -ERESTARTSYS; 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds schedule(); 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds set_current_state(TASK_RUNNING); 10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds remove_wait_queue(&ch->open_wait, &wait); 106633f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox 106733f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox spin_lock_irqsave(&moxa_lock, flags); 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!tty_hung_up_p(filp)) 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->count++; 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->blocked_open--; 107133f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox spin_unlock_irqrestore(&moxa_lock, flags); 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef SERIAL_DEBUG_OPEN 10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("block_til_ready after blocking: ttys%d, count = %d\n", 10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->line, ch->count); 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (retval) 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (retval); 107833f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox /* FIXME: review to see if we need to use set_bit on these */ 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->asyncflags |= ASYNC_NORMAL_ACTIVE; 108033f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox return 0; 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void setup_empty_event(struct tty_struct *tty) 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch = tty->driver_data; 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 108833f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox spin_lock_irqsave(&moxa_lock, flags); 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->statusflags |= EMPTYWAIT; 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaEmptyTimer_on[ch->port] = 0; 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer(&moxaEmptyTimer[ch->port]); 10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaEmptyTimer[ch->port].expires = jiffies + HZ; 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaEmptyTimer_on[ch->port] = 1; 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add_timer(&moxaEmptyTimer[ch->port]); 109533f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox spin_unlock_irqrestore(&moxa_lock, flags); 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void check_xmit_empty(unsigned long data) 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct moxa_str *ch; 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch = (struct moxa_str *) data; 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaEmptyTimer_on[ch->port] = 0; 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds del_timer(&moxaEmptyTimer[ch->port]); 11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ch->tty && (ch->statusflags & EMPTYWAIT)) { 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (MoxaPortTxQueue(ch->port) == 0) { 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->statusflags &= ~EMPTYWAIT; 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tty_wakeup(ch->tty); 11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaEmptyTimer[ch->port].expires = jiffies + HZ; 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaEmptyTimer_on[ch->port] = 1; 11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add_timer(&moxaEmptyTimer[ch->port]); 11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->statusflags &= ~EMPTYWAIT; 11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void shut_down(struct moxa_str *ch) 11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct tty_struct *tp; 11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(ch->asyncflags & ASYNC_INITIALIZED)) 11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp = ch->tty; 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortDisable(ch->port); 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If we're a modem control device and HUPCL is on, drop RTS & DTR. 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tp->termios->c_cflag & HUPCL) 11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortLineCtrl(ch->port, 0, 0); 11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ch->asyncflags &= ~ASYNC_INITIALIZED; 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void receive_data(struct moxa_str *ch) 11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct tty_struct *tp; 11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct termios *ts; 11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ts = NULL; 11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tp = ch->tty; 11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tp) 11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ts = tp->termios; 11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /************************************************** 11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( !tp || !ts || !(ts->c_cflag & CREAD) ) { 11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************/ 11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!tp || !ts) { 11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortFlushData(ch->port, 0); 11531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 11541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 115533f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox spin_lock_irqsave(&moxa_lock, flags); 115633f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox MoxaPortReadData(ch->port, tp); 115733f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox spin_unlock_irqrestore(&moxa_lock, flags); 115833f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox tty_schedule_flip(tp); 11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Magic_code 0x404 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * System Configuration 11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for C218 BIOS initialization 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218_ConfBase 0x800 11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218_status (C218_ConfBase + 0) /* BIOS running status */ 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218_diag (C218_ConfBase + 2) /* diagnostic status */ 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218_key (C218_ConfBase + 4) /* WORD (0x218 for C218) */ 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218DLoad_len (C218_ConfBase + 6) /* WORD */ 11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218check_sum (C218_ConfBase + 8) /* BYTE */ 11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218chksum_ok (C218_ConfBase + 0x0a) /* BYTE (1:ok) */ 11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218_TestRx (C218_ConfBase + 0x10) /* 8 bytes for 8 ports */ 11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218_TestTx (C218_ConfBase + 0x18) /* 8 bytes for 8 ports */ 11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218_RXerr (C218_ConfBase + 0x20) /* 8 bytes for 8 ports */ 11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218_ErrFlag (C218_ConfBase + 0x28) /* 8 bytes for 8 ports */ 11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218_LoadBuf 0x0F00 11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218_KeyCode 0x218 11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CP204J_KeyCode 0x204 11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for C320 BIOS initialization 11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320_ConfBase 0x800 11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320_LoadBuf 0x0f00 11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define STS_init 0x05 /* for C320_status */ 11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320_status C320_ConfBase + 0 /* BIOS running status */ 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320_diag C320_ConfBase + 2 /* diagnostic status */ 11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320_key C320_ConfBase + 4 /* WORD (0320H for C320) */ 11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320DLoad_len C320_ConfBase + 6 /* WORD */ 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320check_sum C320_ConfBase + 8 /* WORD */ 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320chksum_ok C320_ConfBase + 0x0a /* WORD (1:ok) */ 11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320bapi_len C320_ConfBase + 0x0c /* WORD */ 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320UART_no C320_ConfBase + 0x0e /* WORD */ 12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320_KeyCode 0x320 12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FixPage_addr 0x0000 /* starting addr of static page */ 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DynPage_addr 0x2000 /* starting addr of dynamic page */ 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218_start 0x3000 /* starting addr of C218 BIOS prg */ 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Control_reg 0x1ff0 /* select page and reset control */ 12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HW_reset 0x80 12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function Codes 12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_CardReset 0x80 12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_ChannelReset 1 /* C320 firmware not supported */ 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_EnableCH 2 12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_DisableCH 3 12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetParam 4 12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetMode 5 12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetRate 6 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_LineControl 7 12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_LineStatus 8 12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_XmitControl 9 12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_FlushQueue 10 12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SendBreak 11 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_StopBreak 12 12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_LoopbackON 13 12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_LoopbackOFF 14 12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_ClrIrqTable 15 12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SendXon 16 12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetTermIrq 17 /* C320 firmware not supported */ 12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetCntIrq 18 /* C320 firmware not supported */ 12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetBreakIrq 19 12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetLineIrq 20 12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetFlowCtl 21 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_GenIrq 22 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_InCD180 23 12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_OutCD180 24 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_InUARTreg 23 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_OutUARTreg 24 12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetXonXoff 25 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_OutCD180CCR 26 12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_ExtIQueue 27 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_ExtOQueue 28 12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_ClrLineIrq 29 12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_HWFlowCtl 30 12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_GetClockRate 35 12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetBaud 36 12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetDataMode 41 12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_GetCCSR 43 12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_GetDataError 45 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_RxControl 50 12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_ImmSend 51 12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetXonState 52 12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetXoffState 53 12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetRxFIFOTrig 54 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_SetTxFIFOCnt 55 12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_UnixRate 56 12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FC_UnixResetTimer 57 12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RxFIFOTrig1 0 12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RxFIFOTrig4 1 12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RxFIFOTrig8 2 12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RxFIFOTrig14 3 12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Dual-Ported RAM 12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DRAM_global 0 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define INT_data (DRAM_global + 0) 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Config_base (DRAM_global + 0x108) 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IRQindex (INT_data + 0) 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IRQpending (INT_data + 4) 12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IRQtable (INT_data + 8) 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Interrupt Status 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IntrRx 0x01 /* receiver data O.K. */ 12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IntrTx 0x02 /* transmit buffer empty */ 12801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IntrFunc 0x04 /* function complete */ 12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IntrBreak 0x08 /* received break */ 12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IntrLine 0x10 /* line status change 12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for transmitter */ 12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IntrIntr 0x20 /* received INTR code */ 12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IntrQuit 0x40 /* received QUIT code */ 12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IntrEOF 0x80 /* received EOF code */ 12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IntrRxTrigger 0x100 /* rx data count reach tigger value */ 12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IntrTxTrigger 0x200 /* tx data count below trigger value */ 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Magic_no (Config_base + 0) 12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Card_model_no (Config_base + 2) 12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Total_ports (Config_base + 4) 12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Module_cnt (Config_base + 8) 12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Module_no (Config_base + 10) 12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Timer_10ms (Config_base + 14) 12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Disable_IRQ (Config_base + 20) 12981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TMS320_PORT1 (Config_base + 22) 12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TMS320_PORT2 (Config_base + 24) 13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TMS320_CLOCK (Config_base + 26) 13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * DATA BUFFER in DRAM 13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Extern_table 0x400 /* Base address of the external table 13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (24 words * 64) total 3K bytes 13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (24 words * 128) total 6K bytes */ 13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Extern_size 0x60 /* 96 bytes */ 13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RXrptr 0x00 /* read pointer for RX buffer */ 13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RXwptr 0x02 /* write pointer for RX buffer */ 13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TXrptr 0x04 /* read pointer for TX buffer */ 13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TXwptr 0x06 /* write pointer for TX buffer */ 13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HostStat 0x08 /* IRQ flag and general flag */ 13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FlagStat 0x0A 13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FlowControl 0x0C /* B7 B6 B5 B4 B3 B2 B1 B0 */ 13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* x x x x | | | | */ 13171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* | | | + CTS flow */ 13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* | | +--- RTS flow */ 13191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* | +------ TX Xon/Xoff */ 13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* +--------- RX Xon/Xoff */ 13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Break_cnt 0x0E /* received break count */ 13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CD180TXirq 0x10 /* if non-0: enable TX irq */ 13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RX_mask 0x12 13241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TX_mask 0x14 13251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Ofs_rxb 0x16 13261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Ofs_txb 0x18 13271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Page_rxb 0x1A 13281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Page_txb 0x1C 13291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define EndPage_rxb 0x1E 13301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define EndPage_txb 0x20 13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Data_error 0x22 13321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RxTrigger 0x28 13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TxTrigger 0x2a 13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define rRXwptr 0x34 13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Low_water 0x36 13371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FuncCode 0x40 13391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FuncArg 0x42 13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FuncArg1 0x44 13411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218rx_size 0x2000 /* 8K bytes */ 13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218tx_size 0x8000 /* 32K bytes */ 13441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218rx_mask (C218rx_size - 1) 13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218tx_mask (C218tx_size - 1) 13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8rx_size 0x2000 13491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8tx_size 0x8000 13501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8rx_mask (C320p8rx_size - 1) 13511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8tx_mask (C320p8tx_size - 1) 13521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16rx_size 0x2000 13541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16tx_size 0x4000 13551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16rx_mask (C320p16rx_size - 1) 13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16tx_mask (C320p16tx_size - 1) 13571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p24rx_size 0x2000 13591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p24tx_size 0x2000 13601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p24rx_mask (C320p24rx_size - 1) 13611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p24tx_mask (C320p24tx_size - 1) 13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p32rx_size 0x1000 13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p32tx_size 0x1000 13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p32rx_mask (C320p32rx_size - 1) 13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p32tx_mask (C320p32tx_size - 1) 13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Page_size 0x2000 13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Page_mask (Page_size - 1) 13701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218rx_spage 3 13711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218tx_spage 4 13721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218rx_pageno 1 13731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218tx_pageno 4 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C218buf_pageno 5 13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8rx_spage 3 13771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8tx_spage 4 13781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8rx_pgno 1 13791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8tx_pgno 4 13801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p8buf_pgno 5 13811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16rx_spage 3 13831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16tx_spage 4 13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16rx_pgno 1 13851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16tx_pgno 2 13861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p16buf_pgno 3 13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p24rx_spage 3 13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p24tx_spage 4 13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p24rx_pgno 1 13911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p24tx_pgno 1 13921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p24buf_pgno 2 13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p32rx_spage 3 13951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p32tx_ofs C320p32rx_size 13961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p32tx_spage 3 13971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define C320p32buf_pgno 1 13981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Host Status 14011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 14021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WakeupRx 0x01 14031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WakeupTx 0x02 14041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WakeupBreak 0x08 14051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WakeupLine 0x10 14061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WakeupIntr 0x20 14071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WakeupQuit 0x40 14081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WakeupEOF 0x80 /* used in VTIME control */ 14091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WakeupRxTrigger 0x100 14101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define WakeupTxTrigger 0x200 14111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 14121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Flag status 14131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 14141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Rx_over 0x01 14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Xoff_state 0x02 14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Tx_flowOff 0x04 14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Tx_enable 0x08 14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CTS_state 0x10 14191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DSR_state 0x20 14201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DCD_state 0x80 14211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 14221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FlowControl 14231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 14241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CTS_FlowCtl 1 14251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RTS_FlowCtl 2 14261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Tx_FlowCtl 4 14271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define Rx_FlowCtl 8 14281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IXM_IXANY 0x10 14291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LowWater 128 14311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DTR_ON 1 14331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RTS_ON 2 14341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CTS_ON 1 14351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DSR_ON 2 14361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DCD_ON 8 14371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* mode definition */ 14391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MX_CS8 0x03 14401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MX_CS7 0x02 14411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MX_CS6 0x01 14421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MX_CS5 0x00 14431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MX_STOP1 0x00 14451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MX_STOP15 0x04 14461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MX_STOP2 0x08 14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MX_PARNONE 0x00 14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MX_PAREVEN 0x40 14501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MX_PARODD 0xC0 14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 14531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Query 14541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 14551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define QueryPort MAX_PORTS 14561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct mon_str { 14601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int tick; 14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rxcnt[MAX_PORTS]; 14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int txcnt[MAX_PORTS]; 14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 14641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef struct mon_str mon_st; 14651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DCD_changed 0x01 14671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DCD_oldstate 0x80 14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned char moxaBuff[10240]; 14701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __iomem *moxaIntNdx[MAX_BOARDS]; 14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __iomem *moxaIntPend[MAX_BOARDS]; 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __iomem *moxaIntTable[MAX_BOARDS]; 14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char moxaChkPort[MAX_PORTS]; 14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char moxaLineCtrl[MAX_PORTS]; 14751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __iomem *moxaTableAddr[MAX_PORTS]; 14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic long moxaCurBaud[MAX_PORTS]; 14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char moxaDCDState[MAX_PORTS]; 14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char moxaLowChkFlag[MAX_PORTS]; 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaLowWaterChk; 14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaCard; 14811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic mon_st moxaLog; 14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaFuncTout; 14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ushort moxaBreakCnt[MAX_PORTS]; 14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxadelay(int); 14861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxafunc(void __iomem *, int, ushort); 14871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void wait_finish(void __iomem *); 14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void low_water_check(void __iomem *); 14891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaloadbios(int, unsigned char __user *, int); 14901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxafindcard(int); 14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaload320b(int, unsigned char __user *, int); 14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaloadcode(int, unsigned char __user *, int); 14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaloadc218(int, void __iomem *, int); 14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaloadc320(int, void __iomem *, int, int *); 14951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************************************************************** 14971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Driver level functions: * 14981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. MoxaDriverInit(void); * 14991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port); * 15001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. MoxaDriverPoll(void); * 15011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/ 15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid MoxaDriverInit(void) 15031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 15051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaFuncTout = HZ / 2; /* 500 mini-seconds */ 15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaCard = 0; 15081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLog.tick = 0; 15091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLowWaterChk = 0; 15101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_PORTS; i++) { 15111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaChkPort[i] = 0; 15121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLowChkFlag[i] = 0; 15131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLineCtrl[i] = 0; 15141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLog.rxcnt[i] = 0; 15151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLog.txcnt[i] = 0; 15161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA 0x400 15201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_GET_IQUEUE (MOXA + 1) /* get input buffered count */ 15211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_GET_OQUEUE (MOXA + 2) /* get output buffered count */ 15221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_INIT_DRIVER (MOXA + 6) /* moxaCard=0 */ 15231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_LOAD_BIOS (MOXA + 9) /* download BIOS */ 15241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_FIND_BOARD (MOXA + 10) /* Check if MOXA card exist? */ 15251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_LOAD_C320B (MOXA + 11) /* download 320B firmware */ 15261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_LOAD_CODE (MOXA + 12) /* download firmware */ 15271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_GETDATACOUNT (MOXA + 23) 15281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_GET_IOQUEUE (MOXA + 27) 15291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_FLUSH_QUEUE (MOXA + 28) 15301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_GET_CONF (MOXA + 35) /* configuration */ 15311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_GET_MAJOR (MOXA + 63) 15321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_GET_CUMAJOR (MOXA + 64) 15331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOXA_GETMSTATUS (MOXA + 65) 15341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct moxaq_str { 15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int inq; 15381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int outq; 15391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 15401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct dl_str { 15421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char __user *buf; 15431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len; 15441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cardno; 15451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 15461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct moxaq_str temp_queue[MAX_PORTS]; 15481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct dl_str dltmp; 15491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid MoxaPortFlushData(int port, int mode) 15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((mode < 0) || (mode > 2)) 15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 15551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_FlushQueue, mode); 15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mode != 1) { 15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLowChkFlag[port] = 0; 15591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds low_water_check(ofsAddr); 15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port) 15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 15661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int status; 15671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int MoxaPortTxQueue(int), MoxaPortRxQueue(int); 15681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __user *argp = (void __user *)arg; 15691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (port == QueryPort) { 15711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((cmd != MOXA_GET_CONF) && (cmd != MOXA_INIT_DRIVER) && 15721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (cmd != MOXA_LOAD_BIOS) && (cmd != MOXA_FIND_BOARD) && (cmd != MOXA_LOAD_C320B) && 15731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (cmd != MOXA_LOAD_CODE) && (cmd != MOXA_GETDATACOUNT) && 15741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (cmd != MOXA_GET_IOQUEUE) && (cmd != MOXA_GET_MAJOR) && 15751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (cmd != MOXA_GET_CUMAJOR) && (cmd != MOXA_GETMSTATUS)) 15761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-EINVAL); 15771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cmd) { 15791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_GET_CONF: 15801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_to_user(argp, &moxa_boards, MAX_BOARDS * sizeof(moxa_board_conf))) 15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 15821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 15831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_INIT_DRIVER: 15841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((int) arg == 0x404) 15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaDriverInit(); 15861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_GETDATACOUNT: 15881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLog.tick = jiffies; 15891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_to_user(argp, &moxaLog, sizeof(mon_st))) 15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 15911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 15921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_FLUSH_QUEUE: 15931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortFlushData(port, arg); 15941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 15951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_GET_IOQUEUE: 15961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_PORTS; i++) { 15971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaChkPort[i]) { 15981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds temp_queue[i].inq = MoxaPortRxQueue(i); 15991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds temp_queue[i].outq = MoxaPortTxQueue(i); 16001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_to_user(argp, temp_queue, sizeof(struct moxaq_str) * MAX_PORTS)) 16031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 16041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 16051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_GET_OQUEUE: 16061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = MoxaPortTxQueue(port); 16071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return put_user(i, (unsigned long __user *)argp); 16081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_GET_IQUEUE: 16091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = MoxaPortRxQueue(port); 16101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return put_user(i, (unsigned long __user *)argp); 16111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_GET_MAJOR: 16121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_to_user(argp, &ttymajor, sizeof(int))) 16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 16141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 16151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_GET_CUMAJOR: 16161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = 0; 16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_to_user(argp, &i, sizeof(int))) 16181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 16191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 16201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_GETMSTATUS: 16211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < MAX_PORTS; i++) { 16221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].ri = 0; 16231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].dcd = 0; 16241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].dsr = 0; 16251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].cts = 0; 16261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!moxaChkPort[i]) { 16271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 16281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 16291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = MoxaPortLineStatus(moxaChannels[i].port); 16301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status & 1) 16311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].cts = 1; 16321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status & 2) 16331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].dsr = 1; 16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status & 4) 16351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].dcd = 1; 16361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!moxaChannels[i].tty || !moxaChannels[i].tty->termios) 16391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].cflag = moxaChannels[i].cflag; 16401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 16411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GMStatus[i].cflag = moxaChannels[i].tty->termios->c_cflag; 16421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_to_user(argp, GMStatus, sizeof(struct mxser_mstatus) * MAX_PORTS)) 16441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 16451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 16461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 16471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-ENOIOCTLCMD); 16481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_LOAD_BIOS: 16491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_FIND_BOARD: 16501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_LOAD_C320B: 16511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_LOAD_CODE: 16521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 16531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_from_user(&dltmp, argp, sizeof(struct dl_str))) 16561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 16571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS) 16581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 16591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(cmd) 16611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 16621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_LOAD_BIOS: 16631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = moxaloadbios(dltmp.cardno, dltmp.buf, dltmp.len); 16641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (i); 16651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_FIND_BOARD: 16661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return moxafindcard(dltmp.cardno); 16671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_LOAD_C320B: 16681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaload320b(dltmp.cardno, dltmp.buf, dltmp.len); 16691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: /* to keep gcc happy */ 16701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 16711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_LOAD_CODE: 16721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = moxaloadcode(dltmp.cardno, dltmp.buf, dltmp.len); 16731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i == -1) 16741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-EFAULT); 16751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (i); 16761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 16781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaDriverPoll(void) 16811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register ushort temp; 16831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register int card; 16841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 16851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ip; 16861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int port, p, ports; 16871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaCard == 0) 16891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 16901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (card = 0; card < MAX_BOARDS; card++) { 16911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((ports = moxa_boards[card].numPorts) == 0) 16921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 16931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readb(moxaIntPend[card]) == 0xff) { 16941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ip = moxaIntTable[card] + readb(moxaIntNdx[card]); 16951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = card * MAX_PORTS_PER_BOARD; 16961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ports <<= 1; 16971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (port = 0; port < ports; port += 2, p++) { 16981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((temp = readw(ip + port)) != 0) { 16991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0, ip + port); 17001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[p]; 17011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (temp & IntrTx) 17021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(readw(ofsAddr + HostStat) & ~WakeupTx, ofsAddr + HostStat); 17031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (temp & IntrBreak) { 17041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaBreakCnt[p]++; 17051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (temp & IntrLine) { 17071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readb(ofsAddr + FlagStat) & DCD_state) { 17081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((moxaDCDState[p] & DCD_oldstate) == 0) 17091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDCDState[p] = (DCD_oldstate | 17101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DCD_changed); 17111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 17121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaDCDState[p] & DCD_oldstate) 17131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDCDState[p] = DCD_changed; 17141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(0, moxaIntPend[card]); 17191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaLowWaterChk) { 17211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p = card * MAX_PORTS_PER_BOARD; 17221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (port = 0; port < ports; port++, p++) { 17231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaLowChkFlag[p]) { 17241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLowChkFlag[p] = 0; 17251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[p]; 17261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds low_water_check(ofsAddr); 17271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 17311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLowWaterChk = 0; 17321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 17331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************************************************************** 17361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Card level function: * 17371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. MoxaPortsOfCard(int cardno); * 17381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/ 17391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortsOfCard(int cardno) 17401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 17411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxa_boards[cardno].boardType == 0) 17431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 17441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (moxa_boards[cardno].numPorts); 17451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 17461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************************************************************** 17481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Port level functions: * 17491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1. MoxaPortIsValid(int port); * 17501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2. MoxaPortEnable(int port); * 17511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3. MoxaPortDisable(int port); * 17521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4. MoxaPortGetMaxBaud(int port); * 17531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5. MoxaPortGetCurBaud(int port); * 17541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 6. MoxaPortSetBaud(int port, long baud); * 17551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7. MoxaPortSetMode(int port, int databit, int stopbit, int parity); * 17561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8. MoxaPortSetTermio(int port, unsigned char *termio); * 17571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9. MoxaPortGetLineOut(int port, int *dtrState, int *rtsState); * 17581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 10. MoxaPortLineCtrl(int port, int dtrState, int rtsState); * 17591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 11. MoxaPortFlowCtrl(int port, int rts, int cts, int rx, int tx,int xany); * 17601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 12. MoxaPortLineStatus(int port); * 17611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 13. MoxaPortDCDChange(int port); * 17621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 14. MoxaPortDCDON(int port); * 17631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 15. MoxaPortFlushData(int port, int mode); * 17641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 16. MoxaPortWriteData(int port, unsigned char * buffer, int length); * 176533f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox * 17. MoxaPortReadData(int port, struct tty_struct *tty); * 17661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18. MoxaPortTxBufSize(int port); * 17671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19. MoxaPortRxBufSize(int port); * 17681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20. MoxaPortTxQueue(int port); * 17691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 21. MoxaPortTxFree(int port); * 17701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 22. MoxaPortRxQueue(int port); * 17711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 23. MoxaPortRxFree(int port); * 17721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 24. MoxaPortTxDisable(int port); * 17731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 25. MoxaPortTxEnable(int port); * 17741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 26. MoxaPortGetBrkCnt(int port); * 17751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 27. MoxaPortResetBrkCnt(int port); * 17761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 28. MoxaPortSetXonXoff(int port, int xonValue, int xoffValue); * 17771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 29. MoxaPortIsTxHold(int port); * 17781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 30. MoxaPortSendBreak(int port, int ticks); * 17791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/ 17801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 17811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Moxa Port Number Description: 17821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 17831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MOXA serial driver supports up to 4 MOXA-C218/C320 boards. And, 17841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the port number using in MOXA driver functions will be 0 to 31 for 17851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * first MOXA board, 32 to 63 for second, 64 to 95 for third and 96 17861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to 127 for fourth. For example, if you setup three MOXA boards, 17871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * first board is C218, second board is C320-16 and third board is 17881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * C320-32. The port number of first board (C218 - 8 ports) is from 17891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 to 7. The port number of second board (C320 - 16 ports) is form 17901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 32 to 47. The port number of third board (C320 - 32 ports) is from 17911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 64 to 95. And those port numbers form 8 to 31, 48 to 63 and 96 to 17921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 127 will be invalid. 17931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 17941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 17951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Moxa Functions Description: 17961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 17971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 1: Driver initialization routine, this routine must be 17981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * called when initialized driver. 17991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaDriverInit(); 18011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 2: Moxa driver private IOCTL command processing. 18041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port); 18061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * unsigned int cmd : IOCTL command 18081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * unsigned long arg : IOCTL argument 18091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 18101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 (OK) 18121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * -EINVAL 18131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * -ENOIOCTLCMD 18141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 3: Moxa driver polling process routine. 18171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaDriverPoll(void); 18191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 ; polling O.K. 18211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * -1 : no any Moxa card. 18221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 4: Get the ports of this card. 18251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortsOfCard(int cardno); 18271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int cardno : card number (0 - 3) 18291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : this card is invalid 18311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8/16/24/32 18321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 5: Check this port is valid or invalid 18351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortIsValid(int port); 18371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127, ref port description) 18381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : this port is invalid 18401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1 : this port is valid 18411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 6: Enable this port to start Tx/Rx data. 18441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaPortEnable(int port); 18461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 18471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 7: Disable this port 18501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaPortDisable(int port); 18521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 18531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 8: Get the maximun available baud rate of this port. 18561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * long MoxaPortGetMaxBaud(int port); 18581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 18591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : this port is invalid 18611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 38400/57600/115200 bps 18621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 9: Get the current baud rate of this port. 18651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * long MoxaPortGetCurBaud(int port); 18671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 18681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : this port is invalid 18701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 50 - 115200 bps 18711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 10: Setting baud rate of this port. 18741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * long MoxaPortSetBaud(int port, long baud); 18761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 18771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * long baud : baud rate (50 - 115200) 18781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : this port is invalid or baud < 50 18801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 50 - 115200 : the real baud rate set to the port, if 18811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the argument baud is large than maximun 18821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * available baud rate, the real setting 18831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * baud rate will be the maximun baud rate. 18841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 11: Setting the data-bits/stop-bits/parity of this port 18871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 18881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortSetMode(int port, int databits, int stopbits, int parity); 18891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 18901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int databits : data bits (8/7/6/5) 18911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int stopbits : stop bits (2/1/0, 0 show 1.5 stop bits) 18921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int parity : parity (0:None,1:Odd,2:Even,3:Mark,4:Space) 18931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: -1 : invalid parameter 18951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 : setting O.K. 18961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 18981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 12: Configure the port. 18991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 19001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortSetTermio(int port, struct termios *termio); 19011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * struct termios * termio : termio structure pointer 19031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: -1 : this port is invalid or termio == NULL 19051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 : setting O.K. 19061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 13: Get the DTR/RTS state of this port. 19091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 19101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortGetLineOut(int port, int *dtrState, int *rtsState); 19111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int * dtrState : pointer to INT to receive the current DTR 19131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * state. (if NULL, this function will not 19141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * write to this address) 19151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int * rtsState : pointer to INT to receive the current RTS 19161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * state. (if NULL, this function will not 19171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * write to this address) 19181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: -1 : this port is invalid 19201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 : O.K. 19211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 14: Setting the DTR/RTS output state of this port. 19241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 19251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaPortLineCtrl(int port, int dtrState, int rtsState); 19261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int dtrState : DTR output state (0: off, 1: on) 19281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int rtsState : RTS output state (0: off, 1: on) 19291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 15: Setting the flow control of this port. 19321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 19331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaPortFlowCtrl(int port, int rtsFlow, int ctsFlow, int rxFlow, 19341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int txFlow,int xany); 19351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int rtsFlow : H/W RTS flow control (0: no, 1: yes) 19371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int ctsFlow : H/W CTS flow control (0: no, 1: yes) 19381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int rxFlow : S/W Rx XON/XOFF flow control (0: no, 1: yes) 19391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int txFlow : S/W Tx XON/XOFF flow control (0: no, 1: yes) 19401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int xany : S/W XANY flow control (0: no, 1: yes) 19411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 16: Get ths line status of this port 19441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 19451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortLineStatus(int port); 19461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: Bit 0 - CTS state (0: off, 1: on) 19491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 1 - DSR state (0: off, 1: on) 19501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bit 2 - DCD state (0: off, 1: on) 19511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 17: Check the DCD state has changed since the last read 19541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of this function. 19551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 19561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortDCDChange(int port); 19571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : no changed 19601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1 : DCD has changed 19611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 18: Check ths current DCD state is ON or not. 19641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 19651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortDCDON(int port); 19661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : DCD off 19691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1 : DCD on 19701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 19: Flush the Rx/Tx buffer data of this port. 19731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 19741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaPortFlushData(int port, int mode); 19751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int mode 19771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 : flush the Rx buffer 19781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1 : flush the Tx buffer 19791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2 : flush the Rx and Tx buffer 19801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 20: Write data. 19831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 19841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortWriteData(int port, unsigned char * buffer, int length); 19851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 19861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * unsigned char * buffer : pointer to write data buffer. 19871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int length : write data length 19881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 - length : real write data length 19901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 21: Read data. 19931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 199433f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox * int MoxaPortReadData(int port, struct tty_struct *tty); 19951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 199633f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox * struct tty_struct *tty : tty for data 19971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 19981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 - length : real read data length 19991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 22: Get the Tx buffer size of this port 20021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortTxBufSize(int port); 20041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: .. : Tx buffer size 20071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 23: Get the Rx buffer size of this port 20101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortRxBufSize(int port); 20121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: .. : Rx buffer size 20151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 24: Get the Tx buffer current queued data bytes 20181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortTxQueue(int port); 20201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: .. : Tx buffer current queued data bytes 20231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 25: Get the Tx buffer current free space 20261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortTxFree(int port); 20281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: .. : Tx buffer current free space 20311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 26: Get the Rx buffer current queued data bytes 20341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortRxQueue(int port); 20361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: .. : Rx buffer current queued data bytes 20391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 27: Get the Rx buffer current free space 20421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortRxFree(int port); 20441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: .. : Rx buffer current free space 20471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 28: Disable port data transmission. 20501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaPortTxDisable(int port); 20521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 29: Enable port data transmission. 20561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaPortTxEnable(int port); 20581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 30: Get the received BREAK signal count. 20621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortGetBrkCnt(int port); 20641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 - .. : BREAK signal count 20671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 31: Get the received BREAK signal count and reset it. 20701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortResetBrkCnt(int port); 20721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 - .. : BREAK signal count 20751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 32: Set the S/W flow control new XON/XOFF value, default 20781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * XON is 0x11 & XOFF is 0x13. 20791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaPortSetXonXoff(int port, int xonValue, int xoffValue); 20811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int xonValue : new XON value (0 - 255) 20831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int xoffValue : new XOFF value (0 - 255) 20841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 33: Check this port's transmission is hold by remote site 20871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * because the flow control. 20881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int MoxaPortIsTxHold(int port); 20901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 20911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * return: 0 : normal 20931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1 : hold by remote site 20941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 20961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Function 34: Send out a BREAK signal. 20971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Syntax: 20981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * void MoxaPortSendBreak(int port, int ms100); 20991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int port : port number (0 - 127) 21001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * int ms100 : break signal time interval. 21011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * unit: 100 mini-second. if ms100 == 0, it will 21021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * send out a about 250 ms BREAK signal. 21031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 21041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 21051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortIsValid(int port) 21061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 21071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaCard == 0) 21091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 21101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaChkPort[port] == 0) 21111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 21121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (1); 21131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 21141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid MoxaPortEnable(int port) 21161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 21171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 21181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int MoxaPortLineStatus(int); 21191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds short lowwater = 512; 21201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 21221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(lowwater, ofsAddr + Low_water); 21231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaBreakCnt[port] = 0; 21241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || 21251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) { 21261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SetBreakIrq, 0); 21271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 21281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(readw(ofsAddr + HostStat) | WakeupBreak, ofsAddr + HostStat); 21291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 21301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SetLineIrq, Magic_code); 21321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_FlushQueue, 2); 21331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_EnableCH, Magic_code); 21351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortLineStatus(port); 21361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 21371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid MoxaPortDisable(int port) 21391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 21401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr = moxaTableAddr[port]; 21411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SetFlowCtl, 0); /* disable flow control */ 21431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_ClrLineIrq, Magic_code); 21441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0, ofsAddr + HostStat); 21451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_DisableCH, Magic_code); 21461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 21471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldslong MoxaPortGetMaxBaud(int port) 21491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 21501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || 21511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) 21521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (460800L); 21531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 21541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (921600L); 21551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 21561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldslong MoxaPortSetBaud(int port, long baud) 21591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 21601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 21611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long max, clock; 21621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int val; 21631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((baud < 50L) || ((max = MoxaPortGetMaxBaud(port)) == 0)) 21651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 21661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 21671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (baud > max) 21681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = max; 21691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (max == 38400L) 21701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clock = 614400L; /* for 9.8304 Mhz : max. 38400 bps */ 21711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (max == 57600L) 21721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clock = 691200L; /* for 11.0592 Mhz : max. 57600 bps */ 21731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 21741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clock = 921600L; /* for 14.7456 Mhz : max. 115200 bps */ 21751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = clock / baud; 21761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SetBaud, val); 21771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = clock / val; 21781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaCurBaud[port] = baud; 21791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (baud); 21801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 21811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortSetTermio(int port, struct termios *termio) 21831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 21841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 21851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tcflag_t cflag; 21861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long baud; 21871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tcflag_t mode = 0; 21881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaChkPort[port] == 0 || termio == 0) 21901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 21911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 21921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cflag = termio->c_cflag; /* termio->c_cflag */ 21931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode = termio->c_cflag & CSIZE; 21951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mode == CS5) 21961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode = MX_CS5; 21971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (mode == CS6) 21981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode = MX_CS6; 21991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (mode == CS7) 22001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode = MX_CS7; 22011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (mode == CS8) 22021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode = MX_CS8; 22031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (termio->c_cflag & CSTOPB) { 22051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mode == MX_CS5) 22061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode |= MX_STOP15; 22071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 22081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode |= MX_STOP2; 22091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 22101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode |= MX_STOP1; 22111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (termio->c_cflag & PARENB) { 22131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (termio->c_cflag & PARODD) 22141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode |= MX_PARODD; 22151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 22161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode |= MX_PAREVEN; 22171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 22181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode |= MX_PARNONE; 22191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SetDataMode, (ushort) mode); 22211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cflag &= (CBAUD | CBAUDEX); 22231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef B921600 22241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define B921600 (B460800+1) 22251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 22261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (cflag) { 22271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B921600: 22281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 921600L; 22291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B460800: 22311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 460800L; 22321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B230400: 22341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 230400L; 22351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B115200: 22371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 115200L; 22381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B57600: 22401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 57600L; 22411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B38400: 22431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 38400L; 22441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B19200: 22461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 19200L; 22471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B9600: 22491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 9600L; 22501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B4800: 22521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 4800L; 22531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B2400: 22551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 2400L; 22561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B1800: 22581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 1800L; 22591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B1200: 22611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 1200L; 22621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B600: 22641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 600L; 22651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B300: 22671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 300L; 22681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B200: 22701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 200L; 22711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B150: 22731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 150L; 22741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B134: 22761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 134L; 22771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B110: 22791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 110L; 22801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B75: 22821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 75L; 22831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case B50: 22851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 50L; 22861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 22871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 22881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baud = 0; 22891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || 22911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) { 22921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (baud == 921600L) 22931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 22941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 22951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaPortSetBaud(port, baud); 22961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (termio->c_iflag & (IXON | IXOFF | IXANY)) { 22981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(termio->c_cc[VSTART], ofsAddr + FuncArg); 22991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1); 23001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(FC_SetXonXoff, ofsAddr + FuncCode); 23011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wait_finish(ofsAddr); 23021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 23051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 23061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortGetLineOut(int port, int *dtrState, int *rtsState) 23081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 23091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!MoxaPortIsValid(port)) 23111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 23121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dtrState) { 23131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaLineCtrl[port] & DTR_ON) 23141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *dtrState = 1; 23151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 23161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *dtrState = 0; 23171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rtsState) { 23191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaLineCtrl[port] & RTS_ON) 23201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *rtsState = 1; 23211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 23221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *rtsState = 0; 23231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 23251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 23261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid MoxaPortLineCtrl(int port, int dtr, int rts) 23281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 23291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 23301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int mode; 23311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 23331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode = 0; 23341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dtr) 23351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode |= DTR_ON; 23361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rts) 23371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode |= RTS_ON; 23381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLineCtrl[port] = mode; 23391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_LineControl, mode); 23401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 23411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid MoxaPortFlowCtrl(int port, int rts, int cts, int txflow, int rxflow, int txany) 23431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 23441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 23451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int mode; 23461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 23481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode = 0; 23491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rts) 23501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode |= RTS_FlowCtl; 23511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cts) 23521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode |= CTS_FlowCtl; 23531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (txflow) 23541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode |= Tx_FlowCtl; 23551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rxflow) 23561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode |= Rx_FlowCtl; 23571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (txany) 23581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mode |= IXM_IXANY; 23591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SetFlowCtl, mode); 23601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 23611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortLineStatus(int port) 23631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 23641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 23651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int val; 23661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 23681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || 23691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) { 23701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_LineStatus, 0); 23711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = readw(ofsAddr + FuncArg); 23721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 23731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = readw(ofsAddr + FlagStat) >> 4; 23741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val &= 0x0B; 23761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (val & 8) { 23771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val |= 4; 23781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((moxaDCDState[port] & DCD_oldstate) == 0) 23791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDCDState[port] = (DCD_oldstate | DCD_changed); 23801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 23811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaDCDState[port] & DCD_oldstate) 23821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDCDState[port] = DCD_changed; 23831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 23841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val &= 7; 23851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (val); 23861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 23871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortDCDChange(int port) 23891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 23901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int n; 23911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaChkPort[port] == 0) 23931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 23941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = moxaDCDState[port]; 23951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDCDState[port] &= ~DCD_changed; 23961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n &= DCD_changed; 23971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (n); 23981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 23991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortDCDON(int port) 24011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 24021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int n; 24031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaChkPort[port] == 0) 24051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 24061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaDCDState[port] & DCD_oldstate) 24071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = 1; 24081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 24091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds n = 0; 24101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (n); 24111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 24121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 24151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int MoxaDumpMem(int port, unsigned char * buffer, int len) 24161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 24171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 24181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long baseAddr,ofsAddr,ofs; 24191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD]; 24211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofs = baseAddr + DynPage_addr + pageofs; 24221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (len > 0x2000L) 24231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 0x2000L; 24241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < len; i++) 24251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer[i] = readb(ofs+i); 24261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 24271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 24281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortWriteData(int port, unsigned char * buffer, int len) 24311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 24321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int c, total, i; 24331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort tail; 24341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cnt; 24351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort head, tx_mask, spage, epage; 24361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort pageno, pageofs, bufhead; 24371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *baseAddr, *ofsAddr, *ofs; 24381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 24401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD]; 24411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tx_mask = readw(ofsAddr + TX_mask); 24421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spage = readw(ofsAddr + Page_txb); 24431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds epage = readw(ofsAddr + EndPage_txb); 24441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tail = readw(ofsAddr + TXwptr); 24451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds head = readw(ofsAddr + TXrptr); 24461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = (head > tail) ? (head - tail - 1) 24471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds : (head - tail + tx_mask); 24481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c > len) 24491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c = len; 24501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLog.txcnt[port] += c; 24511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds total = c; 24521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (spage == epage) { 24531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bufhead = readw(ofsAddr + Ofs_txb); 24541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(spage, baseAddr + Control_reg); 24551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (c > 0) { 24561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (head > tail) 24571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = head - tail - 1; 24581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 24591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = tx_mask + 1 - tail; 24601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = (c > len) ? len : c; 24611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofs = baseAddr + DynPage_addr + bufhead + tail; 24621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < len; i++) 24631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(*buffer++, ofs + i); 24641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tail = (tail + len) & tx_mask; 24651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c -= len; 24661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 24671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(tail, ofsAddr + TXwptr); 24681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 24691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = c; 24701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pageno = spage + (tail >> 13); 24711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pageofs = tail & Page_mask; 24721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do { 24731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cnt = Page_size - pageofs; 24741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cnt > c) 24751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cnt = c; 24761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds c -= cnt; 24771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(pageno, baseAddr + Control_reg); 24781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofs = baseAddr + DynPage_addr + pageofs; 24791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < cnt; i++) 24801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(*buffer++, ofs + i); 24811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c == 0) { 24821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew((tail + len) & tx_mask, ofsAddr + TXwptr); 24831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 24841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 24851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (++pageno == epage) 24861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pageno = spage; 24871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pageofs = 0; 24881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } while (1); 24891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 24901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(1, ofsAddr + CD180TXirq); /* start to send */ 24911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (total); 24921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 24931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 249433f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Coxint MoxaPortReadData(int port, struct tty_struct *tty) 24951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 24961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds register ushort head, pageofs; 24971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, count, cnt, len, total, remain; 24981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort tail, rx_mask, spage, epage; 24991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort pageno, bufhead; 25001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *baseAddr, *ofsAddr, *ofs; 25011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 25031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD]; 25041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds head = readw(ofsAddr + RXrptr); 25051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tail = readw(ofsAddr + RXwptr); 25061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rx_mask = readw(ofsAddr + RX_mask); 25071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spage = readw(ofsAddr + Page_rxb); 25081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds epage = readw(ofsAddr + EndPage_rxb); 25091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = (tail >= head) ? (tail - head) 25101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds : (tail - head + rx_mask + 1); 25111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count == 0) 251233f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox return 0; 25131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251433f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox total = count; 25151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds remain = count - total; 25161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLog.rxcnt[port] += total; 25171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = total; 25181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (spage == epage) { 25191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bufhead = readw(ofsAddr + Ofs_rxb); 25201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(spage, baseAddr + Control_reg); 25211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (count > 0) { 25221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tail >= head) 25231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = tail - head; 25241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 25251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = rx_mask + 1 - head; 25261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = (count > len) ? len : count; 25271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofs = baseAddr + DynPage_addr + bufhead + head; 25281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < len; i++) 252933f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL); 25301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds head = (head + len) & rx_mask; 25311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count -= len; 25321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(head, ofsAddr + RXrptr); 25341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 25351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = count; 25361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pageno = spage + (head >> 13); 25371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pageofs = head & Page_mask; 25381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do { 25391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cnt = Page_size - pageofs; 25401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cnt > count) 25411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cnt = count; 25421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count -= cnt; 25431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(pageno, baseAddr + Control_reg); 25441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofs = baseAddr + DynPage_addr + pageofs; 25451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < cnt; i++) 254633f0f88f1c51ae5c2d593d26960c760ea154c2e2Alan Cox tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL); 25471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count == 0) { 25481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew((head + len) & rx_mask, ofsAddr + RXrptr); 25491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 25501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (++pageno == epage) 25521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pageno = spage; 25531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pageofs = 0; 25541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } while (1); 25551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((readb(ofsAddr + FlagStat) & Xoff_state) && (remain < LowWater)) { 25571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLowWaterChk = 1; 25581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaLowChkFlag[port] = 1; 25591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 25601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (total); 25611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 25621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortTxQueue(int port) 25651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 25661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 25671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort rptr, wptr, mask; 25681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len; 25691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 25711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rptr = readw(ofsAddr + TXrptr); 25721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wptr = readw(ofsAddr + TXwptr); 25731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask = readw(ofsAddr + TX_mask); 25741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = (wptr - rptr) & mask; 25751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (len); 25761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 25771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortTxFree(int port) 25791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 25801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 25811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort rptr, wptr, mask; 25821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len; 25831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 25851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rptr = readw(ofsAddr + TXrptr); 25861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wptr = readw(ofsAddr + TXwptr); 25871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask = readw(ofsAddr + TX_mask); 25881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = mask - ((wptr - rptr) & mask); 25891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (len); 25901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 25911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortRxQueue(int port) 25931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 25941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 25951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort rptr, wptr, mask; 25961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len; 25971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 25981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 25991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rptr = readw(ofsAddr + RXrptr); 26001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wptr = readw(ofsAddr + RXwptr); 26011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask = readw(ofsAddr + RX_mask); 26021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = (wptr - rptr) & mask; 26031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (len); 26041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 26051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid MoxaPortTxDisable(int port) 26081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 26091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 26101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 26121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SetXoffState, Magic_code); 26131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 26141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid MoxaPortTxEnable(int port) 26161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 26171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 26181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 26201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SetXonState, Magic_code); 26211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 26221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortResetBrkCnt(int port) 26251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 26261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort cnt; 26271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cnt = moxaBreakCnt[port]; 26281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaBreakCnt[port] = 0; 26291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (cnt); 26301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 26311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid MoxaPortSendBreak(int port, int ms100) 26341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 26351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 26361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 26381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ms100) { 26391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SendBreak, Magic_code); 26401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxadelay(ms100 * (HZ / 10)); 26411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 26421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SendBreak, Magic_code); 26431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxadelay(HZ / 4); /* 250 ms */ 26441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 26451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_StopBreak, Magic_code); 26461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 26471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_get_serial_info(struct moxa_str *info, 26491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct serial_struct __user *retinfo) 26501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 26511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct serial_struct tmp; 26521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(&tmp, 0, sizeof(tmp)); 26541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp.type = info->type; 26551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp.line = info->port; 26561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp.port = 0; 26571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp.irq = 0; 26581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp.flags = info->asyncflags; 26591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp.baud_base = 921600; 26601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp.close_delay = info->close_delay; 26611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp.closing_wait = info->closing_wait; 26621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp.custom_divisor = 0; 26631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp.hub6 = 0; 26641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_to_user(retinfo, &tmp, sizeof(*retinfo))) 26651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 26661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 26671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 26681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxa_set_serial_info(struct moxa_str *info, 26711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct serial_struct __user *new_info) 26721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 26731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct serial_struct new_serial; 26741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_from_user(&new_serial, new_info, sizeof(new_serial))) 26761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 26771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((new_serial.irq != 0) || 26791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (new_serial.port != 0) || 26801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds// (new_serial.type != info->type) || 26811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (new_serial.custom_divisor != 0) || 26821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (new_serial.baud_base != 921600)) 26831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-EPERM); 26841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!capable(CAP_SYS_ADMIN)) { 26861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (((new_serial.flags & ~ASYNC_USR_MASK) != 26871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (info->asyncflags & ~ASYNC_USR_MASK))) 26881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-EPERM); 26891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 26901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds info->close_delay = new_serial.close_delay * HZ / 100; 26911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds info->closing_wait = new_serial.closing_wait * HZ / 100; 26921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 26931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS); 26951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_serial.flags |= (info->asyncflags & ASYNC_FLAGS); 26961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (new_serial.type == PORT_16550A) { 26981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaSetFifo(info->port, 1); 26991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 27001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MoxaSetFifo(info->port, 0); 27011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 27021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds info->type = new_serial.type; 27041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 27051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 27061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/***************************************************************************** 27101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Static local functions: * 27111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *****************************************************************************/ 27121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 27131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * moxadelay - delays a specified number ticks 27141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 27151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxadelay(int tick) 27161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 27171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long st, et; 27181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds st = jiffies; 27201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds et = st + tick; 27211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (time_before(jiffies, et)); 27221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 27231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg) 27251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 27261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(arg, ofsAddr + FuncArg); 27281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(cmd, ofsAddr + FuncCode); 27291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wait_finish(ofsAddr); 27301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 27311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void wait_finish(void __iomem *ofsAddr) 27331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 27341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long i, j; 27351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = jiffies; 27371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (readw(ofsAddr + FuncCode) != 0) { 27381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds j = jiffies; 27391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((j - i) > moxaFuncTout) { 27401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 27411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 27421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 27431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 27441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void low_water_check(void __iomem *ofsAddr) 27461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 27471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len; 27481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort rptr, wptr, mask; 27491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readb(ofsAddr + FlagStat) & Xoff_state) { 27511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rptr = readw(ofsAddr + RXrptr); 27521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wptr = readw(ofsAddr + RXwptr); 27531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask = readw(ofsAddr + RX_mask); 27541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = (wptr - rptr) & mask; 27551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (len <= Low_water) 27561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SendXon, 0); 27571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 27581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 27591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaloadbios(int cardno, unsigned char __user *tmp, int len) 27611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 27621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *baseAddr; 27631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 27641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_from_user(moxaBuff, tmp, len)) 27661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 27671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baseAddr = moxaBaseAddr[cardno]; 27681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(HW_reset, baseAddr + Control_reg); /* reset */ 27691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxadelay(1); /* delay 10 ms */ 27701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 4096; i++) 27711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(0, baseAddr + i); /* clear fix page */ 27721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < len; i++) 27731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(moxaBuff[i], baseAddr + i); /* download BIOS */ 27741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(0, baseAddr + Control_reg); /* restart */ 27751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 27761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 27771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxafindcard(int cardno) 27791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 27801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *baseAddr; 27811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort tmp; 27821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baseAddr = moxaBaseAddr[cardno]; 27841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (moxa_boards[cardno].boardType) { 27851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_BOARD_C218_ISA: 27861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_BOARD_C218_PCI: 27871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((tmp = readw(baseAddr + C218_key)) != C218_KeyCode) { 27881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 27891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 27901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 27911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_BOARD_CP204J: 27921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((tmp = readw(baseAddr + C218_key)) != CP204J_KeyCode) { 27931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 27941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 27951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 27961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 27971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((tmp = readw(baseAddr + C320_key)) != C320_KeyCode) { 27981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 27991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 28001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((tmp = readw(baseAddr + C320_status)) != STS_init) { 28011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-2); 28021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 28031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 28041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 28051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 28061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaload320b(int cardno, unsigned char __user *tmp, int len) 28081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 28091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *baseAddr; 28101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 28111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(len > sizeof(moxaBuff)) 28131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 28141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_from_user(moxaBuff, tmp, len)) 28151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 28161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baseAddr = moxaBaseAddr[cardno]; 28171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(len - 7168 - 2, baseAddr + C320bapi_len); 28181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(1, baseAddr + Control_reg); /* Select Page 1 */ 28191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 7168; i++) 28201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(moxaBuff[i], baseAddr + DynPage_addr + i); 28211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(2, baseAddr + Control_reg); /* Select Page 2 */ 28221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < (len - 7168); i++) 28231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(moxaBuff[i + 7168], baseAddr + DynPage_addr + i); 28241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 28251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 28261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaloadcode(int cardno, unsigned char __user *tmp, int len) 28281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 28291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *baseAddr, *ofsAddr; 28301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int retval, port, i; 28311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(copy_from_user(moxaBuff, tmp, len)) 28331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 28341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds baseAddr = moxaBaseAddr[cardno]; 28351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (moxa_boards[cardno].boardType) { 28361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_BOARD_C218_ISA: 28371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_BOARD_C218_PCI: 28381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case MOXA_BOARD_CP204J: 28391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = moxaloadc218(cardno, baseAddr, len); 28401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (retval) 28411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (retval); 28421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds port = cardno * MAX_PORTS_PER_BOARD; 28431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) { 28441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaChkPort[port] = 1; 28451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaCurBaud[port] = 9600L; 28461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDCDState[port] = 0; 28471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaTableAddr[port] = baseAddr + Extern_table + Extern_size * i; 28481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 28491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C218rx_mask, ofsAddr + RX_mask); 28501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C218tx_mask, ofsAddr + TX_mask); 28511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C218rx_spage + i * C218buf_pageno, ofsAddr + Page_rxb); 28521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(readw(ofsAddr + Page_rxb) + C218rx_pageno, ofsAddr + EndPage_rxb); 28531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C218tx_spage + i * C218buf_pageno, ofsAddr + Page_txb); 28551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(readw(ofsAddr + Page_txb) + C218tx_pageno, ofsAddr + EndPage_txb); 28561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 28581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 28591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 28601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retval = moxaloadc320(cardno, baseAddr, len, 28611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &moxa_boards[cardno].numPorts); 28621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (retval) 28631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (retval); 28641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds port = cardno * MAX_PORTS_PER_BOARD; 28651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) { 28661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaChkPort[port] = 1; 28671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaCurBaud[port] = 9600L; 28681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaDCDState[port] = 0; 28691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaTableAddr[port] = baseAddr + Extern_table + Extern_size * i; 28701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 28711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxa_boards[cardno].numPorts == 8) { 28721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p8rx_mask, ofsAddr + RX_mask); 28731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p8tx_mask, ofsAddr + TX_mask); 28741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p8rx_spage + i * C320p8buf_pgno, ofsAddr + Page_rxb); 28751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(readw(ofsAddr + Page_rxb) + C320p8rx_pgno, ofsAddr + EndPage_rxb); 28761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p8tx_spage + i * C320p8buf_pgno, ofsAddr + Page_txb); 28771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(readw(ofsAddr + Page_txb) + C320p8tx_pgno, ofsAddr + EndPage_txb); 28781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (moxa_boards[cardno].numPorts == 16) { 28801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p16rx_mask, ofsAddr + RX_mask); 28811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p16tx_mask, ofsAddr + TX_mask); 28821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p16rx_spage + i * C320p16buf_pgno, ofsAddr + Page_rxb); 28831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(readw(ofsAddr + Page_rxb) + C320p16rx_pgno, ofsAddr + EndPage_rxb); 28841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p16tx_spage + i * C320p16buf_pgno, ofsAddr + Page_txb); 28851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(readw(ofsAddr + Page_txb) + C320p16tx_pgno, ofsAddr + EndPage_txb); 28861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (moxa_boards[cardno].numPorts == 24) { 28881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p24rx_mask, ofsAddr + RX_mask); 28891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p24tx_mask, ofsAddr + TX_mask); 28901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p24rx_spage + i * C320p24buf_pgno, ofsAddr + Page_rxb); 28911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(readw(ofsAddr + Page_rxb) + C320p24rx_pgno, ofsAddr + EndPage_rxb); 28921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p24tx_spage + i * C320p24buf_pgno, ofsAddr + Page_txb); 28931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb); 28941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (moxa_boards[cardno].numPorts == 32) { 28951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p32rx_mask, ofsAddr + RX_mask); 28961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p32tx_mask, ofsAddr + TX_mask); 28971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p32tx_ofs, ofsAddr + Ofs_txb); 28981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p32rx_spage + i * C320p32buf_pgno, ofsAddr + Page_rxb); 28991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(readb(ofsAddr + Page_rxb), ofsAddr + EndPage_rxb); 29001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(C320p32tx_spage + i * C320p32buf_pgno, ofsAddr + Page_txb); 29011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb); 29021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 29051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 29071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 29081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaloadc218(int cardno, void __iomem *baseAddr, int len) 29101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 29111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char retry; 29121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, j, len1, len2; 29131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort usum, *ptr, keycode; 29141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxa_boards[cardno].boardType == MOXA_BOARD_CP204J) 29161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds keycode = CP204J_KeyCode; 29171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 29181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds keycode = C218_KeyCode; 29191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usum = 0; 29201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len1 = len >> 1; 29211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ptr = (ushort *) moxaBuff; 29221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < len1; i++) 29231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usum += *(ptr + i); 29241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retry = 0; 29251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do { 29261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len1 = len >> 1; 29271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds j = 0; 29281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (len1) { 29291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len2 = (len1 > 2048) ? 2048 : len1; 29301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len1 -= len2; 29311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < len2 << 1; i++) 29321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(moxaBuff[i + j], baseAddr + C218_LoadBuf + i); 29331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds j += i; 29341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(len2, baseAddr + C218DLoad_len); 29361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0, baseAddr + C218_key); 29371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 100; i++) { 29381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + C218_key) == keycode) 29391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 29401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxadelay(1); /* delay 10 ms */ 29411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + C218_key) != keycode) { 29431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 29441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0, baseAddr + C218DLoad_len); 29471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(usum, baseAddr + C218check_sum); 29481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0, baseAddr + C218_key); 29491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 100; i++) { 29501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + C218_key) == keycode) 29511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 29521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxadelay(1); /* delay 10 ms */ 29531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retry++; 29551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } while ((readb(baseAddr + C218chksum_ok) != 1) && (retry < 3)); 29561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readb(baseAddr + C218chksum_ok) != 1) { 29571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 29581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0, baseAddr + C218_key); 29601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 100; i++) { 29611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + Magic_no) == Magic_code) 29621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 29631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxadelay(1); /* delay 10 ms */ 29641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + Magic_no) != Magic_code) { 29661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 29671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(1, baseAddr + Disable_IRQ); 29691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0, baseAddr + Magic_no); 29701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 100; i++) { 29711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + Magic_no) == Magic_code) 29721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 29731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxadelay(1); /* delay 10 ms */ 29741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + Magic_no) != Magic_code) { 29761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 29771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 29781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaCard = 1; 29791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaIntNdx[cardno] = baseAddr + IRQindex; 29801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaIntPend[cardno] = baseAddr + IRQpending; 29811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaIntTable[cardno] = baseAddr + IRQtable; 29821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 29831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 29841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int moxaloadc320(int cardno, void __iomem *baseAddr, int len, int *numPorts) 29861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 29871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort usum; 29881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, j, wlen, len2, retry; 29891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort *uptr; 29901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usum = 0; 29921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wlen = len >> 1; 29931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds uptr = (ushort *) moxaBuff; 29941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < wlen; i++) 29951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds usum += uptr[i]; 29961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retry = 0; 29971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds j = 0; 29981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do { 29991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (wlen) { 30001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (wlen > 2048) 30011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len2 = 2048; 30021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 30031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len2 = wlen; 30041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wlen -= len2; 30051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len2 <<= 1; 30061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < len2; i++) 30071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writeb(moxaBuff[j + i], baseAddr + C320_LoadBuf + i); 30081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len2 >>= 1; 30091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds j += i; 30101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(len2, baseAddr + C320DLoad_len); 30111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0, baseAddr + C320_key); 30121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 10; i++) { 30131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + C320_key) == C320_KeyCode) 30141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 30151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxadelay(1); 30161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 30171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + C320_key) != C320_KeyCode) 30181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 30191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 30201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0, baseAddr + C320DLoad_len); 30211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(usum, baseAddr + C320check_sum); 30221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0, baseAddr + C320_key); 30231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 10; i++) { 30241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + C320_key) == C320_KeyCode) 30251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 30261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxadelay(1); 30271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 30281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds retry++; 30291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } while ((readb(baseAddr + C320chksum_ok) != 1) && (retry < 3)); 30301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readb(baseAddr + C320chksum_ok) != 1) 30311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 30321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0, baseAddr + C320_key); 30331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 600; i++) { 30341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + Magic_no) == Magic_code) 30351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 30361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxadelay(1); 30371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 30381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + Magic_no) != Magic_code) 30391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-100); 30401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxa_boards[cardno].busType == MOXA_BUS_TYPE_PCI) { /* ASIC board */ 30421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0x3800, baseAddr + TMS320_PORT1); 30431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0x3900, baseAddr + TMS320_PORT2); 30441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(28499, baseAddr + TMS320_CLOCK); 30451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 30461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0x3200, baseAddr + TMS320_PORT1); 30471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0x3400, baseAddr + TMS320_PORT2); 30481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(19999, baseAddr + TMS320_CLOCK); 30491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 30501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(1, baseAddr + Disable_IRQ); 30511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0, baseAddr + Magic_no); 30521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 500; i++) { 30531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + Magic_no) == Magic_code) 30541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 30551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxadelay(1); 30561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 30571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + Magic_no) != Magic_code) 30581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-102); 30591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds j = readw(baseAddr + Module_cnt); 30611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (j <= 0) 30621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-101); 30631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *numPorts = j * 8; 30641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(j, baseAddr + Module_no); 30651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(0, baseAddr + Magic_no); 30661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 600; i++) { 30671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + Magic_no) == Magic_code) 30681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 30691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxadelay(1); 30701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 30711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(baseAddr + Magic_no) != Magic_code) 30721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-102); 30731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaCard = 1; 30741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaIntNdx[cardno] = baseAddr + IRQindex; 30751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaIntPend[cardno] = baseAddr + IRQpending; 30761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxaIntTable[cardno] = baseAddr + IRQtable; 30771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 30781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 30791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 30811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldslong MoxaPortGetCurBaud(int port) 30821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 30831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (moxaChkPort[port] == 0) 30851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 30861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (moxaCurBaud[port]); 30871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 30881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* 0 */ 30891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void MoxaSetFifo(int port, int enable) 30911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 30921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr = moxaTableAddr[port]; 30931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!enable) { 30951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SetRxFIFOTrig, 0); 30961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SetTxFIFOCnt, 1); 30971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 30981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SetRxFIFOTrig, 3); 30991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SetTxFIFOCnt, 16); 31001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 31011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 31021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 31041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortSetMode(int port, int databits, int stopbits, int parity) 31051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 31061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 31071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int val; 31081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = 0; 31101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (databits) { 31111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 5: 31121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val |= 0; 31131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 31141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 6: 31151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val |= 1; 31161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 31171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 7: 31181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val |= 2; 31191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 31201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 8: 31211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val |= 3; 31221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 31231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 31241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 31251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 31261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (stopbits) { 31271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 31281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val |= 0; 31291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; /* stop bits 1.5 */ 31301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 31311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val |= 0; 31321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 31331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 31341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val |= 4; 31351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 31361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 31371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 31381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 31391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (parity) { 31401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 31411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val |= 0x00; 31421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; /* None */ 31431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 31441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val |= 0x08; 31451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; /* Odd */ 31461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 31471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val |= 0x18; 31481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; /* Even */ 31491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 3: 31501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val |= 0x28; 31511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; /* Mark */ 31521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 4: 31531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val |= 0x38; 31541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; /* Space */ 31551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 31561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (-1); 31571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 31581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 31591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_SetMode, val); 31601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 31611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 31621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortTxBufSize(int port) 31641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 31651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 31661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int size; 31671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 31691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = readw(ofsAddr + TX_mask); 31701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (size); 31711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 31721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortRxBufSize(int port) 31741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 31751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 31761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int size; 31771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 31791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = readw(ofsAddr + RX_mask); 31801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (size); 31811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 31821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortRxFree(int port) 31841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 31851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 31861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ushort rptr, wptr, mask; 31871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len; 31881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 31891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 31901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rptr = readw(ofsAddr + RXrptr); 31911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wptr = readw(ofsAddr + RXwptr); 31921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mask = readw(ofsAddr + RX_mask); 31931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = mask - ((wptr - rptr) & mask); 31941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (len); 31951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 31961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortGetBrkCnt(int port) 31971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 31981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (moxaBreakCnt[port]); 31991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 32001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid MoxaPortSetXonXoff(int port, int xonValue, int xoffValue) 32021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 32031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 32041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 32061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(xonValue, ofsAddr + FuncArg); 32071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(xoffValue, ofsAddr + FuncArg1); 32081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writew(FC_SetXonXoff, ofsAddr + FuncCode); 32091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wait_finish(ofsAddr); 32101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 32111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint MoxaPortIsTxHold(int port) 32131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 32141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __iomem *ofsAddr; 32151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int val; 32161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ofsAddr = moxaTableAddr[port]; 32181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) || 32191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) { 32201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds moxafunc(ofsAddr, FC_GetCCSR, 0); 32211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val = readw(ofsAddr + FuncArg); 32221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (val & 0x04) 32231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (1); 32241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 32251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (readw(ofsAddr + FlagStat) & Tx_flowOff) 32261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (1); 32271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 32281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (0); 32291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 32301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 3231