All our SoM provide one or more USB Host ports which allow connecting USB devices.
Some ports can take both roles, depending on HW/SW configuration they can switch between host and device role. More info can be found here: USB Device Mode (Linux).
Configuration allows to limit the maximum speed the host will switch to when negotiating the speed with a newly connected USB Device. More info can be found here: USB 2.0 High Speed (480Mbps)
Some USB hubs can be controlled over USB to switch the power of their downstream ports. Depending on the SoM this may
include the root hub of the available USB buses.
This allows to switch off unused USB devices to save power or to power cycle USB devices.
The tool uhubctl can be used to control such hubs.
Check additionally the uhubctl README and uhubctl -h
for help.
Some drivers re-enable power if power got switched off. To prevent that one can first remove the USB device from the runtime USB configuration and only then switch off power.
The example use-cases assume the following bus topology.
Such a system reflects in the following lsusb output:
root@verdin-imx8mm:~# lsusb | sort
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 0951:162d Kingston Technology DataTraveler 102
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 0424:2744 Standard Microsystems Corp. Hub
Bus 002 Device 003: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 002 Device 004: ID 0424:2740 Standard Microsystems Corp.
Bus 002 Device 005: ID 0dc6:3100 Precision Squared Technology Corp.
Bus 002 Device 006: ID 0458:0036 KYE Systems Corp. (Mouse Systems) Pocket Mouse LE
root@verdin-imx8mm:~# lsusb -t
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ci_hdrc/1p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 2: Dev 3, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 3: Dev 5, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
|__ Port 4: Dev 6, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
|__ Port 4: Dev 4, If 0, Class=Vendor Specific Class, Driver=, 480M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ci_hdrc/1p, 480M
|__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 480M
Print a list of hubs with the ability to switch ports:
root@verdin-imx8mm:~# uhubctl
Current status for hub 2-1 [0424:2744 Microchip Tech USB2744, USB 2.10, 4 ports]
Port 1: 0100 power
Port 2: 0503 power highspeed enable connect [1a40:0101 USB 2.0 Hub]
Port 3: 0100 power
Port 4: 0503 power highspeed enable connect [0424:2740 Microchip Tech Hub Controller]
Current status for hub 2 [1d6b:0002 Linux 4.14.170-4.0.0-devel+git.5c643afa32be ehci_hcd EHCI Host Controller ci_hdrc.1]
Port 1: 0503 power highspeed enable connect [0424:2744 Microchip Tech USB2744, USB 2.10, 4 ports]
Current status for hub 1 [1d6b:0002 Linux 4.14.170-4.0.0-devel+git.5c643afa32be ehci_hcd EHCI Host Controller ci_hdrc.0]
Port 1: 0503 power highspeed enable connect [0951:162d Kingston DataTraveler 102 001372877298BB31C0000009]
The root hubs for bus 1 and bus 2 and the hub 2-1 on the Dahlia are able to switch their port power. The external hub on X4 does not have that capability as it is not part of the list.
Switching power to the external hub on Bus 2 off:
root@verdin-imx8mm:~# uhubctl -l 2-1 -p 2 -a off
Current status for hub 2-1 [0424:2744 Microchip Tech USB2744, USB 2.10, 4 ports]
Port 2: 0503 power highspeed enable connect [1a40:0101 USB 2.0 Hub]
Sent power off request
New status for hub 2-1 [0424:2744 Microchip Tech USB2744, USB 2.10, 4 ports]
Port 2: 0000 off
root@verdin-imx8mm:~# [ 2944.305210] usb 2-1.2-port4: cannot reset (err = -71)
[ 2944.314338] usb 2-1.2-port4: cannot reset (err = -71)
[ 2944.323451] usb 2-1.2-port4: cannot reset (err = -71)
[ 2944.332574] usb 2-1.2-port4: cannot reset (err = -71)
[ 2944.341694] usb 2-1.2-port4: cannot reset (err = -71)
[ 2944.346783] usb 2-1.2-port4: Cannot enable. Maybe the USB cable is bad?
[ 2944.357892] usb 2-1.2-port4: cannot disable (err = -71)
[ 2944.367204] usb 2-1.2-port3: cannot reset (err = -71)
[ 2944.376319] usb 2-1.2-port3: cannot reset (err = -71)
The driver for the mouse and keyboard try to talk to their devices and complain loudly. So it is better to first remove the driver instances handling mouse, keyboard and the hub connected to X4. Only then remove power to port 2 of the hub on Dahlia:
root@verdin-imx8mm:~# echo 1 > /sys/bus/usb/devices/2-1.2.3/remove
[ 73.942867] usb 2-1.2.3: USB disconnect, device number 5
root@verdin-imx8mm:~# echo 1 > /sys/bus/usb/devices/2-1.2.4/remove
[ 78.813980] usb 2-1.2.4: USB disconnect, device number 6
root@verdin-imx8mm:~# echo 1 > /sys/bus/usb/devices/2-1.2/remove
[ 92.273859] usb 2-1.2: USB disconnect, device number 3
root@verdin-imx8mm:~# uhubctl -l 2-1 -p 2 -a off
Current status for hub 2-1 [0424:2744 Microchip Tech USB2744, USB 2.10, 4 ports]
Port 2: 0101 power connect []
Sent power off request
New status for hub 2-1 [0424:2744 Microchip Tech USB2744, USB 2.10, 4 ports]
Port 2: 0000 off
Now re-enable power on that port. Power is restored, the USB devices announce themselves and the respective drivers are instantiated and bring up the devices:
root@verdin-imx8mm:~# uhubctl -l 2-1 -p 2 -a on
Current status for hub 2-1 [0424:2744 Microchip Tech USB2744, USB 2.10, 4 ports]
Port 2: 0000 off
Sent power on request
New status for hub 2-1 [0424:2744 Microchip Tech USB2744, USB 2.10, 4 ports]
Port 2: 0100 power
root@verdin-imx8mm:~# [ 267.500712] usb 2-1.2: new high-speed USB device number 7 using ci_hdrc
[ 267.615831] hub 2-1.2:1.0: USB hub found
[ 267.619994] hub 2-1.2:1.0: 4 ports detected
[ 267.912724] usb 2-1.2.3: new low-speed USB device number 8 using ci_hdrc
[ 268.051938] input: SCISSORS Keyboard as /devices/platform/32e50000.usb/ci_hdrc.1/usb2/2-1/2-1.2/2-1.2.3/2-1.2.3:1.0/0003:0DC6:3100.0003/input/input4
[ 268.126362] hid-generic 0003:0DC6:3100.0003: input,hidraw0: USB HID v1.00 Keyboard [ SCISSORS Keyboard] on usb-ci_hdrc.1-1.2.3/input0
[ 268.216380] usb 2-1.2.4: new low-speed USB device number 9 using ci_hdrc
[ 268.341552] input: Genius NetScroll + Mini Traveler as /devices/platform/32e50000.usb/ci_hdrc.1/usb2/2-1/2-1.2/2-1.2.4/2-1.2.4:1.0/0003:0458:0036.0004/input/input5
[ 268.356900] hid-generic 0003:0458:0036.0004: input,hidraw1: USB HID v1.10 Mouse [Genius NetScroll + Mini Traveler] on usb-ci_hdrc.1-1.2.4/input0
Similarly for the mass storage device. First we eject it to get the file system in a consistent state, remove it and lastly we switch off port power of the root hub.
root@verdin-imx8mm:~# eject /dev/sda
[ 630.140511] sda: detected capacity change from 2000683008 to 0
root@verdin-imx8mm:~# echo 1 > /sys/bus/usb/devices/1-1/remove
root@verdin-imx8mm:~# [ 642.516578] usb 1-1: USB disconnect, device number 6
root@verdin-imx8mm:~# uhubctl -l 1 -p 1 -a off
Current status for hub 1 [1d6b:0002 Linux 4.14.170-4.0.0-devel+git.5c643afa32be ehci_hcd EHCI Host Controller ci_hdrc.0]
Port 1: 0101 power connect []
Sent power off request
New status for hub 1 [1d6b:0002 Linux 4.14.170-4.0.0-devel+git.5c643afa32be ehci_hcd EHCI Host Controller ci_hdrc.0]
Port 1: 0000 off