Char: moxa, add firmware loading
authorJiri Slaby <jirislaby@gmail.com>
Wed, 30 Apr 2008 07:53:39 +0000 (00:53 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 30 Apr 2008 15:29:42 +0000 (08:29 -0700)
Substitute ioctl load firmware interface by kernel firmware api.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Tested-by: Oyvind Aabling <Oyvind.Aabling@uni-c.dk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/char/moxa.c
drivers/char/moxa.h [new file with mode: 0644]

index 428c1380b7717ddb8571dda83b9e9fb4ac763c50..133819cf2c5c6e1daf3804ce4b6612e5851ed207 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/mm.h>
 #include <linux/ioport.h>
 #include <linux/errno.h>
+#include <linux/firmware.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
+#include "moxa.h"
+
 #define MOXA_VERSION           "5.1k"
 
+#define MOXA_FW_HDRLEN         32
+
 #define MOXAMAJOR              172
 #define MOXACUMAJOR            173
 
@@ -92,6 +97,8 @@ static struct pci_device_id moxa_pcibrds[] = {
 MODULE_DEVICE_TABLE(pci, moxa_pcibrds);
 #endif /* CONFIG_PCI */
 
+struct moxa_port;
+
 static struct moxa_board_conf {
        int boardType;
        int numPorts;
@@ -99,6 +106,8 @@ static struct moxa_board_conf {
 
        int loadstat;
 
+       struct moxa_port *ports;
+
        void __iomem *basemem;
        void __iomem *intNdx;
        void __iomem *intPend;
@@ -156,6 +165,7 @@ struct moxa_port {
 #define WAKEUP_CHARS           256
 
 static int ttymajor = MOXAMAJOR;
+static int moxaCard;
 /* Variables for insmod */
 #ifdef MODULE
 static unsigned long baseaddr[MAX_BOARDS];
@@ -208,7 +218,6 @@ static void moxa_receive_data(struct moxa_port *);
 /*
  * moxa board interface functions:
  */
-static void MoxaDriverInit(void);
 static int MoxaDriverIoctl(unsigned int, unsigned long, int);
 static int MoxaDriverPoll(void);
 static int MoxaPortsOfCard(int);
@@ -263,6 +272,489 @@ static struct moxa_port moxa_ports[MAX_PORTS];
 static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
 static DEFINE_SPINLOCK(moxa_lock);
 
+static int moxa_check_fw_model(struct moxa_board_conf *brd, u8 model)
+{
+       switch (brd->boardType) {
+       case MOXA_BOARD_C218_ISA:
+       case MOXA_BOARD_C218_PCI:
+               if (model != 1)
+                       goto err;
+               break;
+       case MOXA_BOARD_CP204J:
+               if (model != 3)
+                       goto err;
+               break;
+       default:
+               if (model != 2)
+                       goto err;
+               break;
+       }
+       return 0;
+err:
+       return -EINVAL;
+}
+
+static int moxa_check_fw(const void *ptr)
+{
+       const __le16 *lptr = ptr;
+
+       if (*lptr != cpu_to_le16(0x7980))
+               return -EINVAL;
+
+       return 0;
+}
+
+static int moxa_load_bios(struct moxa_board_conf *brd, const u8 *buf,
+               size_t len)
+{
+       void __iomem *baseAddr = brd->basemem;
+       u16 tmp;
+
+       writeb(HW_reset, baseAddr + Control_reg);       /* reset */
+       msleep(10);
+       memset_io(baseAddr, 0, 4096);
+       memcpy_toio(baseAddr, buf, len);        /* download BIOS */
+       writeb(0, baseAddr + Control_reg);      /* restart */
+
+       msleep(2000);
+
+       switch (brd->boardType) {
+       case MOXA_BOARD_C218_ISA:
+       case MOXA_BOARD_C218_PCI:
+               tmp = readw(baseAddr + C218_key);
+               if (tmp != C218_KeyCode)
+                       goto err;
+               break;
+       case MOXA_BOARD_CP204J:
+               tmp = readw(baseAddr + C218_key);
+               if (tmp != CP204J_KeyCode)
+                       goto err;
+               break;
+       default:
+               tmp = readw(baseAddr + C320_key);
+               if (tmp != C320_KeyCode)
+                       goto err;
+               tmp = readw(baseAddr + C320_status);
+               if (tmp != STS_init) {
+                       printk(KERN_ERR "moxa: bios upload failed -- CPU/Basic "
+                                       "module not found\n");
+                       return -EIO;
+               }
+               break;
+       }
+
+       return 0;
+err:
+       printk(KERN_ERR "moxa: bios upload failed -- board not found\n");
+       return -EIO;
+}
+
+static int moxa_load_320b(struct moxa_board_conf *brd, const u8 *ptr,
+               size_t len)
+{
+       void __iomem *baseAddr = brd->basemem;
+
+       if (len < 7168) {
+               printk(KERN_ERR "moxa: invalid 320 bios -- too short\n");
+               return -EINVAL;
+       }
+
+       writew(len - 7168 - 2, baseAddr + C320bapi_len);
+       writeb(1, baseAddr + Control_reg);      /* Select Page 1 */
+       memcpy_toio(baseAddr + DynPage_addr, ptr, 7168);
+       writeb(2, baseAddr + Control_reg);      /* Select Page 2 */
+       memcpy_toio(baseAddr + DynPage_addr, ptr + 7168, len - 7168);
+
+       return 0;
+}
+
+static int moxa_load_c218(struct moxa_board_conf *brd, const void *ptr,
+               size_t len)
+{
+       void __iomem *baseAddr = brd->basemem;
+       const u16 *uptr = ptr;
+       size_t wlen, len2, j;
+       unsigned int i, retry;
+       u16 usum, keycode;
+
+       if (brd->boardType == MOXA_BOARD_CP204J)
+               keycode = CP204J_KeyCode;
+       else
+               keycode = C218_KeyCode;
+       usum = 0;
+       wlen = len >> 1;
+       for (i = 0; i < wlen; i++)
+               usum += le16_to_cpu(uptr[i]);
+       retry = 0;
+       do {
+               wlen = len >> 1;
+               j = 0;
+               while (wlen) {
+                       len2 = (wlen > 2048) ? 2048 : wlen;
+                       wlen -= len2;
+                       memcpy_toio(baseAddr + C218_LoadBuf, ptr + j,
+                                       len2 << 1);
+                       j += len2 << 1;
+
+                       writew(len2, baseAddr + C218DLoad_len);
+                       writew(0, baseAddr + C218_key);
+                       for (i = 0; i < 100; i++) {
+                               if (readw(baseAddr + C218_key) == keycode)
+                                       break;
+                               msleep(10);
+                       }
+                       if (readw(baseAddr + C218_key) != keycode)
+                               return -EIO;
+               }
+               writew(0, baseAddr + C218DLoad_len);
+               writew(usum, baseAddr + C218check_sum);
+               writew(0, baseAddr + C218_key);
+               for (i = 0; i < 100; i++) {
+                       if (readw(baseAddr + C218_key) == keycode)
+                               break;
+                       msleep(10);
+               }
+               retry++;
+       } while ((readb(baseAddr + C218chksum_ok) != 1) && (retry < 3));
+       if (readb(baseAddr + C218chksum_ok) != 1)
+               return -EIO;
+
+       writew(0, baseAddr + C218_key);
+       for (i = 0; i < 100; i++) {
+               if (readw(baseAddr + Magic_no) == Magic_code)
+                       break;
+               msleep(10);
+       }
+       if (readw(baseAddr + Magic_no) != Magic_code)
+               return -EIO;
+
+       writew(1, baseAddr + Disable_IRQ);
+       writew(0, baseAddr + Magic_no);
+       for (i = 0; i < 100; i++) {
+               if (readw(baseAddr + Magic_no) == Magic_code)
+                       break;
+               msleep(10);
+       }
+       if (readw(baseAddr + Magic_no) != Magic_code)
+               return -EIO;
+
+       moxaCard = 1;
+       brd->intNdx = baseAddr + IRQindex;
+       brd->intPend = baseAddr + IRQpending;
+       brd->intTable = baseAddr + IRQtable;
+
+       return 0;
+}
+
+static int moxa_load_c320(struct moxa_board_conf *brd, const void *ptr,
+               size_t len)
+{
+       void __iomem *baseAddr = brd->basemem;
+       const u16 *uptr = ptr;
+       size_t wlen, len2, j;
+       unsigned int i, retry;
+       u16 usum;
+
+       usum = 0;
+       wlen = len >> 1;
+       for (i = 0; i < wlen; i++)
+               usum += le16_to_cpu(uptr[i]);
+       retry = 0;
+       do {
+               wlen = len >> 1;
+               j = 0;
+               while (wlen) {
+                       len2 = (wlen > 2048) ? 2048 : wlen;
+                       wlen -= len2;
+                       memcpy_toio(baseAddr + C320_LoadBuf, ptr + j,
+                                       len2 << 1);
+                       j += len2 << 1;
+                       writew(len2, baseAddr + C320DLoad_len);
+                       writew(0, baseAddr + C320_key);
+                       for (i = 0; i < 10; i++) {
+                               if (readw(baseAddr + C320_key) == C320_KeyCode)
+                                       break;
+                               msleep(10);
+                       }
+                       if (readw(baseAddr + C320_key) != C320_KeyCode)
+                               return -EIO;
+               }
+               writew(0, baseAddr + C320DLoad_len);
+               writew(usum, baseAddr + C320check_sum);
+               writew(0, baseAddr + C320_key);
+               for (i = 0; i < 10; i++) {
+                       if (readw(baseAddr + C320_key) == C320_KeyCode)
+                               break;
+                       msleep(10);
+               }
+               retry++;
+       } while ((readb(baseAddr + C320chksum_ok) != 1) && (retry < 3));
+       if (readb(baseAddr + C320chksum_ok) != 1)
+               return -EIO;
+
+       writew(0, baseAddr + C320_key);
+       for (i = 0; i < 600; i++) {
+               if (readw(baseAddr + Magic_no) == Magic_code)
+                       break;
+               msleep(10);
+       }
+       if (readw(baseAddr + Magic_no) != Magic_code)
+               return -EIO;
+
+       if (brd->busType == MOXA_BUS_TYPE_PCI) {        /* ASIC board */
+               writew(0x3800, baseAddr + TMS320_PORT1);
+               writew(0x3900, baseAddr + TMS320_PORT2);
+               writew(28499, baseAddr + TMS320_CLOCK);
+       } else {
+               writew(0x3200, baseAddr + TMS320_PORT1);
+               writew(0x3400, baseAddr + TMS320_PORT2);
+               writew(19999, baseAddr + TMS320_CLOCK);
+       }
+       writew(1, baseAddr + Disable_IRQ);
+       writew(0, baseAddr + Magic_no);
+       for (i = 0; i < 500; i++) {
+               if (readw(baseAddr + Magic_no) == Magic_code)
+                       break;
+               msleep(10);
+       }
+       if (readw(baseAddr + Magic_no) != Magic_code)
+               return -EIO;
+
+       j = readw(baseAddr + Module_cnt);
+       if (j <= 0)
+               return -EIO;
+       brd->numPorts = j * 8;
+       writew(j, baseAddr + Module_no);
+       writew(0, baseAddr + Magic_no);
+       for (i = 0; i < 600; i++) {
+               if (readw(baseAddr + Magic_no) == Magic_code)
+                       break;
+               msleep(10);
+       }
+       if (readw(baseAddr + Magic_no) != Magic_code)
+               return -EIO;
+       moxaCard = 1;
+       brd->intNdx = baseAddr + IRQindex;
+       brd->intPend = baseAddr + IRQpending;
+       brd->intTable = baseAddr + IRQtable;
+
+       return 0;
+}
+
+static int moxa_load_code(struct moxa_board_conf *brd, const void *ptr,
+               size_t len)
+{
+       void __iomem *ofsAddr, *baseAddr = brd->basemem;
+       struct moxa_port *port;
+       int retval, i;
+
+       if (len % 2) {
+               printk(KERN_ERR "moxa: C2XX bios length is not even\n");
+               return -EINVAL;
+       }
+
+       switch (brd->boardType) {
+       case MOXA_BOARD_C218_ISA:
+       case MOXA_BOARD_C218_PCI:
+       case MOXA_BOARD_CP204J:
+               retval = moxa_load_c218(brd, ptr, len);
+               if (retval)
+                       return retval;
+               port = brd->ports;
+               for (i = 0; i < brd->numPorts; i++, port++) {
+                       port->chkPort = 1;
+                       port->curBaud = 9600L;
+                       port->DCDState = 0;
+                       port->tableAddr = baseAddr + Extern_table +
+                                       Extern_size * i;
+                       ofsAddr = port->tableAddr;
+                       writew(C218rx_mask, ofsAddr + RX_mask);
+                       writew(C218tx_mask, ofsAddr + TX_mask);
+                       writew(C218rx_spage + i * C218buf_pageno, ofsAddr + Page_rxb);
+                       writew(readw(ofsAddr + Page_rxb) + C218rx_pageno, ofsAddr + EndPage_rxb);
+
+                       writew(C218tx_spage + i * C218buf_pageno, ofsAddr + Page_txb);
+                       writew(readw(ofsAddr + Page_txb) + C218tx_pageno, ofsAddr + EndPage_txb);
+
+               }
+               break;
+       default:
+               retval = moxa_load_c320(brd, ptr, len); /* fills in numPorts */
+               if (retval)
+                       return retval;
+               port = brd->ports;
+               for (i = 0; i < brd->numPorts; i++, port++) {
+                       port->chkPort = 1;
+                       port->curBaud = 9600L;
+                       port->DCDState = 0;
+                       port->tableAddr = baseAddr + Extern_table +
+                                       Extern_size * i;
+                       ofsAddr = port->tableAddr;
+                       switch (brd->numPorts) {
+                       case 8:
+                               writew(C320p8rx_mask, ofsAddr + RX_mask);
+                               writew(C320p8tx_mask, ofsAddr + TX_mask);
+                               writew(C320p8rx_spage + i * C320p8buf_pgno, ofsAddr + Page_rxb);
+                               writew(readw(ofsAddr + Page_rxb) + C320p8rx_pgno, ofsAddr + EndPage_rxb);
+                               writew(C320p8tx_spage + i * C320p8buf_pgno, ofsAddr + Page_txb);
+                               writew(readw(ofsAddr + Page_txb) + C320p8tx_pgno, ofsAddr + EndPage_txb);
+
+                               break;
+                       case 16:
+                               writew(C320p16rx_mask, ofsAddr + RX_mask);
+                               writew(C320p16tx_mask, ofsAddr + TX_mask);
+                               writew(C320p16rx_spage + i * C320p16buf_pgno, ofsAddr + Page_rxb);
+                               writew(readw(ofsAddr + Page_rxb) + C320p16rx_pgno, ofsAddr + EndPage_rxb);
+                               writew(C320p16tx_spage + i * C320p16buf_pgno, ofsAddr + Page_txb);
+                               writew(readw(ofsAddr + Page_txb) + C320p16tx_pgno, ofsAddr + EndPage_txb);
+                               break;
+
+                       case 24:
+                               writew(C320p24rx_mask, ofsAddr + RX_mask);
+                               writew(C320p24tx_mask, ofsAddr + TX_mask);
+                               writew(C320p24rx_spage + i * C320p24buf_pgno, ofsAddr + Page_rxb);
+                               writew(readw(ofsAddr + Page_rxb) + C320p24rx_pgno, ofsAddr + EndPage_rxb);
+                               writew(C320p24tx_spage + i * C320p24buf_pgno, ofsAddr + Page_txb);
+                               writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);
+                               break;
+                       case 32:
+                               writew(C320p32rx_mask, ofsAddr + RX_mask);
+                               writew(C320p32tx_mask, ofsAddr + TX_mask);
+                               writew(C320p32tx_ofs, ofsAddr + Ofs_txb);
+                               writew(C320p32rx_spage + i * C320p32buf_pgno, ofsAddr + Page_rxb);
+                               writew(readb(ofsAddr + Page_rxb), ofsAddr + EndPage_rxb);
+                               writew(C320p32tx_spage + i * C320p32buf_pgno, ofsAddr + Page_txb);
+                               writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);
+                               break;
+                       }
+               }
+               break;
+       }
+       brd->loadstat = 1;
+       return 0;
+}
+
+static int moxa_load_fw(struct moxa_board_conf *brd, const struct firmware *fw)
+{
+       void *ptr = fw->data;
+       char rsn[64];
+       u16 lens[5];
+       size_t len;
+       unsigned int a, lenp, lencnt;
+       int ret = -EINVAL;
+       struct {
+               __le32 magic;   /* 0x34303430 */
+               u8 reserved1[2];
+               u8 type;        /* UNIX = 3 */
+               u8 model;       /* C218T=1, C320T=2, CP204=3 */
+               u8 reserved2[8];
+               __le16 len[5];
+       } *hdr = ptr;
+
+       BUILD_BUG_ON(ARRAY_SIZE(hdr->len) != ARRAY_SIZE(lens));
+
+       if (fw->size < MOXA_FW_HDRLEN) {
+               strcpy(rsn, "too short (even header won't fit)");
+               goto err;
+       }
+       if (hdr->magic != cpu_to_le32(0x30343034)) {
+               sprintf(rsn, "bad magic: %.8x", le32_to_cpu(hdr->magic));
+               goto err;
+       }
+       if (hdr->type != 3) {
+               sprintf(rsn, "not for linux, type is %u", hdr->type);
+               goto err;
+       }
+       if (moxa_check_fw_model(brd, hdr->model)) {
+               sprintf(rsn, "not for this card, model is %u", hdr->model);
+               goto err;
+       }
+
+       len = MOXA_FW_HDRLEN;
+       lencnt = hdr->model == 2 ? 5 : 3;
+       for (a = 0; a < ARRAY_SIZE(lens); a++) {
+               lens[a] = le16_to_cpu(hdr->len[a]);
+               if (lens[a] && len + lens[a] <= fw->size &&
+                               moxa_check_fw(&fw->data[len]))
+                       printk(KERN_WARNING "moxa firmware: unexpected input "
+                               "at offset %u, but going on\n", (u32)len);
+               if (!lens[a] && a < lencnt) {
+                       sprintf(rsn, "too few entries in fw file");
+                       goto err;
+               }
+               len += lens[a];
+       }
+
+       if (len != fw->size) {
+               sprintf(rsn, "bad length: %u (should be %u)", (u32)fw->size,
+                               (u32)len);
+               goto err;
+       }
+
+       ptr += MOXA_FW_HDRLEN;
+       lenp = 0; /* bios */
+
+       strcpy(rsn, "read above");
+
+       ret = moxa_load_bios(brd, ptr, lens[lenp]);
+       if (ret)
+               goto err;
+
+       /* we skip the tty section (lens[1]), since we don't need it */
+       ptr += lens[lenp] + lens[lenp + 1];
+       lenp += 2; /* comm */
+
+       if (hdr->model == 2) {
+               ret = moxa_load_320b(brd, ptr, lens[lenp]);
+               if (ret)
+                       goto err;
+               /* skip another tty */
+               ptr += lens[lenp] + lens[lenp + 1];
+               lenp += 2;
+       }
+
+       ret = moxa_load_code(brd, ptr, lens[lenp]);
+       if (ret)
+               goto err;
+
+       return 0;
+err:
+       printk(KERN_ERR "firmware failed to load, reason: %s\n", rsn);
+       return ret;
+}
+
+static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)
+{
+       const struct firmware *fw;
+       const char *file;
+       int ret;
+
+       switch (brd->boardType) {
+       case MOXA_BOARD_C218_ISA:
+       case MOXA_BOARD_C218_PCI:
+               file = "c218tunx.cod";
+               break;
+       case MOXA_BOARD_CP204J:
+               file = "cp204unx.cod";
+               break;
+       default:
+               file = "c320tunx.cod";
+               break;
+       }
+
+       ret = request_firmware(&fw, file, dev);
+       if (ret) {
+               printk(KERN_ERR "request_firmware failed\n");
+               goto end;
+       }
+
+       ret = moxa_load_fw(brd, fw);
+
+       release_firmware(fw);
+end:
+       return ret;
+}
+
 #ifdef CONFIG_PCI
 static int __devinit moxa_pci_probe(struct pci_dev *pdev,
                const struct pci_device_id *ent)
@@ -290,6 +782,7 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev,
        }
 
        board = &moxa_boards[i];
+       board->ports = &moxa_ports[i * MAX_PORTS_PER_BOARD];
 
        retval = pci_request_region(pdev, 2, "moxa-base");
        if (retval) {
@@ -319,9 +812,16 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev,
        }
        board->busType = MOXA_BUS_TYPE_PCI;
 
+       retval = moxa_init_board(board, &pdev->dev);
+       if (retval)
+               goto err_base;
+
        pci_set_drvdata(pdev, board);
 
        return (0);
+err_base:
+       iounmap(board->basemem);
+       board->basemem = NULL;
 err_reg:
        pci_release_region(pdev, 2);
 err:
@@ -406,6 +906,7 @@ static int __init moxa_init(void)
                                        isabrds + 1, moxa_brdname[type[i] - 1],
                                        baseaddr[i]);
                        brd->boardType = type[i];
+                       brd->ports = &moxa_ports[isabrds * MAX_PORTS_PER_BOARD];
                        brd->numPorts = type[i] == MOXA_BOARD_C218_ISA ? 8 :
                                        numports[i];
                        brd->busType = MOXA_BUS_TYPE_ISA;
@@ -415,6 +916,11 @@ static int __init moxa_init(void)
                                                baseaddr[i]);
                                continue;
                        }
+                       if (moxa_init_board(brd, NULL)) {
+                               iounmap(brd->basemem);
+                               brd->basemem = NULL;
+                               continue;
+                       }
 
                        brd++;
                        isabrds++;
@@ -1062,308 +1568,17 @@ static void moxa_receive_data(struct moxa_port *ch)
        if (tp)
                ts = tp->termios;
        /**************************************************
-       if ( !tp || !ts || !(ts->c_cflag & CREAD) ) {
-       *****************************************************/
-       if (!tp || !ts) {
-               MoxaPortFlushData(ch->port, 0);
-               return;
-       }
-       spin_lock_irqsave(&moxa_lock, flags);
-       MoxaPortReadData(ch->port, tp);
-       spin_unlock_irqrestore(&moxa_lock, flags);
-       tty_schedule_flip(tp);
-}
-
-#define Magic_code     0x404
-
-/*
- *    System Configuration
- */
-/*
- *    for C218 BIOS initialization
- */
-#define C218_ConfBase  0x800
-#define C218_status    (C218_ConfBase + 0)     /* BIOS running status    */
-#define C218_diag      (C218_ConfBase + 2)     /* diagnostic status      */
-#define C218_key       (C218_ConfBase + 4)     /* WORD (0x218 for C218) */
-#define C218DLoad_len  (C218_ConfBase + 6)     /* WORD           */
-#define C218check_sum  (C218_ConfBase + 8)     /* BYTE           */
-#define C218chksum_ok  (C218_ConfBase + 0x0a)  /* BYTE (1:ok)            */
-#define C218_TestRx    (C218_ConfBase + 0x10)  /* 8 bytes for 8 ports    */
-#define C218_TestTx    (C218_ConfBase + 0x18)  /* 8 bytes for 8 ports    */
-#define C218_RXerr     (C218_ConfBase + 0x20)  /* 8 bytes for 8 ports    */
-#define C218_ErrFlag   (C218_ConfBase + 0x28)  /* 8 bytes for 8 ports    */
-
-#define C218_LoadBuf   0x0F00
-#define C218_KeyCode   0x218
-#define CP204J_KeyCode 0x204
-
-/*
- *    for C320 BIOS initialization
- */
-#define C320_ConfBase  0x800
-#define C320_LoadBuf   0x0f00
-#define STS_init       0x05    /* for C320_status        */
-
-#define C320_status    C320_ConfBase + 0       /* BIOS running status    */
-#define C320_diag      C320_ConfBase + 2       /* diagnostic status      */
-#define C320_key       C320_ConfBase + 4       /* WORD (0320H for C320) */
-#define C320DLoad_len  C320_ConfBase + 6       /* WORD           */
-#define C320check_sum  C320_ConfBase + 8       /* WORD           */
-#define C320chksum_ok  C320_ConfBase + 0x0a    /* WORD (1:ok)            */
-#define C320bapi_len   C320_ConfBase + 0x0c    /* WORD           */
-#define C320UART_no    C320_ConfBase + 0x0e    /* WORD           */
-
-#define C320_KeyCode   0x320
-
-#define FixPage_addr   0x0000  /* starting addr of static page  */
-#define DynPage_addr   0x2000  /* starting addr of dynamic page */
-#define C218_start     0x3000  /* starting addr of C218 BIOS prg */
-#define Control_reg    0x1ff0  /* select page and reset control */
-#define HW_reset       0x80
-
-/*
- *    Function Codes
- */
-#define FC_CardReset   0x80
-#define FC_ChannelReset 1      /* C320 firmware not supported */
-#define FC_EnableCH    2
-#define FC_DisableCH   3
-#define FC_SetParam    4
-#define FC_SetMode     5
-#define FC_SetRate     6
-#define FC_LineControl 7
-#define FC_LineStatus  8
-#define FC_XmitControl 9
-#define FC_FlushQueue  10
-#define FC_SendBreak   11
-#define FC_StopBreak   12
-#define FC_LoopbackON  13
-#define FC_LoopbackOFF 14
-#define FC_ClrIrqTable 15
-#define FC_SendXon     16
-#define FC_SetTermIrq  17      /* C320 firmware not supported */
-#define FC_SetCntIrq   18      /* C320 firmware not supported */
-#define FC_SetBreakIrq 19
-#define FC_SetLineIrq  20
-#define FC_SetFlowCtl  21
-#define FC_GenIrq      22
-#define FC_InCD180     23
-#define FC_OutCD180    24
-#define FC_InUARTreg   23
-#define FC_OutUARTreg  24
-#define FC_SetXonXoff  25
-#define FC_OutCD180CCR 26
-#define FC_ExtIQueue   27
-#define FC_ExtOQueue   28
-#define FC_ClrLineIrq  29
-#define FC_HWFlowCtl   30
-#define FC_GetClockRate 35
-#define FC_SetBaud     36
-#define FC_SetDataMode  41
-#define FC_GetCCSR      43
-#define FC_GetDataError 45
-#define FC_RxControl   50
-#define FC_ImmSend     51
-#define FC_SetXonState 52
-#define FC_SetXoffState        53
-#define FC_SetRxFIFOTrig 54
-#define FC_SetTxFIFOCnt 55
-#define FC_UnixRate    56
-#define FC_UnixResetTimer 57
-
-#define        RxFIFOTrig1     0
-#define        RxFIFOTrig4     1
-#define        RxFIFOTrig8     2
-#define        RxFIFOTrig14    3
-
-/*
- *    Dual-Ported RAM
- */
-#define DRAM_global    0
-#define INT_data       (DRAM_global + 0)
-#define Config_base    (DRAM_global + 0x108)
-
-#define IRQindex       (INT_data + 0)
-#define IRQpending     (INT_data + 4)
-#define IRQtable       (INT_data + 8)
-
-/*
- *    Interrupt Status
- */
-#define IntrRx         0x01    /* receiver data O.K.             */
-#define IntrTx         0x02    /* transmit buffer empty  */
-#define IntrFunc       0x04    /* function complete              */
-#define IntrBreak      0x08    /* received break         */
-#define IntrLine       0x10    /* line status change
-                                  for transmitter                */
-#define IntrIntr       0x20    /* received INTR code             */
-#define IntrQuit       0x40    /* received QUIT code             */
-#define IntrEOF        0x80    /* received EOF code              */
-
-#define IntrRxTrigger  0x100   /* rx data count reach tigger value */
-#define IntrTxTrigger  0x200   /* tx data count below trigger value */
-
-#define Magic_no       (Config_base + 0)
-#define Card_model_no  (Config_base + 2)
-#define Total_ports    (Config_base + 4)
-#define Module_cnt     (Config_base + 8)
-#define Module_no      (Config_base + 10)
-#define Timer_10ms     (Config_base + 14)
-#define Disable_IRQ    (Config_base + 20)
-#define TMS320_PORT1   (Config_base + 22)
-#define TMS320_PORT2   (Config_base + 24)
-#define TMS320_CLOCK   (Config_base + 26)
-
-/*
- *    DATA BUFFER in DRAM
- */
-#define Extern_table   0x400   /* Base address of the external table
-                                  (24 words *    64) total 3K bytes
-                                  (24 words * 128) total 6K bytes */
-#define Extern_size    0x60    /* 96 bytes                       */
-#define RXrptr         0x00    /* read pointer for RX buffer     */
-#define RXwptr         0x02    /* write pointer for RX buffer    */
-#define TXrptr         0x04    /* read pointer for TX buffer     */
-#define TXwptr         0x06    /* write pointer for TX buffer    */
-#define HostStat       0x08    /* IRQ flag and general flag      */
-#define FlagStat       0x0A
-#define FlowControl    0x0C    /* B7 B6 B5 B4 B3 B2 B1 B0              */
-                                       /*  x  x  x  x  |  |  |  |            */
-                                       /*              |  |  |  + CTS flow   */
-                                       /*              |  |  +--- RTS flow   */
-                                       /*              |  +------ TX Xon/Xoff */
-                                       /*              +--------- RX Xon/Xoff */
-#define Break_cnt      0x0E    /* received break count   */
-#define CD180TXirq     0x10    /* if non-0: enable TX irq        */
-#define RX_mask        0x12
-#define TX_mask        0x14
-#define Ofs_rxb        0x16
-#define Ofs_txb        0x18
-#define Page_rxb       0x1A
-#define Page_txb       0x1C
-#define EndPage_rxb    0x1E
-#define EndPage_txb    0x20
-#define Data_error     0x22
-#define RxTrigger      0x28
-#define TxTrigger      0x2a
-
-#define rRXwptr        0x34
-#define Low_water      0x36
-
-#define FuncCode       0x40
-#define FuncArg        0x42
-#define FuncArg1       0x44
-
-#define C218rx_size    0x2000  /* 8K bytes */
-#define C218tx_size    0x8000  /* 32K bytes */
-
-#define C218rx_mask    (C218rx_size - 1)
-#define C218tx_mask    (C218tx_size - 1)
-
-#define C320p8rx_size  0x2000
-#define C320p8tx_size  0x8000
-#define C320p8rx_mask  (C320p8rx_size - 1)
-#define C320p8tx_mask  (C320p8tx_size - 1)
-
-#define C320p16rx_size 0x2000
-#define C320p16tx_size 0x4000
-#define C320p16rx_mask (C320p16rx_size - 1)
-#define C320p16tx_mask (C320p16tx_size - 1)
-
-#define C320p24rx_size 0x2000
-#define C320p24tx_size 0x2000
-#define C320p24rx_mask (C320p24rx_size - 1)
-#define C320p24tx_mask (C320p24tx_size - 1)
-
-#define C320p32rx_size 0x1000
-#define C320p32tx_size 0x1000
-#define C320p32rx_mask (C320p32rx_size - 1)
-#define C320p32tx_mask (C320p32tx_size - 1)
-
-#define Page_size      0x2000
-#define Page_mask      (Page_size - 1)
-#define C218rx_spage   3
-#define C218tx_spage   4
-#define C218rx_pageno  1
-#define C218tx_pageno  4
-#define C218buf_pageno 5
-
-#define C320p8rx_spage 3
-#define C320p8tx_spage 4
-#define C320p8rx_pgno  1
-#define C320p8tx_pgno  4
-#define C320p8buf_pgno 5
-
-#define C320p16rx_spage 3
-#define C320p16tx_spage 4
-#define C320p16rx_pgno 1
-#define C320p16tx_pgno 2
-#define C320p16buf_pgno 3
-
-#define C320p24rx_spage 3
-#define C320p24tx_spage 4
-#define C320p24rx_pgno 1
-#define C320p24tx_pgno 1
-#define C320p24buf_pgno 2
-
-#define C320p32rx_spage 3
-#define C320p32tx_ofs  C320p32rx_size
-#define C320p32tx_spage 3
-#define C320p32buf_pgno 1
-
-/*
- *    Host Status
- */
-#define WakeupRx       0x01
-#define WakeupTx       0x02
-#define WakeupBreak    0x08
-#define WakeupLine     0x10
-#define WakeupIntr     0x20
-#define WakeupQuit     0x40
-#define WakeupEOF      0x80    /* used in VTIME control */
-#define WakeupRxTrigger        0x100
-#define WakeupTxTrigger        0x200
-/*
- *    Flag status
- */
-#define Rx_over                0x01
-#define Xoff_state     0x02
-#define Tx_flowOff     0x04
-#define Tx_enable      0x08
-#define CTS_state      0x10
-#define DSR_state      0x20
-#define DCD_state      0x80
-/*
- *    FlowControl
- */
-#define CTS_FlowCtl    1
-#define RTS_FlowCtl    2
-#define Tx_FlowCtl     4
-#define Rx_FlowCtl     8
-#define IXM_IXANY      0x10
-
-#define LowWater       128
-
-#define DTR_ON         1
-#define RTS_ON         2
-#define CTS_ON         1
-#define DSR_ON         2
-#define DCD_ON         8
-
-/* mode definition */
-#define        MX_CS8          0x03
-#define        MX_CS7          0x02
-#define        MX_CS6          0x01
-#define        MX_CS5          0x00
-
-#define        MX_STOP1        0x00
-#define        MX_STOP15       0x04
-#define        MX_STOP2        0x08
-
-#define        MX_PARNONE      0x00
-#define        MX_PAREVEN      0x40
-#define        MX_PARODD       0xC0
+       if ( !tp || !ts || !(ts->c_cflag & CREAD) ) {
+       *****************************************************/
+       if (!tp || !ts) {
+               MoxaPortFlushData(ch->port, 0);
+               return;
+       }
+       spin_lock_irqsave(&moxa_lock, flags);
+       MoxaPortReadData(ch->port, tp);
+       spin_unlock_irqrestore(&moxa_lock, flags);
+       tty_schedule_flip(tp);
+}
 
 /*
  *    Query
@@ -1378,55 +1593,22 @@ struct mon_str {
 #define        DCD_changed     0x01
 #define        DCD_oldstate    0x80
 
-static unsigned char moxaBuff[10240];
 static int moxaLowWaterChk;
-static int moxaCard;
 static struct mon_str moxaLog;
 static int moxaFuncTout = HZ / 2;
 
 static void moxafunc(void __iomem *, int, ushort);
 static void moxa_wait_finish(void __iomem *);
 static void moxa_low_water_check(void __iomem *);
-static int moxaloadbios(int, unsigned char __user *, int);
-static int moxafindcard(int);
-static int moxaload320b(int, unsigned char __user *, int);
-static int moxaloadcode(int, unsigned char __user *, int);
-static int moxaloadc218(int, void __iomem *, int);
-static int moxaloadc320(int, void __iomem *, int, int *);
 
 /*****************************************************************************
  *     Driver level functions:                                              *
- *     1. MoxaDriverInit(void);                                             *
  *     2. MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port);   *
  *     3. MoxaDriverPoll(void);                                             *
  *****************************************************************************/
-void MoxaDriverInit(void)
-{
-       struct moxa_port *p;
-       unsigned int i;
-
-       moxaFuncTout = HZ / 2;  /* 500 mini-seconds */
-       moxaCard = 0;
-       moxaLog.tick = 0;
-       moxaLowWaterChk = 0;
-       for (i = 0; i < MAX_PORTS; i++) {
-               p = &moxa_ports[i];
-               p->chkPort = 0;
-               p->lowChkFlag = 0;
-               p->lineCtrl = 0;
-               moxaLog.rxcnt[i] = 0;
-               moxaLog.txcnt[i] = 0;
-       }
-}
-
 #define        MOXA            0x400
 #define MOXA_GET_IQUEUE        (MOXA + 1)      /* get input buffered count */
 #define MOXA_GET_OQUEUE        (MOXA + 2)      /* get output buffered count */
-#define MOXA_INIT_DRIVER       (MOXA + 6)      /* moxaCard=0 */
-#define MOXA_LOAD_BIOS         (MOXA + 9)      /* download BIOS */
-#define MOXA_FIND_BOARD                (MOXA + 10)     /* Check if MOXA card exist? */
-#define MOXA_LOAD_C320B                (MOXA + 11)     /* download 320B firmware */
-#define MOXA_LOAD_CODE         (MOXA + 12)     /* download firmware */
 #define MOXA_GETDATACOUNT       (MOXA + 23)
 #define MOXA_GET_IOQUEUE       (MOXA + 27)
 #define MOXA_FLUSH_QUEUE       (MOXA + 28)
@@ -1435,14 +1617,6 @@ void MoxaDriverInit(void)
 #define MOXA_GET_CUMAJOR        (MOXA + 64)
 #define MOXA_GETMSTATUS         (MOXA + 65)
 
-struct dl_str {
-       char __user *buf;
-       int len;
-       int cardno;
-};
-
-static struct dl_str dltmp;
-
 void MoxaPortFlushData(int port, int mode)
 {
        void __iomem *ofsAddr;
@@ -1464,23 +1638,12 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
        void __user *argp = (void __user *)arg;
 
        if (port == MAX_PORTS) {
-               if ((cmd != MOXA_GET_CONF) && (cmd != MOXA_INIT_DRIVER) &&
-                   (cmd != MOXA_LOAD_BIOS) && (cmd != MOXA_FIND_BOARD) && (cmd != MOXA_LOAD_C320B) &&
-                (cmd != MOXA_LOAD_CODE) && (cmd != MOXA_GETDATACOUNT) &&
-                 (cmd != MOXA_GET_IOQUEUE) && (cmd != MOXA_GET_MAJOR) &&
+               if ((cmd != MOXA_GET_CONF) && (cmd != MOXA_GETDATACOUNT) &&
+                   (cmd != MOXA_GET_IOQUEUE) && (cmd != MOXA_GET_MAJOR) &&
                    (cmd != MOXA_GET_CUMAJOR) && (cmd != MOXA_GETMSTATUS))
                        return (-EINVAL);
        }
        switch (cmd) {
-       case MOXA_GET_CONF:
-               if(copy_to_user(argp, &moxa_boards, MAX_BOARDS *
-                               sizeof(struct moxa_board_conf)))
-                       return -EFAULT;
-               return (0);
-       case MOXA_INIT_DRIVER:
-               if ((int) arg == 0x404)
-                       MoxaDriverInit();
-               return (0);
        case MOXA_GETDATACOUNT:
                moxaLog.tick = jiffies;
                if(copy_to_user(argp, &moxaLog, sizeof(struct mon_str)))
@@ -1547,40 +1710,10 @@ copy:
                                return -EFAULT;
                }
                return 0;
-       } default:
-               return (-ENOIOCTLCMD);
-       case MOXA_LOAD_BIOS:
-       case MOXA_FIND_BOARD:
-       case MOXA_LOAD_C320B:
-       case MOXA_LOAD_CODE:
-               if (!capable(CAP_SYS_RAWIO))
-                       return -EPERM;
-               break;
        }
-
-       if(copy_from_user(&dltmp, argp, sizeof(struct dl_str)))
-               return -EFAULT;
-       if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS || dltmp.len < 0)
-               return -EINVAL;
-
-       switch(cmd)
-       {
-       case MOXA_LOAD_BIOS:
-               i = moxaloadbios(dltmp.cardno, dltmp.buf, dltmp.len);
-               return (i);
-       case MOXA_FIND_BOARD:
-               return moxafindcard(dltmp.cardno);
-       case MOXA_LOAD_C320B:
-               moxaload320b(dltmp.cardno, dltmp.buf, dltmp.len);
-       default: /* to keep gcc happy */
-               return (0);
-       case MOXA_LOAD_CODE:
-               i = moxaloadcode(dltmp.cardno, dltmp.buf, dltmp.len);
-               if (i == -1)
-                       return (-EFAULT);
-               return (i);
-
        }
+
+       return -ENOIOCTLCMD;
 }
 
 int MoxaDriverPoll(void)
@@ -1935,7 +2068,6 @@ int MoxaPortsOfCard(int cardno)
  */
 int MoxaPortIsValid(int port)
 {
-
        if (moxaCard == 0)
                return (0);
        if (moxa_ports[port].chkPort == 0)
@@ -2490,335 +2622,6 @@ static void moxa_low_water_check(void __iomem *ofsAddr)
        }
 }
 
-static int moxaloadbios(int cardno, unsigned char __user *tmp, int len)
-{
-       void __iomem *baseAddr;
-       int i;
-
-       if(len < 0 || len > sizeof(moxaBuff))
-               return -EINVAL;
-       if(copy_from_user(moxaBuff, tmp, len))
-               return -EFAULT;
-       baseAddr = moxa_boards[cardno].basemem;
-       writeb(HW_reset, baseAddr + Control_reg);       /* reset */
-       msleep(10);
-       for (i = 0; i < 4096; i++)
-               writeb(0, baseAddr + i);        /* clear fix page */
-       for (i = 0; i < len; i++)
-               writeb(moxaBuff[i], baseAddr + i);      /* download BIOS */
-       writeb(0, baseAddr + Control_reg);      /* restart */
-       return (0);
-}
-
-static int moxafindcard(int cardno)
-{
-       void __iomem *baseAddr;
-       ushort tmp;
-
-       baseAddr = moxa_boards[cardno].basemem;
-       switch (moxa_boards[cardno].boardType) {
-       case MOXA_BOARD_C218_ISA:
-       case MOXA_BOARD_C218_PCI:
-               if ((tmp = readw(baseAddr + C218_key)) != C218_KeyCode) {
-                       return (-1);
-               }
-               break;
-       case MOXA_BOARD_CP204J:
-               if ((tmp = readw(baseAddr + C218_key)) != CP204J_KeyCode) {
-                       return (-1);
-               }
-               break;
-       default:
-               if ((tmp = readw(baseAddr + C320_key)) != C320_KeyCode) {
-                       return (-1);
-               }
-               if ((tmp = readw(baseAddr + C320_status)) != STS_init) {
-                       return (-2);
-               }
-       }
-       return (0);
-}
-
-static int moxaload320b(int cardno, unsigned char __user *tmp, int len)
-{
-       void __iomem *baseAddr;
-       int i;
-
-       if(len < 0 || len > sizeof(moxaBuff))
-               return -EINVAL;
-       if(copy_from_user(moxaBuff, tmp, len))
-               return -EFAULT;
-       baseAddr = moxa_boards[cardno].basemem;
-       writew(len - 7168 - 2, baseAddr + C320bapi_len);
-       writeb(1, baseAddr + Control_reg);      /* Select Page 1 */
-       for (i = 0; i < 7168; i++)
-               writeb(moxaBuff[i], baseAddr + DynPage_addr + i);
-       writeb(2, baseAddr + Control_reg);      /* Select Page 2 */
-       for (i = 0; i < (len - 7168); i++)
-               writeb(moxaBuff[i + 7168], baseAddr + DynPage_addr + i);
-       return (0);
-}
-
-static int moxaloadcode(int cardno, unsigned char __user *tmp, int len)
-{
-       void __iomem *baseAddr, *ofsAddr;
-       int retval, port, i;
-
-       if(len < 0 || len > sizeof(moxaBuff))
-               return -EINVAL;
-       if(copy_from_user(moxaBuff, tmp, len))
-               return -EFAULT;
-       baseAddr = moxa_boards[cardno].basemem;
-       switch (moxa_boards[cardno].boardType) {
-       case MOXA_BOARD_C218_ISA:
-       case MOXA_BOARD_C218_PCI:
-       case MOXA_BOARD_CP204J:
-               retval = moxaloadc218(cardno, baseAddr, len);
-               if (retval)
-                       return (retval);
-               port = cardno * MAX_PORTS_PER_BOARD;
-               for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) {
-                       struct moxa_port *p = &moxa_ports[port];
-
-                       p->chkPort = 1;
-                       p->curBaud = 9600L;
-                       p->DCDState = 0;
-                       p->tableAddr = baseAddr + Extern_table + Extern_size * i;
-                       ofsAddr = p->tableAddr;
-                       writew(C218rx_mask, ofsAddr + RX_mask);
-                       writew(C218tx_mask, ofsAddr + TX_mask);
-                       writew(C218rx_spage + i * C218buf_pageno, ofsAddr + Page_rxb);
-                       writew(readw(ofsAddr + Page_rxb) + C218rx_pageno, ofsAddr + EndPage_rxb);
-
-                       writew(C218tx_spage + i * C218buf_pageno, ofsAddr + Page_txb);
-                       writew(readw(ofsAddr + Page_txb) + C218tx_pageno, ofsAddr + EndPage_txb);
-
-               }
-               break;
-       default:
-               retval = moxaloadc320(cardno, baseAddr, len,
-                                     &moxa_boards[cardno].numPorts);
-               if (retval)
-                       return (retval);
-               port = cardno * MAX_PORTS_PER_BOARD;
-               for (i = 0; i < moxa_boards[cardno].numPorts; i++, port++) {
-                       struct moxa_port *p = &moxa_ports[port];
-
-                       p->chkPort = 1;
-                       p->curBaud = 9600L;
-                       p->DCDState = 0;
-                       p->tableAddr = baseAddr + Extern_table + Extern_size * i;
-                       ofsAddr = p->tableAddr;
-                       if (moxa_boards[cardno].numPorts == 8) {
-                               writew(C320p8rx_mask, ofsAddr + RX_mask);
-                               writew(C320p8tx_mask, ofsAddr + TX_mask);
-                               writew(C320p8rx_spage + i * C320p8buf_pgno, ofsAddr + Page_rxb);
-                               writew(readw(ofsAddr + Page_rxb) + C320p8rx_pgno, ofsAddr + EndPage_rxb);
-                               writew(C320p8tx_spage + i * C320p8buf_pgno, ofsAddr + Page_txb);
-                               writew(readw(ofsAddr + Page_txb) + C320p8tx_pgno, ofsAddr + EndPage_txb);
-
-                       } else if (moxa_boards[cardno].numPorts == 16) {
-                               writew(C320p16rx_mask, ofsAddr + RX_mask);
-                               writew(C320p16tx_mask, ofsAddr + TX_mask);
-                               writew(C320p16rx_spage + i * C320p16buf_pgno, ofsAddr + Page_rxb);
-                               writew(readw(ofsAddr + Page_rxb) + C320p16rx_pgno, ofsAddr + EndPage_rxb);
-                               writew(C320p16tx_spage + i * C320p16buf_pgno, ofsAddr + Page_txb);
-                               writew(readw(ofsAddr + Page_txb) + C320p16tx_pgno, ofsAddr + EndPage_txb);
-
-                       } else if (moxa_boards[cardno].numPorts == 24) {
-                               writew(C320p24rx_mask, ofsAddr + RX_mask);
-                               writew(C320p24tx_mask, ofsAddr + TX_mask);
-                               writew(C320p24rx_spage + i * C320p24buf_pgno, ofsAddr + Page_rxb);
-                               writew(readw(ofsAddr + Page_rxb) + C320p24rx_pgno, ofsAddr + EndPage_rxb);
-                               writew(C320p24tx_spage + i * C320p24buf_pgno, ofsAddr + Page_txb);
-                               writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);
-                       } else if (moxa_boards[cardno].numPorts == 32) {
-                               writew(C320p32rx_mask, ofsAddr + RX_mask);
-                               writew(C320p32tx_mask, ofsAddr + TX_mask);
-                               writew(C320p32tx_ofs, ofsAddr + Ofs_txb);
-                               writew(C320p32rx_spage + i * C320p32buf_pgno, ofsAddr + Page_rxb);
-                               writew(readb(ofsAddr + Page_rxb), ofsAddr + EndPage_rxb);
-                               writew(C320p32tx_spage + i * C320p32buf_pgno, ofsAddr + Page_txb);
-                               writew(readw(ofsAddr + Page_txb), ofsAddr + EndPage_txb);
-                       }
-               }
-               break;
-       }
-       moxa_boards[cardno].loadstat = 1;
-       return (0);
-}
-
-static int moxaloadc218(int cardno, void __iomem *baseAddr, int len)
-{
-       char retry;
-       int i, j, len1, len2;
-       ushort usum, *ptr, keycode;
-
-       if (moxa_boards[cardno].boardType == MOXA_BOARD_CP204J)
-               keycode = CP204J_KeyCode;
-       else
-               keycode = C218_KeyCode;
-       usum = 0;
-       len1 = len >> 1;
-       ptr = (ushort *) moxaBuff;
-       for (i = 0; i < len1; i++)
-               usum += le16_to_cpu(*(ptr + i));
-       retry = 0;
-       do {
-               len1 = len >> 1;
-               j = 0;
-               while (len1) {
-                       len2 = (len1 > 2048) ? 2048 : len1;
-                       len1 -= len2;
-                       for (i = 0; i < len2 << 1; i++)
-                               writeb(moxaBuff[i + j], baseAddr + C218_LoadBuf + i);
-                       j += i;
-
-                       writew(len2, baseAddr + C218DLoad_len);
-                       writew(0, baseAddr + C218_key);
-                       for (i = 0; i < 100; i++) {
-                               if (readw(baseAddr + C218_key) == keycode)
-                                       break;
-                               msleep(10);
-                       }
-                       if (readw(baseAddr + C218_key) != keycode) {
-                               return (-1);
-                       }
-               }
-               writew(0, baseAddr + C218DLoad_len);
-               writew(usum, baseAddr + C218check_sum);
-               writew(0, baseAddr + C218_key);
-               for (i = 0; i < 100; i++) {
-                       if (readw(baseAddr + C218_key) == keycode)
-                               break;
-                       msleep(10);
-               }
-               retry++;
-       } while ((readb(baseAddr + C218chksum_ok) != 1) && (retry < 3));
-       if (readb(baseAddr + C218chksum_ok) != 1) {
-               return (-1);
-       }
-       writew(0, baseAddr + C218_key);
-       for (i = 0; i < 100; i++) {
-               if (readw(baseAddr + Magic_no) == Magic_code)
-                       break;
-               msleep(10);
-       }
-       if (readw(baseAddr + Magic_no) != Magic_code) {
-               return (-1);
-       }
-       writew(1, baseAddr + Disable_IRQ);
-       writew(0, baseAddr + Magic_no);
-       for (i = 0; i < 100; i++) {
-               if (readw(baseAddr + Magic_no) == Magic_code)
-                       break;
-               msleep(10);
-       }
-       if (readw(baseAddr + Magic_no) != Magic_code) {
-               return (-1);
-       }
-       moxaCard = 1;
-       moxa_boards[cardno].intNdx = baseAddr + IRQindex;
-       moxa_boards[cardno].intPend = baseAddr + IRQpending;
-       moxa_boards[cardno].intTable = baseAddr + IRQtable;
-       return (0);
-}
-
-static int moxaloadc320(int cardno, void __iomem *baseAddr, int len, int *numPorts)
-{
-       ushort usum;
-       int i, j, wlen, len2, retry;
-       ushort *uptr;
-
-       usum = 0;
-       wlen = len >> 1;
-       uptr = (ushort *) moxaBuff;
-       for (i = 0; i < wlen; i++)
-               usum += le16_to_cpu(uptr[i]);
-       retry = 0;
-       j = 0;
-       do {
-               while (wlen) {
-                       if (wlen > 2048)
-                               len2 = 2048;
-                       else
-                               len2 = wlen;
-                       wlen -= len2;
-                       len2 <<= 1;
-                       for (i = 0; i < len2; i++)
-                               writeb(moxaBuff[j + i], baseAddr + C320_LoadBuf + i);
-                       len2 >>= 1;
-                       j += i;
-                       writew(len2, baseAddr + C320DLoad_len);
-                       writew(0, baseAddr + C320_key);
-                       for (i = 0; i < 10; i++) {
-                               if (readw(baseAddr + C320_key) == C320_KeyCode)
-                                       break;
-                               msleep(10);
-                       }
-                       if (readw(baseAddr + C320_key) != C320_KeyCode)
-                               return (-1);
-               }
-               writew(0, baseAddr + C320DLoad_len);
-               writew(usum, baseAddr + C320check_sum);
-               writew(0, baseAddr + C320_key);
-               for (i = 0; i < 10; i++) {
-                       if (readw(baseAddr + C320_key) == C320_KeyCode)
-                               break;
-                       msleep(10);
-               }
-               retry++;
-       } while ((readb(baseAddr + C320chksum_ok) != 1) && (retry < 3));
-       if (readb(baseAddr + C320chksum_ok) != 1)
-               return (-1);
-       writew(0, baseAddr + C320_key);
-       for (i = 0; i < 600; i++) {
-               if (readw(baseAddr + Magic_no) == Magic_code)
-                       break;
-               msleep(10);
-       }
-       if (readw(baseAddr + Magic_no) != Magic_code)
-               return (-100);
-
-       if (moxa_boards[cardno].busType == MOXA_BUS_TYPE_PCI) {         /* ASIC board */
-               writew(0x3800, baseAddr + TMS320_PORT1);
-               writew(0x3900, baseAddr + TMS320_PORT2);
-               writew(28499, baseAddr + TMS320_CLOCK);
-       } else {
-               writew(0x3200, baseAddr + TMS320_PORT1);
-               writew(0x3400, baseAddr + TMS320_PORT2);
-               writew(19999, baseAddr + TMS320_CLOCK);
-       }
-       writew(1, baseAddr + Disable_IRQ);
-       writew(0, baseAddr + Magic_no);
-       for (i = 0; i < 500; i++) {
-               if (readw(baseAddr + Magic_no) == Magic_code)
-                       break;
-               msleep(10);
-       }
-       if (readw(baseAddr + Magic_no) != Magic_code)
-               return (-102);
-
-       j = readw(baseAddr + Module_cnt);
-       if (j <= 0)
-               return (-101);
-       *numPorts = j * 8;
-       writew(j, baseAddr + Module_no);
-       writew(0, baseAddr + Magic_no);
-       for (i = 0; i < 600; i++) {
-               if (readw(baseAddr + Magic_no) == Magic_code)
-                       break;
-               msleep(10);
-       }
-       if (readw(baseAddr + Magic_no) != Magic_code)
-               return (-102);
-       moxaCard = 1;
-       moxa_boards[cardno].intNdx = baseAddr + IRQindex;
-       moxa_boards[cardno].intPend = baseAddr + IRQpending;
-       moxa_boards[cardno].intTable = baseAddr + IRQtable;
-       return (0);
-}
-
 static void MoxaSetFifo(int port, int enable)
 {
        void __iomem *ofsAddr = moxa_ports[port].tableAddr;
diff --git a/drivers/char/moxa.h b/drivers/char/moxa.h
new file mode 100644 (file)
index 0000000..2a38d17
--- /dev/null
@@ -0,0 +1,296 @@
+#ifndef MOXA_H_FILE
+#define MOXA_H_FILE
+
+/*
+ *    System Configuration
+ */
+
+#define Magic_code     0x404
+
+/*
+ *    for C218 BIOS initialization
+ */
+#define C218_ConfBase  0x800
+#define C218_status    (C218_ConfBase + 0)     /* BIOS running status    */
+#define C218_diag      (C218_ConfBase + 2)     /* diagnostic status      */
+#define C218_key       (C218_ConfBase + 4)     /* WORD (0x218 for C218) */
+#define C218DLoad_len  (C218_ConfBase + 6)     /* WORD           */
+#define C218check_sum  (C218_ConfBase + 8)     /* BYTE           */
+#define C218chksum_ok  (C218_ConfBase + 0x0a)  /* BYTE (1:ok)            */
+#define C218_TestRx    (C218_ConfBase + 0x10)  /* 8 bytes for 8 ports    */
+#define C218_TestTx    (C218_ConfBase + 0x18)  /* 8 bytes for 8 ports    */
+#define C218_RXerr     (C218_ConfBase + 0x20)  /* 8 bytes for 8 ports    */
+#define C218_ErrFlag   (C218_ConfBase + 0x28)  /* 8 bytes for 8 ports    */
+
+#define C218_LoadBuf   0x0F00
+#define C218_KeyCode   0x218
+#define CP204J_KeyCode 0x204
+
+/*
+ *    for C320 BIOS initialization
+ */
+#define C320_ConfBase  0x800
+#define C320_LoadBuf   0x0f00
+#define STS_init       0x05    /* for C320_status        */
+
+#define C320_status    C320_ConfBase + 0       /* BIOS running status    */
+#define C320_diag      C320_ConfBase + 2       /* diagnostic status      */
+#define C320_key       C320_ConfBase + 4       /* WORD (0320H for C320) */
+#define C320DLoad_len  C320_ConfBase + 6       /* WORD           */
+#define C320check_sum  C320_ConfBase + 8       /* WORD           */
+#define C320chksum_ok  C320_ConfBase + 0x0a    /* WORD (1:ok)            */
+#define C320bapi_len   C320_ConfBase + 0x0c    /* WORD           */
+#define C320UART_no    C320_ConfBase + 0x0e    /* WORD           */
+
+#define C320_KeyCode   0x320
+
+#define FixPage_addr   0x0000  /* starting addr of static page  */
+#define DynPage_addr   0x2000  /* starting addr of dynamic page */
+#define C218_start     0x3000  /* starting addr of C218 BIOS prg */
+#define Control_reg    0x1ff0  /* select page and reset control */
+#define HW_reset       0x80
+
+/*
+ *    Function Codes
+ */
+#define FC_CardReset   0x80
+#define FC_ChannelReset 1      /* C320 firmware not supported */
+#define FC_EnableCH    2
+#define FC_DisableCH   3
+#define FC_SetParam    4
+#define FC_SetMode     5
+#define FC_SetRate     6
+#define FC_LineControl 7
+#define FC_LineStatus  8
+#define FC_XmitControl 9
+#define FC_FlushQueue  10
+#define FC_SendBreak   11
+#define FC_StopBreak   12
+#define FC_LoopbackON  13
+#define FC_LoopbackOFF 14
+#define FC_ClrIrqTable 15
+#define FC_SendXon     16
+#define FC_SetTermIrq  17      /* C320 firmware not supported */
+#define FC_SetCntIrq   18      /* C320 firmware not supported */
+#define FC_SetBreakIrq 19
+#define FC_SetLineIrq  20
+#define FC_SetFlowCtl  21
+#define FC_GenIrq      22
+#define FC_InCD180     23
+#define FC_OutCD180    24
+#define FC_InUARTreg   23
+#define FC_OutUARTreg  24
+#define FC_SetXonXoff  25
+#define FC_OutCD180CCR 26
+#define FC_ExtIQueue   27
+#define FC_ExtOQueue   28
+#define FC_ClrLineIrq  29
+#define FC_HWFlowCtl   30
+#define FC_GetClockRate 35
+#define FC_SetBaud     36
+#define FC_SetDataMode  41
+#define FC_GetCCSR      43
+#define FC_GetDataError 45
+#define FC_RxControl   50
+#define FC_ImmSend     51
+#define FC_SetXonState 52
+#define FC_SetXoffState        53
+#define FC_SetRxFIFOTrig 54
+#define FC_SetTxFIFOCnt 55
+#define FC_UnixRate    56
+#define FC_UnixResetTimer 57
+
+#define        RxFIFOTrig1     0
+#define        RxFIFOTrig4     1
+#define        RxFIFOTrig8     2
+#define        RxFIFOTrig14    3
+
+/*
+ *    Dual-Ported RAM
+ */
+#define DRAM_global    0
+#define INT_data       (DRAM_global + 0)
+#define Config_base    (DRAM_global + 0x108)
+
+#define IRQindex       (INT_data + 0)
+#define IRQpending     (INT_data + 4)
+#define IRQtable       (INT_data + 8)
+
+/*
+ *    Interrupt Status
+ */
+#define IntrRx         0x01    /* receiver data O.K.             */
+#define IntrTx         0x02    /* transmit buffer empty  */
+#define IntrFunc       0x04    /* function complete              */
+#define IntrBreak      0x08    /* received break         */
+#define IntrLine       0x10    /* line status change
+                                  for transmitter                */
+#define IntrIntr       0x20    /* received INTR code             */
+#define IntrQuit       0x40    /* received QUIT code             */
+#define IntrEOF        0x80    /* received EOF code              */
+
+#define IntrRxTrigger  0x100   /* rx data count reach tigger value */
+#define IntrTxTrigger  0x200   /* tx data count below trigger value */
+
+#define Magic_no       (Config_base + 0)
+#define Card_model_no  (Config_base + 2)
+#define Total_ports    (Config_base + 4)
+#define Module_cnt     (Config_base + 8)
+#define Module_no      (Config_base + 10)
+#define Timer_10ms     (Config_base + 14)
+#define Disable_IRQ    (Config_base + 20)
+#define TMS320_PORT1   (Config_base + 22)
+#define TMS320_PORT2   (Config_base + 24)
+#define TMS320_CLOCK   (Config_base + 26)
+
+/*
+ *    DATA BUFFER in DRAM
+ */
+#define Extern_table   0x400   /* Base address of the external table
+                                  (24 words *    64) total 3K bytes
+                                  (24 words * 128) total 6K bytes */
+#define Extern_size    0x60    /* 96 bytes                       */
+#define RXrptr         0x00    /* read pointer for RX buffer     */
+#define RXwptr         0x02    /* write pointer for RX buffer    */
+#define TXrptr         0x04    /* read pointer for TX buffer     */
+#define TXwptr         0x06    /* write pointer for TX buffer    */
+#define HostStat       0x08    /* IRQ flag and general flag      */
+#define FlagStat       0x0A
+#define FlowControl    0x0C    /* B7 B6 B5 B4 B3 B2 B1 B0              */
+                                       /*  x  x  x  x  |  |  |  |            */
+                                       /*              |  |  |  + CTS flow   */
+                                       /*              |  |  +--- RTS flow   */
+                                       /*              |  +------ TX Xon/Xoff */
+                                       /*              +--------- RX Xon/Xoff */
+#define Break_cnt      0x0E    /* received break count   */
+#define CD180TXirq     0x10    /* if non-0: enable TX irq        */
+#define RX_mask        0x12
+#define TX_mask        0x14
+#define Ofs_rxb        0x16
+#define Ofs_txb        0x18
+#define Page_rxb       0x1A
+#define Page_txb       0x1C
+#define EndPage_rxb    0x1E
+#define EndPage_txb    0x20
+#define Data_error     0x22
+#define RxTrigger      0x28
+#define TxTrigger      0x2a
+
+#define rRXwptr        0x34
+#define Low_water      0x36
+
+#define FuncCode       0x40
+#define FuncArg        0x42
+#define FuncArg1       0x44
+
+#define C218rx_size    0x2000  /* 8K bytes */
+#define C218tx_size    0x8000  /* 32K bytes */
+
+#define C218rx_mask    (C218rx_size - 1)
+#define C218tx_mask    (C218tx_size - 1)
+
+#define C320p8rx_size  0x2000
+#define C320p8tx_size  0x8000
+#define C320p8rx_mask  (C320p8rx_size - 1)
+#define C320p8tx_mask  (C320p8tx_size - 1)
+
+#define C320p16rx_size 0x2000
+#define C320p16tx_size 0x4000
+#define C320p16rx_mask (C320p16rx_size - 1)
+#define C320p16tx_mask (C320p16tx_size - 1)
+
+#define C320p24rx_size 0x2000
+#define C320p24tx_size 0x2000
+#define C320p24rx_mask (C320p24rx_size - 1)
+#define C320p24tx_mask (C320p24tx_size - 1)
+
+#define C320p32rx_size 0x1000
+#define C320p32tx_size 0x1000
+#define C320p32rx_mask (C320p32rx_size - 1)
+#define C320p32tx_mask (C320p32tx_size - 1)
+
+#define Page_size      0x2000
+#define Page_mask      (Page_size - 1)
+#define C218rx_spage   3
+#define C218tx_spage   4
+#define C218rx_pageno  1
+#define C218tx_pageno  4
+#define C218buf_pageno 5
+
+#define C320p8rx_spage 3
+#define C320p8tx_spage 4
+#define C320p8rx_pgno  1
+#define C320p8tx_pgno  4
+#define C320p8buf_pgno 5
+
+#define C320p16rx_spage 3
+#define C320p16tx_spage 4
+#define C320p16rx_pgno 1
+#define C320p16tx_pgno 2
+#define C320p16buf_pgno 3
+
+#define C320p24rx_spage 3
+#define C320p24tx_spage 4
+#define C320p24rx_pgno 1
+#define C320p24tx_pgno 1
+#define C320p24buf_pgno 2
+
+#define C320p32rx_spage 3
+#define C320p32tx_ofs  C320p32rx_size
+#define C320p32tx_spage 3
+#define C320p32buf_pgno 1
+
+/*
+ *    Host Status
+ */
+#define WakeupRx       0x01
+#define WakeupTx       0x02
+#define WakeupBreak    0x08
+#define WakeupLine     0x10
+#define WakeupIntr     0x20
+#define WakeupQuit     0x40
+#define WakeupEOF      0x80    /* used in VTIME control */
+#define WakeupRxTrigger        0x100
+#define WakeupTxTrigger        0x200
+/*
+ *    Flag status
+ */
+#define Rx_over                0x01
+#define Xoff_state     0x02
+#define Tx_flowOff     0x04
+#define Tx_enable      0x08
+#define CTS_state      0x10
+#define DSR_state      0x20
+#define DCD_state      0x80
+/*
+ *    FlowControl
+ */
+#define CTS_FlowCtl    1
+#define RTS_FlowCtl    2
+#define Tx_FlowCtl     4
+#define Rx_FlowCtl     8
+#define IXM_IXANY      0x10
+
+#define LowWater       128
+
+#define DTR_ON         1
+#define RTS_ON         2
+#define CTS_ON         1
+#define DSR_ON         2
+#define DCD_ON         8
+
+/* mode definition */
+#define        MX_CS8          0x03
+#define        MX_CS7          0x02
+#define        MX_CS6          0x01
+#define        MX_CS5          0x00
+
+#define        MX_STOP1        0x00
+#define        MX_STOP15       0x04
+#define        MX_STOP2        0x08
+
+#define        MX_PARNONE      0x00
+#define        MX_PAREVEN      0x40
+#define        MX_PARODD       0xC0
+
+#endif