26

I have a usb lamp which I specifically bought in order to turn it off programmatically at a certain time, thus I need to remove the power to its usb port.

I believe I have a usb-hub at usb6. The lamp is connected to one of the ports in this hub:

#myhost$ lsusb 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 008 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
...
...
Bus 008 Device 006: ID 050d:0234 Belkin Components F5U234 USB 2.0 4-Port Hub

Here's what I've tried:

Two solutions are here, the first suggests:

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

but I get write error: Invalid argument when trying to write to /sys/bus/usb/devices/usb1/power/level:

$sudo bash -c 'echo disabled > /sys/bus/usb/devices/usb6/power/wakeup'
$echo suspend|sudo tee /sys/bus/usb/devices/usb6/power/level suspend
tee: /sys/bus/usb/devices/usb6/power/level: Invalid argument
$sudo bash -c 'echo suspend> /sys/bus/usb/devices/usb6/power/level'bash: line 0: echo: write error: Invalid argument

The second solution:

sudo bash -c 'echo 0 > /sys/bus/usb/devices/usb6/power/autosuspend_delay_ms; echo auto > /sys/bus/usb/devices/usb6/power/control'

which does turn off power to the usb-hub device.

I was also trying to follow this:

But the output of lsusb -t just hangs:

$lsusb -t
4-1:0.0: No such file or directory
4-1:0.1: No such file or directory
^C

Which prevents me from using this method to get the '2-1.1' part to this:

echo '2-1.1' > /sys/bus/usb/drivers/usb/unbind

Is there an alternative way of getting this information?

Alternatively, is there a way to shut off power to the entire usb subsystem? Something like modprobe -r usb_etc?

My kernel is:

$uname -r
3.2.0-4-amd64
  • what syntax errors? in this case, there's no need to quote the simple strings 'suspend', 'disabled'. if you're into a habit of quoting, great for you, but in this case it's not needed. – user84207 Nov 6 '14 at 22:16
  • I tried stracing the lsusb -t call and I didn't find anything useful within the time I had to debug it. I honestly don't have time right now to find bugs in lsub, and I can't even reproduce it right now, so it probably depends on the devices that are plugged in. I'll have to wait to get home to try to reproduce it. – user84207 Nov 6 '14 at 22:18
20
+25

See Controlling a USB power supply (on/off) with linux, short version, for newer kernels "suspend" does not work anymore:

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

But it doesn't literally cut the power, it signals the device to poweroff, it's up to the device to implement power management and do the rigth thing.

You have a lot of details in the official documentation in the kernel, there it explains the various files in /sys/bus/usb/devices/.../power/ and how to manage the devices and ports.

For things that are not real usb devices (does your usb lamp show up in lsusb?) you migth be out of luck, I have tried myself with an usb lamp and with a gps logger that charges its battery and transfers data through usb that shows up as a cp210x usb to serial, and neither does poweroff. I can "disconnect" the gps with echo '5-4.6' > /sys/bus/usb/drivers/usb/unbind and reconnect it with echo '5-4.6' > /sys/bus/usb/drivers/usb/bind but the battery charging ligth is always on.

But it seems that some hubs do it properly.

19

You could use uhubctl - command line utility to control USB power per port for compatible USB hubs.

It works only on hubs that support per-port power switching, but note that many modern motherboards have USB hubs that support this feature.

To compile:

git clone https://github.com/mvp/uhubctl
cd uhubctl
make

To list status of all hubs, their locations and ports that can be controlled by uhubctl:

uhubctl

To turn off power on port 5 of single compatible hub:

uhubctl -a 0 -p 5

If you have more than one compatible hub connected, use -l to specify hub location to control it:

uhubctl -a 0 -p 5 -l 3-1.2

To toggle power off then on:

uhubctl -a 2 -p 5

Note that USB 3.0 hubs are also supported, and quite a few new USB 3.0 hubs actually work well.

Read more here.

Disclosure - I am the author of uhubctl.

  • A little more information would be nice. Especially because you're the author and it's not a standard package examples of how to use it, what if any capabilities/limitations it has, risks if any, Link only answers are not preferred. – Zachary Brady Nov 8 '16 at 20:41
  • 2
    Well, copy/pasting whole README file doesn't seem like bright idea to me. It has all caveats explained. – mvp Nov 8 '16 at 21:01
  • No, the whole readme would be excessive. Just how you can use the program to solve the problem posed in the question. And if there are any caveats to that particular use case, not the whole application. Sorry if I wasn't clear in my first comment. – Zachary Brady Nov 8 '16 at 21:04
  • 1
    FYI: This method does work for the Renesas UPD720202 family of PCIe-USB host controllers. :) Thanks. – Wossname Feb 16 '18 at 15:10
  • Thanks @Wossname. Do you mind adding it as new issue at github.com/mvp/uhubctl/issues ? I will update supported devices list. – mvp Feb 16 '18 at 23:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.