No ads - but links to sites I deem valuable and important:
stop-overpopulation.org - Life could be so good if there'd be fewer of us ...
metabunk.org - Remove the bunk from scary claims

This site is powered by Greenpeace Energy; for details see the provider's page

 

USB_ModeSwitch - Handling Mode-Switching USB Devices on Linux

 
Version française içi - merci au Bullteam

If you don't like the text column width, adjust your browser window

Introduction

USB_ModeSwitch is (surprise!) a mode switching tool for controlling "flip flop" (multiple device) USB gear.

More and more USB devices (especially high-speed WAN stuff, based on cell phone chipsets containing that feature) have their MS Windows drivers onboard; when plugged in for the first time they act like a flash storage and start installing the driver from there. After installation (and on every consecutive plugging) the driver switches the mode internally, the storage device vanishes (in most cases), and a new device (like an USB modem) shows up. Modem maker "Option" calls that feature "ZeroCD (TM)" since it eliminates the need for shipping a separate driver carrier.

In the beginning, nothing of this was documented in any form and there was hardly any Linux support available.
On the good side, most of the known devices do work in both modes with the available Linux drivers like "usb-storage" or "option" (an optimized serial driver for high-speed modems).
That leaves only the problem of the mode switching from storage to modem or whatever the thing is supposed to do.

Fortunately there are things like human reason, USB sniffing programs and "libusb". It is possible to eavesdrop the communication of the MS Windows driver, to isolate the command or action that triggers the mode switching and to reproduce the same thing under the rule of Linux or the BSD variants.

USB_ModeSwitch makes this process easy to handle by taking the important parameters from a configuration file and doing all the initialization and communication stuff, with heavy help from "libusb".
It is mainly used automatically - via udev events and rules - to do the switch without any user interaction. But it can also be run as a command line tool, usually when trying to make unknown devices work with it.

This tool is part of most major distributions; you should not be having to install from the source packages here unless you run into problems and need the latest version.

 

Please read the information on this page carefully before you go around posting questions! If you encounter a new device, it really helps to understand the principle of what is happening, which in turn makes it easier to find out about the switching command and to add a new config entry.

For hints about doing your own sniffing see paragraph Contribute below.

Download

The latest release version is 1.2.3. The tar archive contains only the source. I used libusb-0.1.12 but the "compat" library from libusb-1.0 is working too.

Important: you need the data package as well !!
Changes and updates to the configuration data may happen more often than new releases; most of the valuable knowledge about devices is contained in these files. That's why it is provided separately.

Upon a recent request I provide a static binary for ARM: usb_modeswitch-1.1.9-arm-static.bz2.
The compiler was gcc (arm-none-linux-gnueabi 3.4.4) with no special settings. Libusb 0.1.12 is compiled in.

If you are a system integrator (package maintainer) you can use this XML file to check for new releases:
usb-modeswitch-versions.xml.

How to install

If you have an earlier version installed, de-installation is recommended ("make uninstall"). Several file locations changed in 1.1.0, old ones might be orphaned if not taken care of. If you have a version after 1.1.0 you can just update and overwrite all existing files.

Unpack the source file of the program (who might have thought!). In the newly created directory run as root or superuser:

# make install
This installs a small shell script for udev, the larger wrapper script, a config file, the man page and the freshly compiled binary.
Important: if you install this way, you will need the "tcl" package for the large dispatcher script. There are more ways to install which do not depend on that package. Refer to the included README for further install options !

Now do the same procedure for the data package. It will install the config files in "/usr/share/usb_modeswitch" and the udev rule file in "/lib/udev/rules.d". The earlier "/etc/usb_modeswitch.d" is now reserved for custom config files (new or changed).
You are set already; if your device is known, you should be able to just plug it and use it. If it doesn't work right away we'll find out why.

For manual use just install the program. Work with the command line interface or use a custom config file. The "device_reference" file (see "Download") is a good starting point to create your own configuration. It is heavily commented and should tell you what to do.
Your custom config file can have any name and place; just tell usb_modeswitch how to find it with the -c parameter.

Manual use is intended for testing and analyzing. See next paragraph.

How to use

In most cases, you will be able to use your device without any interaction except plugging it in.

If you think your device is supported, but things are not working out as they should, turn on logging first as described in Troubleshooting.

For testing, debugging and taming new devices from the wild, you can use the binary part of USB_ModeSwitch in manual mode.
There are two ways for that: using a config file or using the command line.

Run "usb-modeswitch -h" to list the command line parameters. If any of them except -W, -D, -I and -q are used, a config file given with -c is ignored and all mandatory parameters have to be provided on the command line. See also the included man page.

To work with a config file, use one of the little files in "/usr/share/usb_modeswitch" or create one yourself. Then give the path and file name to usb_modeswitch with the -c option. You also can have a look into the device_reference.txt for hints about model families and an explanation of the parameters.

Important: USB_ModeSwitch - like all programs using libusb - has to be run as root (or with "sudo") when calling it manually. Otherwise strange error messages turn up and things won't work. When trying out switching commands and strategies, it's probably easier to work at a root shell for a while ("sudo bash" or "su -").

The automatic approach consists of several components working together, listed in the logical order of usage:

After switching and driver-loading, it is the responsibility of the system to discover the new (mostly serial) device.

When dealing with wireless devices, there may be issues with NetworkManager (or its ModemManager component) which up to now may run into touble when trying to auto-detect a proper modem port.
Good results were reported by working with wvdial, UMTSmon and several tools providing a user interface to PPP like kppp; some of these programs may require a bit of basic knowledge though.

There is also a new - unusual but intriguing - concept which shortcuts the tedious path of putting together all components for a successful wireless broadband connection. The Sakis3G tool is a self-containing script (including among others the latest USB_ModeSwitch binary). It supports quite a number of providers already and is rapidly expanding. The beauty of it is that no installation is necessary and only a minimum of input required. Contrary to NetworkManager, it really delivers.
Check it out at Sakis' blog ToDo Forever. There is even a HowTo for setting it up so that it connects right away when a modem is plugged in.

The main hurdle for NetworkManager and others to a fully automated use of a newly switched modem is to find the right port for connecting. Often more than one serial port is created after switching (even up to five). Generally, not all of them are really standard serial (the driver can't decide), some may look like it and even accept AT commands, but usually the right one is providing an interrupt transfer endpoint. Unfortunately, NetworkManager does rely on other ways of probing for the correct port and sometimes fails. It is worth to note that the said Sakis3G tool is able to find this port quite easily.

Starting from version 1.1.2, usb_modeswitch will add a symbolic link to the correct port with interrupt transfer if the device provides standard serial ports. The link will have the name /dev/gsmmodem, with a number appended if more than one device is attached.
You can use this name with connection helpers like wvdial. Note that in many cases you may have to edit the configuration file manually.

If you managed to get a new or badly supported device to switch correctly in manual mode, you can add a udev rule and a config file yourself. But please report it back to share it !!

See Contribute.

Known working hardware

Very important note:
Personally, I could not test the vast majority of supported devices; the list here - as well as the necessary data - relies on reports from third parties (people, that is). So it may happen that you hit sudden obstacles even with your device listed here.
That said, the user base of this little tool has grown considerably, so that any data related problems are generally surfacing quite soon.

There are hitherto three known methods for initiating the switching process:

  1. sending a rarely used or seemingly weird standard storage command (equivalent to those of SCSI) to the storage device ("eject" for example)
  2. sending one or more vendor-specific control messages to the device
  3. actively removing (detaching) the storage driver from the device (only some early devices)

Again, if you don't find the name of your device in the list, it may still be supported.
The important thing is that you find your device's USB ID in the config file folder. Have a look into the latest data package (See Download).

Here is the list of devices, together with the respective contributors:
device_reference.txt.

Troubleshooting

Note: if you still need support after having followed the advice on this page, please use the forum! E-mail may be used for device/config contributions.

Known issues:

For debugging of the automated system integration, edit (as root or su) /etc/usb_modeswitch.conf in a text editor and change the line

 EnableLogging=0
to
 EnableLogging=1
This gives you a verbose output of the hotplug activity to /var/log/usb_modeswitch_<device>.

If you're next to certain that you have the right values for your device, followed all the hints (see Known working hardware), and USB_ModeSwitch seems to do something run after run but to no effect, there are most likely system issues involved.

The first suspects are existing system rules for modems which handle things not quite correctly.
If you own a device with the unswitched ID of 05c6:1000, it may get a wrong switching command in older systems. There are four different types of switching devices, all with that same ID; in the big distributions they were all treated alike as a model from "Option" (the manufacturer) which is wrong in four out of five cases. There are even cell phones with that ID which wrongly get the same treatment when connected to an USB port.

To fix problems like that you can try to remove rules files from "/lib/udev/rules.d" which contain calls to "modem-modeswitch".
USB_ModeSwitch will do additional checks beside the USB ID and treat all known ambiguous devices in the right way. For example, it will leave unknown devices with the 05c6:1000 ID alone.

Annother notorious candidate is again 19d2:2000. It may be switched O.K. by an existing rule, but there is no driver loading if your model is new and its ID is not yet added to the "option" module.
Disable the rule running "eject" and the ID will be handled by usb_modeswitch.

Kernel related issues

In some newer kernels, certain devices (some Option, some Huawei, some ZTE as mentioned above) get a special treatment in the usb-storage code to enable switching right away. You would not need USB_ModeSwitch anymore for these specific devices; on the other hand you have no choice of accessing the "CD-ROM" part of your device. Plus, there were cases when the special treatment brought no results and furthermore prevented USB_ModeSwitch to work properly afterwards (happened with ZTE devices, error "-2").

In case of trouble, look into "unusual_devs.h" in the "drivers/usb/storage" folder of your kernel source. If your default ID (vendor and product ID of the storage part) can be found there and you get errors when running USB_ModeSwitch, try first to blacklist "usb-storage".
If that helps, you should consider rebuilding your kernel with the entry in "unusual_devs.h" deactivated. The only thing that will happen is that usb-storage works in the default way afterwards.
I found a tip in the Russian Gentoo wiki to do exactly what I just suggested for the ZTE MF626.
By the way, at one point there was an agreement among USB developers to keep all future mode switching code out of the kernel drivers if the neccessary steps can be taken in "user space".

Annother way of influencing the kernel behaviour is the parameter "delay_use" of "usb-storage" which sets the time in seconds after plugging when the storage device will actually be used (and probably automounted). The default value is 5; this might affect the switching result under certain conditions.
To change the default add in /etc/modprobe.conf:

 options usb-storage delay_use=1 (or 10, or other)

Old systems (e.g. CentOS 5 or Xandros 6)

If you are running a not-quite-fresh system (with a kernel below 2.6.27), you may run into incompatibilities between versions of "udev", the device manager. If you get no indication of the usb_modeswitch components doing anything at all (no log files), follow these steps:

Contribute

USB_ModeSwitch comes quite handy for experimenting with your own hardware if not supported yet.
The first step would be to try widely used switching methods from known devices, like the "eject" sequence found in the BandLuxe configuration "1a8d:1000". If you have a hint that your device may be made by Huawei originally, try the sequence from "12d1:1446".
Don't worry, it's almost impossible to break anything by experimenting with possibly wrong sequences. Just make sure you re-plug your device after each attempt!

If all this has no effect you can try this approach:
Note the device's Vendor and Product ID from /proc/bus/usb/devices (or from the output of "lsusb"); the assigned driver is usually "usb-storage". Then spy out the USB communication to the device with the same ID inside M$ Windoze, with the on-board driver installed. The device must be switched there too, and you want to log that moment.
I recommend this tool: "SniffUSB" ( http://www.pcausa.com/Utilities/UsbSnoop/default.htm).

This is the short version. There is a very good case example from Mark A. Ziesemer here:
Alltel UM175AL USB EVDO under Ubuntu Hardy Heron

Please post any improvements, new device information and/or bug reports to the ModeSwitchForum !
If you don't need support you can also send me an old-fashioned - and at your demand confidential - e-mail (see below).

Whodunit

Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 Please use the forum for support questions! For other messages like tested new device configurations or personal/confidential stuff you can mail me directly.

Other contributors

Command line parsing, decent usage/config output and handling, bugfixes added by: TargetClass parameter implementation to support new Option devices/firmware: Created with initial help from: Config file parsing stuff borrowed from: Hexstr2bin function borrowed from: Code, ideas and other input from: More contributors (device specific) are listed in the device_reference.txt. Thanks to everyone at the forum too! Sometimes it takes a considerable reservoir of patience on the road to success ...

History

Version 1.2.3, 2012/01/28
Fixed two bugs both causing the embedded-jimsh install variant of the dispatcher crash (the "pure-script" install variant was NOT affected); fixed some "regexp" incompatibilities with Debian's libjim
Version 1.2.2, 2012/01/19
Fixed bad bug preventing mode switch for devices using TargetClass; improved logging in case of negative success check
Version 1.2.1, 2011/12/26
Fixed possible ambiguities when multiple identical modems are plugged synchronously; this is achieved by adding -b and -g parameter (busnum and devnum) for proper id'ing; some resulting workflow changes and shortcuts in "system integration" mode (use sysfs/wrapper for success control, reduce informative checks); improved hub usage robustness; future data packages can be ridded of redundancies (default ID, success check parameters), resulting in smaller files; fixed bad bug which may prevent switching completely when logging is not activated; fixed possible overflow in dispatcher C code (thanks to Gilles Espinasse)
Version 1.2.0, 2011/10/23
Added QisdaMode for Qisda H21 (thanks to Chi-Hang Long for the code); dispatcher can now be installed with an embedded interpreter, so that Tcl is no longer required; added command line options for binary program to accept configuration data via stdin or as a long string parameter - this fixes the bug with non-writable temporary file during boot; reversed skipping of pre-switching delay, which has caused problems; fixed potential buffer overflow (thanks to Rafael Silva for the find); get first interface right even on some broken devices (thanks to Alexander Gordeev for the patch); increased post-switch delay before driver binding to avoid possible conflict with usb-storage
Version 1.1.9, 2011/08/05
Added CiscoMode for Valet device; additional checking for CDC ACM device to prevent erroneous driver loading after switching; no more post-switch check for access to initial device if target parameters are given
Version 1.1.8, 2011/06/19
Cleaned up switchSendMessage(); added workaround for quirky devices not reporting configuration setting; added non-CSW response for arbitrary bulk transfers; added SequansMode and MobileActionMode; check for active configuration will be skipped if bNumConfigurations is 1 (most cases)
Version 1.1.7, 2011/02/27
Attention: paths for runtime files and database have changed! Old places will be found but are deprecated; /usr/share/usb_modeswitch for database, /var/lib/usb_modeswitch for "remembered" IDs;
fix for configuration setting race (thanks to Amit Mendapara); discovered incompatibility between Tcl versions <= 8.3 and >=8.4, so 8.4 is the minimum prerequisite now;
first availability of an alternative source pack which includes "jimsh", a fast Tcl mini shell, intended for resource-constrained systems
Version 1.1.6, 2010/12/22
Moved warm-boot driver binding to sh wrapper, was unreliable in 1.1.5; sh wrapper overhaul, made compatible with Ubuntu's "dash" shell, tclsh calls reduced further; initial device checking includes current "bConfigurationValue" now, should work with config setting for multiple devices; made tcl script conform to limitations of "jimsh", the minimal tcl shell (hint from Barry Kauler); fixes for "usbserial" fallback (driver binding for old systems); in the C program, changed parameter "MessageDelay" (hitherto unused) to "ReleaseDelay", to be used in one device configuration (delay interface release after bulk message sending)
Version 1.1.5, 2010/11/28
Added special control message for Kobil devices (patch from Filip Aben); try to get active configuration for interface class checking (there are some new devices 'switching' via configuration selection); fixed "0000" target product ID - again; new bash and tcl wrapper logic: the convenience functions for driver binding and symlinking will now start the tcl shell ONLY for known devices; changed and appended logging capabilities of said convenience functions; added loading of "usbserial" as a fallback for older systems to support new devices; add workaround for bug in libusb1 which affects device search during success check
Version 1.1.4, 2010/08/17
The package should work at boot time now (cold and warm); product IDs of "0000" do exist but were not accepted, fixed (thanks to Sakis Dimopoulos); response endpoint is now always detected (led to possible error report when resetting all endpoints in version 1.1.3); wrapper script can now work with a packed collection of config files as well as with the plain folder of files; use with the "install-packed" make target of the data package (for use on systems with resource constraints); wrapper fix for the symlink feature: handling of multiple interrupt ports was incomplete; wrapper does not longer use a temporary file for the symlink feature (security considerations, Marco d'Itri)
Version 1.1.3, 2010/06/21
Added delay option to separate multiple message transfers by millisecs; fixed (possibly dangerous) sloppy string handling (thanks to Christophe Fergeau); added "clear_halt" for response endpoint; small additions in Makefile (install with -D); changes in option handling (no more default config file!) and help text; symlink feature in wrapper can now cope with devices providing more than one interrupt port; wrapper now ignores package manager leftovers in config folder; replaced bash-specific syntax in wrapper; changed ZTE skipping (if existing rules are found) to warning
Version 1.1.2, 2010/04/18
Attention: data package now separated from program package! Add support for two additional bulk messages (for Pirelli devices); wrapper handles special ZTE case; generalized driver loading, new parameter "DriverModule" and "DriverIDPath"; new wrapper facility to add symlink pointing to interrupt port (used in rule file from data pack >= 20100418)
Version 1.1.1, 2010/03/17
Attention: old usb_modeswitch.conf renamed to usb_modeswitch.setup! Add separate config file for wrapper (global settings for switching and logging); add config file option to disable driver loading; handling of kernel attribute AVOID_RESET_QUIRK added; bug fixed in SonyMode (reported by "no-0n3"); bug fixed in SuccessCheck logic; minor flow alignments and fixes; new devices
Version 1.1.0, 2010/01/24
Attention: wrapper script location changed, uninstall old versions! Major fixes in the wrapper script (stabilizing and time-saving); back to unified installation, defaults to "integrated" approach; new -D parameter to enable "integrated" behaviour; bugs fixed in success check; man file included (borrowed from the Debian package); C code and binary works with the compat library from libusb-1.0; some new devices
Version 1.0.7, 2010/01/06
Bug fixed for Sony mode, thanks to Marco Chiaranda; fix for parameter substitution in newer udev versions, fix for bad bug in wrapper script practically disabling automatic mode
Version 1.0.6, 2009/12/21
New "GCT Mode", fixes for device quirks (NXP Dragonfly), fix for multiple Huawei devices, cleanups, loads of new devices in config file and database, minor tcl script changes
Version 1.0.5, 2009/08/26
More changes and fixes regarding success check; "--version" option; config "database" updated
Version 1.0.4, 2009/08/23
    Success check bugs (and others) fixed
Version 1.0.3, 2009/08/20
Success check improved; experimental system integration (fully automated), optional; new parameter "TargetProductList" needed for this; other necessary small adaptations; more devices
Version 1.0.2, 2009/06/09
    Some output bugs fixed
Version 1.0.1, 2009/06/08
    Added output of descriptor strings for further identification
Version 1.0.0, 2009/06/03
Attention: possible incompatibilities for command line control! On/off flags don't require arguments anymore (-H, -S, -O, -d, -R, -n, new: -I), meaning "-R 0" does a reset like "-R 1" or "-R"; long option names changed to standard format (e.g. --HuaweiMode to --huawei-mode); added device inquiry, for future help with device identification; catch error -19 as possible success; send and response endpoints now autoselected (consequently NeedResponse is back); code cleanup; new devices
Version 0.9.7, 2009/04/15
    Updated SonyMode, MD 400 now stable; automatic default endpoint detection from Andrew Bird
Version 0.9.7beta, 2009/03/15
    Major code clean up, optional success control (both suggested by Daniel Cooper), new devices
Version 0.9.6, 2009/01/08
    Special modes added for Sierra and Sony Ericsson, new devices
Version 0.9.5, 2008/10/27
    New options for USB tuning added (jokedst), lots of new devices, clean up
Version 0.9.4, 2008/06/09
    Compat fix for libusb on FreeBSD quirks, more devices
Version 0.9.4beta2, 2008/03/19
    Udev 'release' fix
Version 0.9.4beta, 2008/03/16
    Multiple device support
Version 0.9.3, 2008/03/09
    More devices, no other changes from 0.9.3beta
Version 0.9.3beta, 2007/12/30
    New TargetClass parameter for recent Option firmware (Paul Hardwick), more devices
Version 0.9.2, 2007/11/02
    New Huawei mode (code from Miroslav Bobovsky, added by Denis Sutter), more devices
Version 0.9.1beta, 2007/09/11
    Added command line parsing (jokedst), cleaned up config stuff (jokedst), bug fixes, doc updates
Version 0.9beta, 2007/08/12
    Name change from "icon_switch", parameter file and generalizing
Version 0.2, 2006/09/25
    Code cleaning, more messages
Version 0.1, 2006/09/24
    Just very basic functionality ...

Legal

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details:
http://www.gnu.org/licenses/gpl.txt

Page last revised: 2012-01-28