Linux USB: turning the power on and off?
How can I programmatically enable and disable the power to a particular USB port on Linux? Is such a thing even possible? (no -- see below) Mac answers appreciated as well!
I was trying for a BOC (don't pretend you weren't try to get one too!) and ended up with one of these, and would like to get some use out of the thing by hooking it up to our server monitor.
update: It doesn't seem this is possible. All of the API's that suspend power basically tell the connected device to turn off, but power is still available on pin 1, so simple devices such as these lights can't be directly controlled programmatically. Perhaps the hub solution mentioned will work.
Digs through bookmarks
http://blog.andrew.net.au/2009/01/01#usb_power_control
Seems like you need to connect it to a hub and control the hub's power. None of the root hubs I have seen seems to be able to support power control.
There is a sys entry for this in Linux. From Documentation/usb/power-management.txt:
power/level
This file contains one of three words: "on", "auto",
or "suspend". You can write those words to the file
to change the device's setting.
"on" means that the device should be resumed and
autosuspend is not allowed. (Of course, system
suspends are still allowed.)
"auto" is the normal state in which the kernel is
allowed to autosuspend and autoresume the device.
"suspend" means that the device should remain
suspended, and autoresume is not allowed. (But remote
wakeup may still be allowed, since it is controlled
separately by the power/wakeup attribute.)
Something like: echo on > /sys/bus/usb/devices/usb5/power/level
You may need to play with the autosuspend setting as well. Without telling the kernel to stop trying, it may suspend the port automatically.
Good luck!
The usbfs interaction seems to have changed a number of times since this question was originally answered. So, here's how I cycle hub port power on Ubuntu Oneiric Ocelot from a Bash shell.
Search for the bus and device number:
sudo lsusb -v|less
Locate the device in the bus / hub port hierarchy using the bus and device number:
sudo lsusb -t|less
The syntax seems to be 'bus-port.port.port.port.port...' For example, my mouse is connected to an external hub which connects to my computer's hub which internally connects to a root hub:
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci_hcd/2p, 480M
|__ Port 1: Dev 2, If 0, Class=hub, Driver=hub/6p, 480M
|__ Port 1: Dev 3, If 0, Class=hub, Driver=hub/3p, 480M
|__ Port 1: Dev 6, If 0, Class=HID, Driver=usbhid, 1.5M
So, '2-1.1.1' in the above case. Finally, cycle the port power:
echo '2-1.1.1'|sudo tee /sys/bus/usb/drivers/usb/unbind
sleep 1
echo '2-1.1.1'|sudo tee /sys/bus/usb/drivers/usb/bind
I haven't hooked up a protocol analyzer to see what's actually happening on the bus, but I know my mouse light turns off when I unbind it. I'm guessing at a lower layer this is interacting with the EHCI host controller to actually shut power off on the port. This is particularly useful for embedded devices, such as a UVC webcams, which never seem to function properly and would otherwise require a system reboot to reset.
See also the udevadm
command.
上一篇: 控制USB端口的电源?
下一篇: Linux USB:打开和关闭电源?