[devel] ppp-2.4.4 - проблемы с CDMA(3G) USB модемом

Yuriy Kashirin uka на altlinux.ru
Вс Апр 22 16:09:53 MSD 2007


Приветствую!

Довелось на днях поиграться вот с таким девайсом:
http://people.net.ua/ru/equipments/internet/u-550/

Завести его удалось, результат зафиксирован здесь:
http://www.freesource.info/wiki/Stat'i/NastrojjkaInterneta/PeopleNet
Но есть одна проблема, которую в двух словах можно сформулировать
так: все работает с ppp-2.4.2, но не работает с ppp-2.4.4 - pppd
вылетает с ошибкой при попытке запуска chat-скрипта коннекта.

Поразбирался глубже, выяснились такие вещи (дальше будет многабукф,
но есть желание поразбираться, пока есть возможность ;).

Сам модем - USB устройство, поддерживается модулем cdc_acm.
# cat /proc/bus/usb/devices
....
T:  Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=12  MxCh= 0
D:  Ver= 2.00 Cls=02(comm.) Sub=00 Prot=00 MxPS=16 #Cfgs=  1
P:  Vendor=16d8 ProdID=5533 Rev= 0.00
S:  Manufacturer=CMOTECH CO., LTD.
S:  Product=CMOTECH CDMA Technologies
S:  SerialNumber=Serial Number
C:* #Ifs= 3 Cfg#= 1 Atr=80 MxPwr=100mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=01 Driver=cdc_acm
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=32ms
I:  If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_acm
E:  Ad=8a(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms
E:  Ad=0b(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms
I:  If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
E:  Ad=82(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms

По strace видна такая картина. Вот для работающего ppp-2.4.2
(открытие и инициализация устройства):
----
5163  open("/dev/ttyACM0", O_RDWR|O_NONBLOCK) = 8
5163  fcntl64(8, F_GETFL)               = 0x802 (flags O_RDWR|O_NONBLOCK)
5163  fcntl64(8, F_SETFL, O_RDWR)       = 0
5163  fstat64(8, {st_mode=S_IFCHR|0640, st_rdev=makedev(166, 0), ...}) = 0
5163  fchmod(8, 020640)                 = 0
5163  ioctl(8, TIOCMBIS, [TIOCM_DTR])   = 0
5163  ioctl(8, SNDCTL_TMR_TIMEBASE or TCGETS, {B115200 -opost -isig -icanon -echo ...}) = 0
5163  ioctl(8, SNDCTL_TMR_CONTINUE or TCSETSF, {B115200 -opost -isig -icanon -echo ...}) = 0
5163  ioctl(8, TIOCMBIC, [TIOCM_DTR])   = 0
5163  rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
5163  rt_sigaction(SIGCHLD, NULL, {0x8050520, [HUP INT USR2 TERM CHLD], 0}, 8) = 0
5163  rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
5163  nanosleep({1, 0}, {1, 0})         = 0
5163  ioctl(8, TIOCMBIS, [TIOCM_DTR])   = 0
----
А вот аналогичный кусок для ppp-2.4.4:
----
13341 open("/dev/ttyACM0", O_RDWR|O_NONBLOCK) = 8
13341 fcntl64(8, F_GETFL)               = 0x802 (flags O_RDWR|O_NONBLOCK)
13341 fcntl64(8, F_SETFL, O_RDWR)       = 0
13341 ioctl(8, TIOCMBIS, [TIOCM_DTR])   = 0
13341 ioctl(8, SNDCTL_TMR_TIMEBASE or TCGETS, {B115200 -opost -isig -icanon -echo ...}) = 0
13341 ioctl(8, SNDCTL_TMR_CONTINUE or TCSETSF, {B115200 -opost -isig -icanon -echo ...}) = 0
13341 ioctl(8, TIOCMBIC, [TIOCM_DTR])   = 0
13341 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
13341 rt_sigaction(SIGCHLD, NULL, {0x8000bc50, [HUP INT USR2 TERM CHLD], 0}, 8) = 0
13341 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
13341 nanosleep({1, 0}, {1, 0})         = 0
13341 ioctl(8, TIOCMBIS, [TIOCM_DTR])   = -1 EIO (Input/output error)
----
Начиная с этого места все последующие обращения к
устройству вызывают EIO. Второй лог
отличается от первого только отсутствием вызовов fstat
и fchmod перед первым ioctl. То есть, получается, что
если не вызывать fstat,fchmod, то программа дальше не
работает, причем не сразу... Почему - для меня пока загадка,
но решил проверить.

Заглянул в исходники. В pppd/tty.c нашел нужное место в
ходе инициализации устройства:
#ifndef __linux__
        /*
         * Linux 2.4 and above blocks normal writes to the tty
         * when it is in PPP line discipline, so this isn't needed.
         */
        /*
         * Do the equivalent of `mesg n' to stop broadcast messages.
         */
        if (fstat(ttyfd, &statbuf) < 0
            || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) {
            warn("Couldn't restrict write permissions to %s: %m", devnam);
        } else
            tty_mode = statbuf.st_mode;
#endif /* __linux__ */

В ppp-2.4.2 в этом месте нет #ifndef __linux__, поэтому
по strace видны fstat и fchmod, а в ppp-2.4.4 их нет.
Убрал эти #ifndef и пересобрал ppp-2.4.4... и все чудесным
образом заработало! (правда, вылезло в другом месте -
соединение периодически рвется в отличие от 2.4.2, но это уже
другая песня).

Как наличие fstat/fchmod может влиять на отсутствие EIO в
дальнейшем? Или это косяки не ppp, а самого устройства
или драйвера или еще чего? Что еще можно поковырять?

----
Попутно, мэйнтейнеру ppp. В пакете приложен патч
ppp-2.4.2-alt-leave-ttyperms-alone.patch (насколько я 
понимаю, из #6042). Он модифицирует как раз этот кусок
кода, который из-за #ifndef __linux__, не компилируется.
Соответственно, этот патч или становится ненужным, или
его надо исправлять, убирая из исходного кода еще и
#ifndef

-- 
 Best regards
 Yuriy Kashirin


Подробная информация о списке рассылки Devel