Ubuntu – How to turn off power to USB port

lubuntupower-managementusb

I am using Lubuntu 16.04. I have analogue speakers that take their power from a USB socket. I'd like them to turn off when I power down the pc and suspend it. I thought that would be pretty easy, but I have spent a lot of time googling and still do not have a solution.

My best bet seems to be uhubctl as this appears to run on my hardware (the author warns that not all hubcontrollers support the functionality). I believe this because I have successfully turned off the USB keyboard.

So now I need to know what to specify to turn off power on the USB socket for the speakers. This is bound to take some guesswork since they are not real USB devices and will not show in lsusb. Looking at the back panel and the motherboard manual, I see that the group of four sockets where the speakers are plugged in are described as USB 2.0 ports 7-10. My mouse and webcam are plugged into the same group of sockets.

Running uhubctl with no arguments gives:

Current status for hub 2-1 [8087:8002, USB 2.00, 8 ports]
Port 1: 0100 power
Port 2: 0100 power
Port 3: 0100 power
Port 4: 0100 power
Port 5: 0100 power
Port 6: 0100 power
Port 7: 0100 power
Port 8: 0100 power
Current status for hub 1-1 [8087:800a, USB 2.00, 6 ports]
Port 1: 0100 power
Port 2: 0100 power
Port 3: 0100 power
Port 4: 0100 power
Port 5: 0100 power
Port 6: 0100 power
Current status for hub 4-5 [174c:3074 ASUS TEK. ASM107x, USB 3.00, 4 ports]
Port 1: 02a0 power 5gbps Rx.Detect
Port 2: 02a0 power 5gbps Rx.Detect
Port 3: 02a0 power 5gbps Rx.Detect
Port 4: 02a0 power 5gbps Rx.Detect
Current status for hub 3-9 [174c:2074 ASUS TEK. ASM107x, USB 2.10, 4 ports]
Port 1: 0100 power
Port 2: 0303 power lowspeed enable connect [047d:2043 NOVATEK Kensington U+P Keyboard]
Port 3: 0100 power
Port 4: 0100 power

That is not too helpful. My keyboard shows up, but all my other USB devices – mouse, Seagate HDD, webcam – are not mentioned.

I tried various commands:

uhubctl -a off -p 2 -l 3-9     #Turns off keyboard as expected
uhubctl -a off -p 2 -l 4-5     #ALSO turns off keyboard. Why ?

uhubctl -a off -p 12345678 -l 2-1 #Does not turn anything off
uhubctl -a off -p 123456   -l 1-1 #Does not turn anything off
uhubctl -a off -p 134      -l 4-5 #Does not turn anything off.

So I can turn off the keyboard. No other USB device is listed (although they are there) and they cannot be turned off.

I have no idea what the hub names represent i.e. 2-1, 1-1, 4-5, 3-9. Nor does there appear to be any way to infer the hub names from lsusb.

lsusb gives:

Bus 002 Device 002: ID 8087:8002 Intel Corp. 
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 008 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 007 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:800a Intel Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 003: ID 174c:3074 ASMedia Technology Inc. ASM1074 SuperSpeed hub
Bus 004 Device 002: ID 0bc2:ab24 Seagate RSS LLC 
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 007: ID 047d:2043 Kensington 
Bus 003 Device 003: ID 174c:2074 ASMedia Technology Inc. ASM1074 High-Speed hub
Bus 003 Device 002: ID 0f62:1001 Acrox Technologies Co., Ltd Targus Mini Trackball Optical Mouse
Bus 003 Device 006: ID 046d:0994 Logitech, Inc. QuickCam Orbit/Sphere AF
Bus 003 Device 004: ID 0b05:180a ASUSTek Computer, Inc. 
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

lsusb -t gives:

/:  Bus 08.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 10000M
/:  Bus 07.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
/:  Bus 06.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 10000M
/:  Bus 05.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
/:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/6p, 5000M
    |__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=uas, 5000M
    |__ Port 5: Dev 3, If 0, Class=Hub, Driver=hub/4p, 5000M
/:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/15p, 480M
    |__ Port 5: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
    |__ Port 9: Dev 3, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 2: Dev 7, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
        |__ Port 2: Dev 7, If 1, Class=Human Interface Device, Driver=usbhid, 1.5M
    |__ Port 10: Dev 4, If 1, Class=Vendor Specific Class, Driver=btusb, 12M
    |__ Port 10: Dev 4, If 2, Class=Vendor Specific Class, Driver=btusb, 12M
    |__ Port 10: Dev 4, If 0, Class=Vendor Specific Class, Driver=btusb, 12M
    |__ Port 10: Dev 4, If 3, Class=Application Specific Interface, Driver=, 12M
    |__ Port 14: Dev 6, If 0, Class=Video, Driver=uvcvideo, 480M
    |__ Port 14: Dev 6, If 1, Class=Video, Driver=uvcvideo, 480M
    |__ Port 14: Dev 6, If 2, Class=Audio, Driver=snd-usb-audio, 480M
    |__ Port 14: Dev 6, If 3, Class=Audio, Driver=snd-usb-audio, 480M
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/8p, 480M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M
    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/6p, 480M

I can see there is some relationship between the hub names and the bus/port numbers but I can't come up with a rule.

I noticed from lsusb that the USB 2.0 devices seem to use an Intel controller whereas the USB 3.0 and 2.1 devices seem to use an ASUS controller. I wondered whether the Intel chips might not support power control so I tried the speakers in the USB 2.1 socket which I can turn off when it is attached to the keyboard. No luck.

Does anybody have any idea why uhubctrl behaves as it does ?

Maybe uhubctl is a red herring and is not going to work. I know there are other ways to switch power in Ubuntu but they seem to depend on being able to determine the directory which represents the usb socket. This I have no idea how to do.

Best Answer

uhubctl author here:

  • uhubctl is using the same addressing method for USB devices as Linux kernel: b-x.y.z, where b is USB bus number, then x, y, z are port numbers of hub chain starting from root USB hub for a given bus. This addressing is semi-stable - it will not change if you unplug and plug USB devices back into the same physical port(s).
  • To answer your second question, I need to quote this from uhubctl README:

If you have compatible USB 3.0 hub connected to USB3 upstream port, it will be detected as 2 independent virtual hubs: USB2 and USB3, and your USB devices will be connected to USB2 or USB3 virtual hub depending on their capabilities and connection speed. To control power for such hubs, it is necessary to turn off/on power on both USB2 and USB3 virtual hubs for power off/on changes to take effect. uhubctl will try to do this automatically (unless you disable this behavior with option -e).

  • And finally, uhubctl will only list USB hubs that claim to support PPPS (per-port power switching). However, there are hubs that claim support but don't really work (switching circuitry is physically missing). I am maintaining list of all hubs that are known to work for sure.

If you happen to find hub that works with uhubctl but is not listed, please report it here.

Related Question