前几天手欠在x宝上买了个MOXA的UPort1110,USB转RS232串口线(200多大元,别问我为啥不买便宜的(吐魂……今天到手后发现,居然在我的大ArchLinux下默认驱动不上 =_____,=,还好他们官网提供了驱动下载,最新版本1.3号称支持2.6.x和3.“x”内核。二话不说下载编译……果然我的编译路程永远是崎岖的……刷了几屏幕的错误信息之后,华丽地编译失败鸟。

正好今天比较有心情,就跟死磕阿!!!

[more]

显示从Release Notes中看到他们眼中的3.x是up to 3.4.4的……果然是3.4到3.9之间的某个版本中这个驱动用到的api发生了某些奇怪的改动。估计这个驱动发布的时候他们就只有3.4.4的内核,所以还是可以理解的……不过为什么2012.7.30到现在都没有更新过阿!!!内核升级驱动不好使了阿喂!!快来支持阿喂!!!

本来想给他们支持信箱丢封邮件,想了想万一发生了像2009年底的时候,我和某不支持Linux的PCMCIA上网卡厂商交涉,找半天客服,结果电话转给技术一句“支持不了”就打发了一样的事情就浪费时间了。于是本着自己动手丰衣足食的原则,我参照手头上的.h文件以及Eclipse CDT的追踪功能一点一点修改了有问题的代码,经过简单地测试,应该是好使了。

在此附上patch文件,如果有其他朋友遇到了类似的问题,可以直接拿来用=w=

Patch打到mxu11x0.c上。如果您的内核版本介于3.4和3.9之间,也发现编译不过的问题,可以考虑把里面的KERNEL_VERSION(3,9,0)修改成自己的内核大版本号,如KERNEL_VERSION(3,8,0),因为我手头没有低版本的内核,所以也不知道是从哪个版本开始改的

In order to use MOXA UPort1110 Linux driver 1.3 on Linux kernel version 3.9.x (or some versions over 3.4.4 see below). Please use following patch file to patch mxu11x0.c

If your Linux kernel version is between 3.4.4 and 3.9.0 but you can't compile the driver, please modify all KERNEL_VERSION(3,9,0) to your kernel version (eg. to KERNEL_VERSION(3,8,0)) and try it. As I don't have kernel version other than 3.9.2, I don't know which version exactly made the api/struct change.

mxu11x0.patch

diff --git a/driver/mxu11x0.c b/driver/mxu11x0.c
index 2d018bf..1d03ee8 100644
--- a/driver/mxu11x0.c
+++ b/driver/mxu11x0.c
@@ -299,6 +299,7 @@
    { }
 };

+#if(LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
 static struct usb_driver mxu1_usb_driver = {
 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15))   .owner          = THIS_MODULE, @@ -312,6 +313,7 @@      .no_dynamic_id = 1,  #endif  }; +#endif    #if(LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
 static struct usb_serial_driver mxu1110_1port_device = {
@@ -646,7 +648,10 @@
    usb_serial_deregister(&mxu1151_1port_device);
    usb_serial_deregister(&mxu1131_1port_device);
 }
-#else
+module_init(mxu1_init);
+module_exit(mxu1_exit);
+
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))
 static int __init mxu1_init(void)
 {
    int ret;
@@ -664,14 +669,15 @@
 {
    usb_serial_deregister_drivers(&mxu1_usb_driver, serial_drivers);
 }
+module_init(mxu1_init);
+module_exit(mxu1_exit);
+#else
+module_usb_serial_driver(serial_drivers,mxu1_id_table);
 #endif

-
-module_init(mxu1_init);
-module_exit(mxu1_exit);

 static int mxu1_startup(struct usb_serial *serial)
@@ -905,10 +911,12 @@
 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))   if (port->tty)
        port->tty->low_latency = MXU1_DEFAULT_LOW_LATENCY;
-#else
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))     if (port->port.tty)
        port->port.tty->low_latency = MXU1_DEFAULT_LOW_LATENCY;
-#endif 
+#else
+   port->port.low_latency = MXU1_DEFAULT_LOW_LATENCY;
+#endif

    port_number = port->number - port->serial->minor;
@@ -1419,14 +1427,21 @@

    dbg("%s - port %d", __FUNCTION__, port->number);

+#if(LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))    if (!tty || !tty->termios) {
        dbg("%s - no tty or termios", __FUNCTION__);
        return;
    }
-
    cflag = tty->termios->c_cflag;
    iflag = tty->termios->c_iflag;
-
+#else
+   if (!tty) {
+           dbg("%s - no tty or termios", __FUNCTION__);
+           return;
+       }
+   cflag = tty->termios.c_cflag;
+   iflag = tty->termios.c_iflag;
+#endif
    if (old_termios && cflag == old_termios->c_cflag
    && iflag == old_termios->c_iflag) {
        dbg("%s - nothing to change", __FUNCTION__);
@@ -1801,9 +1816,13 @@
 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))                usb_serial_debug_data(dev->driver->name, __FUNCTION__,
            urb->actual_length, urb->transfer_buffer);
-#else
+#elif(LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))          usb_serial_debug_data(debug, dev, __FUNCTION__,             urb->actual_length, urb->transfer_buffer);
+#else
+       if(debug)
+           usb_serial_debug_data( dev, __FUNCTION__,
+                   urb->actual_length, urb->transfer_buffer);
 #endif

        if (!mxport->mxp_is_open)
@@ -1894,22 +1913,28 @@
                    dbg("%s - [1] dropping data, %d bytes lost\n", __FUNCTION__, length);               
                    break;
            }
-       
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))        cnt = tty_buffer_request_room(tty, length); - +#else +      cnt = tty_buffer_request_room(tty->port, length);
+#endif
            if(cnt < length){
                    dbg("%s - [2] dropping data, %d bytes lost\n", __FUNCTION__, length);               
                    break;            
        }

        cnt = length;
-
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))        tty_insert_flip_string(tty, data, cnt); - +#else +      tty_insert_flip_string(tty->port, data, cnt);
+#endif
        length -= cnt;
-
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))        tty_flip_buffer_push(tty); - +#else +       tty_flip_buffer_push(tty->port);
+#endif
    }while(length > 0);

 }
@@ -2035,8 +2060,11 @@
    spin_unlock_irqrestore(&mxport->mxp_lock, flags);
 #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))    usb_serial_debug_data(&port->number, __FUNCTION__, count, port->write_urb->transfer_buffer);
-#else
+#elif(LINUX_VERSION_CODE < KERNEL_VERSION(3,9,0))      usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, port->write_urb->transfer_buffer);
+#else
+   if(debug)
+       usb_serial_debug_data(&port->dev, __FUNCTION__, count, port->write_urb->transfer_buffer);
 #endif

    usb_fill_bulk_urb(port->write_urb, port->serial->dev,