]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/char/mxser_new.c
Char: mxser, 0 to NULL in pointer
[linux-2.6-omap-h63xx.git] / drivers / char / mxser_new.c
index 6a563932ba191f31efbec7e1f4d088dc1ef44fb3..d2dcc546cc7568fc563e4616ba0d1be3a828df1c 100644 (file)
@@ -2,7 +2,7 @@
  *          mxser.c  -- MOXA Smartio/Industio family multiport serial driver.
  *
  *      Copyright (C) 1999-2006  Moxa Technologies (support@moxa.com.tw).
- *     Copyright (C) 2006       Jiri Slaby <jirislaby@gmail.com>
+ *     Copyright (C) 2006-2007  Jiri Slaby <jirislaby@gmail.com>
  *
  *      This code is loosely based on the 1.8 moxa driver which is based on
  *     Linux serial driver, written by Linus Torvalds, Theodore T'so and
@@ -20,7 +20,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/autoconf.h>
 #include <linux/errno.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
+#include <linux/bitops.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/bitops.h>
 #include <asm/uaccess.h>
 
 #include "mxser_new.h"
 
-#define        MXSER_VERSION   "2.0.1"         /* 1.9.15 */
+#define        MXSER_VERSION   "2.0.2"         /* 1.10 */
 #define        MXSERMAJOR       174
 #define        MXSERCUMAJOR     175
 
 #define UART_MCR_AFE           0x20
 #define UART_LSR_SPECIAL       0x1E
 
+#define PCI_DEVICE_ID_CB108    0x1080
+#define PCI_DEVICE_ID_CB114    0x1142
+#define PCI_DEVICE_ID_CB134I   0x1341
+#define PCI_DEVICE_ID_CP138U   0x1380
+#define PCI_DEVICE_ID_POS104UL 0x1044
+
 
 #define C168_ASIC_ID    1
 #define C104_ASIC_ID    2
@@ -107,87 +112,67 @@ struct mxser_cardinfo {
 };
 
 static const struct mxser_cardinfo mxser_cards[] = {
-       { 8, "C168 series", },                  /* C168-ISA */
-       { 4, "C104 series", },                  /* C104-ISA */
-       { 4, "CI-104J series", },               /* CI104J */
-       { 8, "C168H/PCI series", },             /* C168-PCI */
-       { 4, "C104H/PCI series", },             /* C104-PCI */
-       { 4, "C102 series", MXSER_HAS2 },       /* C102-ISA */
-       { 4, "CI-132 series", MXSER_HAS2 },     /* CI132 */
-       { 4, "CI-134 series", },                /* CI134 */
-       { 2, "CP-132 series", },                /* CP132 */
-       { 4, "CP-114 series", },                /* CP114 */
-       { 4, "CT-114 series", },                /* CT114 */
-       { 2, "CP-102 series", MXSER_HIGHBAUD }, /* CP102 */
-       { 4, "CP-104U series", },               /* CP104U */
-       { 8, "CP-168U series", },               /* CP168U */
-       { 2, "CP-132U series", },               /* CP132U */
-       { 4, "CP-134U series", },               /* CP134U */
-       { 4, "CP-104JU series", },              /* CP104JU */
+/* 0*/ { 8, "C168 series", },
+       { 4, "C104 series", },
+       { 4, "CI-104J series", },
+       { 8, "C168H/PCI series", },
+       { 4, "C104H/PCI series", },
+/* 5*/ { 4, "C102 series", MXSER_HAS2 },       /* C102-ISA */
+       { 4, "CI-132 series", MXSER_HAS2 },
+       { 4, "CI-134 series", },
+       { 2, "CP-132 series", },
+       { 4, "CP-114 series", },
+/*10*/ { 4, "CT-114 series", },
+       { 2, "CP-102 series", MXSER_HIGHBAUD },
+       { 4, "CP-104U series", },
+       { 8, "CP-168U series", },
+       { 2, "CP-132U series", },
+/*15*/ { 4, "CP-134U series", },
+       { 4, "CP-104JU series", },
        { 8, "Moxa UC7000 Serial", },           /* RC7000 */
-       { 8, "CP-118U series", },               /* CP118U */
-       { 2, "CP-102UL series", },              /* CP102UL */
-       { 2, "CP-102U series", },               /* CP102U */
-       { 8, "CP-118EL series", },              /* CP118EL */
-       { 8, "CP-168EL series", },              /* CP168EL */
-       { 4, "CP-104EL series", }               /* CP104EL */
+       { 8, "CP-118U series", },
+       { 2, "CP-102UL series", },
+/*20*/ { 2, "CP-102U series", },
+       { 8, "CP-118EL series", },
+       { 8, "CP-168EL series", },
+       { 4, "CP-104EL series", },
+       { 8, "CB-108 series", },
+/*25*/ { 4, "CB-114 series", },
+       { 4, "CB-134I series", },
+       { 8, "CP-138U series", },
+       { 4, "POS-104UL series", }
 };
 
 /* driver_data correspond to the lines in the structure above
    see also ISA probe function before you change something */
 static struct pci_device_id mxser_pcibrds[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168),
-               .driver_data = 3 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C104),
-               .driver_data = 4 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132),
-               .driver_data = 8 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114),
-               .driver_data = 9 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CT114),
-               .driver_data = 10 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102),
-               .driver_data = 11 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104U),
-               .driver_data = 12 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168U),
-               .driver_data = 13 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132U),
-               .driver_data = 14 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134U),
-               .driver_data = 15 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104JU),
-               .driver_data = 16 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_RC7000),
-               .driver_data = 17 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118U),
-               .driver_data = 18 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102UL),
-               .driver_data = 19 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102U),
-               .driver_data = 20 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118EL),
-               .driver_data = 21 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168EL),
-               .driver_data = 22 },
-       { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104EL),
-               .driver_data = 23 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168),   .driver_data = 3 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104),   .driver_data = 4 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132),  .driver_data = 8 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114),  .driver_data = 9 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CT114),  .driver_data = 10 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102),  .driver_data = 11 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104U), .driver_data = 12 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168U), .driver_data = 13 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132U), .driver_data = 14 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134U), .driver_data = 15 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104JU),.driver_data = 16 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_RC7000), .driver_data = 17 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118U), .driver_data = 18 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102UL),.driver_data = 19 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102U), .driver_data = 20 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118EL),.driver_data = 21 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168EL),.driver_data = 22 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104EL),.driver_data = 23 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB108),       .driver_data = 24 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB114),       .driver_data = 25 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB134I),      .driver_data = 26 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U),      .driver_data = 27 },
+       { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL),    .driver_data = 28 },
        { }
 };
 MODULE_DEVICE_TABLE(pci, mxser_pcibrds);
 
-static int mxvar_baud_table[] = {
-       0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400,
-       4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
-};
-static unsigned int mxvar_baud_table1[] = {
-       0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400,
-       B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B921600
-};
-#define BAUD_TABLE_NO ARRAY_SIZE(mxvar_baud_table)
-
-#define B_SPEC B2000000
-
 static int ioaddr[MXSER_BOARDS] = { 0, 0, 0, 0 };
 static int ttymajor = MXSERMAJOR;
 static int calloutmajor = MXSERCUMAJOR;
@@ -246,10 +231,8 @@ struct mxser_port {
        int rx_trigger;         /* Rx fifo trigger level */
        int rx_low_water;
        int baud_base;          /* max. speed */
-       long realbaud;
        int type;               /* UART type */
        int flags;              /* defined in tty.h */
-       int speed;
 
        int x_char;             /* xon/xoff character */
        int IER;                /* Interrupt Enable Register */
@@ -323,7 +306,7 @@ static struct mxser_mon_ext mon_data_ext;
 static int mxser_set_baud_method[MXSER_PORTS + 1];
 
 #ifdef CONFIG_PCI
-static int __devinit CheckIsMoxaMust(int io)
+static int __devinit CheckIsMoxaMust(unsigned long io)
 {
        u8 oldmcr, hwid;
        int i;
@@ -454,38 +437,29 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp,
 
 static int mxser_set_baud(struct mxser_port *info, long newspd)
 {
-       unsigned int i;
-       int quot = 0;
+       int quot = 0, baud;
        unsigned char cval;
-       int ret = 0;
 
        if (!info->tty || !info->tty->termios)
-               return ret;
+               return -1;
 
        if (!(info->ioaddr))
-               return ret;
+               return -1;
 
        if (newspd > info->max_baud)
-               return 0;
+               return -1;
 
-       info->realbaud = newspd;
-       for (i = 0; i < BAUD_TABLE_NO; i++)
-              if (newspd == mxvar_baud_table[i])
-                      break;
-       if (i == BAUD_TABLE_NO) {
-               quot = info->baud_base / info->speed;
-               if (info->speed <= 0 || info->speed > info->max_baud)
-                       quot = 0;
+       if (newspd == 134) {
+               quot = 2 * info->baud_base / 269;
+               tty_encode_baud_rate(info->tty, 134, 134);
+       } else if (newspd) {
+               quot = info->baud_base / newspd;
+               if (quot == 0)
+                       quot = 1;
+               baud = info->baud_base/quot;
+               tty_encode_baud_rate(info->tty, baud, baud);
        } else {
-               if (newspd == 134) {
-                       quot = (2 * info->baud_base / 269);
-               } else if (newspd) {
-                       quot = info->baud_base / newspd;
-                       if (quot == 0)
-                               quot = 1;
-               } else {
-                       quot = 0;
-               }
+               quot = 0;
        }
 
        info->timeout = ((info->xmit_fifo_size * HZ * 10 * quot) / info->baud_base);
@@ -497,7 +471,7 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
        } else {
                info->MCR &= ~UART_MCR_DTR;
                outb(info->MCR, info->ioaddr + UART_MCR);
-               return ret;
+               return 0;
        }
 
        cval = inb(info->ioaddr + UART_LCR);
@@ -508,20 +482,22 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
        outb(quot >> 8, info->ioaddr + UART_DLM);       /* MS of divisor */
        outb(cval, info->ioaddr + UART_LCR);    /* reset DLAB */
 
-       if (i == BAUD_TABLE_NO) {
-               quot = info->baud_base % info->speed;
+#ifdef BOTHER
+       if (C_BAUD(info->tty) == BOTHER) {
+               quot = info->baud_base % newspd;
                quot *= 8;
-               if ((quot % info->speed) > (info->speed / 2)) {
-                       quot /= info->speed;
+               if (quot % newspd > newspd / 2) {
+                       quot /= newspd;
                        quot++;
-               } else {
-                       quot /= info->speed;
-               }
+               } else
+                       quot /= newspd;
+
                SET_MOXA_MUST_ENUM_VALUE(info->ioaddr, quot);
        } else
+#endif
                SET_MOXA_MUST_ENUM_VALUE(info->ioaddr, 0);
 
-       return ret;
+       return 0;
 }
 
 /*
@@ -534,7 +510,6 @@ static int mxser_change_speed(struct mxser_port *info,
        unsigned cflag, cval, fcr;
        int ret = 0;
        unsigned char status;
-       long baud;
 
        if (!info->tty || !info->tty->termios)
                return ret;
@@ -542,13 +517,8 @@ static int mxser_change_speed(struct mxser_port *info,
        if (!(info->ioaddr))
                return ret;
 
-       if (mxser_set_baud_method[info->tty->index] == 0) {
-               if ((cflag & CBAUD) == B_SPEC)
-                       baud = info->speed;
-               else
-                       baud = tty_get_baud_rate(info->tty);
-               mxser_set_baud(info, baud);
-       }
+       if (mxser_set_baud_method[info->tty->index] == 0)
+               mxser_set_baud(info, tty_get_baud_rate(info->tty));
 
        /* byte size and parity */
        switch (cflag & CSIZE) {
@@ -1588,7 +1558,8 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
                                        port->mon_data.up_txcnt;
                                mon_data_ext.modem_status[i] =
                                        port->mon_data.modem_status;
-                               mon_data_ext.baudrate[i] = port->realbaud;
+                               mon_data_ext.baudrate[i] =
+                                       tty_get_baud_rate(port->tty);
 
                                if (!port->tty || !port->tty->termios) {
                                        cflag = port->normal_termios.c_cflag;
@@ -1646,7 +1617,6 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
        struct serial_icounter_struct __user *p_cuser;
        unsigned long templ;
        unsigned long flags;
-       unsigned int i;
        void __user *argp = (void __user *)arg;
        int retval;
 
@@ -1685,36 +1655,6 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
                return 0;
        }
 
-       if (cmd == MOXA_SET_SPECIAL_BAUD_RATE) {
-               int speed;
-
-               if (get_user(speed, (int __user *)argp))
-                       return -EFAULT;
-               if (speed <= 0 || speed > info->max_baud)
-                       return -EFAULT;
-               if (!info->tty || !info->tty->termios || !info->ioaddr)
-                       return 0;
-               info->tty->termios->c_cflag &= ~(CBAUD | CBAUDEX);
-               for (i = 0; i < BAUD_TABLE_NO; i++)
-                       if (speed == mxvar_baud_table[i])
-                               break;
-               if (i == BAUD_TABLE_NO) {
-                       info->tty->termios->c_cflag |= B_SPEC;
-               } else if (speed != 0)
-                       info->tty->termios->c_cflag |= mxvar_baud_table1[i];
-
-               info->speed = speed;
-               spin_lock_irqsave(&info->slock, flags);
-               mxser_change_speed(info, NULL);
-               spin_unlock_irqrestore(&info->slock, flags);
-
-               return 0;
-       } else if (cmd == MOXA_GET_SPECIAL_BAUD_RATE) {
-               if (copy_to_user(argp, &info->speed, sizeof(int)))
-                    return -EFAULT;
-               return 0;
-       }
-
        if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && cmd != TIOCGICOUNT &&
                        test_bit(TTY_IO_ERROR, &tty->flags))
                return -EIO;
@@ -1808,20 +1748,6 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
                info->mon_data.rxcnt = 0;
                info->mon_data.txcnt = 0;
                return 0;
-       case MOXA_ASPP_SETBAUD:{
-               long baud;
-               if (get_user(baud, (long __user *)argp))
-                       return -EFAULT;
-               spin_lock_irqsave(&info->slock, flags);
-               mxser_set_baud(info, baud);
-               spin_unlock_irqrestore(&info->slock, flags);
-               return 0;
-       }
-       case MOXA_ASPP_GETBAUD:
-               if (copy_to_user(argp, &info->realbaud, sizeof(long)))
-                       return -EFAULT;
-
-               return 0;
 
        case MOXA_ASPP_OQUEUE:{
                int len, lsr;
@@ -2227,7 +2153,7 @@ static void mxser_transmit_chars(struct mxser_port *port)
                return;
        }
 
-       if (port->xmit_buf == 0)
+       if (port->xmit_buf == NULL)
                return;
 
        if ((port->xmit_cnt <= 0) || port->tty->stopped ||
@@ -2435,7 +2361,6 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
                info->normal_termios = mxvar_sdriver->init_termios;
                init_waitqueue_head(&info->open_wait);
                init_waitqueue_head(&info->delta_msr_wait);
-               info->speed = 9600;
                memset(&info->mon_data, 0, sizeof(struct mxser_mon));
                info->err_shadow = 0;
                spin_lock_init(&info->slock);