찾아 보니 CP210x driver에 baudrate 초기화 버그가 있는 듯...
http://www.spinics.net/lists/linux-usb/msg56969.html
그래서 driver patch를 적용하여 보겠습니다.
자신이 사용하는 kernel 버전을 확인한다.
커널 버전 확인
$uname -a
Linux codewalker-desktop 2.6.32-38-generic #83-Ubuntu SMP Wed Jan 4 11:12:07 UTC 2012 x86_64 GNU/Linux
linux-source, linux-source-2.6.32
아래 path로 소스 파일이 받아 진다.
/usr/src/linux-source-2.6.32.tar.bz2
/usr/src/linux-source-2.6.32/drivers/usb/serial/cp210x.c 수정한다.
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 3835106..dcba930 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -201,6 +201,8 @@ static struct usb_serial_driver cp210x_device = { #define CP210X_EMBED_EVENTS 0x15 #define CP210X_GET_EVENTSTATE 0x16 #define CP210X_SET_CHARS 0x19 +#define CP210X_GET_BAUDRATE 0x1d +#define CP210X_SET_BAUDRATE 0x1e /* CP210X_IFC_ENABLE */ #define UART_ENABLE 0x0001 @@ -459,16 +461,12 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, unsigned int *cflagp, unsigned int *baudp) { unsigned int cflag, modem_ctl[4]; - unsigned int baud; + u32 baud; unsigned int bits; dbg("%s - port %d", __func__, port->number); - cp210x_get_config(port, CP210X_GET_BAUDDIV, &baud, 2); - /* Convert to baudrate */ - if (baud) - baud = cp210x_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud); - + cp210x_get_config(port, CP210X_GET_BAUDRATE, &baud, sizeof(baud)); dbg("%s - baud rate = %d", __func__, baud); *baudp = baud; @@ -580,7 +578,8 @@ static void cp210x_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { unsigned int cflag, old_cflag; - unsigned int baud = 0, bits; + u32 baud; + unsigned int bits; unsigned int modem_ctl[4]; dbg("%s - port %d", __func__, port->number); @@ -595,8 +594,8 @@ static void cp210x_set_termios(struct tty_struct *tty, /* If the baud rate is to be updated*/ if (baud != tty_termios_baud_rate(old_termios) && baud != 0) { dbg("%s - Setting baud rate to %d baud", __func__, baud); - if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV, - ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { + if (cp210x_set_config(port, CP210X_SET_BAUDRATE, + &baud, sizeof(baud))) { dbg("Baud rate requested not supported by device"); baud = tty_termios_baud_rate(old_termios); } --
$sudo make menuconfig$sudo make -j10
kernel 빌드 시 에러가 발생 아래와 같이 수정.
ERROR-2
LD [M] ubuntu/omnibook/omnibook.o
ld: /ubuntu/omnibook/sections.lds: No such file: No such file or directory
make[2]: *** [ubuntu/omnibook/omnibook.o] Error 1
make[1]: *** [ubuntu/omnibook] Error 2
make: *** [ubuntu] Error 2
SOLUTION-2
$ sudo vi /usr/src/linux/ubuntu/omnibook/Makefile
160: #EXTRA_LDFLAGS += $(src)/sections.lds
161: EXTRA_LDFLAGS += $(PWD)/ubuntu/omnibook/sections.lds
http://thangamaniarun.wordpress.com/2010/07/08/how-to-quickly-build-custom-kernel-on-ubuntu-10-04/
cp210x.ko module 만들기
$sudo make modules
$sudo make modules_install
[/lib/modules]$ ls -l
합계 20
drwxr-xr-x 4 root root 4096 2010-04-29 21:45 2.6.32-21-generic
drwxr-xr-x 5 root root 4096 2011-12-16 18:47 2.6.32-36-generic
drwxr-xr-x 5 root root 4096 2012-01-17 16:24 2.6.32-37-generic
drwxr-xr-x 5 root root 4096 2012-01-24 17:09 2.6.32-38-generic
drwxr-xr-x 3 root root 4096 2012-01-25 17:54 2.6.32.52+drm33.21
kernel 소스 Makefile에 EXTRAVERSION이 실제 설치된 kernel과 틀리다.
그래서 수동으로 cp210x.ko를 2.6.32-38-generic 폴더 밑에 파일로 바꿔주면 된다.
EXTRAVERSION이 다르지만 insmod나 hot-plugin시 문제 없이 module이 올라 간다.
혹시나 드라이버에 문제가 생기면 동일한 linux-image-generic를 synaptic에서 재설치해 주면 해결된다.
module의 EXTRAVERSION을 확인하기 위해서는 modinfo를 이용하면 된다.
alias: usb:v0FCFp1004d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0FCFp1003d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BEDp1101d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BEDp1100d*dc*dsc*dp*ic*isc*ip*
alias: usb:v08FDp000Ad*dc*dsc*dp*ic*isc*ip*
alias: usb:v08E6p5501d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0745p1000d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0489pE000d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0471p066Ad*dc*dsc*dp*ic*isc*ip*
alias: usb:v045Bp0053d*dc*dsc*dp*ic*isc*ip*
depends: usbserial
vermagic: 2.6.32.52+drm33.21 SMP mod_unload modversions
parm: debug:Enable verbose debugging messages (bool)
[/lib/modules/2.6.32-38-generic/kernel/drivers/usb/serial]$