linux/drivers/char/moxa.c
<<
>>
Prefs
   1/*****************************************************************************/
   2/*
   3 *           moxa.c  -- MOXA Intellio family multiport serial driver.
   4 *
   5 *      Copyright (C) 1999-2000  Moxa Technologies (support@moxa.com.tw).
   6 *
   7 *      This code is loosely based on the Linux serial driver, written by
   8 *      Linus Torvalds, Theodore T'so and others.
   9 *
  10 *      This program is free software; you can redistribute it and/or modify
  11 *      it under the terms of the GNU General Public License as published by
  12 *      the Free Software Foundation; either version 2 of the License, or
  13 *      (at your option) any later version.
  14 *
  15 *      This program is distributed in the hope that it will be useful,
  16 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 *      GNU General Public License for more details.
  19 *
  20 *      You should have received a copy of the GNU General Public License
  21 *      along with this program; if not, write to the Free Software
  22 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23 */
  24
  25/*
  26 *    MOXA Intellio Series Driver
  27 *      for             : LINUX
  28 *      date            : 1999/1/7
  29 *      version         : 5.1
  30 */
  31
  32#include <linux/config.h>
  33#include <linux/module.h>
  34#include <linux/types.h>
  35#include <linux/mm.h>
  36#include <linux/ioport.h>
  37#include <linux/errno.h>
  38#include <linux/signal.h>
  39#include <linux/sched.h>
  40#include <linux/timer.h>
  41#include <linux/interrupt.h>
  42#include <linux/tty.h>
  43#include <linux/tty_flip.h>
  44#include <linux/major.h>
  45#include <linux/string.h>
  46#include <linux/fcntl.h>
  47#include <linux/ptrace.h>
  48#include <linux/serial.h>
  49#include <linux/tty_driver.h>
  50#include <linux/delay.h>
  51#include <linux/pci.h>
  52#include <linux/init.h>
  53#include <linux/bitops.h>
  54
  55#include <asm/system.h>
  56#include <asm/io.h>
  57#include <asm/uaccess.h>
  58
  59#define         MOXA_VERSION            "5.1k"
  60
  61#define MOXAMAJOR       172
  62#define MOXACUMAJOR     173
  63
  64#define put_to_user(arg1, arg2) put_user(arg1, (unsigned long *)arg2)
  65#define get_from_user(arg1, arg2) get_user(arg1, (unsigned int *)arg2)
  66
  67#define MAX_BOARDS              4       /* Don't change this value */
  68#define MAX_PORTS_PER_BOARD     32      /* Don't change this value */
  69#define MAX_PORTS               128     /* Don't change this value */
  70
  71/*
  72 *    Define the Moxa PCI vendor and device IDs.
  73 */
  74#define MOXA_BUS_TYPE_ISA               0
  75#define MOXA_BUS_TYPE_PCI               1
  76
  77#ifndef PCI_VENDOR_ID_MOXA
  78#define PCI_VENDOR_ID_MOXA      0x1393
  79#endif
  80#ifndef PCI_DEVICE_ID_CP204J
  81#define PCI_DEVICE_ID_CP204J    0x2040
  82#endif
  83#ifndef PCI_DEVICE_ID_C218
  84#define PCI_DEVICE_ID_C218      0x2180
  85#endif
  86#ifndef PCI_DEVICE_ID_C320
  87#define PCI_DEVICE_ID_C320      0x3200
  88#endif
  89
  90enum {
  91        MOXA_BOARD_C218_PCI = 1,
  92        MOXA_BOARD_C218_ISA,
  93        MOXA_BOARD_C320_PCI,
  94        MOXA_BOARD_C320_ISA,
  95        MOXA_BOARD_CP204J,
  96};
  97
  98static char *moxa_brdname[] =
  99{
 100        "C218 Turbo PCI series",
 101        "C218 Turbo ISA series",
 102        "C320 Turbo PCI series",
 103        "C320 Turbo ISA series",
 104        "CP-204J series",
 105};
 106
 107#ifdef CONFIG_PCI
 108static struct pci_device_id moxa_pcibrds[] = {
 109        { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C218, PCI_ANY_ID, PCI_ANY_ID, 
 110          0, 0, MOXA_BOARD_C218_PCI },
 111        { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C320, PCI_ANY_ID, PCI_ANY_ID, 
 112          0, 0, MOXA_BOARD_C320_PCI },
 113        { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_CP204J, PCI_ANY_ID, PCI_ANY_ID, 
 114          0, 0, MOXA_BOARD_CP204J },
 115        { 0 }
 116};
 117MODULE_DEVICE_TABLE(pci, moxa_pcibrds);
 118#endif /* CONFIG_PCI */
 119
 120typedef struct _moxa_isa_board_conf {
 121        int boardType;
 122        int numPorts;
 123        unsigned long baseAddr;
 124} moxa_isa_board_conf;
 125
 126static moxa_isa_board_conf moxa_isa_boards[] =
 127{
 128/*       {MOXA_BOARD_C218_ISA,8,0xDC000}, */
 129};
 130
 131typedef struct _moxa_pci_devinfo {
 132        ushort busNum;
 133        ushort devNum;
 134} moxa_pci_devinfo;
 135
 136typedef struct _moxa_board_conf {
 137        int boardType;
 138        int numPorts;
 139        unsigned long baseAddr;
 140        int busType;
 141        moxa_pci_devinfo pciInfo;
 142} moxa_board_conf;
 143
 144static moxa_board_conf moxa_boards[MAX_BOARDS];
 145static void __iomem *moxaBaseAddr[MAX_BOARDS];
 146
 147struct moxa_str {
 148        int type;
 149        int port;
 150        int close_delay;
 151        unsigned short closing_wait;
 152        int count;
 153        int blocked_open;
 154        long event; /* long req'd for set_bit --RR */
 155        int asyncflags;
 156        unsigned long statusflags;
 157        struct tty_struct *tty;
 158        int cflag;
 159        wait_queue_head_t open_wait;
 160        wait_queue_head_t close_wait;
 161        struct work_struct tqueue;
 162};
 163
 164struct mxser_mstatus {
 165        tcflag_t cflag;
 166        int cts;
 167        int dsr;
 168        int ri;
 169        int dcd;
 170};
 171
 172static struct mxser_mstatus GMStatus[MAX_PORTS];
 173
 174/* statusflags */
 175#define TXSTOPPED       0x1
 176#define LOWWAIT         0x2
 177#define EMPTYWAIT       0x4
 178#define THROTTLE        0x8
 179
 180/* event */
 181#define MOXA_EVENT_HANGUP       1
 182
 183#define SERIAL_DO_RESTART
 184
 185
 186#define SERIAL_TYPE_NORMAL      1
 187
 188#define WAKEUP_CHARS            256
 189
 190#define PORTNO(x)               ((x)->index)
 191
 192static int verbose = 0;
 193static int ttymajor = MOXAMAJOR;
 194/* Variables for insmod */
 195#ifdef MODULE
 196static int baseaddr[]   =       {0, 0, 0, 0};
 197static int type[]       =       {0, 0, 0, 0};
 198static int numports[]   =       {0, 0, 0, 0};
 199#endif
 200
 201MODULE_AUTHOR("William Chen");
 202MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver");
 203MODULE_LICENSE("GPL");
 204#ifdef MODULE
 205module_param_array(type, int, NULL, 0);
 206module_param_array(baseaddr, int, NULL, 0);
 207module_param_array(numports, int, NULL, 0);
 208#endif
 209module_param(ttymajor, int, 0);
 210module_param(verbose, bool, 0644);
 211
 212static struct tty_driver *moxaDriver;
 213static struct moxa_str moxaChannels[MAX_PORTS];
 214static unsigned char *moxaXmitBuff;
 215static int moxaTimer_on;
 216static struct timer_list moxaTimer;
 217static int moxaEmptyTimer_on[MAX_PORTS];
 218static struct timer_list moxaEmptyTimer[MAX_PORTS];
 219static struct semaphore moxaBuffSem;
 220
 221/*
 222 * static functions:
 223 */
 224static void do_moxa_softint(void *);
 225static int moxa_open(struct tty_struct *, struct file *);
 226static void moxa_close(struct tty_struct *, struct file *);
 227static int moxa_write(struct tty_struct *, const unsigned char *, int);
 228static int moxa_write_room(struct tty_struct *);
 229static void moxa_flush_buffer(struct tty_struct *);
 230static int moxa_chars_in_buffer(struct tty_struct *);
 231static void moxa_flush_chars(struct tty_struct *);
 232static void moxa_put_char(struct tty_struct *, unsigned char);
 233static int moxa_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long);
 234static void moxa_throttle(struct tty_struct *);
 235static void moxa_unthrottle(struct tty_struct *);
 236static void moxa_set_termios(struct tty_struct *, struct termios *);
 237static void moxa_stop(struct tty_struct *);
 238static void moxa_start(struct tty_struct *);
 239static void moxa_hangup(struct tty_struct *);
 240static int moxa_tiocmget(struct tty_struct *tty, struct file *file);
 241static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
 242                         unsigned int set, unsigned int clear);
 243static void moxa_poll(unsigned long);
 244static void set_tty_param(struct tty_struct *);
 245static int block_till_ready(struct tty_struct *, struct file *,
 246                            struct moxa_str *);
 247static void setup_empty_event(struct tty_struct *);
 248static void check_xmit_empty(unsigned long);
 249static void shut_down(struct moxa_str *);
 250static void receive_data(struct moxa_str *);
 251/*
 252 * moxa board interface functions:
 253 */
 254static void MoxaDriverInit(void);
 255static int MoxaDriverIoctl(unsigned int, unsigned long, int);
 256static int MoxaDriverPoll(void);
 257static int MoxaPortsOfCard(int);
 258static int MoxaPortIsValid(int);
 259static void MoxaPortEnable(int);
 260static void MoxaPortDisable(int);
 261static long MoxaPortGetMaxBaud(int);
 262static long MoxaPortSetBaud(int, long);
 263static int MoxaPortSetTermio(int, struct termios *);
 264static int MoxaPortGetLineOut(int, int *, int *);
 265static void MoxaPortLineCtrl(int, int, int);
 266static void MoxaPortFlowCtrl(int, int, int, int, int, int);
 267static int MoxaPortLineStatus(int);
 268static int MoxaPortDCDChange(int);
 269static int MoxaPortDCDON(int);
 270static void MoxaPortFlushData(int, int);
 271static int MoxaPortWriteData(int, unsigned char *, int);
 272static int MoxaPortReadData(int, unsigned char *, int);
 273static int MoxaPortTxQueue(int);
 274static int MoxaPortRxQueue(int);
 275static int MoxaPortTxFree(int);
 276static void MoxaPortTxDisable(int);
 277static void MoxaPortTxEnable(int);
 278static int MoxaPortResetBrkCnt(int);
 279static void MoxaPortSendBreak(int, int);
 280static int moxa_get_serial_info(struct moxa_str *, struct serial_struct __user *);
 281static int moxa_set_serial_info(struct moxa_str *, struct serial_struct __user *);
 282static void MoxaSetFifo(int port, int enable);
 283
 284static struct tty_operations moxa_ops = {
 285        .open = moxa_open,
 286        .close = moxa_close,
 287        .write = moxa_write,
 288        .write_room = moxa_write_room,
 289        .flush_buffer = moxa_flush_buffer,
 290        .chars_in_buffer = moxa_chars_in_buffer,
 291        .flush_chars = moxa_flush_chars,
 292        .put_char = moxa_put_char,
 293        .ioctl = moxa_ioctl,
 294        .throttle = moxa_throttle,
 295        .unthrottle = moxa_unthrottle,
 296        .set_termios = moxa_set_termios,
 297        .stop = moxa_stop,
 298        .start = moxa_start,
 299        .hangup = moxa_hangup,
 300        .tiocmget = moxa_tiocmget,
 301        .tiocmset = moxa_tiocmset,
 302};
 303
 304#ifdef CONFIG_PCI
 305static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board)
 306{
 307        board->baseAddr = pci_resource_start (p, 2);
 308        board->boardType = board_type;
 309        switch (board_type) {
 310        case MOXA_BOARD_C218_ISA:
 311        case MOXA_BOARD_C218_PCI:
 312                board->numPorts = 8;
 313                break;
 314
 315        case MOXA_BOARD_CP204J:
 316                board->numPorts = 4;
 317                break;
 318        default:
 319                board->numPorts = 0;
 320                break;
 321        }
 322        board->busType = MOXA_BUS_TYPE_PCI;
 323        board->pciInfo.busNum = p->bus->number;
 324        board->pciInfo.devNum = p->devfn >> 3;
 325
 326        return (0);
 327}
 328#endif /* CONFIG_PCI */
 329
 330static int __init moxa_init(void)
 331{
 332        int i, numBoards;
 333        struct moxa_str *ch;
 334
 335        printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION);
 336        moxaDriver = alloc_tty_driver(MAX_PORTS + 1);
 337        if (!moxaDriver)
 338                return -ENOMEM;
 339
 340        init_MUTEX(&moxaBuffSem);
 341        moxaDriver->owner = THIS_MODULE;
 342        moxaDriver->name = "ttya";
 343        moxaDriver->devfs_name = "tts/a";
 344        moxaDriver->major = ttymajor;
 345        moxaDriver->minor_start = 0;
 346        moxaDriver->type = TTY_DRIVER_TYPE_SERIAL;
 347        moxaDriver->subtype = SERIAL_TYPE_NORMAL;
 348        moxaDriver->init_termios = tty_std_termios;
 349        moxaDriver->init_termios.c_iflag = 0;
 350        moxaDriver->init_termios.c_oflag = 0;
 351        moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
 352        moxaDriver->init_termios.c_lflag = 0;
 353        moxaDriver->flags = TTY_DRIVER_REAL_RAW;
 354        tty_set_operations(moxaDriver, &moxa_ops);
 355
 356        moxaXmitBuff = NULL;
 357
 358        for (i = 0, ch = moxaChannels; i < MAX_PORTS; i++, ch++) {
 359                ch->type = PORT_16550A;
 360                ch->port = i;
 361                INIT_WORK(&ch->tqueue, do_moxa_softint, ch);
 362                ch->tty = NULL;
 363                ch->close_delay = 5 * HZ / 10;
 364                ch->closing_wait = 30 * HZ;
 365                ch->count = 0;
 366                ch->blocked_open = 0;
 367                ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
 368                init_waitqueue_head(&ch->open_wait);
 369                init_waitqueue_head(&ch->close_wait);
 370        }
 371
 372        for (i = 0; i < MAX_BOARDS; i++) {
 373                moxa_boards[i].boardType = 0;
 374                moxa_boards[i].numPorts = 0;
 375                moxa_boards[i].baseAddr = 0;
 376                moxa_boards[i].busType = 0;
 377                moxa_boards[i].pciInfo.busNum = 0;
 378                moxa_boards[i].pciInfo.devNum = 0;
 379        }
 380        MoxaDriverInit();
 381        printk("Tty devices major number = %d\n", ttymajor);
 382
 383        if (tty_register_driver(moxaDriver)) {
 384                printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n");
 385                put_tty_driver(moxaDriver);
 386                return -1;
 387        }
 388        for (i = 0; i < MAX_PORTS; i++) {
 389                init_timer(&moxaEmptyTimer[i]);
 390                moxaEmptyTimer[i].function = check_xmit_empty;
 391                moxaEmptyTimer[i].data = (unsigned long) & moxaChannels[i];
 392                moxaEmptyTimer_on[i] = 0;
 393        }
 394
 395        init_timer(&moxaTimer);
 396        moxaTimer.function = moxa_poll;
 397        moxaTimer.expires = jiffies + (HZ / 50);
 398        moxaTimer_on = 1;
 399        add_timer(&moxaTimer);
 400
 401        /* Find the boards defined in source code */
 402        numBoards = 0;
 403        for (i = 0; i < MAX_BOARDS; i++) {
 404                if ((moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA) ||
 405                 (moxa_isa_boards[i].boardType == MOXA_BOARD_C320_ISA)) {
 406                        moxa_boards[numBoards].boardType = moxa_isa_boards[i].boardType;
 407                        if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA)
 408                                moxa_boards[numBoards].numPorts = 8;
 409                        else
 410                                moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts;
 411                        moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA;
 412                        moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr;
 413                        if (verbose)
 414                                printk("Board %2d: %s board(baseAddr=%lx)\n",
 415                                       numBoards + 1,
 416                                       moxa_brdname[moxa_boards[numBoards].boardType - 1],
 417                                       moxa_boards[numBoards].baseAddr);
 418                        numBoards++;
 419                }
 420        }
 421        /* Find the boards defined form module args. */
 422#ifdef MODULE
 423        for (i = 0; i < MAX_BOARDS; i++) {
 424                if ((type[i] == MOXA_BOARD_C218_ISA) ||
 425                    (type[i] == MOXA_BOARD_C320_ISA)) {
 426                        if (verbose)
 427                                printk("Board %2d: %s board(baseAddr=%lx)\n",
 428                                       numBoards + 1,
 429                                       moxa_brdname[type[i] - 1],
 430                                       (unsigned long) baseaddr[i]);
 431                        if (numBoards >= MAX_BOARDS) {
 432                                if (verbose)
 433                                        printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS);
 434                                continue;
 435                        }
 436                        moxa_boards[numBoards].boardType = type[i];
 437                        if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA)
 438                                moxa_boards[numBoards].numPorts = 8;
 439                        else
 440                                moxa_boards[numBoards].numPorts = numports[i];
 441                        moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA;
 442                        moxa_boards[numBoards].baseAddr = baseaddr[i];
 443                        numBoards++;
 444                }
 445        }
 446#endif
 447        /* Find PCI boards here */
 448#ifdef CONFIG_PCI
 449        {
 450                struct pci_dev *p = NULL;
 451                int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1;
 452                i = 0;
 453                while (i < n) {
 454                        while ((p = pci_find_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)
 455                        {
 456                                if (pci_enable_device(p))
 457                                        continue;
 458                                if (numBoards >= MAX_BOARDS) {
 459                                        if (verbose)
 460                                                printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS);
 461                                } else {
 462                                        moxa_get_PCI_conf(p, moxa_pcibrds[i].driver_data,
 463                                                &moxa_boards[numBoards]);
 464                                        numBoards++;
 465                                }
 466                        }
 467                        i++;
 468                }
 469        }
 470#endif
 471        for (i = 0; i < numBoards; i++) {
 472                moxaBaseAddr[i] = ioremap((unsigned long) moxa_boards[i].baseAddr, 0x4000);
 473        }
 474
 475        return (0);
 476}
 477
 478static void __exit moxa_exit(void)
 479{
 480        int i;
 481
 482        if (verbose)
 483                printk("Unloading module moxa ...\n");
 484
 485        if (moxaTimer_on)
 486                del_timer(&moxaTimer);
 487
 488        for (i = 0; i < MAX_PORTS; i++)
 489                if (moxaEmptyTimer_on[i])
 490                        del_timer(&moxaEmptyTimer[i]);
 491
 492        if (tty_unregister_driver(moxaDriver))
 493                printk("Couldn't unregister MOXA Intellio family serial driver\n");
 494        put_tty_driver(moxaDriver);
 495        if (verbose)
 496                printk("Done\n");
 497}
 498
 499module_init(moxa_init);
 500module_exit(moxa_exit);
 501
 502static void do_moxa_softint(void *private_)
 503{
 504        struct moxa_str *ch = (struct moxa_str *) private_;
 505        struct tty_struct *tty;
 506
 507        if (ch && (tty = ch->tty)) {
 508                if (test_and_clear_bit(MOXA_EVENT_HANGUP, &ch->event)) {
 509                        tty_hangup(tty);        /* FIXME: module removal race here - AKPM */
 510                        wake_up_interruptible(&ch->open_wait);
 511                        ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
 512                }
 513        }
 514}
 515
 516static int moxa_open(struct tty_struct *tty, struct file *filp)
 517{
 518        struct moxa_str *ch;
 519        int port;
 520        int retval;
 521        unsigned long page;
 522
 523        port = PORTNO(tty);
 524        if (port == MAX_PORTS) {
 525                return (0);
 526        }
 527        if (!MoxaPortIsValid(port)) {
 528                tty->driver_data = NULL;
 529                return (-ENODEV);
 530        }
 531        down(&moxaBuffSem);
 532        if (!moxaXmitBuff) {
 533                page = get_zeroed_page(GFP_KERNEL);
 534                if (!page) {
 535                        up(&moxaBuffSem);
 536                        return (-ENOMEM);
 537                }
 538                /* This test is guarded by the BuffSem so no longer needed
 539                   delete me in 2.5 */
 540                if (moxaXmitBuff)
 541                        free_page(page);
 542                else
 543                        moxaXmitBuff = (unsigned char *) page;
 544        }
 545        up(&moxaBuffSem);
 546
 547        ch = &moxaChannels[port];
 548        ch->count++;
 549        tty->driver_data = ch;
 550        ch->tty = tty;
 551        if (!(ch->asyncflags & ASYNC_INITIALIZED)) {
 552                ch->statusflags = 0;
 553                set_tty_param(tty);
 554                MoxaPortLineCtrl(ch->port, 1, 1);
 555                MoxaPortEnable(ch->port);
 556                ch->asyncflags |= ASYNC_INITIALIZED;
 557        }
 558        retval = block_till_ready(tty, filp, ch);
 559
 560        moxa_unthrottle(tty);
 561
 562        if (ch->type == PORT_16550A) {
 563                MoxaSetFifo(ch->port, 1);
 564        } else {
 565                MoxaSetFifo(ch->port, 0);
 566        }
 567
 568        return (retval);
 569}
 570
 571static void moxa_close(struct tty_struct *tty, struct file *filp)
 572{
 573        struct moxa_str *ch;
 574        int port;
 575
 576        port = PORTNO(tty);
 577        if (port == MAX_PORTS) {
 578                return;
 579        }
 580        if (!MoxaPortIsValid(port)) {
 581#ifdef SERIAL_DEBUG_CLOSE
 582                printk("Invalid portno in moxa_close\n");
 583#endif
 584                tty->driver_data = NULL;
 585                return;
 586        }
 587        if (tty->driver_data == NULL) {
 588                return;
 589        }
 590        if (tty_hung_up_p(filp)) {
 591                return;
 592        }
 593        ch = (struct moxa_str *) tty->driver_data;
 594
 595        if ((tty->count == 1) && (ch->count != 1)) {
 596                printk("moxa_close: bad serial port count; tty->count is 1, "
 597                       "ch->count is %d\n", ch->count);
 598                ch->count = 1;
 599        }
 600        if (--ch->count < 0) {
 601                printk("moxa_close: bad serial port count, device=%s\n",
 602                       tty->name);
 603                ch->count = 0;
 604        }
 605        if (ch->count) {
 606                return;
 607        }
 608        ch->asyncflags |= ASYNC_CLOSING;
 609
 610        ch->cflag = tty->termios->c_cflag;
 611        if (ch->asyncflags & ASYNC_INITIALIZED) {
 612                setup_empty_event(tty);
 613                tty_wait_until_sent(tty, 30 * HZ);      /* 30 seconds timeout */
 614                moxaEmptyTimer_on[ch->port] = 0;
 615                del_timer(&moxaEmptyTimer[ch->port]);
 616        }
 617        shut_down(ch);
 618        MoxaPortFlushData(port, 2);
 619
 620        if (tty->driver->flush_buffer)
 621                tty->driver->flush_buffer(tty);
 622        tty_ldisc_flush(tty);
 623                        
 624        tty->closing = 0;
 625        ch->event = 0;
 626        ch->tty = NULL;
 627        if (ch->blocked_open) {
 628                if (ch->close_delay) {
 629                        msleep_interruptible(jiffies_to_msecs(ch->close_delay));
 630                }
 631                wake_up_interruptible(&ch->open_wait);
 632        }
 633        ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
 634        wake_up_interruptible(&ch->close_wait);
 635}
 636
 637static int moxa_write(struct tty_struct *tty,
 638                      const unsigned char *buf, int count)
 639{
 640        struct moxa_str *ch;
 641        int len, port;
 642        unsigned long flags;
 643
 644        ch = (struct moxa_str *) tty->driver_data;
 645        if (ch == NULL)
 646                return (0);
 647        port = ch->port;
 648        save_flags(flags);
 649        cli();
 650        len = MoxaPortWriteData(port, (unsigned char *) buf, count);
 651        restore_flags(flags);
 652
 653        /*********************************************
 654        if ( !(ch->statusflags & LOWWAIT) &&
 655             ((len != count) || (MoxaPortTxFree(port) <= 100)) )
 656        ************************************************/
 657        ch->statusflags |= LOWWAIT;
 658        return (len);
 659}
 660
 661static int moxa_write_room(struct tty_struct *tty)
 662{
 663        struct moxa_str *ch;
 664
 665        if (tty->stopped)
 666                return (0);
 667        ch = (struct moxa_str *) tty->driver_data;
 668        if (ch == NULL)
 669                return (0);
 670        return (MoxaPortTxFree(ch->port));
 671}
 672
 673static void moxa_flush_buffer(struct tty_struct *tty)
 674{
 675        struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
 676
 677        if (ch == NULL)
 678                return;
 679        MoxaPortFlushData(ch->port, 1);
 680        tty_wakeup(tty);
 681}
 682
 683static int moxa_chars_in_buffer(struct tty_struct *tty)
 684{
 685        int chars;
 686        struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
 687
 688        /*
 689         * Sigh...I have to check if driver_data is NULL here, because
 690         * if an open() fails, the TTY subsystem eventually calls
 691         * tty_wait_until_sent(), which calls the driver's chars_in_buffer()
 692         * routine.  And since the open() failed, we return 0 here.  TDJ
 693         */
 694        if (ch == NULL)
 695                return (0);
 696        chars = MoxaPortTxQueue(ch->port);
 697        if (chars) {
 698                /*
 699                 * Make it possible to wakeup anything waiting for output
 700                 * in tty_ioctl.c, etc.
 701                 */
 702                if (!(ch->statusflags & EMPTYWAIT))
 703                        setup_empty_event(tty);
 704        }
 705        return (chars);
 706}
 707
 708static void moxa_flush_chars(struct tty_struct *tty)
 709{
 710        /*
 711         * Don't think I need this, because this is called to empty the TX
 712         * buffer for the 16450, 16550, etc.
 713         */
 714}
 715
 716static void moxa_put_char(struct tty_struct *tty, unsigned char c)
 717{
 718        struct moxa_str *ch;
 719        int port;
 720        unsigned long flags;
 721
 722        ch = (struct moxa_str *) tty->driver_data;
 723        if (ch == NULL)
 724                return;
 725        port = ch->port;
 726        save_flags(flags);
 727        cli();
 728        moxaXmitBuff[0] = c;
 729        MoxaPortWriteData(port, moxaXmitBuff, 1);
 730        restore_flags(flags);
 731        /************************************************
 732        if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) )
 733        *************************************************/
 734        ch->statusflags |= LOWWAIT;
 735}
 736
 737static int moxa_tiocmget(struct tty_struct *tty, struct file *file)
 738{
 739        struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
 740        int port;
 741        int flag = 0, dtr, rts;
 742
 743        port = PORTNO(tty);
 744        if ((port != MAX_PORTS) && (!ch))
 745                return (-EINVAL);
 746
 747        MoxaPortGetLineOut(ch->port, &dtr, &rts);
 748        if (dtr)
 749                flag |= TIOCM_DTR;
 750        if (rts)
 751                flag |= TIOCM_RTS;
 752        dtr = MoxaPortLineStatus(ch->port);
 753        if (dtr & 1)
 754                flag |= TIOCM_CTS;
 755        if (dtr & 2)
 756                flag |= TIOCM_DSR;
 757        if (dtr & 4)
 758                flag |= TIOCM_CD;
 759        return flag;
 760}
 761
 762static int moxa_tiocmset(struct tty_struct *tty, struct file *file,
 763                         unsigned int set, unsigned int clear)
 764{
 765        struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
 766        int port;
 767        int dtr, rts;
 768
 769        port = PORTNO(tty);
 770        if ((port != MAX_PORTS) && (!ch))
 771                return (-EINVAL);
 772
 773        MoxaPortGetLineOut(ch->port, &dtr, &rts);
 774        if (set & TIOCM_RTS)
 775                rts = 1;
 776        if (set & TIOCM_DTR)
 777                dtr = 1;
 778        if (clear & TIOCM_RTS)
 779                rts = 0;
 780        if (clear & TIOCM_DTR)
 781                dtr = 0;
 782        MoxaPortLineCtrl(ch->port, dtr, rts);
 783        return 0;
 784}
 785
 786static int moxa_ioctl(struct tty_struct *tty, struct file *file,
 787                      unsigned int cmd, unsigned long arg)
 788{
 789        struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
 790        register int port;
 791        void __user *argp = (void __user *)arg;
 792        int retval;
 793
 794        port = PORTNO(tty);
 795        if ((port != MAX_PORTS) && (!ch))
 796                return (-EINVAL);
 797
 798        switch (cmd) {
 799        case TCSBRK:            /* SVID version: non-zero arg --> no break */
 800                retval = tty_check_change(tty);
 801                if (retval)
 802                        return (retval);
 803                setup_empty_event(tty);
 804                tty_wait_until_sent(tty, 0);
 805                if (!arg)
 806                        MoxaPortSendBreak(ch->port, 0);
 807                return (0);
 808        case TCSBRKP:           /* support for POSIX tcsendbreak() */
 809                retval = tty_check_change(tty);
 810                if (retval)
 811                        return (retval);
 812                setup_empty_event(tty);
 813                tty_wait_until_sent(tty, 0);
 814                MoxaPortSendBreak(ch->port, arg);
 815                return (0);
 816        case TIOCGSOFTCAR:
 817                return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp);
 818        case TIOCSSOFTCAR:
 819                if(get_user(retval, (unsigned long __user *) argp))
 820                        return -EFAULT;
 821                arg = retval;
 822                tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) |
 823                                         (arg ? CLOCAL : 0));
 824                if (C_CLOCAL(tty))
 825                        ch->asyncflags &= ~ASYNC_CHECK_CD;
 826                else
 827                        ch->asyncflags |= ASYNC_CHECK_CD;
 828                return (0);
 829        case TIOCGSERIAL:
 830                return moxa_get_serial_info(ch, argp);
 831
 832        case TIOCSSERIAL:
 833                return moxa_set_serial_info(ch, argp);
 834        default:
 835                retval = MoxaDriverIoctl(cmd, arg, port);
 836        }
 837        return (retval);
 838}
 839
 840static void moxa_throttle(struct tty_struct *tty)
 841{
 842        struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
 843
 844        ch->statusflags |= THROTTLE;
 845}
 846
 847static void moxa_unthrottle(struct tty_struct *tty)
 848{
 849        struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
 850
 851        ch->statusflags &= ~THROTTLE;
 852}
 853
 854static void moxa_set_termios(struct tty_struct *tty,
 855                             struct termios *old_termios)
 856{
 857        struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
 858
 859        if (ch == NULL)
 860                return;
 861        set_tty_param(tty);
 862        if (!(old_termios->c_cflag & CLOCAL) &&
 863            (tty->termios->c_cflag & CLOCAL))
 864                wake_up_interruptible(&ch->open_wait);
 865}
 866
 867static void moxa_stop(struct tty_struct *tty)
 868{
 869        struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
 870
 871        if (ch == NULL)
 872                return;
 873        MoxaPortTxDisable(ch->port);
 874        ch->statusflags |= TXSTOPPED;
 875}
 876
 877
 878static void moxa_start(struct tty_struct *tty)
 879{
 880        struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
 881
 882        if (ch == NULL)
 883                return;
 884
 885        if (!(ch->statusflags & TXSTOPPED))
 886                return;
 887
 888        MoxaPortTxEnable(ch->port);
 889        ch->statusflags &= ~TXSTOPPED;
 890}
 891
 892static void moxa_hangup(struct tty_struct *tty)
 893{
 894        struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
 895
 896        moxa_flush_buffer(tty);
 897        shut_down(ch);
 898        ch->event = 0;
 899        ch->count = 0;
 900        ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
 901        ch->tty = NULL;
 902        wake_up_interruptible(&ch->open_wait);
 903}
 904
 905static void moxa_poll(unsigned long ignored)
 906{
 907        register int card;
 908        struct moxa_str *ch;
 909        struct tty_struct *tp;
 910        int i, ports;
 911
 912        moxaTimer_on = 0;
 913        del_timer(&moxaTimer);
 914
 915        if (MoxaDriverPoll() < 0) {
 916                moxaTimer.function = moxa_poll;
 917                moxaTimer.expires = jiffies + (HZ / 50);
 918                moxaTimer_on = 1;
 919                add_timer(&moxaTimer);
 920                return;
 921        }
 922        for (card = 0; card < MAX_BOARDS; card++) {
 923                if ((ports = MoxaPortsOfCard(card)) <= 0)
 924                        continue;
 925                ch = &moxaChannels[card * MAX_PORTS_PER_BOARD];
 926                for (i = 0; i < ports; i++, ch++) {
 927                        if ((ch->asyncflags & ASYNC_INITIALIZED) == 0)
 928                                continue;
 929                        if (!(ch->statusflags & THROTTLE) &&
 930                            (MoxaPortRxQueue(ch->port) > 0))
 931                                receive_data(ch);
 932                        if ((tp = ch->tty) == 0)
 933                                continue;
 934                        if (ch->statusflags & LOWWAIT) {
 935                                if (MoxaPortTxQueue(ch->port) <= WAKEUP_CHARS) {
 936                                        if (!tp->stopped) {
 937                                                ch->statusflags &= ~LOWWAIT;
 938                                                tty_wakeup(tp);
 939                                        }
 940                                }
 941                        }
 942                        if (!I_IGNBRK(tp) && (MoxaPortResetBrkCnt(ch->port) > 0)) {
 943                                tty_insert_flip_char(tp, 0, TTY_BREAK);
 944                                tty_schedule_flip(tp);
 945                        }
 946                        if (MoxaPortDCDChange(ch->port)) {
 947                                if (ch->asyncflags & ASYNC_CHECK_CD) {
 948                                        if (MoxaPortDCDON(ch->port))
 949                                                wake_up_interruptible(&ch->open_wait);
 950                                        else {
 951                                                set_bit(MOXA_EVENT_HANGUP, &ch->event);
 952                                                schedule_work(&ch->tqueue);
 953                                        }
 954                                }
 955                        }
 956                }
 957        }
 958
 959        moxaTimer.function = moxa_poll;
 960        moxaTimer.expires = jiffies + (HZ / 50);
 961        moxaTimer_on = 1;
 962        add_timer(&moxaTimer);
 963}
 964
 965/******************************************************************************/
 966
 967static void set_tty_param(struct tty_struct *tty)
 968{
 969        register struct termios *ts;
 970        struct moxa_str *ch;
 971        int rts, cts, txflow, rxflow, xany;
 972
 973        ch = (struct moxa_str *) tty->driver_data;
 974        ts = tty->termios;
 975        if (ts->c_cflag & CLOCAL)
 976                ch->asyncflags &= ~ASYNC_CHECK_CD;
 977        else
 978                ch->asyncflags |= ASYNC_CHECK_CD;
 979        rts = cts = txflow = rxflow = xany = 0;
 980        if (ts->c_cflag & CRTSCTS)
 981                rts = cts = 1;
 982        if (ts->c_iflag & IXON)
 983                txflow = 1;
 984        if (ts->c_iflag & IXOFF)
 985                rxflow = 1;
 986        if (ts->c_iflag & IXANY)
 987                xany = 1;
 988        MoxaPortFlowCtrl(ch->port, rts, cts, txflow, rxflow, xany);
 989        MoxaPortSetTermio(ch->port, ts);
 990}
 991
 992static int block_till_ready(struct tty_struct *tty, struct file *filp,
 993                            struct moxa_str *ch)
 994{
 995        DECLARE_WAITQUEUE(wait,current);
 996        unsigned long flags;
 997        int retval;
 998        int do_clocal = C_CLOCAL(tty);
 999
1000        /*
1001         * If the device is in the middle of being closed, then block
1002         * until it's done, and then try again.
1003         */
1004        if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) {
1005                if (ch->asyncflags & ASYNC_CLOSING)
1006                        interruptible_sleep_on(&ch->close_wait);
1007#ifdef SERIAL_DO_RESTART
1008                if (ch->asyncflags & ASYNC_HUP_NOTIFY)
1009                        return (-EAGAIN);
1010                else
1011                        return (-ERESTARTSYS);
1012#else
1013                return (-EAGAIN);
1014#endif
1015        }
1016        /*
1017         * If non-blocking mode is set, then make the check up front
1018         * and then exit.
1019         */
1020        if (filp->f_flags & O_NONBLOCK) {
1021                ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
1022                return (0);
1023        }
1024        /*
1025         * Block waiting for the carrier detect and the line to become free
1026         */
1027        retval = 0;
1028        add_wait_queue(&ch->open_wait, &wait);
1029#ifdef SERIAL_DEBUG_OPEN
1030        printk("block_til_ready before block: ttys%d, count = %d\n",
1031               ch->line, ch->count);
1032#endif
1033        save_flags(flags);
1034        cli();
1035        if (!tty_hung_up_p(filp))
1036                ch->count--;
1037        restore_flags(flags);
1038        ch->blocked_open++;
1039        while (1) {
1040                set_current_state(TASK_INTERRUPTIBLE);
1041                if (tty_hung_up_p(filp) ||
1042                    !(ch->asyncflags & ASYNC_INITIALIZED)) {
1043#ifdef SERIAL_DO_RESTART
1044                        if (ch->asyncflags & ASYNC_HUP_NOTIFY)
1045                                retval = -EAGAIN;
1046                        else
1047                                retval = -ERESTARTSYS;
1048#else
1049                        retval = -EAGAIN;
1050#endif
1051                        break;
1052                }
1053                if (!(ch->asyncflags & ASYNC_CLOSING) && (do_clocal ||
1054                                                MoxaPortDCDON(ch->port)))
1055                        break;
1056
1057                if (signal_pending(current)) {
1058                        retval = -ERESTARTSYS;
1059                        break;
1060                }
1061                schedule();
1062        }
1063        set_current_state(TASK_RUNNING);
1064        remove_wait_queue(&ch->open_wait, &wait);
1065        if (!tty_hung_up_p(filp))
1066                ch->count++;
1067        ch->blocked_open--;
1068#ifdef SERIAL_DEBUG_OPEN
1069        printk("block_til_ready after blocking: ttys%d, count = %d\n",
1070               ch->line, ch->count);
1071#endif
1072        if (retval)
1073                return (retval);
1074        ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
1075        return (0);
1076}
1077
1078static void setup_empty_event(struct tty_struct *tty)
1079{
1080        struct moxa_str *ch = tty->driver_data;
1081        unsigned long flags;
1082
1083        save_flags(flags);
1084        cli();
1085        ch->statusflags |= EMPTYWAIT;
1086        moxaEmptyTimer_on[ch->port] = 0;
1087        del_timer(&moxaEmptyTimer[ch->port]);
1088        moxaEmptyTimer[ch->port].expires = jiffies + HZ;
1089        moxaEmptyTimer_on[ch->port] = 1;
1090        add_timer(&moxaEmptyTimer[ch->port]);
1091        restore_flags(flags);
1092}
1093
1094static void check_xmit_empty(unsigned long data)
1095{
1096        struct moxa_str *ch;
1097
1098        ch = (struct moxa_str *) data;
1099        moxaEmptyTimer_on[ch->port] = 0;
1100        del_timer(&moxaEmptyTimer[ch->port]);
1101        if (ch->tty && (ch->statusflags & EMPTYWAIT)) {
1102                if (MoxaPortTxQueue(ch->port) == 0) {
1103                        ch->statusflags &= ~EMPTYWAIT;
1104                        tty_wakeup(ch->tty);
1105                        return;
1106                }
1107                moxaEmptyTimer[ch->port].expires = jiffies + HZ;
1108                moxaEmptyTimer_on[ch->port] = 1;
1109                add_timer(&moxaEmptyTimer[ch->port]);
1110        } else
1111                ch->statusflags &= ~EMPTYWAIT;
1112}
1113
1114static void shut_down(struct moxa_str *ch)
1115{
1116        struct tty_struct *tp;
1117
1118        if (!(ch->asyncflags & ASYNC_INITIALIZED))
1119                return;
1120
1121        tp = ch->tty;
1122
1123        MoxaPortDisable(ch->port);
1124
1125        /*
1126         * If we're a modem control device and HUPCL is on, drop RTS & DTR.
1127         */
1128        if (tp->termios->c_cflag & HUPCL)
1129                MoxaPortLineCtrl(ch->port, 0, 0);
1130
1131        ch->asyncflags &= ~ASYNC_INITIALIZED;
1132}
1133
1134static void receive_data(struct moxa_str *ch)
1135{
1136        struct tty_struct *tp;
1137        struct termios *ts;
1138        int i, count, rc, space;
1139        unsigned char *charptr, *flagptr;
1140        unsigned long flags;
1141
1142        ts = NULL;
1143        tp = ch->tty;
1144        if (tp)
1145                ts = tp->termios;
1146        /**************************************************
1147        if ( !tp || !ts || !(ts->c_cflag & CREAD) ) {
1148        *****************************************************/
1149        if (!tp || !ts) {
1150                MoxaPortFlushData(ch->port, 0);
1151                return;
1152        }
1153        space = TTY_FLIPBUF_SIZE - tp->flip.count;
1154        if (space <= 0)
1155                return;
1156        charptr = tp->flip.char_buf_ptr;
1157        flagptr = tp->flip.flag_buf_ptr;
1158        rc = tp->flip.count;
1159        save_flags(flags);
1160        cli();
1161        count = MoxaPortReadData(ch->port, charptr, space);
1162        restore_flags(flags);
1163        for (i = 0; i < count; i++)
1164                *flagptr++ = 0;
1165        charptr += count;
1166        rc += count;
1167        tp->flip.count = rc;
1168        tp->flip.char_buf_ptr = charptr;
1169        tp->flip.flag_buf_ptr = flagptr;
1170        tty_schedule_flip(ch->tty);
1171}
1172
1173#define Magic_code      0x404
1174
1175/*
1176 *    System Configuration
1177 */
1178/*
1179 *    for C218 BIOS initialization
1180 */
1181#define C218_ConfBase   0x800
1182#define C218_status     (C218_ConfBase + 0)     /* BIOS running status    */
1183#define C218_diag       (C218_ConfBase + 2)     /* diagnostic status      */
1184#define C218_key        (C218_ConfBase + 4)     /* WORD (0x218 for C218) */
1185#define C218DLoad_len   (C218_ConfBase + 6)     /* WORD           */
1186#define C218check_sum   (C218_ConfBase + 8)     /* BYTE           */
1187#define C218chksum_ok   (C218_ConfBase + 0x0a)  /* BYTE (1:ok)            */
1188#define C218_TestRx     (C218_ConfBase + 0x10)  /* 8 bytes for 8 ports    */
1189#define C218_TestTx     (C218_ConfBase + 0x18)  /* 8 bytes for 8 ports    */
1190#define C218_RXerr      (C218_ConfBase + 0x20)  /* 8 bytes for 8 ports    */
1191#define C218_ErrFlag    (C218_ConfBase + 0x28)  /* 8 bytes for 8 ports    */
1192
1193#define C218_LoadBuf    0x0F00
1194#define C218_KeyCode    0x218
1195#define CP204J_KeyCode  0x204
1196
1197/*
1198 *    for C320 BIOS initialization
1199 */
1200#define C320_ConfBase   0x800
1201#define C320_LoadBuf    0x0f00
1202#define STS_init        0x05    /* for C320_status        */
1203
1204#define C320_status     C320_ConfBase + 0       /* BIOS running status    */
1205#define C320_diag       C320_ConfBase + 2       /* diagnostic status      */
1206#define C320_key        C320_ConfBase + 4       /* WORD (0320H for C320) */
1207#define C320DLoad_len   C320_ConfBase + 6       /* WORD           */
1208#define C320check_sum   C320_ConfBase + 8       /* WORD           */
1209#define C320chksum_ok   C320_ConfBase + 0x0a    /* WORD (1:ok)            */
1210#define C320bapi_len    C320_ConfBase + 0x0c    /* WORD           */
1211#define C320UART_no     C320_ConfBase + 0x0e    /* WORD           */
1212
1213#define C320_KeyCode    0x320
1214
1215#define FixPage_addr    0x0000  /* starting addr of static page  */
1216#define DynPage_addr    0x2000  /* starting addr of dynamic page */
1217#define C218_start      0x3000  /* starting addr of C218 BIOS prg */
1218#define Control_reg     0x1ff0  /* select page and reset control */
1219#define HW_reset        0x80
1220
1221/*
1222 *    Function Codes
1223 */
1224#define FC_CardReset    0x80
1225#define FC_ChannelReset 1       /* C320 firmware not supported */
1226#define FC_EnableCH     2
1227#define FC_DisableCH    3
1228#define FC_SetParam     4
1229#define FC_SetMode      5
1230#define FC_SetRate      6
1231#define FC_LineControl  7
1232#define FC_LineStatus   8
1233#define FC_XmitControl  9
1234#define FC_FlushQueue   10
1235#define FC_SendBreak    11
1236#define FC_StopBreak    12
1237#define FC_LoopbackON   13
1238#define FC_LoopbackOFF  14
1239#define FC_ClrIrqTable  15
1240#define FC_SendXon      16
1241#define FC_SetTermIrq   17      /* C320 firmware not supported */
1242#define FC_SetCntIrq    18      /* C320 firmware not supported */
1243#define FC_SetBreakIrq  19
1244#define FC_SetLineIrq   20
1245#define FC_SetFlowCtl   21
1246#define FC_GenIrq       22
1247#define FC_InCD180      23
1248#define FC_OutCD180     24
1249#define FC_InUARTreg    23
1250#define FC_OutUARTreg   24
1251#define FC_SetXonXoff   25
1252#define FC_OutCD180CCR  26
1253#define FC_ExtIQueue    27
1254#define FC_ExtOQueue    28
1255#define FC_ClrLineIrq   29
1256#define FC_HWFlowCtl    30
1257#define FC_GetClockRate 35
1258#define FC_SetBaud      36
1259#define FC_SetDataMode  41
1260#define FC_GetCCSR      43
1261#define FC_GetDataError 45
1262#define FC_RxControl    50
1263#define FC_ImmSend      51
1264#define FC_SetXonState  52
1265#define FC_SetXoffState 53
1266#define FC_SetRxFIFOTrig 54
1267#define FC_SetTxFIFOCnt 55
1268#define FC_UnixRate     56
1269#define FC_UnixResetTimer 57
1270
1271#define RxFIFOTrig1     0
1272#define RxFIFOTrig4     1
1273#define RxFIFOTrig8     2
1274#define RxFIFOTrig14    3
1275
1276/*
1277 *    Dual-Ported RAM
1278 */
1279#define DRAM_global     0
1280#define INT_data        (DRAM_global + 0)
1281#define Config_base     (DRAM_global + 0x108)
1282
1283#define IRQindex        (INT_data + 0)
1284#define IRQpending      (INT_data + 4)
1285#define IRQtable        (INT_data + 8)
1286
1287/*
1288 *    Interrupt Status
1289 */
1290#define IntrRx          0x01    /* receiver data O.K.             */
1291#define IntrTx          0x02    /* transmit buffer empty  */
1292#define IntrFunc        0x04    /* function complete              */
1293#define IntrBreak       0x08    /* received break         */
1294#define IntrLine        0x10    /* line status change
1295                                   for transmitter                */
1296#define IntrIntr        0x20    /* received INTR code             */
1297#define IntrQuit        0x40    /* received QUIT code             */
1298#define IntrEOF         0x80    /* received EOF code              */
1299
1300#define IntrRxTrigger   0x100   /* rx data count reach tigger value */
1301#define IntrTxTrigger   0x200   /* tx data count below trigger value */
1302
1303#define Magic_no        (Config_base + 0)
1304#define Card_model_no   (Config_base + 2)
1305#define Total_ports     (Config_base + 4)
1306#define Module_cnt      (Config_base + 8)
1307#define Module_no       (Config_base + 10)
1308#define Timer_10ms      (Config_base + 14)
1309#define Disable_IRQ     (Config_base + 20)
1310#define TMS320_PORT1    (Config_base + 22)
1311#define TMS320_PORT2    (Config_base + 24)
1312#define TMS320_CLOCK    (Config_base + 26)
1313
1314/*
1315 *    DATA BUFFER in DRAM
1316 */
1317#define Extern_table    0x400   /* Base address of the external table
1318                                   (24 words *    64) total 3K bytes
1319                                   (24 words * 128) total 6K bytes */
1320#define Extern_size     0x60    /* 96 bytes                       */
1321#define RXrptr          0x00    /* read pointer for RX buffer     */
1322#define RXwptr          0x02    /* write pointer for RX buffer    */
1323#define TXrptr          0x04    /* read pointer for TX buffer     */
1324#define TXwptr          0x06    /* write pointer for TX buffer    */
1325#define HostStat        0x08    /* IRQ flag and general flag      */
1326#define FlagStat        0x0A
1327#define FlowControl     0x0C    /* B7 B6 B5 B4 B3 B2 B1 B0              */
1328                                        /*  x  x  x  x  |  |  |  |            */
1329                                        /*              |  |  |  + CTS flow   */
1330                                        /*              |  |  +--- RTS flow   */
1331                                        /*              |  +------ TX Xon/Xoff */
1332                                        /*              +--------- RX Xon/Xoff */
1333#define Break_cnt       0x0E    /* received break count   */
1334#define CD180TXirq      0x10    /* if non-0: enable TX irq        */
1335#define RX_mask         0x12
1336#define TX_mask         0x14
1337#define Ofs_rxb         0x16
1338#define Ofs_txb         0x18
1339#define Page_rxb        0x1A
1340#define Page_txb        0x1C
1341#define EndPage_rxb     0x1E
1342#define EndPage_txb     0x20
1343#define Data_error      0x22
1344#define RxTrigger       0x28
1345#define TxTrigger       0x2a
1346
1347#define rRXwptr         0x34
1348#define Low_water       0x36
1349
1350#define FuncCode        0x40
1351#define FuncArg         0x42
1352#define FuncArg1        0x44
1353
1354#define C218rx_size     0x2000  /* 8K bytes */
1355#define C218tx_size     0x8000  /* 32K bytes */
1356
1357#define C218rx_mask     (C218rx_size - 1)
1358#define C218tx_mask     (C218tx_size - 1)
1359
1360#define C320p8rx_size   0x2000
1361#define C320p8tx_size   0x8000
1362#define C320p8rx_mask   (C320p8rx_size - 1)
1363#define C320p8tx_mask   (C320p8tx_size - 1)
1364
1365#define C320p16rx_size  0x2000
1366#define C320p16tx_size  0x4000
1367#define C320p16rx_mask  (C320p16rx_size - 1)
1368#define C320p16tx_mask  (C320p16tx_size - 1)
1369
1370#define C320p24rx_size  0x2000
1371#define C320p24tx_size  0x2000
1372#define C320p24rx_mask  (C320p24rx_size - 1)
1373#define C320p24tx_mask  (C320p24tx_size - 1)
1374
1375#define C320p32rx_size  0x1000
1376#define C320p32tx_size  0x1000
1377#define C320p32rx_mask  (C320p32rx_size - 1)
1378#define C320p32tx_mask  (C320p32tx_size - 1)
1379
1380#define Page_size       0x2000
1381#define Page_mask       (Page_size - 1)
1382#define C218rx_spage    3
1383#define C218tx_spage    4
1384#define C218rx_pageno   1
1385#define C218tx_pageno   4
1386#define C218buf_pageno  5
1387
1388#define C320p8rx_spage  3
1389#define C320p8tx_spage  4
1390#define C320p8rx_pgno   1
1391#define C320p8tx_pgno   4
1392#define C320p8buf_pgno  5
1393
1394#define C320p16rx_spage 3
1395#define C320p16tx_spage 4
1396#define C320p16rx_pgno  1
1397#define C320p16tx_pgno  2
1398#define C320p16buf_pgno 3
1399
1400#define C320p24rx_spage 3
1401#define C320p24tx_spage 4
1402#define C320p24rx_pgno  1
1403#define C320p24tx_pgno  1
1404#define C320p24buf_pgno 2
1405
1406#define C320p32rx_spage 3
1407#define C320p32tx_ofs   C320p32rx_size
1408#define C320p32tx_spage 3
1409#define C320p32buf_pgno 1
1410
1411/*
1412 *    Host Status
1413 */
1414#define WakeupRx        0x01
1415#define WakeupTx        0x02
1416#define WakeupBreak     0x08
1417#define WakeupLine      0x10
1418#define WakeupIntr      0x20
1419#define WakeupQuit      0x40
1420#define WakeupEOF       0x80    /* used in VTIME control */
1421#define WakeupRxTrigger 0x100
1422#define WakeupTxTrigger 0x200
1423/*
1424 *    Flag status
1425 */
1426#define Rx_over         0x01
1427#define Xoff_state      0x02
1428#define Tx_flowOff      0x04
1429#define Tx_enable       0x08
1430#define CTS_state       0x10
1431#define DSR_state       0x20
1432#define DCD_state       0x80
1433/*
1434 *    FlowControl
1435 */
1436#define CTS_FlowCtl     1
1437#define RTS_FlowCtl     2
1438#define Tx_FlowCtl      4
1439#define Rx_FlowCtl      8
1440#define IXM_IXANY       0x10
1441
1442#define LowWater        128
1443
1444#define DTR_ON          1
1445#define RTS_ON          2
1446#define CTS_ON          1
1447#define DSR_ON          2
1448#define DCD_ON          8
1449
1450/* mode definition */
1451#define MX_CS8          0x03
1452#define MX_CS7          0x02
1453#define MX_CS6          0x01
1454#define MX_CS5          0x00
1455
1456#define MX_STOP1        0x00
1457#define MX_STOP15       0x04
1458#define MX_STOP2        0x08
1459
1460#define MX_PARNONE      0x00
1461#define MX_PAREVEN      0x40
1462#define MX_PARODD       0xC0
1463
1464/*
1465 *    Query
1466 */
1467#define QueryPort       MAX_PORTS
1468
1469
1470
1471struct mon_str {
1472        int tick;
1473        int rxcnt[MAX_PORTS];
1474        int txcnt[MAX_PORTS];
1475};
1476typedef struct mon_str mon_st;
1477
1478#define         DCD_changed     0x01
1479#define         DCD_oldstate    0x80
1480
1481static unsigned char moxaBuff[10240];
1482static void __iomem *moxaIntNdx[MAX_BOARDS];
1483static void __iomem *moxaIntPend[MAX_BOARDS];
1484static void __iomem *moxaIntTable[MAX_BOARDS];
1485static char moxaChkPort[MAX_PORTS];
1486static char moxaLineCtrl[MAX_PORTS];
1487static void __iomem *moxaTableAddr[MAX_PORTS];
1488static long moxaCurBaud[MAX_PORTS];
1489static char moxaDCDState[MAX_PORTS];
1490static char moxaLowChkFlag[MAX_PORTS];
1491static int moxaLowWaterChk;
1492static int moxaCard;
1493static mon_st moxaLog;
1494static int moxaFuncTout;
1495static ushort moxaBreakCnt[MAX_PORTS];
1496
1497static void moxadelay(int);
1498static void moxafunc(void __iomem *, int, ushort);
1499static void wait_finish(void __iomem *);
1500static void low_water_check(void __iomem *);
1501static int moxaloadbios(int, unsigned char __user *, int);
1502static int moxafindcard(int);
1503static int moxaload320b(int, unsigned char __user *, int);
1504static int moxaloadcode(int, unsigned char __user *, int);
1505static int moxaloadc218(int, void __iomem *, int);
1506static int moxaloadc320(int, void __iomem *, int, int *);
1507
1508/*****************************************************************************
1509 *      Driver level functions:                                              *
1510 *      1. MoxaDriverInit(void);                                             *
1511 *      2. MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port);   *
1512 *      3. MoxaDriverPoll(void);                                             *
1513 *****************************************************************************/
1514void MoxaDriverInit(void)
1515{
1516        int i;
1517
1518        moxaFuncTout = HZ / 2;  /* 500 mini-seconds */
1519        moxaCard = 0;
1520        moxaLog.tick = 0;
1521        moxaLowWaterChk = 0;
1522        for (i = 0; i < MAX_PORTS; i++) {
1523                moxaChkPort[i] = 0;
1524                moxaLowChkFlag[i] = 0;
1525                moxaLineCtrl[i] = 0;
1526                moxaLog.rxcnt[i] = 0;
1527                moxaLog.txcnt[i] = 0;
1528        }
1529}
1530
1531#define MOXA            0x400
1532#define MOXA_GET_IQUEUE         (MOXA + 1)      /* get input buffered count */
1533#define MOXA_GET_OQUEUE         (MOXA + 2)      /* get output buffered count */
1534#define MOXA_INIT_DRIVER        (MOXA + 6)      /* moxaCard=0 */
1535#define MOXA_LOAD_BIOS          (MOXA + 9)      /* download BIOS */
1536#define MOXA_FIND_BOARD         (MOXA + 10)     /* Check if MOXA card exist? */
1537#define MOXA_LOAD_C320B         (MOXA + 11)     /* download 320B firmware */
1538#define MOXA_LOAD_CODE          (MOXA + 12)     /* download firmware */
1539#define MOXA_GETDATACOUNT       (MOXA + 23)
1540#define MOXA_GET_IOQUEUE        (MOXA + 27)
1541#define MOXA_FLUSH_QUEUE        (MOXA + 28)
1542#define MOXA_GET_CONF           (MOXA + 35)     /* configuration */
1543#define MOXA_GET_MAJOR          (MOXA + 63)
1544#define MOXA_GET_CUMAJOR        (MOXA + 64)
1545#define MOXA_GETMSTATUS         (MOXA + 65)
1546
1547
1548struct moxaq_str {
1549        int inq;
1550        int outq;
1551};
1552
1553struct dl_str {
1554        char __user *buf;
1555        int len;
1556        int cardno;
1557};
1558
1559static struct moxaq_str temp_queue[MAX_PORTS];
1560static struct dl_str dltmp;
1561
1562void MoxaPortFlushData(int port, int mode)
1563{
1564        void __iomem *ofsAddr;
1565        if ((mode < 0) || (mode > 2))
1566                return;
1567        ofsAddr = moxaTableAddr[port];
1568        moxafunc(ofsAddr, FC_FlushQueue, mode);
1569        if (mode != 1) {
1570                moxaLowChkFlag[port] = 0;
1571                low_water_check(ofsAddr);
1572        }
1573}
1574
1575int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
1576{
1577        int i;
1578        int status;
1579        int MoxaPortTxQueue(int), MoxaPortRxQueue(int);
1580        void __user *argp = (void __user *)arg;
1581
1582        if (port == QueryPort) {
1583                if ((cmd != MOXA_GET_CONF) && (cmd != MOXA_INIT_DRIVER) &&
1584                    (cmd != MOXA_LOAD_BIOS) && (cmd != MOXA_FIND_BOARD) && (cmd != MOXA_LOAD_C320B) &&
1585                 (cmd != MOXA_LOAD_CODE) && (cmd != MOXA_GETDATACOUNT) &&
1586                  (cmd != MOXA_GET_IOQUEUE) && (cmd != MOXA_GET_MAJOR) &&
1587                    (cmd != MOXA_GET_CUMAJOR) && (cmd != MOXA_GETMSTATUS))
1588                        return (-EINVAL);
1589        }
1590        switch (cmd) {
1591        case MOXA_GET_CONF:
1592                if(copy_to_user(argp, &moxa_boards, MAX_BOARDS * sizeof(moxa_board_conf)))
1593                        return -EFAULT;
1594                return (0);
1595        case MOXA_INIT_DRIVER:
1596                if ((int) arg == 0x404)
1597                        MoxaDriverInit();
1598                return (0);
1599        case MOXA_GETDATACOUNT:
1600                moxaLog.tick = jiffies;
1601                if(copy_to_user(argp, &moxaLog, sizeof(mon_st)))
1602                        return -EFAULT;
1603                return (0);
1604        case MOXA_FLUSH_QUEUE:
1605                MoxaPortFlushData(port, arg);
1606                return (0);
1607        case MOXA_GET_IOQUEUE:
1608                for (i = 0; i < MAX_PORTS; i++) {
1609                        if (moxaChkPort[i]) {
1610                                temp_queue[i].inq = MoxaPortRxQueue(i);
1611                                temp_queue[i].outq = MoxaPortTxQueue(i);
1612                        }
1613                }
1614                if(copy_to_user(argp, temp_queue, sizeof(struct moxaq_str) * MAX_PORTS))
1615                        return -EFAULT;
1616                return (0);
1617        case MOXA_GET_OQUEUE:
1618                i = MoxaPortTxQueue(port);
1619                return put_user(i, (unsigned long __user *)argp);
1620        case MOXA_GET_IQUEUE:
1621                i = MoxaPortRxQueue(port);
1622                return put_user(i, (unsigned long __user *)argp);
1623        case MOXA_GET_MAJOR:
1624                if(copy_to_user(argp, &ttymajor, sizeof(int)))
1625                        return -EFAULT;
1626                return 0;
1627        case MOXA_GET_CUMAJOR:
1628                i = 0;
1629                if(copy_to_user(argp, &i, sizeof(int)))
1630                        return -EFAULT;
1631                return 0;
1632        case MOXA_GETMSTATUS:
1633                for (i = 0; i < MAX_PORTS; i++) {
1634                        GMStatus[i].ri = 0;
1635                        GMStatus[i].dcd = 0;
1636                        GMStatus[i].dsr = 0;
1637                        GMStatus[i].cts = 0;
1638                        if (!moxaChkPort[i]) {
1639                                continue;
1640                        } else {
1641                                status = MoxaPortLineStatus(moxaChannels[i].port);
1642                                if (status & 1)
1643                                        GMStatus[i].cts = 1;
1644                                if (status & 2)
1645                                        GMStatus[i].dsr = 1;
1646                                if (status & 4)
1647                                        GMStatus[i].dcd = 1;
1648                        }
1649
1650                        if (!moxaChannels[i].tty || !moxaChannels[i].tty->termios)
1651                                GMStatus[i].cflag = moxaChannels[i].cflag;
1652                        else
1653                                GMStatus[i].cflag = moxaChannels[i].tty->termios->c_cflag;
1654                }
1655                if(copy_to_user(argp, GMStatus, sizeof(struct mxser_mstatus) * MAX_PORTS))
1656                        return -EFAULT;
1657                return 0;
1658        default:
1659                return (-ENOIOCTLCMD);
1660        case MOXA_LOAD_BIOS:
1661        case MOXA_FIND_BOARD:
1662        case MOXA_LOAD_C320B:
1663        case MOXA_LOAD_CODE:
1664                break;
1665        }
1666
1667        if(copy_from_user(&dltmp, argp, sizeof(struct dl_str)))
1668                return -EFAULT;
1669        if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS)
1670                return -EINVAL;
1671
1672        switch(cmd)
1673        {
1674        case MOXA_LOAD_BIOS:
1675                i = moxaloadbios(dltmp.cardno, dltmp.buf, dltmp.len);
1676                return (i);
1677        case MOXA_FIND_BOARD:
1678                return moxafindcard(dltmp.cardno);
1679        case MOXA_LOAD_C320B:
1680                moxaload320b(dltmp.cardno, dltmp.buf, dltmp.len);
1681        default: /* to keep gcc happy */
1682                return (0);
1683        case MOXA_LOAD_CODE:
1684                i = moxaloadcode(dltmp.cardno, dltmp.buf, dltmp.len);
1685                if (i == -1)
1686                        return (-EFAULT);
1687                return (i);
1688
1689        }
1690}
1691
1692int MoxaDriverPoll(void)
1693{
1694        register ushort temp;
1695        register int card;
1696        void __iomem *ofsAddr;
1697        void __iomem *ip;
1698        int port, p, ports;
1699
1700        if (moxaCard == 0)
1701                return (-1);
1702        for (card = 0; card < MAX_BOARDS; card++) {
1703                if ((ports = moxa_boards[card].numPorts) == 0)
1704                        continue;
1705                if (readb(moxaIntPend[card]) == 0xff) {
1706                        ip = moxaIntTable[card] + readb(moxaIntNdx[card]);
1707                        p = card * MAX_PORTS_PER_BOARD;
1708                        ports <<= 1;
1709                        for (port = 0; port < ports; port += 2, p++) {
1710                                if ((temp = readw(ip + port)) != 0) {
1711                                        writew(0, ip + port);
1712                                        ofsAddr = moxaTableAddr[p];
1713                                        if (temp & IntrTx)
1714                                                writew(readw(ofsAddr + HostStat) & ~WakeupTx, ofsAddr + HostStat);
1715                                        if (temp & IntrBreak) {
1716                                                moxaBreakCnt[p]++;
1717                                        }
1718                                        if (temp & IntrLine) {
1719                                                if (readb(ofsAddr + FlagStat) & DCD_state) {
1720                                                        if ((moxaDCDState[p] & DCD_oldstate) == 0)
1721                                                                moxaDCDState[p] = (DCD_oldstate |
1722                                                                                   DCD_changed);
1723                                                } else {
1724                                                        if (moxaDCDState[p] & DCD_oldstate)
1725                                                                moxaDCDState[p] = DCD_changed;
1726                                                }
1727                                        }
1728                                }
1729                        }
1730                        writeb(0, moxaIntPend[card]);
1731                }
1732                if (moxaLowWaterChk) {
1733                        p = card * MAX_PORTS_PER_BOARD;
1734                        for (port = 0; port < ports; port++, p++) {
1735                                if (moxaLowChkFlag[p]) {
1736                                        moxaLowChkFlag[p] = 0;
1737                                        ofsAddr = moxaTableAddr[p];
1738                                        low_water_check(ofsAddr);
1739                                }
1740                        }
1741                }
1742        }
1743        moxaLowWaterChk = 0;
1744        return (0);
1745}
1746
1747/*****************************************************************************
1748 *      Card level function:                                                 *
1749 *      1. MoxaPortsOfCard(int cardno);                                      *
1750 *****************************************************************************/
1751int MoxaPortsOfCard(int cardno)
1752{
1753
1754        if (moxa_boards[cardno].boardType == 0)
1755                return (0);
1756        return (moxa_boards[cardno].numPorts);
1757}
1758
1759/*****************************************************************************
1760 *      Port level functions:                                                *
1761 *      1.  MoxaPortIsValid(int port);                                       *
1762 *      2.  MoxaPortEnable(int port);                                        *
1763 *      3.  MoxaPortDisable(int port);                                       *
1764 *      4.  MoxaPortGetMaxBaud(int port);                                    *
1765 *      5.  MoxaPortGetCurBaud(int port);                                    *
1766 *      6.  MoxaPortSetBaud(int port, long baud);                            *
1767 *      7.  MoxaPortSetMode(int port, int databit, int stopbit, int parity); *
1768 *      8.  MoxaPortSetTermio(int port, unsigned char *termio);              *
1769 *      9.  MoxaPortGetLineOut(int port, int *dtrState, int *rtsState);      *
1770 *      10. MoxaPortLineCtrl(int port, int dtrState, int rtsState);          *
1771 *      11. MoxaPortFlowCtrl(int port, int rts, int cts, int rx, int tx,int xany);    *
1772 *      12. MoxaPortLineStatus(int port);                                    *
1773 *      13. MoxaPortDCDChange(int port);                                     *
1774 *      14. MoxaPortDCDON(int port);                                         *
1775 *      15. MoxaPortFlushData(int port, int mode);                           *
1776 *      16. MoxaPortWriteData(int port, unsigned char * buffer, int length); *
1777 *      17. MoxaPortReadData(int port, unsigned char * buffer, int length);  *
1778 *      18. MoxaPortTxBufSize(int port);                                     *
1779 *      19. MoxaPortRxBufSize(int port);                                     *
1780 *      20. MoxaPortTxQueue(int port);                                       *
1781 *      21. MoxaPortTxFree(int port);                                        *
1782 *      22. MoxaPortRxQueue(int port);                                       *
1783 *      23. MoxaPortRxFree(int port);                                        *
1784 *      24. MoxaPortTxDisable(int port);                                     *
1785 *      25. MoxaPortTxEnable(int port);                                      *
1786 *      26. MoxaPortGetBrkCnt(int port);                                     *
1787 *      27. MoxaPortResetBrkCnt(int port);                                   *
1788 *      28. MoxaPortSetXonXoff(int port, int xonValue, int xoffValue);       *
1789 *      29. MoxaPortIsTxHold(int port);                                      *
1790 *      30. MoxaPortSendBreak(int port, int ticks);                          *
1791 *****************************************************************************/
1792/*
1793 *    Moxa Port Number Description:
1794 *
1795 *      MOXA serial driver supports up to 4 MOXA-C218/C320 boards. And,
1796 *      the port number using in MOXA driver functions will be 0 to 31 for
1797 *      first MOXA board, 32 to 63 for second, 64 to 95 for third and 96
1798 *      to 127 for fourth. For example, if you setup three MOXA boards,
1799 *      first board is C218, second board is C320-16 and third board is
1800 *      C320-32. The port number of first board (C218 - 8 ports) is from
1801 *      0 to 7. The port number of second board (C320 - 16 ports) is form
1802 *      32 to 47. The port number of third board (C320 - 32 ports) is from
1803 *      64 to 95. And those port numbers form 8 to 31, 48 to 63 and 96 to
1804 *      127 will be invalid.
1805 *
1806 *
1807 *      Moxa Functions Description:
1808 *
1809 *      Function 1:     Driver initialization routine, this routine must be
1810 *                      called when initialized driver.
1811 *      Syntax:
1812 *      void MoxaDriverInit();
1813 *
1814 *
1815 *      Function 2:     Moxa driver private IOCTL command processing.
1816 *      Syntax:
1817 *      int  MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port);
1818 *
1819 *           unsigned int cmd   : IOCTL command
1820 *           unsigned long arg  : IOCTL argument
1821 *           int port           : port number (0 - 127)
1822 *
1823 *           return:    0  (OK)
1824 *                      -EINVAL
1825 *                      -ENOIOCTLCMD
1826 *
1827 *
1828 *      Function 3:     Moxa driver polling process routine.
1829 *      Syntax:
1830 *      int  MoxaDriverPoll(void);
1831 *
1832 *           return:    0       ; polling O.K.
1833 *                      -1      : no any Moxa card.             
1834 *
1835 *
1836 *      Function 4:     Get the ports of this card.
1837 *      Syntax:
1838 *      int  MoxaPortsOfCard(int cardno);
1839 *
1840 *           int cardno         : card number (0 - 3)
1841 *
1842 *           return:    0       : this card is invalid
1843 *                      8/16/24/32
1844 *
1845 *
1846 *      Function 5:     Check this port is valid or invalid
1847 *      Syntax:
1848 *      int  MoxaPortIsValid(int port);
1849 *           int port           : port number (0 - 127, ref port description)
1850 *
1851 *           return:    0       : this port is invalid
1852 *                      1       : this port is valid
1853 *
1854 *
1855 *      Function 6:     Enable this port to start Tx/Rx data.
1856 *      Syntax:
1857 *      void MoxaPortEnable(int port);
1858 *           int port           : port number (0 - 127)
1859 *
1860 *
1861 *      Function 7:     Disable this port
1862 *      Syntax:
1863 *      void MoxaPortDisable(int port);
1864 *           int port           : port number (0 - 127)
1865 *
1866 *
1867 *      Function 8:     Get the maximun available baud rate of this port.
1868 *      Syntax:
1869 *      long MoxaPortGetMaxBaud(int port);
1870 *           int port           : port number (0 - 127)
1871 *
1872 *           return:    0       : this port is invalid
1873 *                      38400/57600/115200 bps
1874 *
1875 *
1876 *      Function 9:     Get the current baud rate of this port.
1877 *      Syntax:
1878 *      long MoxaPortGetCurBaud(int port);
1879 *           int port           : port number (0 - 127)
1880 *
1881 *           return:    0       : this port is invalid
1882 *                      50 - 115200 bps
1883 *
1884 *
1885 *      Function 10:    Setting baud rate of this port.
1886 *      Syntax:
1887 *      long MoxaPortSetBaud(int port, long baud);
1888 *           int port           : port number (0 - 127)
1889 *           long baud          : baud rate (50 - 115200)
1890 *
1891 *           return:    0       : this port is invalid or baud < 50
1892 *                      50 - 115200 : the real baud rate set to the port, if
1893 *                                    the argument baud is large than maximun
1894 *                                    available baud rate, the real setting
1895 *                                    baud rate will be the maximun baud rate.
1896 *
1897 *
1898 *      Function 11:    Setting the data-bits/stop-bits/parity of this port
1899 *      Syntax:
1900 *      int  MoxaPortSetMode(int port, int databits, int stopbits, int parity);
1901 *           int port           : port number (0 - 127)
1902 *           int databits       : data bits (8/7/6/5)
1903 *           int stopbits       : stop bits (2/1/0, 0 show 1.5 stop bits)
1904 int parity     : parity (0:None,1:Odd,2:Even,3:Mark,4:Space)
1905 *
1906 *           return:    -1      : invalid parameter
1907 *                      0       : setting O.K.
1908 *
1909 *
1910 *      Function 12:    Configure the port.
1911 *      Syntax:
1912 *      int  MoxaPortSetTermio(int port, struct termios *termio);
1913 *           int port           : port number (0 - 127)
1914 *           struct termios * termio : termio structure pointer
1915 *
1916 *           return:    -1      : this port is invalid or termio == NULL
1917 *                      0       : setting O.K.
1918 *
1919 *
1920 *      Function 13:    Get the DTR/RTS state of this port.
1921 *      Syntax:
1922 *      int  MoxaPortGetLineOut(int port, int *dtrState, int *rtsState);
1923 *           int port           : port number (0 - 127)
1924 *           int * dtrState     : pointer to INT to receive the current DTR
1925 *                                state. (if NULL, this function will not
1926 *                                write to this address)
1927 *           int * rtsState     : pointer to INT to receive the current RTS
1928 *                                state. (if NULL, this function will not
1929 *                                write to this address)
1930 *
1931 *           return:    -1      : this port is invalid
1932 *                      0       : O.K.
1933 *
1934 *
1935 *      Function 14:    Setting the DTR/RTS output state of this port.
1936 *      Syntax:
1937 *      void MoxaPortLineCtrl(int port, int dtrState, int rtsState);
1938 *           int port           : port number (0 - 127)
1939 *           int dtrState       : DTR output state (0: off, 1: on)
1940 *           int rtsState       : RTS output state (0: off, 1: on)
1941 *
1942 *
1943 *      Function 15:    Setting the flow control of this port.
1944 *      Syntax:
1945 *      void MoxaPortFlowCtrl(int port, int rtsFlow, int ctsFlow, int rxFlow,
1946 *                            int txFlow,int xany);
1947 *           int port           : port number (0 - 127)
1948 *           int rtsFlow        : H/W RTS flow control (0: no, 1: yes)
1949 *           int ctsFlow        : H/W CTS flow control (0: no, 1: yes)
1950 *           int rxFlow         : S/W Rx XON/XOFF flow control (0: no, 1: yes)
1951 *           int txFlow         : S/W Tx XON/XOFF flow control (0: no, 1: yes)
1952 *           int xany           : S/W XANY flow control (0: no, 1: yes)
1953 *
1954 *
1955 *      Function 16:    Get ths line status of this port
1956 *      Syntax:
1957 *      int  MoxaPortLineStatus(int port);
1958 *           int port           : port number (0 - 127)
1959 *
1960 *           return:    Bit 0 - CTS state (0: off, 1: on)
1961 *                      Bit 1 - DSR state (0: off, 1: on)
1962 *                      Bit 2 - DCD state (0: off, 1: on)
1963 *
1964 *
1965 *      Function 17:    Check the DCD state has changed since the last read
1966 *                      of this function.
1967 *      Syntax:
1968 *      int  MoxaPortDCDChange(int port);
1969 *           int port           : port number (0 - 127)
1970 *
1971 *           return:    0       : no changed
1972 *                      1       : DCD has changed
1973 *
1974 *
1975 *      Function 18:    Check ths current DCD state is ON or not.
1976 *      Syntax:
1977 *      int  MoxaPortDCDON(int port);
1978 *           int port           : port number (0 - 127)
1979 *
1980 *           return:    0       : DCD off
1981 *                      1       : DCD on
1982 *
1983 *
1984 *      Function 19:    Flush the Rx/Tx buffer data of this port.
1985 *      Syntax:
1986 *      void MoxaPortFlushData(int port, int mode);
1987 *           int port           : port number (0 - 127)
1988 *           int mode    
1989 *                      0       : flush the Rx buffer 
1990 *                      1       : flush the Tx buffer 
1991 *                      2       : flush the Rx and Tx buffer 
1992 *
1993 *
1994 *      Function 20:    Write data.
1995 *      Syntax:
1996 *      int  MoxaPortWriteData(int port, unsigned char * buffer, int length);
1997 *           int port           : port number (0 - 127)
1998 *           unsigned char * buffer     : pointer to write data buffer.
1999 *           int length         : write data length
2000 *
2001 *           return:    0 - length      : real write data length
2002 *
2003 *
2004 *      Function 21:    Read data.
2005 *      Syntax:
2006 *      int  MoxaPortReadData(int port, unsigned char * buffer, int length);
2007 *           int port           : port number (0 - 127)
2008 *           unsigned char * buffer     : pointer to read data buffer.
2009 *           int length         : read data buffer length
2010 *
2011 *           return:    0 - length      : real read data length
2012 *
2013 *
2014 *      Function 22:    Get the Tx buffer size of this port
2015 *      Syntax:
2016 *      int  MoxaPortTxBufSize(int port);
2017 *           int port           : port number (0 - 127)
2018 *
2019 *           return:    ..      : Tx buffer size
2020 *
2021 *
2022 *      Function 23:    Get the Rx buffer size of this port
2023 *      Syntax:
2024 *      int  MoxaPortRxBufSize(int port);
2025 *           int port           : port number (0 - 127)
2026 *
2027 *           return:    ..      : Rx buffer size
2028 *
2029 *
2030 *      Function 24:    Get the Tx buffer current queued data bytes
2031 *      Syntax:
2032 *      int  MoxaPortTxQueue(int port);
2033 *           int port           : port number (0 - 127)
2034 *
2035 *           return:    ..      : Tx buffer current queued data bytes
2036 *
2037 *
2038 *      Function 25:    Get the Tx buffer current free space
2039 *      Syntax:
2040 *      int  MoxaPortTxFree(int port);
2041 *           int port           : port number (0 - 127)
2042 *
2043 *           return:    ..      : Tx buffer current free space
2044 *
2045 *
2046 *      Function 26:    Get the Rx buffer current queued data bytes
2047 *      Syntax:
2048 *      int  MoxaPortRxQueue(int port);
2049 *           int port           : port number (0 - 127)
2050 *
2051 *           return:    ..      : Rx buffer current queued data bytes
2052 *
2053 *
2054 *      Function 27:    Get the Rx buffer current free space
2055 *      Syntax:
2056 *      int  MoxaPortRxFree(int port);
2057 *           int port           : port number (0 - 127)
2058 *
2059 *           return:    ..      : Rx buffer current free space
2060 *
2061 *
2062 *      Function 28:    Disable port data transmission.
2063 *      Syntax:
2064 *      void MoxaPortTxDisable(int port);
2065 *           int port           : port number (0 - 127)
2066 *
2067 *
2068 *      Function 29:    Enable port data transmission.
2069 *      Syntax:
2070 *      void MoxaPortTxEnable(int port);
2071 *           int port           : port number (0 - 127)
2072 *
2073 *
2074 *      Function 30:    Get the received BREAK signal count.
2075 *      Syntax:
2076 *      int  MoxaPortGetBrkCnt(int port);
2077 *           int port           : port number (0 - 127)
2078 *
2079 *           return:    0 - ..  : BREAK signal count
2080 *
2081 *
2082 *      Function 31:    Get the received BREAK signal count and reset it.
2083 *      Syntax:
2084 *      int  MoxaPortResetBrkCnt(int port);
2085 *           int port           : port number (0 - 127)
2086 *
2087 *           return:    0 - ..  : BREAK signal count
2088 *
2089 *
2090 *      Function 32:    Set the S/W flow control new XON/XOFF value, default
2091 *                      XON is 0x11 & XOFF is 0x13.
2092 *      Syntax:
2093 *      void MoxaPortSetXonXoff(int port, int xonValue, int xoffValue);
2094 *           int port           : port number (0 - 127)
2095 *           int xonValue       : new XON value (0 - 255)
2096 *           int xoffValue      : new XOFF value (0 - 255)
2097 *
2098 *
2099 *      Function 33:    Check this port's transmission is hold by remote site
2100 *                      because the flow control.
2101 *      Syntax:
2102 *      int  MoxaPortIsTxHold(int port);
2103 *           int port           : port number (0 - 127)
2104 *
2105 *           return:    0       : normal
2106 *                      1       : hold by remote site
2107 *
2108 *
2109 *      Function 34:    Send out a BREAK signal.
2110 *      Syntax:
2111 *      void MoxaPortSendBreak(int port, int ms100);
2112 *           int port           : port number (0 - 127)
2113 *           int ms100          : break signal time interval.
2114 *                                unit: 100 mini-second. if ms100 == 0, it will
2115 *                                send out a about 250 ms BREAK signal.
2116 *
2117 */
2118int MoxaPortIsValid(int port)
2119{
2120
2121        if (moxaCard == 0)
2122                return (0);
2123        if (moxaChkPort[port] == 0)
2124                return (0);
2125        return (1);
2126}
2127
2128void MoxaPortEnable(int port)
2129{
2130        void __iomem *ofsAddr;
2131        int MoxaPortLineStatus(int);
2132        short lowwater = 512;
2133
2134        ofsAddr = moxaTableAddr[port];
2135        writew(lowwater, ofsAddr + Low_water);
2136        moxaBreakCnt[port] = 0;
2137        if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
2138            (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
2139                moxafunc(ofsAddr, FC_SetBreakIrq, 0);
2140        } else {
2141                writew(readw(ofsAddr + HostStat) | WakeupBreak, ofsAddr + HostStat);
2142        }
2143
2144        moxafunc(ofsAddr, FC_SetLineIrq, Magic_code);
2145        moxafunc(ofsAddr, FC_FlushQueue, 2);
2146
2147        moxafunc(ofsAddr, FC_EnableCH, Magic_code);
2148        MoxaPortLineStatus(port);
2149}
2150
2151void MoxaPortDisable(int port)
2152{
2153        void __iomem *ofsAddr = moxaTableAddr[port];
2154
2155        moxafunc(ofsAddr, FC_SetFlowCtl, 0);    /* disable flow control */
2156        moxafunc(ofsAddr, FC_ClrLineIrq, Magic_code);
2157        writew(0, ofsAddr + HostStat);
2158        moxafunc(ofsAddr, FC_DisableCH, Magic_code);
2159}
2160
2161long MoxaPortGetMaxBaud(int port)
2162{
2163        if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
2164            (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI))
2165                return (460800L);
2166        else
2167                return (921600L);
2168}
2169
2170
2171long MoxaPortSetBaud(int port, long baud)
2172{
2173        void __iomem *ofsAddr;
2174        long max, clock;
2175        unsigned int val;
2176
2177        if ((baud < 50L) || ((max = MoxaPortGetMaxBaud(port)) == 0))
2178                return (0);
2179        ofsAddr = moxaTableAddr[port];
2180        if (baud > max)
2181                baud = max;
2182        if (max == 38400L)
2183                clock = 614400L;        /* for 9.8304 Mhz : max. 38400 bps */
2184        else if (max == 57600L)
2185                clock = 691200L;        /* for 11.0592 Mhz : max. 57600 bps */
2186        else
2187                clock = 921600L;        /* for 14.7456 Mhz : max. 115200 bps */
2188        val = clock / baud;
2189        moxafunc(ofsAddr, FC_SetBaud, val);
2190        baud = clock / val;
2191        moxaCurBaud[port] = baud;
2192        return (baud);
2193}
2194
2195int MoxaPortSetTermio(int port, struct termios *termio)
2196{
2197        void __iomem *ofsAddr;
2198        tcflag_t cflag;
2199        long baud;
2200        tcflag_t mode = 0;
2201
2202        if (moxaChkPort[port] == 0 || termio == 0)
2203                return (-1);
2204        ofsAddr = moxaTableAddr[port];
2205        cflag = termio->c_cflag;        /* termio->c_cflag */
2206
2207        mode = termio->c_cflag & CSIZE;
2208        if (mode == CS5)
2209                mode = MX_CS5;
2210        else if (mode == CS6)
2211                mode = MX_CS6;
2212        else if (mode == CS7)
2213                mode = MX_CS7;
2214        else if (mode == CS8)
2215                mode = MX_CS8;
2216
2217        if (termio->c_cflag & CSTOPB) {
2218                if (mode == MX_CS5)
2219                        mode |= MX_STOP15;
2220                else
2221                        mode |= MX_STOP2;
2222        } else
2223                mode |= MX_STOP1;
2224
2225        if (termio->c_cflag & PARENB) {
2226                if (termio->c_cflag & PARODD)
2227                        mode |= MX_PARODD;
2228                else
2229                        mode |= MX_PAREVEN;
2230        } else
2231                mode |= MX_PARNONE;
2232
2233        moxafunc(ofsAddr, FC_SetDataMode, (ushort) mode);
2234
2235        cflag &= (CBAUD | CBAUDEX);
2236#ifndef B921600
2237#define B921600 (B460800+1)
2238#endif
2239        switch (cflag) {
2240        case B921600:
2241                baud = 921600L;
2242                break;
2243        case B460800:
2244                baud = 460800L;
2245                break;
2246        case B230400:
2247                baud = 230400L;
2248                break;
2249        case B115200:
2250                baud = 115200L;
2251                break;
2252        case B57600:
2253                baud = 57600L;
2254                break;
2255        case B38400:
2256                baud = 38400L;
2257                break;
2258        case B19200:
2259                baud = 19200L;
2260                break;
2261        case B9600:
2262                baud = 9600L;
2263                break;
2264        case B4800:
2265                baud = 4800L;
2266                break;
2267        case B2400:
2268                baud = 2400L;
2269                break;
2270        case B1800:
2271                baud = 1800L;
2272                break;
2273        case B1200:
2274                baud = 1200L;
2275                break;
2276        case B600:
2277                baud = 600L;
2278                break;
2279        case B300:
2280                baud = 300L;
2281                break;
2282        case B200:
2283                baud = 200L;
2284                break;
2285        case B150:
2286                baud = 150L;
2287                break;
2288        case B134:
2289                baud = 134L;
2290                break;
2291        case B110:
2292                baud = 110L;
2293                break;
2294        case B75:
2295                baud = 75L;
2296                break;
2297        case B50:
2298                baud = 50L;
2299                break;
2300        default:
2301                baud = 0;
2302        }
2303        if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
2304            (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
2305                if (baud == 921600L)
2306                        return (-1);
2307        }
2308        MoxaPortSetBaud(port, baud);
2309
2310        if (termio->c_iflag & (IXON | IXOFF | IXANY)) {
2311                writeb(termio->c_cc[VSTART], ofsAddr + FuncArg);
2312                writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1);
2313                writeb(FC_SetXonXoff, ofsAddr + FuncCode);
2314                wait_finish(ofsAddr);
2315
2316        }
2317        return (0);
2318}
2319
2320int MoxaPortGetLineOut(int port, int *dtrState, int *rtsState)
2321{
2322
2323        if (!MoxaPortIsValid(port))
2324                return (-1);
2325        if (dtrState) {
2326                if (moxaLineCtrl[port] & DTR_ON)
2327                        *dtrState = 1;
2328                else
2329                        *dtrState = 0;
2330        }
2331        if (rtsState) {
2332                if (moxaLineCtrl[port] & RTS_ON)
2333                        *rtsState = 1;
2334                else
2335                        *rtsState = 0;
2336        }
2337        return (0);
2338}
2339
2340void MoxaPortLineCtrl(int port, int dtr, int rts)
2341{
2342        void __iomem *ofsAddr;
2343        int mode;
2344
2345        ofsAddr = moxaTableAddr[port];
2346        mode = 0;
2347        if (dtr)
2348                mode |= DTR_ON;
2349        if (rts)
2350                mode |= RTS_ON;
2351        moxaLineCtrl[port] = mode;
2352        moxafunc(ofsAddr, FC_LineControl, mode);
2353}
2354
2355void MoxaPortFlowCtrl(int port, int rts, int cts, int txflow, int rxflow, int txany)
2356{
2357        void __iomem *ofsAddr;
2358        int mode;
2359
2360        ofsAddr = moxaTableAddr[port];
2361        mode = 0;
2362        if (rts)
2363                mode |= RTS_FlowCtl;
2364        if (cts)
2365                mode |= CTS_FlowCtl;
2366        if (txflow)
2367                mode |= Tx_FlowCtl;
2368        if (rxflow)
2369                mode |= Rx_FlowCtl;
2370        if (txany)
2371                mode |= IXM_IXANY;
2372        moxafunc(ofsAddr, FC_SetFlowCtl, mode);
2373}
2374
2375int MoxaPortLineStatus(int port)
2376{
2377        void __iomem *ofsAddr;
2378        int val;
2379
2380        ofsAddr = moxaTableAddr[port];
2381        if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
2382            (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
2383                moxafunc(ofsAddr, FC_LineStatus, 0);
2384                val = readw(ofsAddr + FuncArg);
2385        } else {
2386                val = readw(ofsAddr + FlagStat) >> 4;
2387        }
2388        val &= 0x0B;
2389        if (val & 8) {
2390                val |= 4;
2391                if ((moxaDCDState[port] & DCD_oldstate) == 0)
2392                        moxaDCDState[port] = (DCD_oldstate | DCD_changed);
2393        } else {
2394                if (moxaDCDState[port] & DCD_oldstate)
2395                        moxaDCDState[port] = DCD_changed;
2396        }
2397        val &= 7;
2398        return (val);
2399}
2400
2401int MoxaPortDCDChange(int port)
2402{
2403        int n;
2404
2405        if (moxaChkPort[port] == 0)
2406                return (0);
2407        n = moxaDCDState[port];
2408        moxaDCDState[port] &= ~DCD_changed;
2409        n &= DCD_changed;
2410        return (n);
2411}
2412
2413int MoxaPortDCDON(int port)
2414{
2415        int n;
2416
2417        if (moxaChkPort[port] == 0)
2418                return (0);
2419        if (moxaDCDState[port] & DCD_oldstate)
2420                n = 1;
2421        else
2422                n = 0;
2423        return (n);
2424}
2425
2426
2427/*
2428   int MoxaDumpMem(int port, unsigned char * buffer, int len)
2429   {
2430   int          i;
2431   unsigned long                baseAddr,ofsAddr,ofs;
2432
2433   baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD];
2434   ofs = baseAddr + DynPage_addr + pageofs;
2435   if (len > 0x2000L)
2436   len = 0x2000L;
2437   for (i = 0; i < len; i++)
2438   buffer[i] = readb(ofs+i);
2439   }
2440 */
2441
2442
2443int MoxaPortWriteData(int port, unsigned char * buffer, int len)
2444{
2445        int c, total, i;
2446        ushort tail;
2447        int cnt;
2448        ushort head, tx_mask, spage, epage;
2449        ushort pageno, pageofs, bufhead;
2450        void __iomem *baseAddr, *ofsAddr, *ofs;
2451
2452        ofsAddr = moxaTableAddr[port];
2453        baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD];
2454        tx_mask = readw(ofsAddr + TX_mask);
2455        spage = readw(ofsAddr + Page_txb);
2456        epage = readw(ofsAddr + EndPage_txb);
2457        tail = readw(ofsAddr + TXwptr);
2458        head = readw(ofsAddr + TXrptr);
2459        c = (head > tail) ? (head - tail - 1)
2460            : (head - tail + tx_mask);
2461        if (c > len)
2462                c = len;
2463        moxaLog.txcnt[port] += c;
2464        total = c;
2465        if (spage == epage) {
2466                bufhead = readw(ofsAddr + Ofs_txb);
2467                writew(spage, baseAddr + Control_reg);
2468                while (c > 0) {
2469                        if (head > tail)
2470                                len = head - tail - 1;
2471                        else
2472                                len = tx_mask + 1 - tail;
2473                        len = (c > len) ? len : c;
2474                        ofs = baseAddr + DynPage_addr + bufhead + tail;
2475                        for (i = 0; i < len; i++)
2476                                writeb(*buffer++, ofs + i);
2477                        tail = (tail + len) & tx_mask;
2478                        c -= len;
2479                }
2480                writew(tail, ofsAddr + TXwptr);
2481        } else {
2482                len = c;
2483                pageno = spage + (tail >> 13);
2484                pageofs = tail & Page_mask;
2485                do {
2486                        cnt = Page_size - pageofs;
2487                        if (cnt > c)
2488                                cnt = c;
2489                        c -= cnt;
2490                        writeb(pageno, baseAddr + Control_reg);
2491                        ofs = baseAddr + DynPage_addr + pageofs;
2492                        for (i = 0; i < cnt; i++)
2493                                writeb(*buffer++, ofs + i);
2494                        if (c == 0) {
2495                                writew((tail + len) & tx_mask, ofsAddr + TXwptr);
2496                                break;
2497                        }
2498                        if (++pageno == epage)
2499                                pageno = spage;
2500                        pageofs = 0;
2501                } while (1);
2502        }
2503        writeb(1, ofsAddr + CD180TXirq);        /* start to send */
2504        return (total);
2505}
2506
2507int MoxaPortReadData(int port, unsigned char * buffer, int space)
2508{
2509        register ushort head, pageofs;
2510        int i, count, cnt, len, total, remain;
2511        ushort tail, rx_mask, spage, epage;
2512        ushort pageno, bufhead;
2513        void __iomem *baseAddr, *ofsAddr, *ofs;
2514
2515        ofsAddr = moxaTableAddr[port];
2516        baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD];
2517        head = readw(ofsAddr + RXrptr);
2518        tail = readw(ofsAddr + RXwptr);
2519        rx_mask = readw(ofsAddr + RX_mask);
2520        spage = readw(ofsAddr + Page_rxb);
2521        epage = readw(ofsAddr + EndPage_rxb);
2522        count = (tail >= head) ? (tail - head)
2523            : (tail - head + rx_mask + 1);
2524        if (count == 0)
2525                return (0);
2526
2527        total = (space > count) ? count : space;
2528        remain = count - total;
2529        moxaLog.rxcnt[port] += total;
2530        count = total;
2531        if (spage == epage) {
2532                bufhead = readw(ofsAddr + Ofs_rxb);
2533                writew(spage, baseAddr + Control_reg);
2534                while (count > 0) {
2535                        if (tail >= head)
2536                                len = tail - head;
2537                        else
2538                                len = rx_mask + 1 - head;
2539                        len = (count > len) ? len : count;
2540                        ofs = baseAddr + DynPage_addr + bufhead + head;
2541                        for (i = 0; i < len; i++)
2542                                *buffer++ = readb(ofs + i);
2543                        head = (head + len) & rx_mask;
2544                        count -= len;
2545                }
2546                writew(head, ofsAddr + RXrptr);
2547        } else {
2548                len = count;
2549                pageno = spage + (head >> 13);
2550                pageofs = head & Page_mask;
2551                do {
2552                        cnt = Page_size - pageofs;
2553                        if (cnt > count)
2554                                cnt = count;
2555                        count -= cnt;
2556                        writew(pageno, baseAddr + Control_reg);
2557                        ofs = baseAddr + DynPage_addr + pageofs;
2558                        for (i = 0; i < cnt; i++)
2559                                *buffer++ = readb(ofs + i);
2560                        if (count == 0) {
2561                                writew((head + len) & rx_mask, ofsAddr + RXrptr);
2562                                break;
2563                        }
2564                        if (++pageno == epage)
2565                                pageno = spage;
2566                        pageofs = 0;
2567                } while (1);
2568        }
2569        if ((readb(ofsAddr + FlagStat) & Xoff_state) && (remain < LowWater)) {
2570                moxaLowWaterChk = 1;
2571                moxaLowChkFlag[port] = 1;
2572        }
2573        return (total);
2574}
2575
2576
2577int MoxaPortTxQueue(int port)
2578{
2579        void __iomem *ofsAddr;
2580        ushort rptr, wptr, mask;
2581        int len;
2582
2583        ofsAddr = moxaTableAddr[port];
2584        rptr = readw(ofsAddr + TXrptr);
2585        wptr = readw(ofsAddr + TXwptr);
2586        mask = readw(ofsAddr + TX_mask);
2587        len = (wptr - rptr) & mask;
2588        return (len);
2589}
2590
2591int MoxaPortTxFree(int port)
2592{
2593        void __iomem *ofsAddr;
2594        ushort rptr, wptr, mask;
2595        int len;
2596
2597        ofsAddr = moxaTableAddr[port];
2598        rptr = readw(ofsAddr + TXrptr);
2599        wptr = readw(ofsAddr + TXwptr);
2600        mask = readw(ofsAddr + TX_mask);
2601        len = mask - ((wptr - rptr) & mask);
2602        return (len);
2603}
2604
2605int MoxaPortRxQueue(int port)
2606{
2607        void __iomem *ofsAddr;
2608        ushort rptr, wptr, mask;
2609        int len;
2610
2611        ofsAddr = moxaTableAddr[port];
2612        rptr = readw(ofsAddr + RXrptr);
2613        wptr = readw(ofsAddr + RXwptr);
2614        mask = readw(ofsAddr + RX_mask);
2615        len = (wptr - rptr) & mask;
2616        return (len);
2617}
2618
2619
2620void MoxaPortTxDisable(int port)
2621{
2622        void __iomem *ofsAddr;
2623
2624        ofsAddr = moxaTableAddr[port];
2625        moxafunc(ofsAddr, FC_SetXoffState, Magic_code);
2626}
2627
2628void MoxaPortTxEnable(int port)
2629{
2630        void __iomem *ofsAddr;
2631
2632        ofsAddr = moxaTableAddr[port];
2633        moxafunc(ofsAddr, FC_SetXonState, Magic_code);
2634}
2635
2636
2637int MoxaPortResetBrkCnt(int port)
2638{
2639        ushort cnt;
2640        cnt = moxaBreakCnt[port];
2641        moxaBreakCnt[port] = 0;
2642        return (cnt);
2643}
2644
2645
2646void MoxaPortSendBreak(int port, int ms100)
2647{
2648        void __iomem *ofsAddr;
2649
2650        ofsAddr = moxaTableAddr[port];
2651        if (ms100) {
2652                moxafunc(ofsAddr, FC_SendBreak, Magic_code);
2653                moxadelay(ms100 * (HZ / 10));
2654        } else {
2655                moxafunc(ofsAddr, FC_SendBreak, Magic_code);
2656                moxadelay(HZ / 4);      /* 250 ms */
2657        }
2658        moxafunc(ofsAddr, FC_StopBreak, Magic_code);
2659}
2660
2661static int moxa_get_serial_info(struct moxa_str *info,
2662                                struct serial_struct __user *retinfo)
2663{
2664        struct serial_struct tmp;
2665
2666        memset(&tmp, 0, sizeof(tmp));
2667        tmp.type = info->type;
2668        tmp.line = info->port;
2669        tmp.port = 0;
2670        tmp.irq = 0;
2671        tmp.flags = info->asyncflags;
2672        tmp.baud_base = 921600;
2673        tmp.close_delay = info->close_delay;
2674        tmp.closing_wait = info->closing_wait;
2675        tmp.custom_divisor = 0;
2676        tmp.hub6 = 0;
2677        if(copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
2678                return -EFAULT;
2679        return (0);
2680}
2681
2682
2683static int moxa_set_serial_info(struct moxa_str *info,
2684                                struct serial_struct __user *new_info)
2685{
2686        struct serial_struct new_serial;
2687
2688        if(copy_from_user(&new_serial, new_info, sizeof(new_serial)))
2689                return -EFAULT;
2690
2691        if ((new_serial.irq != 0) ||
2692            (new_serial.port != 0) ||
2693//           (new_serial.type != info->type) ||
2694            (new_serial.custom_divisor != 0) ||
2695            (new_serial.baud_base != 921600))
2696                return (-EPERM);
2697
2698        if (!capable(CAP_SYS_ADMIN)) {
2699                if (((new_serial.flags & ~ASYNC_USR_MASK) !=
2700                     (info->asyncflags & ~ASYNC_USR_MASK)))
2701                        return (-EPERM);
2702        } else {
2703                info->close_delay = new_serial.close_delay * HZ / 100;
2704                info->closing_wait = new_serial.closing_wait * HZ / 100;
2705        }
2706
2707        new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS);
2708        new_serial.flags |= (info->asyncflags & ASYNC_FLAGS);
2709
2710        if (new_serial.type == PORT_16550A) {
2711                MoxaSetFifo(info->port, 1);
2712        } else {
2713                MoxaSetFifo(info->port, 0);
2714        }
2715
2716        info->type = new_serial.type;
2717        return (0);
2718}
2719
2720
2721
2722/*****************************************************************************
2723 *      Static local functions:                                              *
2724 *****************************************************************************/
2725/*
2726 * moxadelay - delays a specified number ticks
2727 */
2728static void moxadelay(int tick)
2729{
2730        unsigned long st, et;
2731
2732        st = jiffies;
2733        et = st + tick;
2734        while (time_before(jiffies, et));
2735}
2736
2737static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg)
2738{
2739
2740        writew(arg, ofsAddr + FuncArg);
2741        writew(cmd, ofsAddr + FuncCode);
2742        wait_finish(ofsAddr);
2743}
2744
2745static void wait_finish(void __iomem *ofsAddr)
2746{
2747        unsigned long i, j;
2748
2749        i = jiffies;
2750        while (readw(ofsAddr + FuncCode) != 0) {
2751                j = jiffies;
2752                if ((j - i) > moxaFuncTout) {
2753                        return;
2754                }
2755        }
2756}
2757
2758static void low_water_check(void __iomem *ofsAddr)
2759{
2760        int len;
2761        ushort rptr, wptr, mask;
2762
2763        if (readb(ofsAddr + FlagStat) & Xoff_state) {
2764                rptr = readw(ofsAddr + RXrptr);
2765                wptr = readw(ofsAddr + RXwptr);
2766                mask = readw(ofsAddr + RX_mask);
2767                len = (wptr - rptr) & mask;
2768                if (len <= Low_water)
2769                        moxafunc(ofsAddr, FC_SendXon, 0);
2770        }
2771}
2772
2773static int moxaloadbios(int cardno, unsigned char __user *tmp, int len)
2774{
2775        void __iomem *baseAddr;
2776        int i;
2777
2778        if(copy_from_user(moxaBuff, tmp, len))
2779                return -EFAULT;
2780        baseAddr = moxaBaseAddr[cardno];
2781        writeb(HW_reset, baseAddr + Control_reg);       /* reset */
2782        moxadelay(1);           /* delay 10 ms */
2783        for (i = 0; i < 4096; i++)
2784                writeb(0, baseAddr + i);        /* clear fix page */
2785        for (i = 0; i < len; i++)
2786                writeb(moxaBuff[i], baseAddr + i);      /* download BIOS */
2787        writeb(0, baseAddr + Control_reg);      /* restart */
2788        return (0);
2789}
2790
2791static int moxafindcard(int cardno)
2792{
2793        void __iomem *baseAddr;
2794        ushort tmp;
2795
2796        baseAddr = moxaBaseAddr[cardno];
2797        switch (moxa_boards[cardno].boardType) {
2798        case MOXA_BOARD_C218_ISA:
2799        case MOXA_BOARD_C218_PCI:
2800                if ((tmp = readw(baseAddr + C218_key)) != C218_KeyCode) {
2801                        return (-1);
2802                }
2803                break;
2804        case MOXA_BOARD_CP204J:
2805                if ((tmp = readw(baseAddr + C218_key)) != CP204J_KeyCode) {
2806                        return (-1);
2807                }
2808                break;
2809        default:
2810                if ((tmp = readw(baseAddr + C320_key)) != C320_KeyCode) {
2811                        return (-1);
2812                }
2813                if ((tmp = readw(baseAddr + C320_status)) != STS_init) {
2814                        return (-2);
2815                }
2816        }
2817        return (0);
2818}
2819
2820static int moxaload320b(int cardno, unsigned char __user *tmp, int len)
2821{
2822        void __iomem *baseAddr;
2823        int i;
2824
2825        if(len > sizeof(moxaBuff))
2826                return -EINVAL;
2827        if(copy_from_user(moxaBuff, tmp, len))
2828                return -EFAULT;
2829        baseAddr = moxaBaseAddr[cardno];
2830        writew(len - 7168 - 2, baseAddr + C320bapi_len);
2831        writeb(1, baseAddr + Control_reg);      /* Select Page 1 */
2832        for (i = 0; i < 7168; i++)
2833                writeb(moxaBuff[i], baseAddr + DynPage_addr + i);
2834        writeb(2, baseAddr + Control_reg);      /* Select Page 2 */
2835        for (i = 0; i < (len - 7168); i++)
2836                writeb(moxaBuff[i + 7168], baseAddr + DynPage_addr + i);
2837        return (0);
2838}
2839
2840static int moxaloadcode(int cardno, unsigned char __user *tmp, int len)
2841{
2842        void __iomem *baseAddr, *ofsAddr;
2843        int retval, port, i;
2844
2845        if(copy_from_user(moxaBuff, tmp, len))
2846                return -EFAULT;
2847        baseAddr = moxaBaseAddr[cardno];
2848        switch (moxa_boards[cardno].boardType) {
2849        case MOXA_BOARD_C218_ISA:
2850        case MOXA_BOARD_C218_PCI:
2851        case MOXA_BOARD_CP204J:
2852                retval = moxaloadc218(cardno, baseAddr, len);
2853                if (retval)
2854                        return (retval);
2855                port = cardno * MAX_PORTS_PER_BOARD;
2856                for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) {
2857                        moxaChkPort[port] = 1;
2858                        moxaCurBaud[port] = 9600L;
2859                        moxaDCDState[port] = 0;
2860                        moxaTableAddr[port] = baseAddr + Extern_table + Extern_size * i;
2861                        ofsAddr = moxaTableAddr[port];
2862                        writew(C218rx_mask, ofsAddr + RX_mask);
2863                        writew(C218tx_mask, ofsAddr + TX_mask);
2864                        writew(C218rx_spage + i * C218buf_pageno, ofsAddr + Page_rxb);
2865                        writew(readw(ofsAddr + Page_rxb) + C218rx_pageno, ofsAddr + EndPage_rxb);
2866
2867                        writew(C218tx_spage + i * C218buf_pageno, ofsAddr + Page_txb);
2868                        writew(readw(ofsAddr + Page_txb) + C218tx_pageno, ofsAddr + EndPage_txb);
2869
2870                }
2871                break;
2872        default:
2873                retval = moxaloadc320(cardno, baseAddr, len,
2874                                      &moxa_boards[cardno].numPorts);
2875                if (retval)
2876                        return (retval);
2877                port = cardno * MAX_PORTS_PER_BOARD;
2878                for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) {
2879                        moxaChkPort[port] = 1;
2880                        moxaCurBaud[port] = 9600L;
2881                        moxaDCDState[port] = 0;
2882                        moxaTableAddr[port] = baseAddr + Extern_table + Extern_size * i;
2883                        ofsAddr = moxaTableAddr[port];
2884                        if (moxa_boards[cardno].numPorts == 8) {
2885                                writew(C320p8rx_mask, ofsAddr + RX_mask);
2886                                writew(C320p8tx_mask, ofsAddr + TX_mask);
2887                                writew(C320p8rx_spage + i * C320p8buf_pgno, ofsAddr + Page_rxb);
2888                                writew(readw(ofsAddr + Page_rxb) + C320p8rx_pgno, ofsAddr + EndPage_rxb);
2889                                writew(C320p8tx_spage + i * C320p8buf_pgno, ofsAddr + Page_txb);
2890                                writew(readw(ofsAddr + Page_txb) + C320p8tx_pgno, ofsAddr + EndPage_txb);
2891
2892                        } else if (moxa_boards[cardno].numPorts == 16) {
2893                                writew(C320p16rx_mask, ofsAddr + RX_mask);
2894                                writew(C320p16tx_mask, ofsAddr + TX_mask);
2895                                writew(C320p16rx_spage + i * C320p16buf_pgno, ofsAddr + Page_rxb);
2896                                writew(readw(ofsAddr + Page_rxb) + C320p16rx_pgno, ofsAddr + EndPage_rxb);
2897                                writew(C320p16tx_spage + i * C320p16buf_pgno, ofsAddr + Page_txb);
2898                                writew(readw(ofsAddr + Page_txb) + C320p16tx_pgno, ofsAddr + EndPage_txb);
2899
2900                        } else if (moxa_boards[cardno].numPorts == 24) {
2901                                writew(C320p24rx_mask, ofsAddr + RX_mask);
2902                                writew(C320p24tx_mask, ofsAddr + TX_mask);
2903                                writew(C320p24rx_spage + i * C320p24buf_pgno, ofsAddr + Page_rxb);
2904                                writew(readw(ofsAddr + Page_rxb) + C320p24rx_pgno, ofsAddr + EndPage_rxb);
2905                                writew(C320p24tx_spage + i * C320p24buf_pgno, ofsAddr + Page_txb);
2906                                writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);
2907                        } else if (moxa_boards[cardno].numPorts == 32) {
2908                                writew(C320p32rx_mask, ofsAddr + RX_mask);
2909                                writew(C320p32tx_mask, ofsAddr + TX_mask);
2910                                writew(C320p32tx_ofs, ofsAddr + Ofs_txb);
2911                                writew(C320p32rx_spage + i * C320p32buf_pgno, ofsAddr + Page_rxb);
2912                                writew(readb(ofsAddr + Page_rxb), ofsAddr + EndPage_rxb);
2913                                writew(C320p32tx_spage + i * C320p32buf_pgno, ofsAddr + Page_txb);
2914                                writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);
2915                        }
2916                }
2917                break;
2918        }
2919        return (0);
2920}
2921
2922static int moxaloadc218(int cardno, void __iomem *baseAddr, int len)
2923{
2924        char retry;
2925        int i, j, len1, len2;
2926        ushort usum, *ptr, keycode;
2927
2928        if (moxa_boards[cardno].boardType == MOXA_BOARD_CP204J)
2929                keycode = CP204J_KeyCode;
2930        else
2931                keycode = C218_KeyCode;
2932        usum = 0;
2933        len1 = len >> 1;
2934        ptr = (ushort *) moxaBuff;
2935        for (i = 0; i < len1; i++)
2936                usum += *(ptr + i);
2937        retry = 0;
2938        do {
2939                len1 = len >> 1;
2940                j = 0;
2941                while (len1) {
2942                        len2 = (len1 > 2048) ? 2048 : len1;
2943                        len1 -= len2;
2944                        for (i = 0; i < len2 << 1; i++)
2945                                writeb(moxaBuff[i + j], baseAddr + C218_LoadBuf + i);
2946                        j += i;
2947
2948                        writew(len2, baseAddr + C218DLoad_len);
2949                        writew(0, baseAddr + C218_key);
2950                        for (i = 0; i < 100; i++) {
2951                                if (readw(baseAddr + C218_key) == keycode)
2952                                        break;
2953                                moxadelay(1);   /* delay 10 ms */
2954                        }
2955                        if (readw(baseAddr + C218_key) != keycode) {
2956                                return (-1);
2957                        }
2958                }
2959                writew(0, baseAddr + C218DLoad_len);
2960                writew(usum, baseAddr + C218check_sum);
2961                writew(0, baseAddr + C218_key);
2962                for (i = 0; i < 100; i++) {
2963                        if (readw(baseAddr + C218_key) == keycode)
2964                                break;
2965                        moxadelay(1);   /* delay 10 ms */
2966                }
2967                retry++;
2968        } while ((readb(baseAddr + C218chksum_ok) != 1) && (retry < 3));
2969        if (readb(baseAddr + C218chksum_ok) != 1) {
2970                return (-1);
2971        }
2972        writew(0, baseAddr + C218_key);
2973        for (i = 0; i < 100; i++) {
2974                if (readw(baseAddr + Magic_no) == Magic_code)
2975                        break;
2976                moxadelay(1);   /* delay 10 ms */
2977        }
2978        if (readw(baseAddr + Magic_no) != Magic_code) {
2979                return (-1);
2980        }
2981        writew(1, baseAddr + Disable_IRQ);
2982        writew(0, baseAddr + Magic_no);
2983        for (i = 0; i < 100; i++) {
2984                if (readw(baseAddr + Magic_no) == Magic_code)
2985                        break;
2986                moxadelay(1);   /* delay 10 ms */
2987        }
2988        if (readw(baseAddr + Magic_no) != Magic_code) {
2989                return (-1);
2990        }
2991        moxaCard = 1;
2992        moxaIntNdx[cardno] = baseAddr + IRQindex;
2993        moxaIntPend[cardno] = baseAddr + IRQpending;
2994        moxaIntTable[cardno] = baseAddr + IRQtable;
2995        return (0);
2996}
2997
2998static int moxaloadc320(int cardno, void __iomem *baseAddr, int len, int *numPorts)
2999{
3000        ushort usum;
3001        int i, j, wlen, len2, retry;
3002        ushort *uptr;
3003
3004        usum = 0;
3005        wlen = len >> 1;
3006        uptr = (ushort *) moxaBuff;
3007        for (i = 0; i < wlen; i++)
3008                usum += uptr[i];
3009        retry = 0;
3010        j = 0;
3011        do {
3012                while (wlen) {
3013                        if (wlen > 2048)
3014                                len2 = 2048;
3015                        else
3016                                len2 = wlen;
3017                        wlen -= len2;
3018                        len2 <<= 1;
3019                        for (i = 0; i < len2; i++)
3020                                writeb(moxaBuff[j + i], baseAddr + C320_LoadBuf + i);
3021                        len2 >>= 1;
3022                        j += i;
3023                        writew(len2, baseAddr + C320DLoad_len);
3024                        writew(0, baseAddr + C320_key);
3025                        for (i = 0; i < 10; i++) {
3026                                if (readw(baseAddr + C320_key) == C320_KeyCode)
3027                                        break;
3028                                moxadelay(1);
3029                        }
3030                        if (readw(baseAddr + C320_key) != C320_KeyCode)
3031                                return (-1);
3032                }
3033                writew(0, baseAddr + C320DLoad_len);
3034                writew(usum, baseAddr + C320check_sum);
3035                writew(0, baseAddr + C320_key);
3036                for (i = 0; i < 10; i++) {
3037                        if (readw(baseAddr + C320_key) == C320_KeyCode)
3038                                break;
3039                        moxadelay(1);
3040                }
3041                retry++;
3042        } while ((readb(baseAddr + C320chksum_ok) != 1) && (retry < 3));
3043        if (readb(baseAddr + C320chksum_ok) != 1)
3044                return (-1);
3045        writew(0, baseAddr + C320_key);
3046        for (i = 0; i < 600; i++) {
3047                if (readw(baseAddr + Magic_no) == Magic_code)
3048                        break;
3049                moxadelay(1);
3050        }
3051        if (readw(baseAddr + Magic_no) != Magic_code)
3052                return (-100);
3053
3054        if (moxa_boards[cardno].busType == MOXA_BUS_TYPE_PCI) {         /* ASIC board */
3055                writew(0x3800, baseAddr + TMS320_PORT1);
3056                writew(0x3900, baseAddr + TMS320_PORT2);
3057                writew(28499, baseAddr + TMS320_CLOCK);
3058        } else {
3059                writew(0x3200, baseAddr + TMS320_PORT1);
3060                writew(0x3400, baseAddr + TMS320_PORT2);
3061                writew(19999, baseAddr + TMS320_CLOCK);
3062        }
3063        writew(1, baseAddr + Disable_IRQ);
3064        writew(0, baseAddr + Magic_no);
3065        for (i = 0; i < 500; i++) {
3066                if (readw(baseAddr + Magic_no) == Magic_code)
3067                        break;
3068                moxadelay(1);
3069        }
3070        if (readw(baseAddr + Magic_no) != Magic_code)
3071                return (-102);
3072
3073        j = readw(baseAddr + Module_cnt);
3074        if (j <= 0)
3075                return (-101);
3076        *numPorts = j * 8;
3077        writew(j, baseAddr + Module_no);
3078        writew(0, baseAddr + Magic_no);
3079        for (i = 0; i < 600; i++) {
3080                if (readw(baseAddr + Magic_no) == Magic_code)
3081                        break;
3082                moxadelay(1);
3083        }
3084        if (readw(baseAddr + Magic_no) != Magic_code)
3085                return (-102);
3086        moxaCard = 1;
3087        moxaIntNdx[cardno] = baseAddr + IRQindex;
3088        moxaIntPend[cardno] = baseAddr + IRQpending;
3089        moxaIntTable[cardno] = baseAddr + IRQtable;
3090        return (0);
3091}
3092
3093long MoxaPortGetCurBaud(int port)
3094{
3095
3096        if (moxaChkPort[port] == 0)
3097                return (0);
3098        return (moxaCurBaud[port]);
3099}
3100
3101static void MoxaSetFifo(int port, int enable)
3102{
3103        void __iomem *ofsAddr = moxaTableAddr[port];
3104
3105        if (!enable) {
3106                moxafunc(ofsAddr, FC_SetRxFIFOTrig, 0);
3107                moxafunc(ofsAddr, FC_SetTxFIFOCnt, 1);
3108        } else {
3109                moxafunc(ofsAddr, FC_SetRxFIFOTrig, 3);
3110                moxafunc(ofsAddr, FC_SetTxFIFOCnt, 16);
3111        }
3112}
3113
3114#if 0
3115int MoxaPortSetMode(int port, int databits, int stopbits, int parity)
3116{
3117        void __iomem *ofsAddr;
3118        int val;
3119
3120        val = 0;
3121        switch (databits) {
3122        case 5:
3123                val |= 0;
3124                break;
3125        case 6:
3126                val |= 1;
3127                break;
3128        case 7:
3129                val |= 2;
3130                break;
3131        case 8:
3132                val |= 3;
3133                break;
3134        default:
3135                return (-1);
3136        }
3137        switch (stopbits) {
3138        case 0:
3139                val |= 0;
3140                break;          /* stop bits 1.5 */
3141        case 1:
3142                val |= 0;
3143                break;
3144        case 2:
3145                val |= 4;
3146                break;
3147        default:
3148                return (-1);
3149        }
3150        switch (parity) {
3151        case 0:
3152                val |= 0x00;
3153                break;          /* None  */
3154        case 1:
3155                val |= 0x08;
3156                break;          /* Odd   */
3157        case 2:
3158                val |= 0x18;
3159                break;          /* Even  */
3160        case 3:
3161                val |= 0x28;
3162                break;          /* Mark  */
3163        case 4:
3164                val |= 0x38;
3165                break;          /* Space */
3166        default:
3167                return (-1);
3168        }
3169        ofsAddr = moxaTableAddr[port];
3170        moxafunc(ofsAddr, FC_SetMode, val);
3171        return (0);
3172}
3173
3174int MoxaPortTxBufSize(int port)
3175{
3176        void __iomem *ofsAddr;
3177        int size;
3178
3179        ofsAddr = moxaTableAddr[port];
3180        size = readw(ofsAddr + TX_mask);
3181        return (size);
3182}
3183
3184int MoxaPortRxBufSize(int port)
3185{
3186        void __iomem *ofsAddr;
3187        int size;
3188
3189        ofsAddr = moxaTableAddr[port];
3190        size = readw(ofsAddr + RX_mask);
3191        return (size);
3192}
3193
3194int MoxaPortRxFree(int port)
3195{
3196        void __iomem *ofsAddr;
3197        ushort rptr, wptr, mask;
3198        int len;
3199
3200        ofsAddr = moxaTableAddr[port];
3201        rptr = readw(ofsAddr + RXrptr);
3202        wptr = readw(ofsAddr + RXwptr);
3203        mask = readw(ofsAddr + RX_mask);
3204        len = mask - ((wptr - rptr) & mask);
3205        return (len);
3206}
3207int MoxaPortGetBrkCnt(int port)
3208{
3209        return (moxaBreakCnt[port]);
3210}
3211
3212void MoxaPortSetXonXoff(int port, int xonValue, int xoffValue)
3213{
3214        void __iomem *ofsAddr;
3215
3216        ofsAddr = moxaTableAddr[port];
3217        writew(xonValue, ofsAddr + FuncArg);
3218        writew(xoffValue, ofsAddr + FuncArg1);
3219        writew(FC_SetXonXoff, ofsAddr + FuncCode);
3220        wait_finish(ofsAddr);
3221}
3222
3223int MoxaPortIsTxHold(int port)
3224{
3225        void __iomem *ofsAddr;
3226        int val;
3227
3228        ofsAddr = moxaTableAddr[port];
3229        if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
3230            (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
3231                moxafunc(ofsAddr, FC_GetCCSR, 0);
3232                val = readw(ofsAddr + FuncArg);
3233                if (val & 0x04)
3234                        return (1);
3235        } else {
3236                if (readw(ofsAddr + FlagStat) & Tx_flowOff)
3237                        return (1);
3238        }
3239        return (0);
3240}
3241#endif
3242
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.