mvp / uhubctl

uhubctl - USB hub per-port power control
Other
2.19k stars 229 forks source link

My Raspberry Pi 4 does not appear to behave as described in the uhubctl documentation. #226

Closed GWHAYWOOD closed 4 years ago

GWHAYWOOD commented 4 years ago

Thank you for all your effort on uhubctl, it is very much appreciated. I have used the utility for more than a year to keep an unreliable USB Webcam running on a Raspberry Pi 3B+. The Webcam is only asked to take a still every minute, but even so the Webcam firmware occasionally crashes. A USB reset will not recover it, but power cycling the USB port almost always does the trick (in more than a year it has failed only once to my knowledge). A 'cron' job looks for the most recent image, and calls uhubctl to cycle the camera power if the image file is older than a few minutes. The Pi 3B+ also has attached a USB 3.0 to SATA interface to a 3TB SATA disc drive. This performs flawlessly on another USB 2.0 port on the Pi 3B+.

root@pi3bplus:~# uhubctl -v v2.0.0-dev

root@pi3bplus:~# lsusb Bus 001 Device 014: ID 05a9:a511 OmniVision Technologies, Inc. OV511+ Webcam Bus 001 Device 007: ID 174c:55aa ASMedia Technology Inc. Name: ASM1051E SATA 6Gb/s bridge, ASM1053E SATA 6Gb/s bridge, ASM1153 SATA 3Gb/s bridge, ASM1153E SATA 6Gb/s bridge Bus 001 Device 005: ID 413c:2005 Dell Computer Corp. RT7D50 Keyboard Bus 001 Device 006: ID 0424:7800 Standard Microsystems Corp. Bus 001 Device 003: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub Bus 001 Device 002: ID 0424:2514 Standard Microsystems Corp. USB 2.0 Hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

root@pi3bplus:~# lsusb -t /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=dwc_otg/1p, 480M | Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M | Port 1: Dev 3, If 0, Class=Hub, Driver=hub/3p, 480M | Port 3: Dev 5, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M | Port 1: Dev 6, If 0, Class=Vendor Specific Class, Driver=lan78xx, 480M | Port 2: Dev 7, If 0, Class=Mass Storage, Driver=usb-storage, 480M | Port 3: Dev 14, If 0, Class=Vendor Specific Class, Driver=ov519, 12M

So far, so good. :)

This is my first attempt to describe issues that I see with the Raspberry Pi 4B. The firmware on the Pi 4B is recent, and I am using v2.1.0-dev from Github, which was compiled on the Pi 4B itself:

pi4b650625:~# >>> rpi-eeprom-update BCM2711 detected BOOTLOADER: up-to-date CURRENT: Fri 17 Jan 17:37:11 UTC 2020 (1579282631) LATEST: Tue 10 Sep 10:41:50 UTC 2019 (1568112110) FW DIR: /lib/firmware/raspberrypi/bootloader/critical VL805: up-to-date CURRENT: 000137ad LATEST: 000137ad

pi4b650625:~# >>> uhubctl -v v2.1.0-dev

ISSUE 1.

If I send a command to change the state on Hub 2, two commands seem to be executed, to change state on both Hub 2 and Hub 1-1. This seems a little odd, but it's just an observation and I can live with it:

pi4b650625:~# >>> uhubctl -l 2 -a 1 Current status for hub 2 [1d6b:0003 Linux 4.19.97-v7l+ xhci-hcd xHCI Host Controller 0000:01:00.0, USB 3.00, 4 ports] Port 1: 02a0 power 5gbps Rx.Detect Port 2: 0080 off Port 3: 02a0 power 5gbps Rx.Detect Port 4: 0080 off Sent power on request New status for hub 2 [1d6b:0003 Linux 4.19.97-v7l+ xhci-hcd xHCI Host Controller 0000:01:00.0, 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 1-1 [2109:3431 USB2.0 Hub, USB 2.10, 4 ports] Port 1: 0503 power highspeed enable connect [0525:a4a2 Linux 4.19.97+ with 20980000.usb iota] Port 2: 0000 off Port 3: 0503 power highspeed enable connect [0525:a4a2 Linux 4.19.97+ with 20980000.usb zero] Port 4: 0000 off Sent power on request New status for hub 1-1 [2109:3431 USB2.0 Hub, USB 2.10, 4 ports] Port 1: 0503 power highspeed enable connect [0525:a4a2 Linux 4.19.97+ with 20980000.usb iota] Port 2: 0100 power Port 3: 0503 power highspeed enable connect [0525:a4a2 Linux 4.19.97+ with 20980000.usb zero] Port 4: 0100 power

Issue 2.

The uhubctl documentation seems to tell me that the power to all four USB ports on the Pi 4B can simultaneously be switched on or off by giving commands to switch on or off the power to port 4.

This is not what I seem to see. For example in one setting I stream video from two Pi Zeros via USB ports 1 and 3. Each Zero has a 'Picam' camera and runs in 'USB gadget' mode. The Zeros take power from their USB connections and communicate with the host Pi 4B over these same connections. The wireless devices in the Zeros are disabled. Power to all the Pi 4B USB ports is ON. If I tell the Pi 4B to switch OFF the power to port 4, then power continues to be supplied to ports 1 and 3. The video streaming continues and I can continue to communicate with the Pi Zeros using ping, ssh, etc..

Suppose power to Hub 1 Port 1 is ON, power to Hub 1-1 Port 2 and Port 4 is OFF, and power to Hub 1-1 Port 1 and Port 3 is ON. A Pi Zero in USB gadget mode is connected to each of Port 1 and Port 3. If I try to switch OFF the power to Port 1 or Port 3, then the Zero connected to that port remains powered (the LEDs on both Zeros remain illuminated) but the communication with the Zero then fails. The communication with the second Zero is unaffected. If I now give the command to switch OFF the power to the port powering the second Zero, then the power to BOTH Zeros is immediately switched off. Contact with them is lost until the power is restored to the ports to which they are connected. If I switch ON the power to ANY port on Hub 1-1 then I see the LEDs on BOTH Pi Zeros illuminate, but (1) uhubctl claims that power is supplied to only the switched port, and (2) I cannot communicate with a Zero unless I tell uhubctl to switch on the power to the port to which that Zero is connected.

I don't think that what I have done so far entirely eliminates possible software issues, but it does look to me almost like there's some sort of logical OR going on with the power switching inside the Pi 4B, so that switching on power to any of the ports switches on power to all of them - yet this only enables the data connection to the specified port. Maybe diodes in the power lines? Although I have looked for detailed circuit diagrams for the USB ports I have not yet found anything useful. The "reduced" schematic published by the Pi Foundation (PDF, 337685 bytes) is dated "2018" and does not seem to show the four USB 'A' ports at all, although it does show the single USB 'C' port from which the Pi 4B takes its own power.

pi4b650625:~# >>> lsusb Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 027: ID 0525:a4a2 Netchip Technology, Inc. Linux-USB Ethernet/RNDIS Gadget Bus 001 Device 028: ID 0525:a4a2 Netchip Technology, Inc. Linux-USB Ethernet/RNDIS Gadget Bus 001 Device 014: ID 2109:3431 VIA Labs, Inc. Hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

pi4b650625:~# >>> lsusb -t /: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M | Port 1: Dev 14, If 0, Class=Hub, Driver=hub/4p, 480M | Port 1: Dev 28, If 1, Class=CDC Data, Driver=cdc_ether, 480M | Port 1: Dev 28, If 0, Class=Communications, Driver=cdc_ether, 480M |__ Port 3: Dev 27, If 0, Class=Communications, Driver=cdc_ether, 480M | Port 3: Dev 27, If 1, Class=CDC Data, Driver=cdc_ether, 480M

These are not critical issues for me. I'm simply trying to understand them, and to make sure that I understand the documentation and that the documentation is correct, and to find out how best to use whatever controls are available to have some way of recovering a USB-connected device, e.g. by means of a script, automatically, if it goes down in service because of something like a software fault e.g. a memory leak or whatever. If I have to switch off all the USB devices in order to power cycle just one of them then I can live with that, but if possible I should prefer to control them individually - and without using a separate smart hub.

If you would like me to provide more information, run any suggested commands, scripts etc. I shall be happy to try to help. I am very familiar with electronics hardware, building software in general and using Linux in particular.

Once again, thank you for your efforts on uhubctl and I hope that this information proves useful.

mvp commented 4 years ago

If I send a command to change the state on Hub 2, two commands seem to be executed, to change state on both Hub 2 and Hub 1-1. This seems a little odd

This is because of USB3 duality: https://github.com/mvp/uhubctl#usb-30-duality-note : If you have 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).

The uhubctl documentation seems to tell me that the power to all four USB ports on the Pi 4B can simultaneously be switched on or off by giving commands to switch on or off the power to port 4.

I do not have Raspberry Pi 4B in my possession, so cannot fully test it. Few weeks ago I was given ssh access to Raspberry Pi 4B and was able to fix obvious issues, but not fully test outcome myself. That said, some users have reported that turning off port 4 of hub 2 (and necessarily 1-1 at the same time due to duality requirement) would kill power on all 4 ports wired outside. That's quite possibly not 100% correct, and port 4 may not be enough.

However, it is absolutely proven that turning power off on all 4 ports:

sudo uhubctl -l 2 -a 0

which is equivalent to:

sudo uhubctl -l 2 -p 1-4 -a 0

does reliably kill power on all of them.

If I have to switch off all the USB devices in order to power cycle just one of them then I can live with that, but if possible I should prefer to control them individually - and without using a separate smart hub.

I'm afraid that none of RPi models support true per-port power switching :-( So external compatible hub is definitely a cure for this.

Once again, thank you for your efforts on uhubctl and I hope that this information proves useful.

You're welcome! ;-)