We need it to ensure we don't regress in hardware support in Fedora 24. Will be gone in Fedora 25.
334 lines
9.2 KiB
Diff
334 lines
9.2 KiB
Diff
From cf2afa734597ef88b8f5871bf18cf849b105e51d Mon Sep 17 00:00:00 2001
|
|
From: Lubomir Rintel <lkundrak@v3.sk>
|
|
Date: Mon, 25 Jul 2016 12:03:22 +0200
|
|
Subject: [PATCH] Bring back the module binding
|
|
|
|
We still need it for some devices.
|
|
|
|
http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?f=2&t=2560
|
|
---
|
|
usb_modeswitch.sh | 23 +++++-
|
|
usb_modeswitch.tcl | 214 +++++++++++++++++++++++++++++++++++++++++++++++++----
|
|
2 files changed, 221 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/usb_modeswitch.sh b/usb_modeswitch.sh
|
|
index b126ec3..f4b76dd 100755
|
|
--- a/usb_modeswitch.sh
|
|
+++ b/usb_modeswitch.sh
|
|
@@ -40,7 +40,27 @@ fi
|
|
PATH=/sbin:/usr/sbin:$PATH
|
|
case "$1" in
|
|
--driver-bind)
|
|
- # driver binding code removed
|
|
+ (
|
|
+ dir=$(ls -d /sys$2/ttyUSB* 2>/dev/null)
|
|
+ sleep 1
|
|
+ if [ ! -z "$dir" ]; then
|
|
+ exit 0
|
|
+ fi
|
|
+ set +e
|
|
+ device_in "bind_list" $v_id $p_id
|
|
+ if [ "$?" = "1" ]; then
|
|
+ id_attr="/sys/bus/usb-serial/drivers/option1/new_id"
|
|
+ if [ ! -e "$id_attr" ]; then
|
|
+ modprobe option 2>/dev/null || true
|
|
+ fi
|
|
+ if [ -e "$id_attr" ]; then
|
|
+ echo "$v_id $p_id ff" > $id_attr
|
|
+ else
|
|
+ modprobe -r usbserial 2>/dev/null
|
|
+ modprobe usbserial "vendor=0x$v_id" "product=0x$p_id" 2>/dev/null
|
|
+ fi
|
|
+ fi
|
|
+ ) &
|
|
exit 0
|
|
;;
|
|
--symlink-name)
|
|
@@ -53,7 +73,6 @@ case "$1" in
|
|
exit 0
|
|
;;
|
|
esac
|
|
-
|
|
IFS='/' read -r p1 p2 <<EOF
|
|
$1
|
|
EOF
|
|
diff --git a/usb_modeswitch.tcl b/usb_modeswitch.tcl
|
|
index 3e590fd..b74d46c 100755
|
|
--- a/usb_modeswitch.tcl
|
|
+++ b/usb_modeswitch.tcl
|
|
@@ -276,6 +276,7 @@ foreach mconfig $configList {
|
|
set cfgno [string trim $cfgno]
|
|
if {$cfgno > 0} {
|
|
set config(Configuration) $cfgno
|
|
+ set config(DriverModule) ""
|
|
set flags(config) "Configuration=$cfgno"
|
|
} else {
|
|
Log " No MBIM configuration found, switch to legacy modem mode"
|
|
@@ -290,10 +291,6 @@ foreach mconfig $configList {
|
|
set report "ok:busdev"
|
|
break
|
|
}
|
|
- if {$config(Configuration) == 0} {
|
|
- Log "Config file contains dummy method, do nothing. Exit"
|
|
- SafeExit
|
|
- }
|
|
UnbindDriver $devdir $ifdir
|
|
# Now we are actually switching
|
|
if $flags(logging) {
|
|
@@ -348,19 +345,68 @@ if [regexp {ok:busdev} $report] {
|
|
ReadUSBAttrs $devdir $ifdir
|
|
}
|
|
|
|
-# driver binding removed !!
|
|
+# Checking for bound drivers if there is an interface with class 0xff
|
|
|
|
-if {[string length "$usb(idVendor)$usb(idProduct)"] < 8} {
|
|
- if {![regexp {ok:(\w{4}):(\w{4})} $report d usb(idVendor) usb(idProduct)]} {
|
|
- Log "No target vendor/product ID found or given, can't continue. Abort"
|
|
- SafeExit
|
|
+if {$config(DriverModule) != "" && [regexp {ok:} $report]} {
|
|
+ if [HasFF $devdir] {
|
|
+ AddToList link_list $usb(idVendor):$usb(idProduct)
|
|
+ } else {
|
|
+ set config(DriverModule) ""
|
|
+ Log " No vendor-specific class found, skip driver check"
|
|
}
|
|
}
|
|
-# wait for drivers to bind
|
|
-after 500
|
|
-if {[llength [glob -nocomplain $devdir/$ifdir/ttyUSB*]] > 0} {
|
|
- Log "Serial USB driver bound to interface 0\n will try to guess and symlink modem port on next connect"
|
|
- AddToList link_list $usb(idVendor):$usb(idProduct)
|
|
+
|
|
+# If module is set (it is by default), driver shall be loaded.
|
|
+# If not, then NoDriverLoading is active
|
|
+
|
|
+if {$config(DriverModule) != ""} {
|
|
+ if {[string length "$usb(idVendor)$usb(idProduct)"] < 8} {
|
|
+ if {![regexp {ok:(\w{4}):(\w{4})} $report d usb(idVendor) usb(idProduct)]} {
|
|
+ Log "No target vendor/product ID found or given, can't continue. Abort"
|
|
+ SafeExit
|
|
+ }
|
|
+ }
|
|
+ # wait for any drivers to bind automatically
|
|
+ after 1500
|
|
+ Log "Now check for bound driver ..."
|
|
+ if {![file exists $devdir/$ifdir/driver]} {
|
|
+ Log " no driver has bound to interface 0 yet"
|
|
+
|
|
+ # If device is known, the sh wrapper will take care, else:
|
|
+ if {[InBindList $usb(idVendor):$usb(idProduct)] == 0} {
|
|
+ Log "Device is not in \"bind_list\" yet, bind it now"
|
|
+
|
|
+ # Load driver
|
|
+ CheckDriverBind $usb(idVendor) $usb(idProduct)
|
|
+
|
|
+ # Old/slow systems may take a while to create the devices
|
|
+ set counter 0
|
|
+ while {![file exists $devdir/$ifdir/driver]} {
|
|
+ if {$counter == 14} {break}
|
|
+ after 500
|
|
+ incr counter
|
|
+ }
|
|
+ if {$counter == 14} {
|
|
+ Log " driver binding failed"
|
|
+ } else {
|
|
+ Log " driver was bound to the device"
|
|
+ AddToList bind_list $usb(idVendor):$usb(idProduct)
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ Log " driver has bound, device is known"
|
|
+ if {[llength [glob -nocomplain $devdir/$ifdir/ttyUSB*]] > 0} {
|
|
+ AddToList link_list $usb(idVendor):$usb(idProduct)
|
|
+ }
|
|
+ }
|
|
+} else {
|
|
+ # Just in case "NoDriverLoading" was added after the first bind
|
|
+ RemoveFromBindList $usb(idVendor):$usb(idProduct)
|
|
+}
|
|
+
|
|
+if [regexp {ok:$} $report] {
|
|
+ # "NoDriverLoading" was set
|
|
+ Log "No driver check or bind for this device"
|
|
}
|
|
|
|
# In newer kernels there is a switch to avoid the use of a device
|
|
@@ -553,6 +599,8 @@ return "Use global config file: $configFile"
|
|
proc ParseDeviceConfig {cfg} {
|
|
|
|
global config
|
|
+set config(DriverModule) ""
|
|
+set config(DriverIDPath) ""
|
|
set config(WaitBefore) ""
|
|
set config(TargetVendor) ""
|
|
set config(TargetProduct) ""
|
|
@@ -561,6 +609,7 @@ set config(Configuration) ""
|
|
set config(NoMBIMCheck) 0
|
|
set config(PantechMode) 0
|
|
set config(CheckSuccess) 20
|
|
+set loadDriver 1
|
|
|
|
foreach pname [lsort [array names config]] {
|
|
if [regexp -line "^\[^# \]*?$pname.*?= *(0x(\\w+)|\"(\[0-9a-fA-F,\]+)\"|(\[0-9\]+)) *\$" $cfg d config($pname)] {
|
|
@@ -568,6 +617,26 @@ foreach pname [lsort [array names config]] {
|
|
}
|
|
}
|
|
|
|
+if [regexp -line {^[^#]*?NoDriverLoading.*?=.*?(1|yes|true).*?$} $cfg] {
|
|
+ set loadDriver 0
|
|
+ Log "config: NoDriverLoading is set to active"
|
|
+}
|
|
+
|
|
+# For general driver loading; TODO: add respective device names.
|
|
+# Presently only useful for HSO devices (which are recounted now)
|
|
+if $loadDriver {
|
|
+ if {$config(DriverModule) == ""} {
|
|
+ set config(DriverModule) "option"
|
|
+ set config(DriverIDPath) "/sys/bus/usb-serial/drivers/option1"
|
|
+ } else {
|
|
+ if {$config(DriverIDPath) == ""} {
|
|
+ set config(DriverIDPath) "/sys/bus/usb/drivers/$config(DriverModule)"
|
|
+ }
|
|
+ }
|
|
+ Log "Driver module is \"$config(DriverModule)\", ID path is $config(DriverIDPath)\n"
|
|
+} else {
|
|
+ Log "Driver will not be handled by usb_modeswitch"
|
|
+}
|
|
set config(WaitBefore) [string trimleft $config(WaitBefore) 0]
|
|
|
|
}
|
|
@@ -768,6 +837,92 @@ return $symlinkName
|
|
# end of proc {SymLinkName}
|
|
|
|
|
|
+# Load and bind driver (default "option")
|
|
+#
|
|
+proc {CheckDriverBind} {vid pid} {
|
|
+global config
|
|
+
|
|
+foreach fn {/sbin/modprobe /usr/sbin/modprobe} {
|
|
+ if [file exists $fn] {
|
|
+ set loader $fn
|
|
+ }
|
|
+}
|
|
+Log "Module loader is $loader"
|
|
+
|
|
+set idfile $config(DriverIDPath)/new_id
|
|
+if {![file exists $idfile]} {
|
|
+ if {$loader == ""} {
|
|
+ Log "Can't do anymore without module loader; get \"modtools\"!"
|
|
+ return
|
|
+ }
|
|
+ Log "\nTry to load module \"$config(DriverModule)\""
|
|
+ if [catch {set result [exec $loader -v $config(DriverModule)]} err] {
|
|
+ Log " Running \"$loader $config(DriverModule)\" gave an error:\n $err"
|
|
+ } else {
|
|
+ Log " Module was loaded successfully:\n$result"
|
|
+ }
|
|
+} else {
|
|
+ Log "Module is active already"
|
|
+}
|
|
+set i 0
|
|
+while {$i < 50} {
|
|
+ if [file exists $idfile] {
|
|
+ break
|
|
+ }
|
|
+ after 20
|
|
+ incr i
|
|
+}
|
|
+if {$i < 50} {
|
|
+ Log "Try to add ID to driver \"$config(DriverModule)\""
|
|
+ SysLog "usb_modeswitch: add device ID $vid:$pid to driver \"$config(DriverModule)\""
|
|
+ SysLog "usb_modeswitch: please report the device ID to the Linux USB developers!"
|
|
+ if [catch {exec echo "$vid $pid ff" >$idfile} err] {
|
|
+ Log " Error adding ID to driver:\n $err"
|
|
+ } else {
|
|
+ Log " ID added to driver; check for new devices in /dev"
|
|
+ }
|
|
+} else {
|
|
+ Log " \"$idfile\" not found, check if kernel version is at least 2.6.27"
|
|
+ Log "Fall back to \"usbserial\""
|
|
+ set config(DriverModule) usbserial
|
|
+ Log "\nTry to unload driver \"usbserial\""
|
|
+ if [catch {exec $loader -r usbserial} err] {
|
|
+ Log " Running \"$loader -r usbserial\" gave an error:\n $err"
|
|
+ Log "No more fallbacks"
|
|
+ return
|
|
+ }
|
|
+ after 50
|
|
+ Log "\nTry to load driver \"usbserial\" with device IDs"
|
|
+ if [catch {set result [exec $loader -v usbserial vendor=0x$vid product=0x$pid]} err] {
|
|
+ Log " Running \"$loader usbserial\" gave an error:\n $err"
|
|
+ } else {
|
|
+ Log " Driver was loaded successfully:\n$result"
|
|
+ }
|
|
+}
|
|
+
|
|
+}
|
|
+# end of proc {CheckDriverBind}
|
|
+
|
|
+
|
|
+# Check if USB ID is listed as needing driver binding
|
|
+proc {InBindList} {id} {
|
|
+
|
|
+set listfile /var/lib/usb_modeswitch/bind_list
|
|
+if {![file exists $listfile]} {return 0}
|
|
+set rc [open $listfile r]
|
|
+set buffer [read $rc]
|
|
+close $rc
|
|
+if [string match *$id* $buffer] {
|
|
+Log "Found $id in bind_list"
|
|
+ return 1
|
|
+} else {
|
|
+Log "No $id in bind_list"
|
|
+ return 0
|
|
+}
|
|
+
|
|
+}
|
|
+# end of proc {InBindList}
|
|
+
|
|
# Add USB ID to list of devices needing later treatment
|
|
proc {AddToList} {name id} {
|
|
|
|
@@ -791,6 +946,37 @@ close $lc
|
|
# end of proc {AddToList}
|
|
|
|
|
|
+# Remove USB ID from bind list (NoDriverLoading is set)
|
|
+proc {RemoveFromBindList} {id} {
|
|
+
|
|
+set listfile /var/lib/usb_modeswitch/bind_list
|
|
+if [file exists $listfile] {
|
|
+ set rc [open $listfile r]
|
|
+ set buffer [read $rc]
|
|
+ close $rc
|
|
+ set idList [split [string trim $buffer] \n]
|
|
+} else {
|
|
+ return
|
|
+}
|
|
+set idx [lsearch $idList $id]
|
|
+if {$idx > -1} {
|
|
+ set idList [lreplace $idList $idx $idx]
|
|
+} else {
|
|
+ return
|
|
+}
|
|
+if {[llength $idList] == 0} {
|
|
+ file delete $listfile
|
|
+ return
|
|
+}
|
|
+set buffer [join $idList "\n"]
|
|
+if [catch {set lc [open $listfile w]}] {return}
|
|
+puts $lc $buffer
|
|
+close $lc
|
|
+
|
|
+}
|
|
+# end of proc {RemoveFromBindList}
|
|
+
|
|
+
|
|
proc {CheckSuccess} {devdir} {
|
|
|
|
global config usb flags
|
|
--
|
|
2.7.4
|
|
|