26

I know that this topic has been discussed many times, but none of the answers helped me. For the record, i'm running Debian.

The deal is: I bought an usb powered led lamp, which is very simple and doesn't even have an on/off switch (it works and is always on). I want to be able to turn it on/off via command line. Here's what i tried:

    echo on > /sys/bus/usb/devices/usb1/power/level       # turn on
    echo suspend > /sys/bus/usb/devices/usb1/power/level  # turn off

which is what i've found on many forums. Turning "on" works, but "suspending" yields

    -su: echo: write error: Invalid argument

for every usbN. I also tried

    echo "0" > "/sys/bus/usb/devices/usbX/power/autosuspend_delay_ms"

which doesn't give an error, but also doesn't do anything (again, for every usbN)

trying

    echo "usb1" > /sys/bus/usb/drivers/usb/unbind

works only for more "inteligent" devices, like the keyboard, the mouse, or the usb wifi card. What i mean is that only tyhose devices are turned off, other usbN don't give an error, but the lamp never goes off.

the contents of /sys/bus/usb/devices/ are

    1-0:1.0 1-1:1.0 1-2:1.0 1-2:1.2 2-0:1.0 4-0:1.0 4-1:1.0 6-0:1.0 8-0:1.0 8-2:1.0 usb2 usb4 usb6 usb8
    1-1 1-2 1-2:1.1 1-2:1.3 3-0:1.0 4-1 5-0:1.0 7-0:1.0 8-2 usb1 usb3 usb5 usb7

i tried to do

    echo device_name > /sys/bus/usb/drivers/usb/unbind

with every single one of them, but only the devices usbN and N-M react, the ones of the form n-m:x.y yield

    tee: /sys/bus/usb/drivers/usb/bind: No such device

(i tried putting in, for instance, "1-0:1.0", "1-0\:1.0" and "1-0\:1.0", all gave the same result).

One last thing, what is shown after executing

    lsusb -t

does not change when i plug or unplug the lamp.

Any ideas?

Arnestig
  • 2,285
  • 18
  • 30
user2772761
  • 261
  • 1
  • 3
  • 3

3 Answers3

27

Turn off device ID 2-1:

echo '2-1' |sudo tee /sys/bus/usb/drivers/usb/unbind

Turn device ID 2-1 back on:

echo '2-1' |sudo tee /sys/bus/usb/drivers/usb/bind

In my case, using device ID 2-1 controls power to my usb stick, and as a consequence controls the light.

  • TIP: If they work for you in Debian, create an alias for them to make life easier for you later.

Hope this helps, Su

N8TRO
  • 3,348
  • 3
  • 22
  • 40
user3534136
  • 271
  • 3
  • 3
  • Very nice, but exactly where in the startup sequence should I place this command, if I would like to permanently disable a device/port this way? For instance, I would like to permanently disable the built-in webcam, and always have the user-plugged-in webcam become /dev/video0 . – Douglas Held Nov 25 '14 at 19:27
  • 3
    How do you identify which device ID controls what? – Cheetaiean Aug 17 '21 at 16:45
  • @Cheetaiean `lsusb` to get the hex value for vendor/product you need. Then: ``` for DIR in $(find /sys/bus/usb/devices/ -maxdepth 1 -type l); do if [[ -f $DIR/idVendor && -f $DIR/idProduct && $(cat $DIR/idVendor) == $VENDOR && $(cat $DIR/idProduct) == $PRODUCT ]]; then DEVICE=$(basename $DIR) echo $DEVICE > /sys/bus/usb/drivers/usb/unbind done ``` – erwin Jul 21 '22 at 06:56
  • @erwin, would you care to elaborate what your script snippet was supposed to do? It gives syntax error and I cannot grasp its basic idea because am not familiar with all that /sys filesystem let alone totally over-engineering way of how USB is structured. – Van Jone Apr 18 '23 at 07:28
  • @VanJone sorry about that, there is a missing `fi` before the done... I've posted my whole script as a gist so the formatting is readable: https://gist.github.com/erwin/a66a4c3f8a5d940ab6c434b48568ff39 – erwin Apr 18 '23 at 15:45
12

If all you want to do is reset a USB device to fix it once it gets into a broken state, then using the bind/unbind usbfs special files can be a bit of a pain (since device IDs can change, and they're a bit tricky to identify precisely if you don't want to rebind other devices). In this case I've found it much easier to use the vendor and product IDs given by lsusb with usb_modeswitch. For example, if I identify my wireless adapter using:

$ lsusb
Bus 001 Device 042: ID 7392:7811 Edimax Technology Co., Ltd EW-7811Un 802.11n Wireless Adapter [Realtek RTL8188CUS]
Bus 001 Device 035: ID 0409:005a NEC Corp. HighSpeed Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

I can then reset the wireless adapter using:

$ sudo usb_modeswitch -v 0x7392 -p 0x7811 --reset-usb

If you have more than one device attached with the same vendor and product IDs then usb_modeswitch provides bus and device number flags. For the wireless adapter example above I'd add -b 1 -g 42 to the flags.

jwatt
  • 860
  • 10
  • 8
  • 2
    This was the only method that worked for me on Ubuntu (12.04 LTS) for restarting my USB Wireless adapter that wasn't re-connecting after suspends. Thanks! – yaraju Aug 05 '15 at 03:15
  • The usb_modeswitch method didn't work for me with a problematic USB dongle modem - it normally comes up as /dev/ttyUSB0, 1 and 2, but after the usb_modeswitch reset it came back as /dev/ttyUSB1, 2 and 3 which broke the hardcoded association in /etc/ppp/peers/. I find I need a pause of around 10-15 seconds between unbind and bind to avoid this. – kbro Jan 25 '16 at 17:42
  • If the system isn't detecting something like a USB wireless adapter at startup this method doesn't work as there is not such device to reset (the output of the command is "No devices in default mode found. Nothing to do. Bye!"), but obviously this method has it's own use cases. – Tedpac Apr 14 '23 at 23:02
0

Try this code it works for me (Only for rooted)

 String[] cmdline = { "su", "-c", "echo '1-1' >/sys/bus/usb/drivers/usb/unbind" };
try {
    Runtime.getRuntime().exec(cmdline);
} catch (IOException e) {
    Log.e("MainActivity","Failed"+e);
}

and for bind again do this

    String[] cmdline = { "su", "-c", "echo '1-1' >/sys/bus/usb/drivers/usb/bind" };
try {
    Runtime.getRuntime().exec(cmdline);
} catch (IOException e) {
    Log.e("MainActivity","Failed"+e);
}
Innocent
  • 703
  • 10
  • 21