fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / char / moxa.c
index c6430cf..f391a24 100644 (file)
@@ -29,7 +29,6 @@
  *      version         : 5.1
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/bitops.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 
 #define                MOXA_VERSION            "5.1k"
@@ -104,6 +103,7 @@ static char *moxa_brdname[] =
        "CP-204J series",
 };
 
+#ifdef CONFIG_PCI
 static struct pci_device_id moxa_pcibrds[] = {
        { PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C218, PCI_ANY_ID, PCI_ANY_ID, 
          0, 0, MOXA_BOARD_C218_PCI },
@@ -114,6 +114,7 @@ static struct pci_device_id moxa_pcibrds[] = {
        { 0 }
 };
 MODULE_DEVICE_TABLE(pci, moxa_pcibrds);
+#endif /* CONFIG_PCI */
 
 typedef struct _moxa_isa_board_conf {
        int boardType;
@@ -129,6 +130,7 @@ static moxa_isa_board_conf moxa_isa_boards[] =
 typedef struct _moxa_pci_devinfo {
        ushort busNum;
        ushort devNum;
+       struct pci_dev *pdev;
 } moxa_pci_devinfo;
 
 typedef struct _moxa_board_conf {
@@ -140,7 +142,8 @@ typedef struct _moxa_board_conf {
 } moxa_board_conf;
 
 static moxa_board_conf moxa_boards[MAX_BOARDS];
-static unsigned long moxaBaseAddr[MAX_BOARDS];
+static void __iomem *moxaBaseAddr[MAX_BOARDS];
+static int loadstat[MAX_BOARDS];
 
 struct moxa_str {
        int type;
@@ -190,18 +193,22 @@ static struct mxser_mstatus GMStatus[MAX_PORTS];
 static int verbose = 0;
 static int ttymajor = MOXAMAJOR;
 /* Variables for insmod */
+#ifdef MODULE
 static int baseaddr[]  =       {0, 0, 0, 0};
 static int type[]      =       {0, 0, 0, 0};
 static int numports[]  =       {0, 0, 0, 0};
+#endif
 
 MODULE_AUTHOR("William Chen");
 MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver");
 MODULE_LICENSE("GPL");
-MODULE_PARM(type, "1-4i");
-MODULE_PARM(baseaddr, "1-4i");
-MODULE_PARM(numports, "1-4i");
-MODULE_PARM(ttymajor, "i");
-MODULE_PARM(verbose, "i");
+#ifdef MODULE
+module_param_array(type, int, NULL, 0);
+module_param_array(baseaddr, int, NULL, 0);
+module_param_array(numports, int, NULL, 0);
+#endif
+module_param(ttymajor, int, 0);
+module_param(verbose, bool, 0644);
 
 static struct tty_driver *moxaDriver;
 static struct moxa_str moxaChannels[MAX_PORTS];
@@ -215,11 +222,10 @@ static struct semaphore moxaBuffSem;
 /*
  * static functions:
  */
-static int moxa_get_PCI_conf(struct pci_dev *, int, moxa_board_conf *);
-static void do_moxa_softint(void *);
+static void do_moxa_softint(struct work_struct *);
 static int moxa_open(struct tty_struct *, struct file *);
 static void moxa_close(struct tty_struct *, struct file *);
-static int moxa_write(struct tty_struct *, int, const unsigned char *, int);
+static int moxa_write(struct tty_struct *, const unsigned char *, int);
 static int moxa_write_room(struct tty_struct *);
 static void moxa_flush_buffer(struct tty_struct *);
 static int moxa_chars_in_buffer(struct tty_struct *);
@@ -228,7 +234,7 @@ static void moxa_put_char(struct tty_struct *, unsigned char);
 static int moxa_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long);
 static void moxa_throttle(struct tty_struct *);
 static void moxa_unthrottle(struct tty_struct *);
-static void moxa_set_termios(struct tty_struct *, struct termios *);
+static void moxa_set_termios(struct tty_struct *, struct ktermios *);
 static void moxa_stop(struct tty_struct *);
 static void moxa_start(struct tty_struct *);
 static void moxa_hangup(struct tty_struct *);
@@ -255,7 +261,7 @@ static void MoxaPortEnable(int);
 static void MoxaPortDisable(int);
 static long MoxaPortGetMaxBaud(int);
 static long MoxaPortSetBaud(int, long);
-static int MoxaPortSetTermio(int, struct termios *);
+static int MoxaPortSetTermio(int, struct ktermios *, speed_t);
 static int MoxaPortGetLineOut(int, int *, int *);
 static void MoxaPortLineCtrl(int, int, int);
 static void MoxaPortFlowCtrl(int, int, int, int, int, int);
@@ -264,7 +270,7 @@ static int MoxaPortDCDChange(int);
 static int MoxaPortDCDON(int);
 static void MoxaPortFlushData(int, int);
 static int MoxaPortWriteData(int, unsigned char *, int);
-static int MoxaPortReadData(int, unsigned char *, int);
+static int MoxaPortReadData(int, struct tty_struct *tty);
 static int MoxaPortTxQueue(int);
 static int MoxaPortRxQueue(int);
 static int MoxaPortTxFree(int);
@@ -272,11 +278,11 @@ static void MoxaPortTxDisable(int);
 static void MoxaPortTxEnable(int);
 static int MoxaPortResetBrkCnt(int);
 static void MoxaPortSendBreak(int, int);
-static int moxa_get_serial_info(struct moxa_str *, struct serial_struct *);
-static int moxa_set_serial_info(struct moxa_str *, struct serial_struct *);
+static int moxa_get_serial_info(struct moxa_str *, struct serial_struct __user *);
+static int moxa_set_serial_info(struct moxa_str *, struct serial_struct __user *);
 static void MoxaSetFifo(int port, int enable);
 
-static struct tty_operations moxa_ops = {
+static const struct tty_operations moxa_ops = {
        .open = moxa_open,
        .close = moxa_close,
        .write = moxa_write,
@@ -296,6 +302,37 @@ static struct tty_operations moxa_ops = {
        .tiocmset = moxa_tiocmset,
 };
 
+static DEFINE_SPINLOCK(moxa_lock);
+
+#ifdef CONFIG_PCI
+static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board)
+{
+       board->baseAddr = pci_resource_start (p, 2);
+       board->boardType = board_type;
+       switch (board_type) {
+       case MOXA_BOARD_C218_ISA:
+       case MOXA_BOARD_C218_PCI:
+               board->numPorts = 8;
+               break;
+
+       case MOXA_BOARD_CP204J:
+               board->numPorts = 4;
+               break;
+       default:
+               board->numPorts = 0;
+               break;
+       }
+       board->busType = MOXA_BUS_TYPE_PCI;
+       board->pciInfo.busNum = p->bus->number;
+       board->pciInfo.devNum = p->devfn >> 3;
+       board->pciInfo.pdev = p;
+       /* don't lose the reference in the next pci_get_device iteration */
+       pci_dev_get(p);
+
+       return (0);
+}
+#endif /* CONFIG_PCI */
+
 static int __init moxa_init(void)
 {
        int i, numBoards;
@@ -308,8 +345,7 @@ static int __init moxa_init(void)
 
        init_MUTEX(&moxaBuffSem);
        moxaDriver->owner = THIS_MODULE;
-       moxaDriver->name = "ttya";
-       moxaDriver->devfs_name = "tts/a";
+       moxaDriver->name = "ttyMX";
        moxaDriver->major = ttymajor;
        moxaDriver->minor_start = 0;
        moxaDriver->type = TTY_DRIVER_TYPE_SERIAL;
@@ -319,16 +355,18 @@ static int __init moxa_init(void)
        moxaDriver->init_termios.c_oflag = 0;
        moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
        moxaDriver->init_termios.c_lflag = 0;
+       moxaDriver->init_termios.c_ispeed = 9600;
+       moxaDriver->init_termios.c_ospeed = 9600;
        moxaDriver->flags = TTY_DRIVER_REAL_RAW;
        tty_set_operations(moxaDriver, &moxa_ops);
 
-       moxaXmitBuff = 0;
+       moxaXmitBuff = NULL;
 
        for (i = 0, ch = moxaChannels; i < MAX_PORTS; i++, ch++) {
                ch->type = PORT_16550A;
                ch->port = i;
-               INIT_WORK(&ch->tqueue, do_moxa_softint, ch);
-               ch->tty = 0;
+               INIT_WORK(&ch->tqueue, do_moxa_softint);
+               ch->tty = NULL;
                ch->close_delay = 5 * HZ / 10;
                ch->closing_wait = 30 * HZ;
                ch->count = 0;
@@ -417,10 +455,10 @@ static int __init moxa_init(void)
 #ifdef CONFIG_PCI
        {
                struct pci_dev *p = NULL;
-               int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1;
+               int n = ARRAY_SIZE(moxa_pcibrds) - 1;
                i = 0;
                while (i < n) {
-                       while ((p = pci_find_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)
+                       while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)
                        {
                                if (pci_enable_device(p))
                                        continue;
@@ -438,7 +476,7 @@ static int __init moxa_init(void)
        }
 #endif
        for (i = 0; i < numBoards; i++) {
-               moxaBaseAddr[i] = (unsigned long) ioremap((unsigned long) moxa_boards[i].baseAddr, 0x4000);
+               moxaBaseAddr[i] = ioremap((unsigned long) moxa_boards[i].baseAddr, 0x4000);
        }
 
        return (0);
@@ -461,41 +499,24 @@ static void __exit moxa_exit(void)
        if (tty_unregister_driver(moxaDriver))
                printk("Couldn't unregister MOXA Intellio family serial driver\n");
        put_tty_driver(moxaDriver);
+
+       for (i = 0; i < MAX_BOARDS; i++) {
+               if (moxaBaseAddr[i])
+                       iounmap(moxaBaseAddr[i]);
+               if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI)
+                       pci_dev_put(moxa_boards[i].pciInfo.pdev);
+       }
+
        if (verbose)
                printk("Done\n");
-
 }
 
 module_init(moxa_init);
 module_exit(moxa_exit);
 
-static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board)
-{
-       board->baseAddr = pci_resource_start (p, 2);
-       board->boardType = board_type;
-       switch (board_type) {
-       case MOXA_BOARD_C218_ISA:
-       case MOXA_BOARD_C218_PCI:
-               board->numPorts = 8;
-               break;
-
-       case MOXA_BOARD_CP204J:
-               board->numPorts = 4;
-               break;
-       default:
-               board->numPorts = 0;
-               break;
-       }
-       board->busType = MOXA_BUS_TYPE_PCI;
-       board->pciInfo.busNum = p->bus->number;
-       board->pciInfo.devNum = p->devfn >> 3;
-
-       return (0);
-}
-
-static void do_moxa_softint(void *private_)
+static void do_moxa_softint(struct work_struct *work)
 {
-       struct moxa_str *ch = (struct moxa_str *) private_;
+       struct moxa_str *ch = container_of(work, struct moxa_str, tqueue);
        struct tty_struct *tty;
 
        if (ch && (tty = ch->tty)) {
@@ -613,15 +634,14 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
 
        if (tty->driver->flush_buffer)
                tty->driver->flush_buffer(tty);
-       if (tty->ldisc.flush_buffer)
-               tty->ldisc.flush_buffer(tty);
+       tty_ldisc_flush(tty);
+                       
        tty->closing = 0;
        ch->event = 0;
-       ch->tty = 0;
+       ch->tty = NULL;
        if (ch->blocked_open) {
                if (ch->close_delay) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(ch->close_delay);
+                       msleep_interruptible(jiffies_to_msecs(ch->close_delay));
                }
                wake_up_interruptible(&ch->open_wait);
        }
@@ -629,7 +649,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
        wake_up_interruptible(&ch->close_wait);
 }
 
-static int moxa_write(struct tty_struct *tty, int from_user,
+static int moxa_write(struct tty_struct *tty,
                      const unsigned char *buf, int count)
 {
        struct moxa_str *ch;
@@ -640,26 +660,10 @@ static int moxa_write(struct tty_struct *tty, int from_user,
        if (ch == NULL)
                return (0);
        port = ch->port;
-       save_flags(flags);
-       if (from_user) {
-               if (count > PAGE_SIZE)
-                       count = PAGE_SIZE;
-               down(&moxaBuffSem);
-               if (copy_from_user(moxaXmitBuff, buf, count)) {
-                       len = -EFAULT;
-               } else {
-                       cli();
-                       len = MoxaPortWriteData(port, moxaXmitBuff, count);
-                       restore_flags(flags);
-               }
-               up(&moxaBuffSem);
-               if (len < 0)
-                       return len;
-       } else {
-               cli();
-               len = MoxaPortWriteData(port, (unsigned char *) buf, count);
-               restore_flags(flags);
-       }
+
+       spin_lock_irqsave(&moxa_lock, flags);
+       len = MoxaPortWriteData(port, (unsigned char *) buf, count);
+       spin_unlock_irqrestore(&moxa_lock, flags);
 
        /*********************************************
        if ( !(ch->statusflags & LOWWAIT) &&
@@ -688,10 +692,7 @@ static void moxa_flush_buffer(struct tty_struct *tty)
        if (ch == NULL)
                return;
        MoxaPortFlushData(ch->port, 1);
-       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-           tty->ldisc.write_wakeup)
-               (tty->ldisc.write_wakeup) (tty);
-       wake_up_interruptible(&tty->write_wait);
+       tty_wakeup(tty);
 }
 
 static int moxa_chars_in_buffer(struct tty_struct *tty)
@@ -737,11 +738,10 @@ static void moxa_put_char(struct tty_struct *tty, unsigned char c)
        if (ch == NULL)
                return;
        port = ch->port;
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&moxa_lock, flags);
        moxaXmitBuff[0] = c;
        MoxaPortWriteData(port, moxaXmitBuff, 1);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&moxa_lock, flags);
        /************************************************
        if ( !(ch->statusflags & LOWWAIT) && (MoxaPortTxFree(port) <= 100) )
        *************************************************/
@@ -802,6 +802,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
 {
        struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
        register int port;
+       void __user *argp = (void __user *)arg;
        int retval;
 
        port = PORTNO(tty);
@@ -827,9 +828,9 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
                MoxaPortSendBreak(ch->port, arg);
                return (0);
        case TIOCGSOFTCAR:
-               return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg);
+               return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *) argp);
        case TIOCSSOFTCAR:
-               if(get_user(retval, (unsigned long *) arg))
+               if(get_user(retval, (unsigned long __user *) argp))
                        return -EFAULT;
                arg = retval;
                tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) |
@@ -840,10 +841,10 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
                        ch->asyncflags |= ASYNC_CHECK_CD;
                return (0);
        case TIOCGSERIAL:
-               return (moxa_get_serial_info(ch, (struct serial_struct *) arg));
+               return moxa_get_serial_info(ch, argp);
 
        case TIOCSSERIAL:
-               return (moxa_set_serial_info(ch, (struct serial_struct *) arg));
+               return moxa_set_serial_info(ch, argp);
        default:
                retval = MoxaDriverIoctl(cmd, arg, port);
        }
@@ -865,7 +866,7 @@ static void moxa_unthrottle(struct tty_struct *tty)
 }
 
 static void moxa_set_termios(struct tty_struct *tty,
-                            struct termios *old_termios)
+                            struct ktermios *old_termios)
 {
        struct moxa_str *ch = (struct moxa_str *) tty->driver_data;
 
@@ -911,7 +912,7 @@ static void moxa_hangup(struct tty_struct *tty)
        ch->event = 0;
        ch->count = 0;
        ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE;
-       ch->tty = 0;
+       ch->tty = NULL;
        wake_up_interruptible(&ch->open_wait);
 }
 
@@ -948,10 +949,7 @@ static void moxa_poll(unsigned long ignored)
                                if (MoxaPortTxQueue(ch->port) <= WAKEUP_CHARS) {
                                        if (!tp->stopped) {
                                                ch->statusflags &= ~LOWWAIT;
-                                               if ((tp->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                                                 tp->ldisc.write_wakeup)
-                                                       (tp->ldisc.write_wakeup) (tp);
-                                               wake_up_interruptible(&tp->write_wait);
+                                               tty_wakeup(tp);
                                        }
                                }
                        }
@@ -982,7 +980,7 @@ static void moxa_poll(unsigned long ignored)
 
 static void set_tty_param(struct tty_struct *tty)
 {
-       register struct termios *ts;
+       register struct ktermios *ts;
        struct moxa_str *ch;
        int rts, cts, txflow, rxflow, xany;
 
@@ -1002,7 +1000,7 @@ static void set_tty_param(struct tty_struct *tty)
        if (ts->c_iflag & IXANY)
                xany = 1;
        MoxaPortFlowCtrl(ch->port, rts, cts, txflow, rxflow, xany);
-       MoxaPortSetTermio(ch->port, ts);
+       MoxaPortSetTermio(ch->port, ts, tty_get_baud_rate(tty));
 }
 
 static int block_till_ready(struct tty_struct *tty, struct file *filp,
@@ -1046,12 +1044,12 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp,
        printk("block_til_ready before block: ttys%d, count = %d\n",
               ch->line, ch->count);
 #endif
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&moxa_lock, flags);
        if (!tty_hung_up_p(filp))
                ch->count--;
-       restore_flags(flags);
        ch->blocked_open++;
+       spin_unlock_irqrestore(&moxa_lock, flags);
+
        while (1) {
                set_current_state(TASK_INTERRUPTIBLE);
                if (tty_hung_up_p(filp) ||
@@ -1078,17 +1076,21 @@ static int block_till_ready(struct tty_struct *tty, struct file *filp,
        }
        set_current_state(TASK_RUNNING);
        remove_wait_queue(&ch->open_wait, &wait);
+
+       spin_lock_irqsave(&moxa_lock, flags);
        if (!tty_hung_up_p(filp))
                ch->count++;
        ch->blocked_open--;
+       spin_unlock_irqrestore(&moxa_lock, flags);
 #ifdef SERIAL_DEBUG_OPEN
        printk("block_til_ready after blocking: ttys%d, count = %d\n",
               ch->line, ch->count);
 #endif
        if (retval)
                return (retval);
+       /* FIXME: review to see if we need to use set_bit on these */
        ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
-       return (0);
+       return 0;
 }
 
 static void setup_empty_event(struct tty_struct *tty)
@@ -1096,15 +1098,14 @@ static void setup_empty_event(struct tty_struct *tty)
        struct moxa_str *ch = tty->driver_data;
        unsigned long flags;
 
-       save_flags(flags);
-       cli();
+       spin_lock_irqsave(&moxa_lock, flags);
        ch->statusflags |= EMPTYWAIT;
        moxaEmptyTimer_on[ch->port] = 0;
        del_timer(&moxaEmptyTimer[ch->port]);
        moxaEmptyTimer[ch->port].expires = jiffies + HZ;
        moxaEmptyTimer_on[ch->port] = 1;
        add_timer(&moxaEmptyTimer[ch->port]);
-       restore_flags(flags);
+       spin_unlock_irqrestore(&moxa_lock, flags);
 }
 
 static void check_xmit_empty(unsigned long data)
@@ -1117,10 +1118,7 @@ static void check_xmit_empty(unsigned long data)
        if (ch->tty && (ch->statusflags & EMPTYWAIT)) {
                if (MoxaPortTxQueue(ch->port) == 0) {
                        ch->statusflags &= ~EMPTYWAIT;
-                       if ((ch->tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-                           ch->tty->ldisc.write_wakeup)
-                               (ch->tty->ldisc.write_wakeup) (ch->tty);
-                       wake_up_interruptible(&ch->tty->write_wait);
+                       tty_wakeup(ch->tty);
                        return;
                }
                moxaEmptyTimer[ch->port].expires = jiffies + HZ;
@@ -1153,12 +1151,10 @@ static void shut_down(struct moxa_str *ch)
 static void receive_data(struct moxa_str *ch)
 {
        struct tty_struct *tp;
-       struct termios *ts;
-       int i, count, rc, space;
-       unsigned char *charptr, *flagptr;
+       struct ktermios *ts;
        unsigned long flags;
 
-       ts = 0;
+       ts = NULL;
        tp = ch->tty;
        if (tp)
                ts = tp->termios;
@@ -1169,24 +1165,10 @@ static void receive_data(struct moxa_str *ch)
                MoxaPortFlushData(ch->port, 0);
                return;
        }
-       space = TTY_FLIPBUF_SIZE - tp->flip.count;
-       if (space <= 0)
-               return;
-       charptr = tp->flip.char_buf_ptr;
-       flagptr = tp->flip.flag_buf_ptr;
-       rc = tp->flip.count;
-       save_flags(flags);
-       cli();
-       count = MoxaPortReadData(ch->port, charptr, space);
-       restore_flags(flags);
-       for (i = 0; i < count; i++)
-               *flagptr++ = 0;
-       charptr += count;
-       rc += count;
-       tp->flip.count = rc;
-       tp->flip.char_buf_ptr = charptr;
-       tp->flip.flag_buf_ptr = flagptr;
-       tty_schedule_flip(ch->tty);
+       spin_lock_irqsave(&moxa_lock, flags);
+       MoxaPortReadData(ch->port, tp);
+       spin_unlock_irqrestore(&moxa_lock, flags);
+       tty_schedule_flip(tp);
 }
 
 #define Magic_code     0x404
@@ -1498,12 +1480,12 @@ typedef struct mon_str mon_st;
 #define        DCD_oldstate    0x80
 
 static unsigned char moxaBuff[10240];
-static unsigned long moxaIntNdx[MAX_BOARDS];
-static unsigned long moxaIntPend[MAX_BOARDS];
-static unsigned long moxaIntTable[MAX_BOARDS];
+static void __iomem *moxaIntNdx[MAX_BOARDS];
+static void __iomem *moxaIntPend[MAX_BOARDS];
+static void __iomem *moxaIntTable[MAX_BOARDS];
 static char moxaChkPort[MAX_PORTS];
 static char moxaLineCtrl[MAX_PORTS];
-static unsigned long moxaTableAddr[MAX_PORTS];
+static void __iomem *moxaTableAddr[MAX_PORTS];
 static long moxaCurBaud[MAX_PORTS];
 static char moxaDCDState[MAX_PORTS];
 static char moxaLowChkFlag[MAX_PORTS];
@@ -1514,15 +1496,15 @@ static int moxaFuncTout;
 static ushort moxaBreakCnt[MAX_PORTS];
 
 static void moxadelay(int);
-static void moxafunc(unsigned long, int, ushort);
-static void wait_finish(unsigned long);
-static void low_water_check(unsigned long);
-static int moxaloadbios(int, unsigned char *, int);
+static void moxafunc(void __iomem *, int, ushort);
+static void wait_finish(void __iomem *);
+static void low_water_check(void __iomem *);
+static int moxaloadbios(int, unsigned char __user *, int);
 static int moxafindcard(int);
-static int moxaload320b(int, unsigned char *, int);
-static int moxaloadcode(int, unsigned char *, int);
-static int moxaloadc218(int, unsigned long, int);
-static int moxaloadc320(int, unsigned long, int, 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:                                              *
@@ -1570,7 +1552,7 @@ struct moxaq_str {
 };
 
 struct dl_str {
-       char *buf;
+       char __user *buf;
        int len;
        int cardno;
 };
@@ -1580,7 +1562,7 @@ static struct dl_str dltmp;
 
 void MoxaPortFlushData(int port, int mode)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
        if ((mode < 0) || (mode > 2))
                return;
        ofsAddr = moxaTableAddr[port];
@@ -1596,6 +1578,7 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
        int i;
        int status;
        int MoxaPortTxQueue(int), MoxaPortRxQueue(int);
+       void __user *argp = (void __user *)arg;
 
        if (port == QueryPort) {
                if ((cmd != MOXA_GET_CONF) && (cmd != MOXA_INIT_DRIVER) &&
@@ -1607,7 +1590,7 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
        }
        switch (cmd) {
        case MOXA_GET_CONF:
-               if(copy_to_user((void *)arg, &moxa_boards, MAX_BOARDS * sizeof(moxa_board_conf)))
+               if(copy_to_user(argp, &moxa_boards, MAX_BOARDS * sizeof(moxa_board_conf)))
                        return -EFAULT;
                return (0);
        case MOXA_INIT_DRIVER:
@@ -1616,7 +1599,7 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
                return (0);
        case MOXA_GETDATACOUNT:
                moxaLog.tick = jiffies;
-               if(copy_to_user((void *)arg, &moxaLog, sizeof(mon_st)))
+               if(copy_to_user(argp, &moxaLog, sizeof(mon_st)))
                        return -EFAULT;
                return (0);
        case MOXA_FLUSH_QUEUE:
@@ -1629,22 +1612,22 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
                                temp_queue[i].outq = MoxaPortTxQueue(i);
                        }
                }
-               if(copy_to_user((void *)arg, temp_queue, sizeof(struct moxaq_str) * MAX_PORTS))
+               if(copy_to_user(argp, temp_queue, sizeof(struct moxaq_str) * MAX_PORTS))
                        return -EFAULT;
                return (0);
        case MOXA_GET_OQUEUE:
                i = MoxaPortTxQueue(port);
-               return put_user(i, (unsigned long *) arg);
+               return put_user(i, (unsigned long __user *)argp);
        case MOXA_GET_IQUEUE:
                i = MoxaPortRxQueue(port);
-               return put_user(i, (unsigned long *) arg);
+               return put_user(i, (unsigned long __user *)argp);
        case MOXA_GET_MAJOR:
-               if(copy_to_user((void *)arg, &ttymajor, sizeof(int)))
+               if(copy_to_user(argp, &ttymajor, sizeof(int)))
                        return -EFAULT;
                return 0;
        case MOXA_GET_CUMAJOR:
                i = 0;
-               if(copy_to_user((void *)arg, &i, sizeof(int)))
+               if(copy_to_user(argp, &i, sizeof(int)))
                        return -EFAULT;
                return 0;
        case MOXA_GETMSTATUS:
@@ -1670,7 +1653,7 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
                        else
                                GMStatus[i].cflag = moxaChannels[i].tty->termios->c_cflag;
                }
-               if(copy_to_user((void *)arg, GMStatus, sizeof(struct mxser_mstatus) * MAX_PORTS))
+               if(copy_to_user(argp, GMStatus, sizeof(struct mxser_mstatus) * MAX_PORTS))
                        return -EFAULT;
                return 0;
        default:
@@ -1679,10 +1662,12 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port)
        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, (void *)arg, sizeof(struct dl_str)))
+       if(copy_from_user(&dltmp, argp, sizeof(struct dl_str)))
                return -EFAULT;
        if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS)
                return -EINVAL;
@@ -1711,12 +1696,15 @@ int MoxaDriverPoll(void)
 {
        register ushort temp;
        register int card;
-       unsigned long ip, ofsAddr;
+       void __iomem *ofsAddr;
+       void __iomem *ip;
        int port, p, ports;
 
        if (moxaCard == 0)
                return (-1);
        for (card = 0; card < MAX_BOARDS; card++) {
+               if (loadstat[card] == 0)
+                       continue;
                if ((ports = moxa_boards[card].numPorts) == 0)
                        continue;
                if (readb(moxaIntPend[card]) == 0xff) {
@@ -1791,7 +1779,7 @@ int MoxaPortsOfCard(int cardno)
  *     14. MoxaPortDCDON(int port);                                         *
  *     15. MoxaPortFlushData(int port, int mode);                           *
  *     16. MoxaPortWriteData(int port, unsigned char * buffer, int length); *
- *     17. MoxaPortReadData(int port, unsigned char * buffer, int length);  *
+ *     17. MoxaPortReadData(int port, struct tty_struct *tty);              *
  *     18. MoxaPortTxBufSize(int port);                                     *
  *     19. MoxaPortRxBufSize(int port);                                     *
  *     20. MoxaPortTxQueue(int port);                                       *
@@ -1926,9 +1914,10 @@ int MoxaPortsOfCard(int cardno)
  *
  *      Function 12:    Configure the port.
  *      Syntax:
- *      int  MoxaPortSetTermio(int port, struct termios *termio);
+ *      int  MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud);
  *           int port           : port number (0 - 127)
- *           struct termios * termio : termio structure pointer
+ *           struct ktermios * termio : termio structure pointer
+ *          speed_t baud       : baud rate
  *
  *           return:    -1      : this port is invalid or termio == NULL
  *                      0       : setting O.K.
@@ -2020,10 +2009,9 @@ int MoxaPortsOfCard(int cardno)
  *
  *      Function 21:    Read data.
  *      Syntax:
- *      int  MoxaPortReadData(int port, unsigned char * buffer, int length);
+ *      int  MoxaPortReadData(int port, struct tty_struct *tty);
  *           int port           : port number (0 - 127)
- *           unsigned char * buffer     : pointer to read data buffer.
- *           int length         : read data buffer length
+ *          struct tty_struct *tty : tty for data
  *
  *           return:    0 - length      : real read data length
  *
@@ -2144,7 +2132,7 @@ int MoxaPortIsValid(int port)
 
 void MoxaPortEnable(int port)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
        int MoxaPortLineStatus(int);
        short lowwater = 512;
 
@@ -2167,9 +2155,8 @@ void MoxaPortEnable(int port)
 
 void MoxaPortDisable(int port)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr = moxaTableAddr[port];
 
-       ofsAddr = moxaTableAddr[port];
        moxafunc(ofsAddr, FC_SetFlowCtl, 0);    /* disable flow control */
        moxafunc(ofsAddr, FC_ClrLineIrq, Magic_code);
        writew(0, ofsAddr + HostStat);
@@ -2188,7 +2175,7 @@ long MoxaPortGetMaxBaud(int port)
 
 long MoxaPortSetBaud(int port, long baud)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
        long max, clock;
        unsigned int val;
 
@@ -2210,11 +2197,10 @@ long MoxaPortSetBaud(int port, long baud)
        return (baud);
 }
 
-int MoxaPortSetTermio(int port, struct termios *termio)
+int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
        tcflag_t cflag;
-       long baud;
        tcflag_t mode = 0;
 
        if (moxaChkPort[port] == 0 || termio == 0)
@@ -2250,77 +2236,9 @@ int MoxaPortSetTermio(int port, struct termios *termio)
 
        moxafunc(ofsAddr, FC_SetDataMode, (ushort) mode);
 
-       cflag &= (CBAUD | CBAUDEX);
-#ifndef B921600
-#define        B921600 (B460800+1)
-#endif
-       switch (cflag) {
-       case B921600:
-               baud = 921600L;
-               break;
-       case B460800:
-               baud = 460800L;
-               break;
-       case B230400:
-               baud = 230400L;
-               break;
-       case B115200:
-               baud = 115200L;
-               break;
-       case B57600:
-               baud = 57600L;
-               break;
-       case B38400:
-               baud = 38400L;
-               break;
-       case B19200:
-               baud = 19200L;
-               break;
-       case B9600:
-               baud = 9600L;
-               break;
-       case B4800:
-               baud = 4800L;
-               break;
-       case B2400:
-               baud = 2400L;
-               break;
-       case B1800:
-               baud = 1800L;
-               break;
-       case B1200:
-               baud = 1200L;
-               break;
-       case B600:
-               baud = 600L;
-               break;
-       case B300:
-               baud = 300L;
-               break;
-       case B200:
-               baud = 200L;
-               break;
-       case B150:
-               baud = 150L;
-               break;
-       case B134:
-               baud = 134L;
-               break;
-       case B110:
-               baud = 110L;
-               break;
-       case B75:
-               baud = 75L;
-               break;
-       case B50:
-               baud = 50L;
-               break;
-       default:
-               baud = 0;
-       }
        if ((moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_ISA) ||
            (moxa_boards[port / MAX_PORTS_PER_BOARD].boardType == MOXA_BOARD_C320_PCI)) {
-               if (baud == 921600L)
+               if (baud >= 921600L)
                        return (-1);
        }
        MoxaPortSetBaud(port, baud);
@@ -2357,7 +2275,7 @@ int MoxaPortGetLineOut(int port, int *dtrState, int *rtsState)
 
 void MoxaPortLineCtrl(int port, int dtr, int rts)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
        int mode;
 
        ofsAddr = moxaTableAddr[port];
@@ -2372,7 +2290,7 @@ void MoxaPortLineCtrl(int port, int dtr, int rts)
 
 void MoxaPortFlowCtrl(int port, int rts, int cts, int txflow, int rxflow, int txany)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
        int mode;
 
        ofsAddr = moxaTableAddr[port];
@@ -2392,7 +2310,7 @@ void MoxaPortFlowCtrl(int port, int rts, int cts, int txflow, int rxflow, int tx
 
 int MoxaPortLineStatus(int port)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
        int val;
 
        ofsAddr = moxaTableAddr[port];
@@ -2465,7 +2383,7 @@ int MoxaPortWriteData(int port, unsigned char * buffer, int len)
        int cnt;
        ushort head, tx_mask, spage, epage;
        ushort pageno, pageofs, bufhead;
-       unsigned long baseAddr, ofsAddr, ofs;
+       void __iomem *baseAddr, *ofsAddr, *ofs;
 
        ofsAddr = moxaTableAddr[port];
        baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD];
@@ -2522,13 +2440,13 @@ int MoxaPortWriteData(int port, unsigned char * buffer, int len)
        return (total);
 }
 
-int MoxaPortReadData(int port, unsigned char * buffer, int space)
+int MoxaPortReadData(int port, struct tty_struct *tty)
 {
        register ushort head, pageofs;
        int i, count, cnt, len, total, remain;
        ushort tail, rx_mask, spage, epage;
        ushort pageno, bufhead;
-       unsigned long baseAddr, ofsAddr, ofs;
+       void __iomem *baseAddr, *ofsAddr, *ofs;
 
        ofsAddr = moxaTableAddr[port];
        baseAddr = moxaBaseAddr[port / MAX_PORTS_PER_BOARD];
@@ -2540,9 +2458,9 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space)
        count = (tail >= head) ? (tail - head)
            : (tail - head + rx_mask + 1);
        if (count == 0)
-               return (0);
+               return 0;
 
-       total = (space > count) ? count : space;
+       total = count;
        remain = count - total;
        moxaLog.rxcnt[port] += total;
        count = total;
@@ -2557,7 +2475,7 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space)
                        len = (count > len) ? len : count;
                        ofs = baseAddr + DynPage_addr + bufhead + head;
                        for (i = 0; i < len; i++)
-                               *buffer++ = readb(ofs + i);
+                               tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL);
                        head = (head + len) & rx_mask;
                        count -= len;
                }
@@ -2574,7 +2492,7 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space)
                        writew(pageno, baseAddr + Control_reg);
                        ofs = baseAddr + DynPage_addr + pageofs;
                        for (i = 0; i < cnt; i++)
-                               *buffer++ = readb(ofs + i);
+                               tty_insert_flip_char(tty, readb(ofs + i), TTY_NORMAL);
                        if (count == 0) {
                                writew((head + len) & rx_mask, ofsAddr + RXrptr);
                                break;
@@ -2594,7 +2512,7 @@ int MoxaPortReadData(int port, unsigned char * buffer, int space)
 
 int MoxaPortTxQueue(int port)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
        ushort rptr, wptr, mask;
        int len;
 
@@ -2608,7 +2526,7 @@ int MoxaPortTxQueue(int port)
 
 int MoxaPortTxFree(int port)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
        ushort rptr, wptr, mask;
        int len;
 
@@ -2622,7 +2540,7 @@ int MoxaPortTxFree(int port)
 
 int MoxaPortRxQueue(int port)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
        ushort rptr, wptr, mask;
        int len;
 
@@ -2637,7 +2555,7 @@ int MoxaPortRxQueue(int port)
 
 void MoxaPortTxDisable(int port)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
 
        ofsAddr = moxaTableAddr[port];
        moxafunc(ofsAddr, FC_SetXoffState, Magic_code);
@@ -2645,7 +2563,7 @@ void MoxaPortTxDisable(int port)
 
 void MoxaPortTxEnable(int port)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
 
        ofsAddr = moxaTableAddr[port];
        moxafunc(ofsAddr, FC_SetXonState, Magic_code);
@@ -2663,7 +2581,7 @@ int MoxaPortResetBrkCnt(int port)
 
 void MoxaPortSendBreak(int port, int ms100)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
 
        ofsAddr = moxaTableAddr[port];
        if (ms100) {
@@ -2677,12 +2595,10 @@ void MoxaPortSendBreak(int port, int ms100)
 }
 
 static int moxa_get_serial_info(struct moxa_str *info,
-                               struct serial_struct *retinfo)
+                               struct serial_struct __user *retinfo)
 {
        struct serial_struct tmp;
 
-       if (!retinfo)
-               return (-EFAULT);
        memset(&tmp, 0, sizeof(tmp));
        tmp.type = info->type;
        tmp.line = info->port;
@@ -2701,7 +2617,7 @@ static int moxa_get_serial_info(struct moxa_str *info,
 
 
 static int moxa_set_serial_info(struct moxa_str *info,
-                               struct serial_struct *new_info)
+                               struct serial_struct __user *new_info)
 {
        struct serial_struct new_serial;
 
@@ -2754,7 +2670,7 @@ static void moxadelay(int tick)
        while (time_before(jiffies, et));
 }
 
-static void moxafunc(unsigned long ofsAddr, int cmd, ushort arg)
+static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg)
 {
 
        writew(arg, ofsAddr + FuncArg);
@@ -2762,7 +2678,7 @@ static void moxafunc(unsigned long ofsAddr, int cmd, ushort arg)
        wait_finish(ofsAddr);
 }
 
-static void wait_finish(unsigned long ofsAddr)
+static void wait_finish(void __iomem *ofsAddr)
 {
        unsigned long i, j;
 
@@ -2775,7 +2691,7 @@ static void wait_finish(unsigned long ofsAddr)
        }
 }
 
-static void low_water_check(unsigned long ofsAddr)
+static void low_water_check(void __iomem *ofsAddr)
 {
        int len;
        ushort rptr, wptr, mask;
@@ -2790,9 +2706,9 @@ static void low_water_check(unsigned long ofsAddr)
        }
 }
 
-static int moxaloadbios(int cardno, unsigned char *tmp, int len)
+static int moxaloadbios(int cardno, unsigned char __user *tmp, int len)
 {
-       unsigned long baseAddr;
+       void __iomem *baseAddr;
        int i;
 
        if(copy_from_user(moxaBuff, tmp, len))
@@ -2810,7 +2726,7 @@ static int moxaloadbios(int cardno, unsigned char *tmp, int len)
 
 static int moxafindcard(int cardno)
 {
-       unsigned long baseAddr;
+       void __iomem *baseAddr;
        ushort tmp;
 
        baseAddr = moxaBaseAddr[cardno];
@@ -2837,9 +2753,9 @@ static int moxafindcard(int cardno)
        return (0);
 }
 
-static int moxaload320b(int cardno, unsigned char tmp, int len)
+static int moxaload320b(int cardno, unsigned char __user *tmp, int len)
 {
-       unsigned long baseAddr;
+       void __iomem *baseAddr;
        int i;
 
        if(len > sizeof(moxaBuff))
@@ -2857,9 +2773,9 @@ static int moxaload320b(int cardno, unsigned char * tmp, int len)
        return (0);
 }
 
-static int moxaloadcode(int cardno, unsigned char tmp, int len)
+static int moxaloadcode(int cardno, unsigned char __user *tmp, int len)
 {
-       unsigned long baseAddr, ofsAddr;
+       void __iomem *baseAddr, *ofsAddr;
        int retval, port, i;
 
        if(copy_from_user(moxaBuff, tmp, len))
@@ -2936,10 +2852,11 @@ static int moxaloadcode(int cardno, unsigned char * tmp, int len)
                }
                break;
        }
+       loadstat[cardno] = 1;
        return (0);
 }
 
-static int moxaloadc218(int cardno, unsigned long baseAddr, int len)
+static int moxaloadc218(int cardno, void __iomem *baseAddr, int len)
 {
        char retry;
        int i, j, len1, len2;
@@ -2953,7 +2870,7 @@ static int moxaloadc218(int cardno, unsigned long baseAddr, int len)
        len1 = len >> 1;
        ptr = (ushort *) moxaBuff;
        for (i = 0; i < len1; i++)
-               usum += *(ptr + i);
+               usum += le16_to_cpu(*(ptr + i));
        retry = 0;
        do {
                len1 = len >> 1;
@@ -3015,7 +2932,7 @@ static int moxaloadc218(int cardno, unsigned long baseAddr, int len)
        return (0);
 }
 
-static int moxaloadc320(int cardno, unsigned long baseAddr, int len, int *numPorts)
+static int moxaloadc320(int cardno, void __iomem *baseAddr, int len, int *numPorts)
 {
        ushort usum;
        int i, j, wlen, len2, retry;
@@ -3025,7 +2942,7 @@ static int moxaloadc320(int cardno, unsigned long baseAddr, int len, int *numPor
        wlen = len >> 1;
        uptr = (ushort *) moxaBuff;
        for (i = 0; i < wlen; i++)
-               usum += uptr[i];
+               usum += le16_to_cpu(uptr[i]);
        retry = 0;
        j = 0;
        do {
@@ -3110,6 +3027,7 @@ static int moxaloadc320(int cardno, unsigned long baseAddr, int len, int *numPor
        return (0);
 }
 
+#if 0
 long MoxaPortGetCurBaud(int port)
 {
 
@@ -3117,10 +3035,11 @@ long MoxaPortGetCurBaud(int port)
                return (0);
        return (moxaCurBaud[port]);
 }
+#endif  /*  0  */
 
 static void MoxaSetFifo(int port, int enable)
 {
-       unsigned long ofsAddr = moxaTableAddr[port];
+       void __iomem *ofsAddr = moxaTableAddr[port];
 
        if (!enable) {
                moxafunc(ofsAddr, FC_SetRxFIFOTrig, 0);
@@ -3134,7 +3053,7 @@ static void MoxaSetFifo(int port, int enable)
 #if 0
 int MoxaPortSetMode(int port, int databits, int stopbits, int parity)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
        int val;
 
        val = 0;
@@ -3193,7 +3112,7 @@ int MoxaPortSetMode(int port, int databits, int stopbits, int parity)
 
 int MoxaPortTxBufSize(int port)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
        int size;
 
        ofsAddr = moxaTableAddr[port];
@@ -3203,7 +3122,7 @@ int MoxaPortTxBufSize(int port)
 
 int MoxaPortRxBufSize(int port)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
        int size;
 
        ofsAddr = moxaTableAddr[port];
@@ -3213,7 +3132,7 @@ int MoxaPortRxBufSize(int port)
 
 int MoxaPortRxFree(int port)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
        ushort rptr, wptr, mask;
        int len;
 
@@ -3231,7 +3150,7 @@ int MoxaPortGetBrkCnt(int port)
 
 void MoxaPortSetXonXoff(int port, int xonValue, int xoffValue)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
 
        ofsAddr = moxaTableAddr[port];
        writew(xonValue, ofsAddr + FuncArg);
@@ -3242,7 +3161,7 @@ void MoxaPortSetXonXoff(int port, int xonValue, int xoffValue)
 
 int MoxaPortIsTxHold(int port)
 {
-       unsigned long ofsAddr;
+       void __iomem *ofsAddr;
        int val;
 
        ofsAddr = moxaTableAddr[port];