Hey,
Getting well again is top prio.
Right now I'm investigating an interesting issue:
lsusb -v -d 19d2: |grep -C 13 Interrupt
...
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 3
Transfer Type Interrupt
...
ls -l /dev/gsmmodem /dev/ttyU*
lrwxrwxrwx 1 root root 7 23 mag 11.50 /dev/gsmmodem -> ttyUSB1
crw-rw---- 1 root dialout 188, 0 23 mag 11.50 /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 1 23 mag 11.50 /dev/ttyUSB1
crw-rw---- 1 root dialout 188, 2 23 mag 13.14 /dev/ttyUSB2
So, INT line is port 3, out of three IF.
Then, dialling using gsmmodem works perfectly. Furthermore, dialling
using wvdial inet modem=/dev/ttyUSB2 works perfectly as well but it's printing alot of ctrl char stuff like this:
--> pppd: ��0b] p�0b] [18]�0b]
--> Authentication (PAP) started
--> pppd: ��0b] p�0b] [18]�0b]
--> pppd: ��0b] p�0b] [18]�0b]
--> Authentication (PAP) successful
--> pppd: ��0b] p�0b] [18]�0b]
--> pppd: ��0b] p�0b] [18]�0b]
--> pppd: ��0b] p�0b] [18]�0b]
--> pppd: ��0b] p�0b] [18]�0b]
Note that this isn't the olicard100 stick, though (maybe wrong thread then) but it's occurring right now the first time some days after my changes to usb_modeswitch, so maybe there's some correlation.
I choose ttyUSB2 for the second dial as it's been so far the port used to dial and pointed to by gsmmodem.
My dbg output shows:
symlink call
dirList: {} devices pci0000:00 0000:00:1a.7 usb1 1-3 1-3:1.3 ttyUSB2 tty ttyUSB2
tty: ttyUSB2
ttyNo: 2
ifDir: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3
port: ttyUSB2
dev_top: 1-3
found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.3/ep_84/type
INT-portList: 3
returning symlinkname: gsmmodem
for just every port..
1-3:1.3 means IF 3 but there's only ttyUSB[0,1,2] and then there are dirs /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.[0,1,2,3]
Using the original usb_modeswitch script, it's consistent as before.
Using the above patch (plus dbg log) works repeatedly fine w/ the olicard100 stick. Only the onda stick is giving trouble. So there's probably some correlation about the number of INT lines.
Hey, nice:
l /dev/gsmmodem* /dev/ttyUSB*
lrwxrwxrwx 1 root root 7 23 mag 13.40 /dev/gsmmodem -> ttyUSB2
lrwxrwxrwx 1 root root 7 23 mag 13.40 /dev/gsmmodem2 -> ttyUSB1
crw-rw---- 1 root dialout 188, 0 23 mag 13.40 /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 1 23 mag 13.40 /dev/ttyUSB1
crw-rw---- 1 root dialout 188, 2 23 mag 13.40 /dev/ttyUSB2
Onda stick is plugged only..
Wheather is particularly hot today...
I'm using
Linux host 2.6.33.3 #22 SMP PREEMPT Thu May 13 12:52:22 CEST 2010 i686 GNU/Linux
I've been searching the logs for an older lsusb entry, showing INT lines and stuff. Seems like I got none left..
gsmmodem2 doesn't dial.
gsmmodem does dial. w/ and w/o output like the one above..
Intriguing that is, indeed.
Gonna fix that..
The dbg tells that there should be three gsmmodem links. but there're only two of them. Could there be some unresolved bad udev behaviour showing up?
When I'm debugging the original usb_modeswitch, I noticed it seems skipping dir /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.2, working w/ ...1-3:1.[0,1,3] though.
Maybe I'm missing something or getting something wrong in my understanding of how things should work out..
olicard: INT on IF number 0 and 4, w/ original script gssmodem points sometimes to ttyUSB0 and other times to ttyUSB4. W/ patch, pointing to ttyUSB0 (first INT line).
onda: INT on IF number 3, w/ original script gssmodem points to ttyUSB2. W/ patch pointing to either ttyUSB1 or ttyUSB2 and sometimes to ttyUSB1 _and_ ttyUSB2.
Note that w/ onda the INT IF no is 3 where contrarily to this gsmmodem points to ttyUSB2, there isn't even a ttyUSB3. How comes?
I noticed during dbg that w/ the orignal script symlink returns gsmmodem for ttyUSB4 first and then ttyUSB0 second, in case olicard is plugged and that time the gsmmodem link really ends up pointing to ttyUSB0 (which is incidentically correct).
Wasn't this also the case w/ the patch and issuing more than one gsmmodem but something going wrong w/ the symlinking process above? Timing problem?
BTW, using this dbg patch against original script from usb-modeswitch pkg version 1.1.2-2:
Code: Select all
--- /lib/udev/usb_modeswitch.orig 2010-05-18 12:01:18.000000000 +0200
+++ /lib/udev/usb_modeswitch.orig.dbg 2010-05-23 14:15:01.000000000 +0200
@@ -531,6 +531,18 @@
}
# end of proc {ParseConfigFile}
+proc {pLog} {msg} {
+
+global wc
+if {![info exists wc]} {
+ set wc [open /tmp/usb_modeswitch_dbg.log a]
+ puts $wc "\n\nUSB_ModeSwitch log from [clock format [clock seconds]]\n"
+}
+puts $wc $msg
+
+}
+# end of proc {Log}
+
proc {Log} {msg} {
@@ -553,20 +565,37 @@
proc {SymLinkName} {path} {
+pLog "symlink call"
# HACK ... /tmp/gsmmodem_* was generated by a switching run before;
# no way found to signal annother instance in the udev environment
set tmpname [lindex [glob -nocomplain /tmp/gsmmodem_*] 0]
set dev_top [lindex [split $tmpname _] 1]
set dirList [split $path /]
+set tty [lindex $dirList end]
+regsub {ttyUSB} $tty {} ttyNo
+pLog "dirList: $dirList"
+pLog "tty: $tty"
+pLog "ttyNo: $ttyNo"
+#pLog "Path: $path"
set idx -1
set idx [lsearch -regexp $dirList {\d+-\d+:\d+\.\d+}]
if {$idx == -1} {
return ""
}
set ifDir /sys[join [lrange $dirList 0 $idx] /]
+pLog "ifDir: $ifDir"
+### Idea is: lower the tty no better it is: ttyUSB0 is working, ttyUSB4 isn't
+### (holds for devices with more than one interrupt line)
+### This doesn't take into account more than one /dev/gsmmodem link.
+set range [lrange $dirList 0 [expr {$idx-1}]]
+set spath [lappend range $dev_top]
+set ifDir2 /sys[join $spath /]
+pLog "ifDir2: $ifDir2"
set port [lindex $dirList end]
+pLog "port: $port"
+pLog "dev_top: $dev_top"
if {![regexp "/$dev_top/" $path]} {
return ""
}
@@ -583,6 +612,30 @@
}
}
}
+
+set devNo {}
+foreach epDir2 [glob -nocomplain $ifDir2:\[0-9\].\[0-9\]/ep_*] {
+ if [file exists $epDir2/type] {
+ set rc [open $epDir2/type r]
+ set type [read $rc]
+ close $rc
+ if [regexp {Interrupt} $type] {
+ pLog "found INT: $epDir2/type\n"
+ regsub $ifDir2:.\.(\[0-9\])/.* $epDir2 {\1} localId
+ lappend devNo $localId
+ break
+ }
+ }
+ }
+
+set minDevNo [lindex [lsort -decreasing $devNo] end]
+pLog "INT-portList: $minDevNo\n"
+if {$ttyNo > $minDevNo} {
+ pLog "Skipping $ttyNo, larger than $minDevNo\n"
+# return ""
+}
+pLog "INFO: $ttyNo smaller than or equal to $minDevNo\n"
+
cd /dev
set idx 2
set trunkName $symlinkName
@@ -594,6 +647,7 @@
incr idx
}
+pLog "returning symlinkname: $symlinkName\n"
return $symlinkName
}
I then noticed that this "break" in the dbg loop isn't correct. Removed it and the original script w/ dbg patch is working better (showing all INT lines in list). Backported this change to the fix. Now, orig script patched to support the olicard (now w/ dbg enabled) tells, that all ports are lower than 3 (correct) and therefore issues for every port a gsmmodem link name. The actual order of appearance was in the latest run: ports 1, 0, 2. The gsmmodem ended up pointing to ttyUSB1. Maybe because it was the first one issued.. Correct would have been ttyUSB2. ttyUSB1 isn't working. ttyUSB2 does work.
Deductions to verify:
1) Iff count(INT lines) is larger than max(ports) (onda: INT line no 3, port no max 2) then set gsmmodem to max(ports).
2) Iff count(INT lines) is larger than max(ports) (onda: INT line no 3, port no max 2) then set gsmmodem to count(INT lines) - 1: 3 - 1 = 2.
(ttyUSB_2_ is working)
But then, does this hold:
max(ports) == count(INT lines) - 1?
In this case deductions 1 and 2 coincide.
No clue so far. Neither can I verify whether I am going to break the script for all sticks in the wild out there w/ one of those assumptions..
Additionally, it seems that the deductions only apply to sticks w/ only one single INT line (like onda mf363 here), whereas olicard w/ 2 INT lines do already work w/ the fix.
ONDA: w/ fix patch: symlinks issued for all ports, in order: 0,2,1 and gsmmodem points to ttyUSB2. This looks quite like a timing problem.
I once tried some code w/ timing mods like "after 1000".. to no avail.. It's also not that deterministic to just wait. OTOH, how does udev work when there's already a link? I'd think it's skipping it's new link. At least it looks like this to me when ttyUSB1 is showing up but no ttyUSB[0,2] after that in the second last example above (order 1,0,2). Another point this is the case when there are gsmmodem[,2].. That means the timing problem didn't catch us and the script detected the first gsmmodem link. But isn't this rather udev missing to set some link instead of a race condition?
w/ fix patch: (reminder: the "break" removed from the loop)
onda:
cat /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/bNumInterfaces
4
Interesting thing:
olicard:
1-3:1.*/bInterfaceClass
ff
ff
ff
ff
ff
onda: whether gsmmodem is pointing ttyUSB0 or ttyUSB2.
cat 1-3:1.*/bInterfaceClass
ff
ff
08
ff
So, can we use bInterfaceClass content for devs w/ count(INT lines) == 1? Obviously we need more info when handling devs w/ count(INT lines) >= 2 (bInterfaceClass always ff). Or are those bInterfaceClass values dev dependent (and maybe more than one is different from ff, or more than one is 08 or those different from ff aren't the same (as 08 here))?
Just noticed that udev calls us w/ path /devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.3/ttyUSB2/tty/ttyUSB2 for ttyUSB2! Hm. That's a hint regarding the deductions above.
Latest dbg output: (onda)
USB_ModeSwitch log from Sun May 23 16:02:19 CEST 2010
symlink call
dirList: {} devices pci0000:00 0000:00:1a.7 usb1 1-3 1-3:1.1 ttyUSB1 tty ttyUSB1
tty: ttyUSB1
ttyNo: 1
Path: /devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.1/ttyUSB1/tty/ttyUSB1
ifDir: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3
port: ttyUSB1
dev_top: 1-3
className: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.1/bInterfaceClass
classType: ff
found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.3/ep_84/type
INT-portList: 3
INFO: 1 smaller than or equal to 3
returning symlinkname: gsmmodem
USB_ModeSwitch log from Sun May 23 16:02:19 CEST 2010
symlink call
dirList: {} devices pci0000:00 0000:00:1a.7 usb1 1-3 1-3:1.0 ttyUSB0 tty ttyUSB0
tty: ttyUSB0
ttyNo: 0
Path: /devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.0/ttyUSB0/tty/ttyUSB0
ifDir: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3
port: ttyUSB0
dev_top: 1-3
className: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.0/bInterfaceClass
classType: ff
found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.3/ep_84/type
INT-portList: 3
INFO: 0 smaller than or equal to 3
returning symlinkname: gsmmodem
USB_ModeSwitch log from Sun May 23 16:02:19 CEST 2010
symlink call
dirList: {} devices pci0000:00 0000:00:1a.7 usb1 1-3 1-3:1.3 ttyUSB2 tty ttyUSB2
tty: ttyUSB2
ttyNo: 2
Path: /devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.3/ttyUSB2/tty/ttyUSB2
ifDir: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3
port: ttyUSB2
dev_top: 1-3
className: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.3/bInterfaceClass
classType: ff
found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.3/ep_84/type
INT-portList: 3
INFO: 2 smaller than or equal to 3
returning symlinkname: gsmmodem2
In the last call (the one for ttyUSB2) here's the correlation between path element __1.3__/ttyUSB2 and "found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:__1.3__/ep_84/type"
That could be it.
dbg log for the olicard: only the relevant port
USB_ModeSwitch log from Sun May 23 16:14:54 CEST 2010
symlink call
dirList: {} devices pci0000:00 0000:00:1a.7 usb1 1-3 1-3:1.0 ttyUSB0 tty ttyUSB0
tty: ttyUSB0
ttyNo: 0
Path: /devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.0/ttyUSB0/tty/ttyUSB0
ifDir: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3
port: ttyUSB0
dev_top: 1-3
className: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.0/bInterfaceClass
classType: ff
found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.0/ep_81/type
found INT: /sys/devices/pci0000:00/0000:00:1a.7/usb1/1-3/1-3:1.4/ep_86/type
INT-portList: 0
INFO: 0 smaller than or equal to 0
returning symlinkname: gsmmodem
I think that was it. The id in the path name from udev and the one from the lowest found interrupt must be identical, then it works harmoniously (for me again)tm.
Josh, please give this patch a look and try. Forget about the above, I consider the first one a first shot that didn't go far enough.
I already did some minor cleanup and even did some language usage improvement. But there's probably more potential.
Again, this isn't multi-device-reentrant yet..
Everything regarding "pLog" can be safely removed, it's kind of "privateLog" used for local debugging as the "Log" fct isn't available within the "SymlinkName" fct.
Code: Select all
--- /lib/udev/usb_modeswitch.orig 2010-05-18 12:01:18.000000000 +0200
+++ /lib/udev/usb_modeswitch.dbg 2010-05-23 18:03:57.000000000 +0200
@@ -531,6 +531,17 @@
}
# end of proc {ParseConfigFile}
+proc {pLog} {msg} {
+
+global wc
+if {![info exists wc]} {
+ set wc [open /tmp/usb_modeswitch_dbg.log a]
+ puts $wc "\n\nUSB_ModeSwitch log from [clock format [clock seconds]]\n"
+}
+puts $wc $msg
+
+}
+# end of proc {Log}
proc {Log} {msg} {
@@ -553,36 +564,100 @@
proc {SymLinkName} {path} {
+pLog "symlink call"
# HACK ... /tmp/gsmmodem_* was generated by a switching run before;
# no way found to signal annother instance in the udev environment
set tmpname [lindex [glob -nocomplain /tmp/gsmmodem_*] 0]
set dev_top [lindex [split $tmpname _] 1]
set dirList [split $path /]
+set tty [lindex $dirList end]
+regsub {ttyUSB} $tty {} ttyNo
+pLog "dirList: $dirList"
+pLog "tty: $tty"
+pLog "ttyNo: $ttyNo"
+pLog "Path: $path"
set idx -1
set idx [lsearch -regexp $dirList {\d+-\d+:\d+\.\d+}]
if {$idx == -1} {
return ""
}
-set ifDir /sys[join [lrange $dirList 0 $idx] /]
+### Idea is: lower the tty no better it is: ttyUSB0 is working,
+### ttyUSB4 isn't (holds for devices with more than one
+### interrupt line like olicard100) This doesn't take into
+### account more than one /dev/gsmmodem link.
+set devDirBricks [lrange $dirList 0 [expr {$idx-1}]]
+set devDir /sys[join $devDirBricks /]
+lappend devDirBricks $dev_top
+set ifDirPrefixed /sys[join $devDirBricks /]
+pLog "ifDirPrefixed: $ifDirPrefixed"
+set vendorF "idVendor"
+set productF "idProduct"
+set idVendor ""
+set idProduct ""
+if [file exists $devDir/$vendorF] {
+ set fh [open $devDir/$vendorF r]
+ set idVendor [read $fh]
+ close $fh
+}
+if [file exists $devDir/$productF] {
+ set fh [open $devDir/$productF r]
+ set idProduct [read $fh]
+ close $fh
+}
+set idVendor [lindex [split $idVendor \n] 0]
+set idProduct [lindex [split $idProduct \n] 0]
+pLog "device: $idVendor:$idProduct"
+
set port [lindex $dirList end]
+pLog "port: $port"
+pLog "dev_top: $dev_top"
if {![regexp "/$dev_top/" $path]} {
return ""
}
+set usbPathId [lindex $dirList 6]
+set subPaths [split $usbPathId :]
+set pathId [lindex $subPaths end]
+set className $ifDirPrefixed:$pathId/bInterfaceClass
+pLog "className: $className"
+if [file exists $className] {
+ set classFh [open $className r]
+ set classType [read $classFh]
+ close $classFh
+ set classType [lindex [split $classType \n] 0]
+ pLog "classType: $classType"
+}
+
set symlinkName ""
-foreach epDir [glob -nocomplain $ifDir/ep_*] {
+set usbIds {}
+foreach epDir [glob -nocomplain $ifDirPrefixed:\[0-9\].\[0-9\]/ep_*] {
if [file exists $epDir/type] {
set rc [open $epDir/type r]
set type [read $rc]
close $rc
if [regexp {Interrupt} $type] {
- set symlinkName "gsmmodem"
- break
+ pLog "INTERRUPT: $epDir/type"
+ regsub $ifDirPrefixed:.\.(\[0-9\])/.* $epDir {\1} localUsbId
+ lappend usbIds $localUsbId
}
}
}
+
+set minUsbId [lindex [lsort -decreasing $usbIds] end]
+pLog "minUsbId(INTERRUPT): $minUsbId"
+
+set lastCharUsbPathId [lindex [split $usbPathId .] end]
+### The id from the device on the given usb port (path from udev)
+### and the lowest found interrupt line path id must be identical.
+### This works for 1-interrupt devs like the Onda ZTE MF636 and
+### multi-interrupt devices like the Olivetti Olicard100 sticks.
+pLog "INFO: lastCharUsbPathId: $lastCharUsbPathId, minUsbId: $minUsbId"
+if {$lastCharUsbPathId == $minUsbId} {
+ set symlinkName "gsmmodem"
+}
+
cd /dev
set idx 2
set trunkName $symlinkName
@@ -594,6 +669,7 @@
incr idx
}
+pLog "returning symlinkname: $symlinkName"
return $symlinkName
}
Cheers,
Nils
PS: sorry 4 the monster post!
