イーモバイルの D01HW を Debian/GNU Linux etch で使う。その 2

イーモバイルの D01HW を Debian/GNU Linux etch で使う。その 2

http://d.hatena.ne.jp/osaboh/20071209/p1
上記エントリに書いたイーモバイルのモデムが linux 環境で遅い件だが、drivers/usb/serial/usb-serial.c に以下の patch をあてて USB のパケットサイズを変更したら劇的に改善した。
http://www.junxion.com/opensource/linux_highspeed_usbserial.html

ring サーバから数十 MB のファイルをダウンロードするとコンスタントに 1Mbps 、最大で 1.6Mbps 程度は出るようになった。Windows 環境では 640kbps 程度だったのに。 Windows オワタw

以下に Debian etch デフォルトカーネルにおける usb-serial.c の diff を示す。
# unified 形式に変えた 2008/1/6

osanai@X40:~/src/kernel/linux-source-2.6.18/drivers/usb/serial$ diff -u usb-serial.c.org usb-serial.c
--- usb-serial.c.org    2007-12-10 23:57:07.109973365 +0900
+++ usb-serial.c        2007-12-11 00:02:32.926335615 +0900
@@ -57,6 +57,7 @@
    drivers depend on it.
 */

+static ushort maxSize = 0;
 static int debug;
 static struct usb_serial *serial_table[SERIAL_TTY_MINORS];     /* initially all NULL */
 static LIST_HEAD(usb_serial_driver_list);
@@ -815,7 +816,7 @@
                        dev_err(&interface->dev, "No free urbs available\n");
                        goto probe_error;
                }
-               buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
+               buffer_size = (endpoint->wMaxPacketSize > maxSize)?endpoint->wMaxPacketSize:maxSize;
                port->bulk_in_size = buffer_size;
                port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
                port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
@@ -1190,3 +1191,5 @@

 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug enabled or not");
+module_param(maxSize, ushort,0);
+MODULE_PARM_DESC(maxSize,"User specified USB endpoint size");

patch をあてたら動作を確認して

$ cd ~/src/kernel/linux-source-2.6.18/drivers/usb/serial
$ make -C /lib/modules/2.6.18/build/ M=`pwd`
# insmod usbserial.ko vendor=0x12d1 product=0x1003 maxSize=2048
# wvdial

うまくいったらモジュールをインストールする。

# cd ~/src/kernel/linux-source-2.6.18/
# make modules_install