int numPorts;
        int busType;
 
-       int loadstat;
+       unsigned int ready;
 
        struct moxa_port *ports;
 
 
        struct timer_list emptyTimer;
 
-       char chkPort;
        char lineCtrl;
        void __iomem *tableAddr;
        char DCDState;
 #define WAKEUP_CHARS           256
 
 static int ttymajor = MOXAMAJOR;
-static int moxaCard;
 /* Variables for insmod */
 #ifdef MODULE
 static unsigned long baseaddr[MAX_BOARDS];
 static int MoxaDriverIoctl(struct tty_struct *, unsigned int, unsigned long);
 static int MoxaDriverPoll(void);
 static int MoxaPortsOfCard(int);
-static int MoxaPortIsValid(int);
 static void MoxaPortEnable(struct moxa_port *);
 static void MoxaPortDisable(struct moxa_port *);
 static int MoxaPortSetTermio(struct moxa_port *, struct ktermios *, speed_t);
 };
 
 static struct tty_driver *moxaDriver;
-static struct moxa_port moxa_ports[MAX_PORTS];
 static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);
 static DEFINE_SPINLOCK(moxa_lock);
 
                if (readw(baseAddr + Magic_no) != Magic_code)
                        return -EIO;
        }
-       moxaCard = 1;
        brd->intNdx = baseAddr + IRQindex;
        brd->intPend = baseAddr + IRQpending;
        brd->intTable = baseAddr + IRQtable;
                port = brd->ports;
                for (i = 0; i < brd->numPorts; i++, port++) {
                        port->board = brd;
-                       port->chkPort = 1;
                        port->DCDState = 0;
                        port->tableAddr = baseAddr + Extern_table +
                                        Extern_size * i;
                port = brd->ports;
                for (i = 0; i < brd->numPorts; i++, port++) {
                        port->board = brd;
-                       port->chkPort = 1;
                        port->DCDState = 0;
                        port->tableAddr = baseAddr + Extern_table +
                                        Extern_size * i;
                }
                break;
        }
-       brd->loadstat = 1;
        return 0;
 }
 
 {
        const struct firmware *fw;
        const char *file;
+       struct moxa_port *p;
+       unsigned int i;
        int ret;
 
+       brd->ports = kcalloc(MAX_PORTS_PER_BOARD, sizeof(*brd->ports),
+                       GFP_KERNEL);
+       if (brd->ports == NULL) {
+               printk(KERN_ERR "cannot allocate memory for ports\n");
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       for (i = 0, p = brd->ports; i < MAX_PORTS_PER_BOARD; i++, p++) {
+               p->type = PORT_16550A;
+               p->close_delay = 5 * HZ / 10;
+               p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
+               init_waitqueue_head(&p->open_wait);
+               init_completion(&p->close_wait);
+
+               setup_timer(&p->emptyTimer, moxa_check_xmit_empty,
+                               (unsigned long)p);
+       }
+
        switch (brd->boardType) {
        case MOXA_BOARD_C218_ISA:
        case MOXA_BOARD_C218_PCI:
        ret = request_firmware(&fw, file, dev);
        if (ret) {
                printk(KERN_ERR "request_firmware failed\n");
-               goto end;
+               goto err_free;
        }
 
        ret = moxa_load_fw(brd, fw);
 
        release_firmware(fw);
-end:
+
+       if (ret)
+               goto err_free;
+
+       brd->ready = 1;
+
+       return 0;
+err_free:
+       kfree(brd->ports);
+err:
        return ret;
 }
 
+static void moxa_board_deinit(struct moxa_board_conf *brd)
+{
+       unsigned int i;
+
+       brd->ready = 0;
+       for (i = 0; i < MAX_PORTS_PER_BOARD; i++)
+               del_timer_sync(&brd->ports[i].emptyTimer);
+
+       iounmap(brd->basemem);
+       brd->basemem = NULL;
+       kfree(brd->ports);
+}
+
 #ifdef CONFIG_PCI
 static int __devinit moxa_pci_probe(struct pci_dev *pdev,
                const struct pci_device_id *ent)
        }
 
        board = &moxa_boards[i];
-       board->ports = &moxa_ports[i * MAX_PORTS_PER_BOARD];
 
        retval = pci_request_region(pdev, 2, "moxa-base");
        if (retval) {
 {
        struct moxa_board_conf *brd = pci_get_drvdata(pdev);
 
-       iounmap(brd->basemem);
-       brd->basemem = NULL;
+       moxa_board_deinit(brd);
+
        pci_release_region(pdev, 2);
 }
 
 
 static int __init moxa_init(void)
 {
-       struct moxa_port *ch;
-       unsigned int i, isabrds = 0;
+       unsigned int isabrds = 0;
        int retval = 0;
 
        printk(KERN_INFO "MOXA Intellio family driver version %s\n",
        moxaDriver->flags = TTY_DRIVER_REAL_RAW;
        tty_set_operations(moxaDriver, &moxa_ops);
 
-       for (i = 0, ch = moxa_ports; i < MAX_PORTS; i++, ch++) {
-               ch->type = PORT_16550A;
-               ch->close_delay = 5 * HZ / 10;
-               ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
-               init_waitqueue_head(&ch->open_wait);
-               init_completion(&ch->close_wait);
-
-               setup_timer(&ch->emptyTimer, moxa_check_xmit_empty,
-                               (unsigned long)ch);
-       }
-
        pr_debug("Moxa tty devices major number = %d\n", ttymajor);
 
        if (tty_register_driver(moxaDriver)) {
 #ifdef MODULE
        {
        struct moxa_board_conf *brd = moxa_boards;
+       unsigned int i;
        for (i = 0; i < MAX_BOARDS; i++) {
                if (!baseaddr[i])
                        break;
                                        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;
 
        del_timer_sync(&moxaTimer);
 
-       for (i = 0; i < MAX_PORTS; i++)
-               del_timer_sync(&moxa_ports[i].emptyTimer);
-
        if (tty_unregister_driver(moxaDriver))
                printk(KERN_ERR "Couldn't unregister MOXA Intellio family "
                                "serial driver\n");
        pci_unregister_driver(&moxa_pci_driver);
 #endif
 
-       for (i = 0; i < MAX_BOARDS; i++)
-               if (moxa_boards[i].basemem)
-                       iounmap(moxa_boards[i].basemem);
+       for (i = 0; i < MAX_BOARDS; i++) /* ISA boards */
+               if (moxa_boards[i].ready)
+                       moxa_board_deinit(&moxa_boards[i]);
 }
 
 module_init(moxa_init);
 
 static int moxa_open(struct tty_struct *tty, struct file *filp)
 {
+       struct moxa_board_conf *brd;
        struct moxa_port *ch;
        int port;
        int retval;
        if (port == MAX_PORTS) {
                return (0);
        }
-       if (!MoxaPortIsValid(port)) {
-               tty->driver_data = NULL;
-               return (-ENODEV);
-       }
+       brd = &moxa_boards[port / MAX_PORTS_PER_BOARD];
+       if (!brd->ready)
+               return -ENODEV;
 
-       ch = &moxa_ports[port];
+       ch = &brd->ports[port % MAX_PORTS_PER_BOARD];
        ch->count++;
        tty->driver_data = ch;
        ch->tty = tty;
        if (port == MAX_PORTS) {
                return;
        }
-       if (!MoxaPortIsValid(port)) {
-               pr_debug("Invalid portno in moxa_close\n");
-               tty->driver_data = NULL;
-               return;
-       }
        if (tty->driver_data == NULL) {
                return;
        }
        for (card = 0; card < MAX_BOARDS; card++) {
                if ((ports = MoxaPortsOfCard(card)) <= 0)
                        continue;
-               ch = &moxa_ports[card * MAX_PORTS_PER_BOARD];
+               ch = moxa_boards[card].ports;
                for (i = 0; i < ports; i++, ch++) {
                        if ((ch->asyncflags & ASYNC_INITIALIZED) == 0)
                                continue;
        case MOXA_GET_IOQUEUE: {
                struct moxaq_str __user *argm = argp;
                struct moxaq_str tmp;
-
-               for (i = 0; i < MAX_PORTS; i++, argm++) {
-                       memset(&tmp, 0, sizeof(tmp));
-                       if (moxa_ports[i].chkPort) {
-                               tmp.inq = MoxaPortRxQueue(&moxa_ports[i]);
-                               tmp.outq = MoxaPortTxQueue(&moxa_ports[i]);
+               struct moxa_port *p;
+               unsigned int j;
+
+               for (i = 0; i < MAX_BOARDS; i++) {
+                       p = moxa_boards[i].ports;
+                       for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
+                               memset(&tmp, 0, sizeof(tmp));
+                               if (moxa_boards[i].ready) {
+                                       tmp.inq = MoxaPortRxQueue(p);
+                                       tmp.outq = MoxaPortTxQueue(p);
+                               }
+                               if (copy_to_user(argm, &tmp, sizeof(tmp)))
+                                       return -EFAULT;
                        }
-                       if (copy_to_user(argm, &tmp, sizeof(tmp)))
-                               return -EFAULT;
                }
-               return (0);
+               return 0;
        } case MOXA_GET_OQUEUE:
                i = MoxaPortTxQueue(port);
                return put_user(i, (unsigned long __user *)argp);
                struct mxser_mstatus __user *argm = argp;
                struct mxser_mstatus tmp;
                struct moxa_port *p;
+               unsigned int j;
+
+               for (i = 0; i < MAX_BOARDS; i++) {
+                       p = moxa_boards[i].ports;
+                       for (j = 0; j < MAX_PORTS_PER_BOARD; j++, p++, argm++) {
+                               memset(&tmp, 0, sizeof(tmp));
+                               if (!moxa_boards[i].ready)
+                                       goto copy;
 
-               for (i = 0; i < MAX_PORTS; i++, argm++) {
-                       p = &moxa_ports[i];
-                       memset(&tmp, 0, sizeof(tmp));
-                       if (!p->chkPort) {
-                               goto copy;
-                       } else {
                                status = MoxaPortLineStatus(p);
                                if (status & 1)
                                        tmp.cts = 1;
                                        tmp.dsr = 1;
                                if (status & 4)
                                        tmp.dcd = 1;
-                       }
 
-                       if (!p->tty || !p->tty->termios)
-                               tmp.cflag = p->cflag;
-                       else
-                               tmp.cflag = p->tty->termios->c_cflag;
+                               if (!p->tty || !p->tty->termios)
+                                       tmp.cflag = p->cflag;
+                               else
+                                       tmp.cflag = p->tty->termios->c_cflag;
 copy:
-                       if (copy_to_user(argm, &tmp, sizeof(tmp)))
-                               return -EFAULT;
+                               if (copy_to_user(argm, &tmp, sizeof(tmp)))
+                                       return -EFAULT;
+                       }
                }
                return 0;
        }
 int MoxaDriverPoll(void)
 {
        struct moxa_board_conf *brd;
+       struct moxa_port *p;
        register ushort temp;
        register int card;
        void __iomem *ofsAddr;
        void __iomem *ip;
-       int port, p, ports;
+       int port, ports;
 
-       if (moxaCard == 0)
-               return (-1);
        for (card = 0; card < MAX_BOARDS; card++) {
                brd = &moxa_boards[card];
-               if (brd->loadstat == 0)
+               if (brd->ready == 0)
                        continue;
                if ((ports = brd->numPorts) == 0)
                        continue;
                if (readb(brd->intPend) == 0xff) {
                        ip = brd->intTable + readb(brd->intNdx);
-                       p = card * MAX_PORTS_PER_BOARD;
+                       p = brd->ports;
                        ports <<= 1;
                        for (port = 0; port < ports; port += 2, p++) {
-                               if ((temp = readw(ip + port)) != 0) {
-                                       writew(0, ip + port);
-                                       ofsAddr = moxa_ports[p].tableAddr;
-                                       if (temp & IntrTx)
-                                               writew(readw(ofsAddr + HostStat) & ~WakeupTx, ofsAddr + HostStat);
-                                       if (temp & IntrBreak) {
-                                               moxa_ports[p].breakCnt++;
-                                       }
-                                       if (temp & IntrLine) {
-                                               if (readb(ofsAddr + FlagStat) & DCD_state) {
-                                                       if ((moxa_ports[p].DCDState & DCD_oldstate) == 0)
-                                                               moxa_ports[p].DCDState = (DCD_oldstate |
-                                                                                  DCD_changed);
-                                               } else {
-                                                       if (moxa_ports[p].DCDState & DCD_oldstate)
-                                                               moxa_ports[p].DCDState = DCD_changed;
-                                               }
+                               temp = readw(ip + port);
+                               if (temp == 0)
+                                       continue;
+
+                               writew(0, ip + port);
+                               ofsAddr = p->tableAddr;
+                               if (temp & IntrTx)
+                                       writew(readw(ofsAddr + HostStat) &
+                                               ~WakeupTx, ofsAddr + HostStat);
+                               if (temp & IntrBreak)
+                                       p->breakCnt++;
+
+                               if (temp & IntrLine) {
+                                       if (readb(ofsAddr + FlagStat) & DCD_state) {
+                                               if ((p->DCDState & DCD_oldstate) == 0)
+                                                       p->DCDState = (DCD_oldstate |
+                                                                          DCD_changed);
+                                       } else {
+                                               if (p->DCDState & DCD_oldstate)
+                                                       p->DCDState = DCD_changed;
                                        }
                                }
                        }
                        writeb(0, brd->intPend);
                }
                if (moxaLowWaterChk) {
-                       p = card * MAX_PORTS_PER_BOARD;
+                       p = brd->ports;
                        for (port = 0; port < ports; port++, p++) {
-                               if (moxa_ports[p].lowChkFlag) {
-                                       moxa_ports[p].lowChkFlag = 0;
-                                       ofsAddr = moxa_ports[p].tableAddr;
+                               if (p->lowChkFlag) {
+                                       p->lowChkFlag = 0;
+                                       ofsAddr = p->tableAddr;
                                        moxa_low_water_check(ofsAddr);
                                }
                        }
 
 /*****************************************************************************
  *     Port level functions:                                                *
- *     1.  MoxaPortIsValid(int port);                                       *
  *     2.  MoxaPortEnable(int port);                                        *
  *     3.  MoxaPortDisable(int port);                                       *
  *     4.  MoxaPortGetMaxBaud(int port);                                    *
  *                      8/16/24/32
  *
  *
- *      Function 5:     Check this port is valid or invalid
- *      Syntax:
- *      int  MoxaPortIsValid(int port);
- *           int port           : port number (0 - 127, ref port description)
- *
- *           return:    0       : this port is invalid
- *                      1       : this port is valid
- *
- *
  *      Function 6:     Enable this port to start Tx/Rx data.
  *      Syntax:
  *      void MoxaPortEnable(int port);
  *                                send out a about 250 ms BREAK signal.
  *
  */
-static int MoxaPortIsValid(int port)
-{
-       if (moxaCard == 0)
-               return (0);
-       if (moxa_ports[port].chkPort == 0)
-               return (0);
-       return (1);
-}
 
 static void MoxaPortEnable(struct moxa_port *port)
 {
        tcflag_t cflag;
        tcflag_t mode = 0;
 
-       if (port->chkPort == 0 || termio == 0)
-               return (-1);
        ofsAddr = port->tableAddr;
        cflag = termio->c_cflag;        /* termio->c_cflag */
 
                int *rtsState)
 {
 
-       if (!MoxaPortIsValid(port->tty->index))
-               return (-1);
        if (dtrState)
                *dtrState = !!(port->lineCtrl & DTR_ON);
        if (rtsState)
 {
        int n;
 
-       if (port->chkPort == 0)
-               return (0);
        n = port->DCDState;
        port->DCDState &= ~DCD_changed;
        n &= DCD_changed;
 {
        int n;
 
-       if (port->chkPort == 0)
-               return (0);
        if (port->DCDState & DCD_oldstate)
                n = 1;
        else