http://www.draisberghof.de/usb_modeswitch/

USB_ModeSwitch - Activating Switchable 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.

Several new USB devices (especially high-speed wireless WAN stuff, there seems to be a chipset from Qualcomm offering 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 that (and on every consecutive plugging) this driver switches the mode internally, the storage device vanishes (in most cases), and a new device (like an USB modem) shows up. The WWAN gear maker Option calls that feature "ZeroCD (TM)".

As you may have guessed, nothing of this is documented in any form and so far there are no official Linux drivers available (with the notable exception of Option products). On the good side, most of the known devices work out of the box with the available Linux drivers like "usb-storage" or "usbserial" (in recent kernels quite a lot of devices are acknowledged by the "option" module). That leaves 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 does the switching, and to reproduce the same thing with Linux.

USB_ModeSwitch makes the last step considerably easier by taking the important parameters from a configuration file and doing all the initialization and communication stuff.
Starting from version 0.9.7 it has an optional success check which spares the manual call of "lsusb" to note any changes after execution. This comes at a price though: to work properly, the success check needs a system/device dependent delay to give the device time to settle after the switch. This delay is configurable, but it obviously prevents USB_ModeSwitch to return immediately. Thus it is mostly useful during testing.

Please read the information on this page carefully before you go around posting questions! This is no tool that does it all for you automagically (yet). It really helps to understand in principle what is happening, which in turn makes it easy to adapt the config file to your setup or even do your own exploring of new devices.

For hints about doing your own sniffing see paragraph Contribute below

Breaking News: just found this humble tool in the source code of the fine Dovado UMR router, which they publish in compliance with the GPL. So if you want the power of your Wireless Broadband across your local network, but without the "fun" of setting up your own Linux router (as I did), consider investing in such a machine.

Download

The latest release version is 1.0.5. The tar archive contains the source and a i586 binary (32 bit, GCC 4.3.2). I used libusb-0.1.12.

There are changes and updates to the config file more often than new releases; most of the valuable knowledge about devices is contained in this file. So you better use the latest version linked here.

  • Download usb_modeswitch-1.0.5.tar.bz2, dated from 2009-08-26; a Debian (Xandros/Ubuntu) package should be available soon at the Debian Repository. Many architectures are supported there (like amd64 or ia64).
  • Load the latest usb_modeswitch.conf; the default place is "/etc". Last updated 2009-08-26
  • Don't forget libusb if you don't have it. In your distribution, there is most likely a package named "libusb-dev" or "libusb-devel"

How to install

Unpack and run "make install". Edit "/etc/usb_modeswitch.conf" according to your hardware (it's heavily commented and should tell you what to do).

If you want to compile it for yourself, just delete the binary, then run "make" or type on the shell:

$ gcc -l usb -o usb_modeswitch usb_modeswitch.c
That's as easy as it gets. And it should be as portable as libusb itself (some limitations on FreeBSD based systems are known).

If installing manually, take the executable "usb_modeswitch" and put it into your path (preferably "/sbin" or "/usr/sbin").
Put "usb_modeswitch.conf" into "/etc" and don't forget to edit it.

Alternatively you can use the command line interface to tell USB_ModeSwitch the things it needs to know; try "usb_modeswitch -h" to list the parameters. This way you can handle multiple configurations. If any command line parameters except -W and -q are used, the default config file is NOT read.
For a command line parameter reference, you have to consult /etc/usb_modeswitch.conf at the moment. Until I decide to put up a fight with groff and provide a man page.

Important: USB_ModeSwitch - like all programs with libusb routines - has to be run as root. Otherwise strange error messages come up ...

How to use and to automate

If your device was switched successfully, there are three possible outcomes:
  1. It changed to a CDC ACM device and was recognized by the "cdc-acm" driver. If you run "dmesg", you should see that new device files were generated starting from "/dev/ttyACM0". These are your new serial ports to use, most likely the one with the lowest number.
  2. It changed to a serial device and was recognized by the "option" driver. If you run "dmesg", you should see that new device files were generated starting from "/dev/ttyUSB0". These are your new serial ports to use, most likely the one with the lowest number.
  3. It changed to a serial device, but no driver was loaded. If you run "dmesg", it says something of a "new fullspeed device" but nothing more happened. To use it immediately, you have to load the driver manually and tell it to bind to your specific device. You need the (new) target IDs for this. Enter in a terminal (as root!):
    # modprobe usbserial vendor=<YourTargetVendID> product=<YourTargetProdID>
    Run "dmesg" again and you should see the changes as in 2.
    The use of the generic usbserial module is discouraged by the Linux USB maintainers. Instead, new modems should have their IDs added to the "option" driver which is optimized for high speed wireless devices. If this has not happened yet for your device, you can still use this driver. There is a way to add new device IDs to it even after it was loaded:
    # modprobe -v option
    # echo "<YourTargetVendID> <YourTargetProdID>" >/sys/bus/usb-serial/drivers/option1/new_id
    Note that the IDs you give have no prepended "0x" (for example "0af0 6600") !!
Please note that further steps of using the modem to connect are outside the scope of this site. There is plenty of information on that subject, distribution-specific and in general.

Mind that you have to run USB_ModeSwitch every time you plug your device or boot with it. If you have "udev" in your distribution it's really not hard to automate this and just forget about it, once you figured how to switch your device manually.
>From version 1.0.3 onward, there is an option to install an integrated version which does almost everything automatically. If you encounter a new device it's easy to add.

Here is the manual way:

You should have a folder named "/etc/udev" or similar. Somewhere in there (I have a folder "rules.d") you find some files with the extension ".rules". Create a new one (or edit an existing one, but by convention not the default "50-something.rules"). I chose one named "45-hotplug.rules" since hotplugging is what USB is about after all.
In the chosen/new file add the line

SUBSYSTEM=="usb", SYSFS{idProduct}=="<YourDefaultProdID>", SYSFS{idVendor}=="<YourDefaultVendID>", RUN+="<YourPathToUSB_ModeSwitch>"
That's basically it.

From here, there are several ways to continue. If your GSM device is recognized by a recent version of the "option" driver you shouldn't have to do anything but to load the module (most certainly handled by udev automatically). Some devices switch to the ACM class and are bound to the module "cdc-acm" ("USB Abstract Control Model driver for USB modems and ISDN adapters"). The created serial devices are named "ttyACM0", "..1", etc. instead of "ttyUSB0" ...
If your (serial) device works with "usbserial" as described above, you can as well add the "echo" line (see above as well) to a script and run it after a certain settling time. This gives you "option" driver support without fiddling around with the kernel source.

As for the difference between "usbserial" and "option", here is a quote from option.c:

  This driver exists because the "normal" serial driver doesn't work too well
  with GSM modems. Issues:
  - data loss -- one single Receive URB is not nearly enough
  - nonstandard flow (Option devices) control
  - controlling the baud rate doesn't make sense

Devices supported by the "option" driver that don't change their IDs after switching might run into problems because of the driver trying to attach before the switching happened. In this case it could help to blacklist it and to load it manually via the helper script after execution of usb_modeswitch. In newer kernels (definitely in 2.6.28) this problem is handled by probing for the device class before binding.

Known working hardware

Very important note:
Personally, I could only test my Option Icon and the S.E. MD400; the list here - as well as all the necessary data - relies on reports from third parties (people, that is). So don't be surprised if you hit sudden obstacles even with your device listed here. You have been warned.

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. actively removing (rather detaching) the storage driver from the device
3. sending a certain control message to the device

  • All Option devices
    All known Option devices use the USB storage command REZERO UNIT for switching (inherited from SCSI). Older devices change vendor and product ID, newer ones don't (just their device class). These newer sticks have a special interface after switching (HSO) for which there is a special driver. Some older devices are able to be loaded with the new HSO firmware which changes their behaviour.
    Note: for HSO driver questions and HowTos consult the fine Pharscape site!
    If you have a newer Option device not listed here there is a good chance to get it working by using any HSO driven device entry and just adapting your vendor/product ID.
    There is a switching routine for Option devices in the kernel driver usb-storage (since beginning of 2009). It works only for devices entered in "unusual_devs.h". More to that below.
  • Option GlobeSurfer iCON (aka "Vodafone EasyBox")
    The thing that started it all, because I wanted it to work on my Linux router.
  • Option GlobeSurfer iCON 7.2
    If you get hardware lockups of this thing when plugging in (flashing LEDs), update the firmware. You can probably update it to the new HSO interface
  • Option GlobeTrotter HSUPA Modem (aka "T-Mobile wnw Card Compact III")
    HSO interface
  • Option GlobeTrotter GT MAX 3.6 (aka "T-Mobile wnw Card Compact II")
  • Option GlobeTrotter EXPRESS 7.2 (aka "T-Mobile wnw Card Express II")
  • Option GlobeTrotter GT MAX "7.2 Ready"
  • Option iCON 210
    Not sure if this is a generic Option design (see PROLiNK A600)
  • Option iCON 225 HSDPA (aka "T-Mobile web'n'walk Stick")
    HSO interface
  • Option iCON 401 and AT&T Quicksilver
    HSO interface; has additional Micro SD.
    The Quicksilver looks exactly like the 401 but the product ID is different.
  • Vodafone K3760 (an Option device, original name yet unknown)
    HSO interface
  • All Huawei devices
    We have two options (no pun intended!) for Huawei devices: 1. detaching of "usb-storage" 2. the special control message found by Miroslav Bobovsky. The latter is independent of "usb-storage" and even leaves the storage portion of the device functional. Both methods leave other USB storage devices alone (compared to removing the storage module completely, which works as well).
    Newer kernels try to switch Huawei devices from the driver (special treatment in usb-storage), which does not seem to work all the time. Read last paragraph of Troubleshooting
    If you have a more recent Huawei device not listed here, just try and adapt your vendor/product ID. The switching method is the same for all known devices so far.
  • Huawei E220 (aka "Vodafone EasyBox II", aka "T-Mobile wnw Box Micro")
  • Huawei E160, Huawei E160G, Huawei E169, Huawei E180, Huawei E230, Huawei E270, Huawei E270+, Huawei E280, Huawei E1550, Huawei E1692
  • Huawei E630
    There are reportedly modem-only variants around (without the storage part); for these no switching is required.
  • Novatel Wireless Ovation MC950D HSUPA, Ovation 930D and Merlin XU950D
    They use the USB storage command START/STOP (Eject) for switching. Should switch with "eject <cd device>" as well
  • Novatel Wireless U727, Novatel Wireless U760
    Similar setup as the MC950D, different product IDs
  • Novatel MC990D
    Uses new feature of 0.9.5
  • All ZTE devices
    Some ZTE devices can be switched by issueing the "eject" command to the "CD-ROM" device as well.
    Please read the last paragraph in Troubleshooting!
  • ZTE MF620 (aka "Onda MH600HS")
    Uses the USB storage command TEST UNIT READY for switching.
  • ZTE MF622 (aka "Onda MDC502HS")
    Detachment of storage driver
  • ZTE MF626, ZTE MF628, ZTE MF628+
  • ZTE MF636 (aka "Telstra / BigPond 7.2 Mobile Card")
  • ZTE MF638 (aka "Onda MDC525UP")
  • ZTE AC8710, ZTE AC2710 (EVDO, featured by PTCL)
  • ZTE 6535-Z (featured by SFR)
  • ZTE K3520-Z
  • ONDA MT503HS (most likely a ZTE model)
  • ONDA MT505UP (most likely a ZTE model)
  • Alcatel One touch X020 (aka OT-X020, aka "MBD-100HU", aka "Nuton 3.5G", works with "Emobile D11LC")
  • Alcatel One touch X030 (aka OT-X030, aka "Nuton NT36HD")
  • Alcatel X200
  • AnyDATA ADU-500A, AnyDATA ADU-510A, AnyDATA ADU-510L, AnyDATA ADU-520A
  • BandLuxe C120
    Special treatment reportedly necessary. See Forum Entry
  • Solomon S3Gm-660
    Same notes apply as with the BandLuxe C120 above
  • C-motech D-50 (aka "CDU-680")
    Important notes at this Forum Entry
  • C-motech CGU-628 (aka "Franklin Wireless CGU-628A" aka "4G Systems XS Stick W12")
  • Toshiba G450
  • UTStarcom UM175 (distributor "Alltel")
  • Hummer DTM5731
  • A-Link 3GU
  • Quanta MU-Q101, also referred to as "Quanta (NU) MU-Q101"
    You probably need to do the "power suspend" trick (see Troubleshooting) to make it usable
  • Sierra Wireless AirCard 881U (most likely 880U too)
    Supported by newer kernels. If you are stuck with an older one, use this
  • Sierra Wireless Compass 597
    Supported by newer kernels. If you are stuck with an older one, use this
  • Sony Ericsson MD400
    Special handling, takes around 25 seconds to switch
  • LG LDU-1900D EV-DO (Rev. A)
  • Samsung SGH-Z810 USB (with microSD card)
  • MobiData MBD-100HU, MobiData MBD-200HU
  • MyWave SW006 Sport Phone/Modem Combination
  • Hyundai Mobile MB-810
    Same parameters as Option iCON 210
  • PROLiNK PHS100 (various looks)
    Same parameters as Option iCON 210
  • Cricket A600
    Switches to ACM device. Might need a ResetUSB after switching - or not
  • EpiValley SEC-7089 (featured by Alegro and Starcomms / iZAP)
  • ST Mobile Connect HSUPA USB Modem

Troubleshooting

Note: if you still need support after having followed the advice on this page, please use the forum!

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. Almost all distributions today are using "udev" as a device and hotplug manager, and in some cases this daemon is not able to "release" the established connection of a switched device and to see it as a freshly plugged one (after all, this is something outside the USB specs).

There are several ways to analyze and tackle these problems:

  • To see what udev is doing, run udevmonitor in one console and watch what happens if you plug the device and run USB_ModeSwitch. "lsusb" and "dmesg" can give additional information
  • If you suspect timing issues, try to run USB_ModeSwitch with a defined delay after plugging
  • Find the device's sysfs access. It's in the file system under /sys/bus/usb/devices. "dmesg" tells you what bus address it got after plugging; should look like "1-2" or "2-4" or similar. Then - after doing the switch - set it's power level to suspend mode. For example like this:
    $ echo suspend > /sys/bus/usb/devices/1-2/power/level
    Mind that the USB powersaving option must have been configured in your kernel. Thanks to mixmaxtw for this neat trick
  • Try the ResetUSB option with your device. This is somewhat brutal and may also reset an internally switched device back to storage mode
  • Sometimes it is recommended to use the latest firmware available as there have been issues in the past with at least one device (Icon 7.2, resolved now). In other cases devices have stopped working with the usb-serial driver after a firmware update. So the advice is simple: update if not working, otherwise leave alone

Kernel related issues

In newer kernels, some device families (Huawei, ZTE since 2.6.26) get a special treatment in the usb-storage code to enable switching right away. You don't even need USB_ModeSwitch anymore; 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 obviously brought no results and even 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.
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 mounted). The default value is 5; this might affect the switching result in some way, especially when using an udev rule. I'd be interested to learn about good or bad results of playing around with it.
Add in /etc/modprobe.conf:
options usb-storage delay_use=1 (or 10, or other)

Kernel Support

Standby for more content ...

Contribute

USB_ModeSwitch comes quite handy for experimenting with your own hardware if not supported yet. You could 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 try spying out the USB communication to the device with the same ID inside M$ Windoze.
I recommend this tool: "SniffUSB" (http://www.pcausa.com/Utilities/UsbSnoop/default.htm).

This is the extremely 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 know about a new device configuration you can also send me an old-fashioned - and at your demand confidential - e-mail (see below).

Whodunit

Copyright (C) 2007, 2008, 2009
  • Josua Dietze (usb_admin at this domain)
Please use the forum for support questions! For personal/confidential messages mail me directly.

Other contributors

Command line parsing, decent usage/config output and handling, bugfixes added by:
  • Joakim Wennergren (jokedst) (gmail.com)
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:
  • Aki Makkonen
  • Denis Sutter
  • Lucas Benedičič
  • Roman Laube
  • Luigi Iotti
  • Vincent Teoh
  • Tommy Cheng
  • Daniel Cooper
  • Andrew Bird
More contributors (device specific) are listed in the config file. Thanks to everyone at the forum too!

History

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




Reply via email to