Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package uhubctl for openSUSE:Factory checked in at 2024-09-10 21:13:17 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/uhubctl (Old) and /work/SRC/openSUSE:Factory/.uhubctl.new.17570 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "uhubctl" Tue Sep 10 21:13:17 2024 rev:7 rq:1199715 version:2.6.0 Changes: -------- --- /work/SRC/openSUSE:Factory/uhubctl/uhubctl.changes 2022-11-06 12:43:28.541838038 +0100 +++ /work/SRC/openSUSE:Factory/.uhubctl.new.17570/uhubctl.changes 2024-09-10 21:14:31.425263387 +0200 @@ -1,0 +2,11 @@ +Mon Sep 9 13:44:50 UTC 2024 - Martin Hauke <[email protected]> + +- Update to version 2.6.0 + * Added support for Raspberry Pi 5 . + * Fixed bug for big-endian platforms. + * Fixed sysfs path bug for Linux kernel 6.x or higher. + * Added flash (inverted cycle) option - turn power on then off. + * Improved Linux detection. + * Added more devices to supported table. + +------------------------------------------------------------------- Old: ---- uhubctl-2.5.0.tar.gz New: ---- uhubctl-2.6.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ uhubctl.spec ++++++ --- /var/tmp/diff_new_pack.sHKp74/_old 2024-09-10 21:14:32.049289387 +0200 +++ /var/tmp/diff_new_pack.sHKp74/_new 2024-09-10 21:14:32.053289554 +0200 @@ -1,7 +1,7 @@ # # spec file for package uhubctl # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: uhubctl -Version: 2.5.0 +Version: 2.6.0 Release: 0 Summary: USB hub per-port power control License: GPL-2.0-only ++++++ uhubctl-2.5.0.tar.gz -> uhubctl-2.6.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uhubctl-2.5.0/Formula/uhubctl.rb new/uhubctl-2.6.0/Formula/uhubctl.rb --- old/uhubctl-2.5.0/Formula/uhubctl.rb 2022-11-02 04:26:08.000000000 +0100 +++ new/uhubctl-2.6.0/Formula/uhubctl.rb 2024-09-01 01:30:35.000000000 +0200 @@ -2,8 +2,8 @@ desc "USB hub per-port power control" homepage "https://github.com/mvp/uhubctl" head "https://github.com/mvp/uhubctl.git" - url "https://github.com/mvp/uhubctl/archive/v2.4.0.tar.gz" - sha256 "391f24fd1f89cacce801df38ecc289b34c3627bc08ee69eec515af7e1a283d97" + url "https://github.com/mvp/uhubctl/archive/v2.5.0.tar.gz" + sha256 "d4452252f7862f7a45dd9c62f2ea7cd3a57ab5f5ab0e54a857d4c695699bbba3" license "GPL-2.0" depends_on "libusb" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uhubctl-2.5.0/LICENSE new/uhubctl-2.6.0/LICENSE --- old/uhubctl-2.5.0/LICENSE 2022-11-02 04:26:08.000000000 +0100 +++ new/uhubctl-2.6.0/LICENSE 2024-09-01 01:30:35.000000000 +0200 @@ -1,6 +1,6 @@ uhubctl â USB hub per-port power control. -Copyright (c) 2009-2022, Vadim Mikhailov +Copyright (c) 2009-2024, Vadim Mikhailov This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uhubctl-2.5.0/README.md new/uhubctl-2.6.0/README.md --- old/uhubctl-2.5.0/README.md 2022-11-02 04:26:08.000000000 +0100 +++ new/uhubctl-2.6.0/README.md 2024-09-01 01:30:35.000000000 +0200 @@ -18,44 +18,47 @@ | Manufacturer | Product | Ports | USB | VID:PID | Release | EOL | |:-------------------|:-----------------------------------------------------|:------|:----|:----------|:--------|:-----| +| Acer | BE270U monitor ([see](https://tinyurl.com/acer550)) | 4 | 3.0 |`2109:2811`| 2016 | | | AmazonBasics | HU3641V1 ([RPi issue](https://goo.gl/CLt46M)) | 4 | 3.0 |`2109:2811`| 2013 | | | AmazonBasics | HU3770V1 ([RPi issue](https://goo.gl/CLt46M)) | 7 | 3.0 |`2109:2811`| 2013 | | | AmazonBasics | HU9003V1EBL, HUC9003V1EBL | 7 | 3.1 |`2109:2817`| 2018 | | | AmazonBasics | HU9002V1SBL, HU9002V1EBL, HU9002V1ESL ([note](https://bit.ly/3awM2Ei)) | 10 | 3.1 |`2109:2817`| 2018 | | | AmazonBasics | HUC9002V1SBL, HUC9002V1EBL, HUC9002V1ESL | 10 | 3.1 |`2109:2817`| 2018 | | | AmazonBasics | U3-7HUB (only works for 1 charge port) | 7 | 3.0 |`2109:2813`| 2020 | | -| Anker | AK-A83650A1 ([note](https://git.io/JzpPb)) | 4 | 3.1 |`2109:0817`| 2020 | | | Anker | AK-68ANHUB-BV7A-0004 ([note](https://git.io/JLnZb)) | 7 | 3.0 |`2109:0812`| 2014 | | | Apple | Pro Display XDR MWPE2LL/A (internal USB hub) | 4 | 2.0 |`05AC:9139`| 2019 | | | Apple | Thunderbolt Display 27" (internal USB hub) | 6 | 2.0 | | 2011 | 2016 | | Apple | USB Keyboard With Numeric Pad (internal USB hub) | 3 | 2.0 | | 2011 | | +| Asus | Z77 Sabertooth Motherboard (onboard USB hub) | 6 | 2.0 | | 2012 | | | Asus | Z87-PLUS Motherboard (onboard USB hub) | 4 | 3.0 | | 2013 | 2016 | -| Aukey | CB-C59 | 4 | 3.1 |`2109:2813`| 2017 | | +| Aukey | CB-C59 | 4 | 3.0 |`2109:2813`| 2017 | | | B+B SmartWorx | UHR204 | 4 | 2.0 |`0856:DB00`| 2013 | | -| B+B SmartWorx | USH304 | 4 | 3.0 |`04B4:6506`| 2017 | | +| B+B SmartWorx | USH304 | 4 | 3.0 |`04B4:6506`| 2017 | 2019 | | Basler | 2000036234 | 4 | 3.0 |`0451:8046`| 2016 | | | Belkin | F5U101 | 4 | 2.0 |`0451:2046`| 2005 | 2010 | -| BenQ | PD2700U 4K Monitor (works only in USB2 mode) | 4 | 3.1 |`05E3:0610`| 2018 | | +| Belkin | F5U238UKCRL-MOB | 4 | 2.0 |`0409:0059`| 2004 | 2010 | +| BenQ | PD2700U 4K Monitor (works only in USB2 mode) | 4 | 3.0 |`05E3:0610`| 2018 | | | BenQ | PD3220U | 4 | 3.1 |`05E3:0610`| 2019 | | | Buffalo | BSH4A05U3BK | 4 | 3.0 |`05E3:0610`| 2015 | | | Bytecc | BT-UH340 ([warning](https://bit.ly/35BNi5U)) | 4 | 3.0 |`2109:8110`| 2010 | | -| Centech | CT-USB4HUB ReTRY HUB | 4 | 3.1 |`0424:2744`| 2017 | | +| Centech | CT-USB4HUB ReTRY HUB | 4 | 3.0 |`0424:2744`| 2017 | | | Circuitco | Beagleboard-xM (internal USB hub) | 4 | 2.0 |`0424:9514`| 2010 | | | Club3D | CSV-3242HD Dual Display Docking Station | 4 | 3.0 |`2109:2811`| 2015 | | -| CyberPower | CP-H420P | 4 | 2.0 |`0409:0059`| 2004 | | +| Coolgear | USBG-12U2ML | 12 | 2.0 |`05e3:0607`| 2015 | | | Cypress | CY4608 HX2VL devkit ([note](https://bit.ly/3sMPfpu)) | 4 | 2.0 |`04B4:6570`| 2012 | | | D-Link | DUB-H4 rev D,E (black). Note: rev A,C,F not supported| 4 | 2.0 |`05E3:0608`| 2012 | | | D-Link | DUB-H7 rev A (silver) | 7 | 2.0 |`2001:F103`| 2005 | 2010 | | D-Link | DUB-H7 rev D,E (black). Rev B,C,F,G not supported | 7 | 2.0 |`05E3:0608`| 2012 | | | Dell | P2416D 24" QHD Monitor ([note](https://git.io/JUAu8))| 4 | 2.0 | | 2017 | | -| Dell | S2719DGF 27" WQHD Gaming-Monitor | 5 | 3.1 |`0424:5734`| 2018 | | +| Dell | S2719DGF 27" WQHD Gaming-Monitor | 5 | 3.0 |`0424:5734`| 2018 | | | Dell | UltraSharp 1704FPT 17" LCD Monitor | 4 | 2.0 |`0424:A700`| 2005 | 2015 | | Dell | UltraSharp U2415 24" LCD Monitor | 5 | 3.0 | | 2014 | | | Dell | UltraSharp U3419W 34" Curved Monitor | 6 | 3.0 | | 2020 | | -| Delock | 62537 | 4 | 3.1 | | 2020 | | +| Dell | Wyse 3040 ([-f required](https://tinyurl.com/wyse3k))| 6 | 3.0 | | 2017 | | +| Delock | 62537 | 4 | 3.0 | | 2017 | 2021 | | Delock | 87445 ([note](https://git.io/Jsuz5)) | 4 | 2.0 |`05E3:0608`| 2009 | 2013 | | Elecom | U2H-G4S | 4 | 2.0 | | 2006 | 2011 | -| ExSys | EX-1113HMS | 16 | 3.1 | | 2018 | | +| Gigabyte | G27Q monitor ([see](http://tinyurl.com/G27Q551) | 4 | 3.0 |`2109:0817`| 2020 | | | GlobalScale | ESPRESSObin SBUD102 V5 | 1 | 3.0 |`1D6B:0003`| 2017 | | | Hardkernel | ODROID-C4 ([note](https://git.io/JG0mP)) | 4 | 3.0 | | 2020 | | | Hawking Technology | UH214 | 4 | 2.0 | | 2003 | 2008 | @@ -66,8 +69,13 @@ | j5create | JUH377 ([note](https://bit.ly/3Mx9eQI)) | 7 | 3.0 | | 2016 | | | j5create | JUH470 ([note](https://bit.ly/3CRWamP)) | 3 | 3.0 |`05E3:0610`| 2014 | | | Juiced Systems | 6HUB-01 | 7 | 3.0 |`0BDA:0411`| 2014 | 2018 | -| LG Electronics | 27MD5KL-B monitor | 4 | 3.1 |`043E:9A60`| 2019 | | +| KUNBUS GmbH | RevPi Connect (+) / S / SE | 2 | 2.0 |`0424:9514`| 2018 | | +| KUNBUS GmbH | RevPi Connect 4 | 2 | 3.0 | | 2022 | | +| KUNBUS GmbH | RevPi Core 3 / S / SE | 2 | 2.0 |`0424:9514`| 2017 | | +| LG Electronics | 27MD5KL-B monitor | 4 | 3.0 |`043E:9A60`| 2019 | | +| LG Electronics | 27GL850-B monitor | 4 | 3.0 |`0451:8142`| 2019 | | | LG Electronics | 27UK850-W monitor | 2 | 3.0 | | 2018 | | +| LG Electronics | 27UN83A-W monitor | 2 | 3.0 |`0451:8142`| 2020 | | | LG Electronics | 38WK95C-W monitor | 4 | 3.0 |`0451:8142`| 2018 | | | Lenovo | ThinkPad Ultra Docking Station (40A20090EU) | 6 | 2.0 |`17EF:100F`| 2015 | | | Lenovo | ThinkPad Ultra Docking Station (40AJ0135EU) | 7 | 3.1 |`17EF:3070`| 2018 | | @@ -75,38 +83,49 @@ | Lenovo | ThinkPad X6 Ultrabase 42W3107 | 4 | 2.0 |`17EF:1000`| 2006 | 2009 | | Lenovo | ThinkPlus 4-in-1 USB-C hub 4X90W86497 | 3 | 3.0 | | 2021 | | | Lenovo | ThinkVision T24i-10 Monitor | 4 | 2.0 |`17EF:0610`| 2018 | | +| Lenovo | USB-C to 4 Port USB-A Hub | 4 | 2.0 |`17EF:103A`| 2020 | | | Lindy | USB serial converter 4 port | 4 | 1.1 |`058F:9254`| 2008 | | | Linksys | USB2HUB4 ([note](https://git.io/JYiDZ)) | 4 | 2.0 | | 2004 | 2010 | | Maplin | A08CQ | 7 | 2.0 |`0409:0059`| 2008 | 2011 | +| Metadot | Das Keyboard 4 | 2 | 3.0 | | 2014 | | +| Microchip | EVB9512 | 2 | 2.0 | | 2009 | | | Microchip | EVB-USB2517 | 7 | 2.0 | | 2008 | | | Microchip | EVB-USB2534BC | 4 | 2.0 | | 2013 | | -| Microchip | EVB-USB5807 | 7 | 3.1 | | 2016 | | +| Microchip | EVB-USB5807 | 7 | 3.0 | | 2016 | | | Moxa | Uport-407 | 7 | 2.0 |`110A:0407`| 2009 | | | NVidia | Jetson Nano B01 ([details](https://git.io/JJaFR)) | 4 | 3.0 | | 2019 | | | NVidia | Jetson Xavier NX ([details](https://bit.ly/3PN2DDp)) | 4 | 3.0 | | 2020 | | | Phidgets | HUB0003_0 | 7 | 2.0 |`1A40:0201`| 2017 | | +| Philips | 346B1C UltraWide 34" Curved Monitor | 4 | 3.0 |`05E3:0610`| 2019 | | | Plugable | USB3-HUB7BC | 7 | 3.0 |`2109:0813`| 2015 | | | Plugable | USB3-HUB7C (only works for 2 charge ports) | 7 | 3.0 |`2109:0813`| 2015 | | | Plugable | USBC-HUB7BC (works for 6/7 ports, not the rightmost) | 7 | 3.0 |`2109:0817`| 2021 | | -| Plugable | USB3-HUB7-81X (only works for 2 charge ports) | 7 | 3.0 |`2109:0813`| 2012 | | | Plugable | USB3-HUB10-C2 (only works for 2 charge ports) | 10 | 3.0 | | 2014 | | | Port Inc | NWUSB01 | 4 | 1.1 |`0451:1446`| 1999 | 2003 | | Raspberry Pi | B+, 2B, 3B ([see below](#raspberry-pi-b2b3b)) | 4 | 2.0 | | 2011 | | | Raspberry Pi | 3B+ ([see below](#raspberry-pi-3b)) | 4 | 2.0 |`0424:2514`| 2018 | | | Raspberry Pi | 4B ([see below](#raspberry-pi-4b)) | 4 | 3.0 |`2109:3431`| 2019 | | +| Raspberry Pi | 5 ([see below](#raspberry-pi-5)) | 4 | 3.0 |`1d6b:0002`| 2023 | | | Renesas | uPD720202 PCIe USB 3.0 host controller | 2 | 3.0 | | 2013 | | | Rosewill | RHUB-210 | 4 | 2.0 |`0409:005A`| 2011 | 2014 | | Rosonway | RSH-518C ([note](https://bit.ly/3kYZUsA)) | 7 | 3.0 |`2109:0817`| 2021 | | +| Rosonway | RSH-A10 ([see](https://tinyurl.com/2ppyyaj8)) | 10 | 3.0 |`0bda:0411`| 2020 | | | Rosonway | RSH-A13 ([warning](https://bit.ly/3OToUOL)) | 13 | 3.1 |`2109:2822`| 2021 | | | Rosonway | RSH-A16 ([note](https://git.io/JTawg), [warning](https://bit.ly/39B0tGS)) | 16 | 3.0 |`0bda:0411`| 2020 | | | Rosonway | RSH-A104 ([USB2 only](https://bit.ly/3A0qiKF)) | 4 | 3.1 |`2109:2822`| 2022 | | +| Rosonway | RSH-A107 (aka ikuai A107-5) | 7 | 3.1 |`0bda:5411`| 2022 | | +| Rosonway | RSH-ST07C ([only 4](https://tinyurl.com/4pjnujrn)) | 7 | 3.0 |`2109:2822`| 2023 | | | Sanwa Supply | USB-HUB14GPH | 4 | 1.1 | | 2001 | 2003 | | Seagate | Backup Plus Hub STEL8000100 | 2 | 3.0 |`0BC2:AB44`| 2016 | | | Seeed Studio | reTerminal CM4104032 | 2 | 2.0 |`0424:2514`| 2021 | | +| StarTech | HB30A4AIB ([warning](https://tinyurl.com/ycxravwk)) | 4 | 3.0 |`2109:2817`| 2018 | | | Sunix | SHB4200MA | 4 | 2.0 |`0409:0058`| 2006 | 2009 | +| System Talks | Sugoi USB2-HUB4X | 4 | 2.0 | | 2007 | | +| Targus | PA095UZ | 2 | 2.0 | | 2004 | | | Targus | PAUH212/PAUH212U | 7 | 2.0 | | 2004 | 2009 | | Texas Instruments | TUSB4041PAPEVM | 4 | 2.1 |`0451:8142`| 2015 | | -| UUGear | MEGA4 (for Raspberry Pi 4B) | 4 | 3.1 |`2109:0817`| 2021 | | +| UUGear | MEGA4 (for Raspberry Pi 4B) | 4 | 3.0 |`2109:0817`| 2021 | | +| VirtualHere | USB3 4-port hub ([note](https://tinyurl.com/vhusb)) | 4 | 3.0 | | 2024 | | This table is by no means complete. If your hub works with `uhubctl`, but is not listed above, please report it @@ -138,9 +157,6 @@ This utility was tested to compile and work on Linux (Ubuntu/Debian, Redhat/Fedora/CentOS, Arch Linux, Gentoo, openSUSE, Buildroot), FreeBSD, NetBSD, SunOS and MacOS. -> :warning: MacOS 12.4 x86 has [USB stack bug](https://github.com/libusb/libusb/issues/1156) which breaks `uhubctl` operation. -Solution is to upgrade to MacOS 12.5 which has this bug fixed. - While `uhubctl` compiles on Windows, USB power switching does not work on Windows because `libusb` is using `winusb.sys` driver, which according to Microsoft does not support [necessary USB control requests](https://social.msdn.microsoft.com/Forums/sqlserver/en-US/f680b63f-ca4f-4e52-baa9-9e64f8eee101). @@ -225,23 +241,23 @@ Then, add udev rules like below to file `/etc/udev/rules.d/52-usb.rules` (replace `2001` with your hub vendor id, or completely remove `ATTR{idVendor}` filter to allow any USB hub access): - SUBSYSTEM=="usb", DRIVER=="hub", MODE="0666", ATTR{idVendor}=="2001" + SUBSYSTEM=="usb", DRIVER=="usb", MODE="0666", ATTR{idVendor}=="2001" # Linux 6.0 or later (its ok to have this block present for older Linux kernels): - SUBSYSTEM=="usb", DRIVER=="hub", \ + SUBSYSTEM=="usb", DRIVER=="usb", \ RUN="/bin/sh -c \"chmod -f 666 $sys$devpath/*-port*/disable || true\"" Note that for USB3 hubs, some hubs use different vendor ID for USB2 vs USB3 components of the same chip, and both need permissions to make uhubctl work properly. E.g. for Raspberry Pi 4B, you need to add these 2 lines (or remove idVendor filter): - SUBSYSTEM=="usb", DRIVER=="hub", MODE="0666", ATTR{idVendor}=="2109" - SUBSYSTEM=="usb", DRIVER=="hub", MODE="0666", ATTR{idVendor}=="1d6b" + SUBSYSTEM=="usb", DRIVER=="usb", MODE="0666", ATTR{idVendor}=="2109" + SUBSYSTEM=="usb", DRIVER=="usb", MODE="0666", ATTR{idVendor}=="1d6b" If you don't like wide open mode `0666`, you can restrict access by group like this: - SUBSYSTEM=="usb", DRIVER=="hub", MODE="0664", GROUP="dialout" + SUBSYSTEM=="usb", DRIVER=="usb", MODE="0664", GROUP="dialout" # Linux 6.0 or later (its ok to have this block present for older Linux kernels): - SUBSYSTEM=="usb", DRIVER=="hub", \ + SUBSYSTEM=="usb", DRIVER=="usb", \ RUN+="/bin/sh -c \"chown -f root:dialout $sys$devpath/*-port*/disable || true\"" \ RUN+="/bin/sh -c \"chmod -f 660 $sys$devpath/*-port*/disable || true\"" @@ -309,16 +325,13 @@ #### _USB devices are not removed after port power down on Linux_ -> :arrow_right: This is fixed by [#450](https://github.com/mvp/uhubctl/pull/450) if you are using Linux kernel 6.0 or later. - After powering down USB port, udev does not get any event, so it keeps the device files around. However, trying to access the device files will lead to an IO error. -This is Linux kernel issue. It may be eventually fixed in kernel, see more discussion [here](https://bit.ly/2JzczjZ). -Basically what happens here is that kernel USB driver knows about power off, -but doesn't send notification about it to udev. +This is Linux kernel [issue](https://bit.ly/2JzczjZ) and is [fixed](https://github.com/mvp/uhubctl/pull/450) +since uhubctl 2.5.0 for systems with Linux kernel 6.0 or later. -You can use this workaround for this issue: +If you are still using Linux 5.x or older, you can use this workaround for this issue: sudo uhubctl -a off -l ${location} -p ${port} sudo udevadm trigger --action=remove /sys/bus/usb/devices/${location}.${port}/ @@ -329,13 +342,15 @@ #### _Power comes back on after few seconds on Linux_ -> :arrow_right: This is fixed by [#450](https://github.com/mvp/uhubctl/pull/450) if you are using Linux kernel 6.0 or later. - Some device drivers in kernel are surprised by USB device being turned off and automatically try to power it back on. -You can use option `-r N` where N is some number from 10 to 1000 to fix this - +This is Linux kernel [issue](https://bit.ly/2JzczjZ) and is [fixed](https://github.com/mvp/uhubctl/pull/450) +since uhubctl 2.5.0 for systems with Linux kernel 6.0 or later. + +If you are still using Linux 5.x or older: + +You can use option `-r N`, where N is some number from 10 to 1000 to fix this - `uhubctl` will try to turn power off many times in quick succession, and it should suppress that. -This may be eventually fixed in kernel, see more discussion [here](https://bit.ly/2JzczjZ). Disabling USB authorization for device in question before turning power off with `uhubctl` should help: @@ -405,39 +420,70 @@ * USB2 hub `3`, 1 port, OTG controller. Power switching is [not supported](https://git.io/JUc5Q). +##### Raspberry Pi 5 + + Raspberry Pi 5 has two USB2 ports and two USB3 ports (total 4). +These ports are connected to 4 distinct USB hubs `1`,`2`,`3`,`4` in really weird configuration. +If USB3 device is connected to blue socket, it will be detected on USB3 hub `2` or `4`. +If USB2 device is connected to any socket or USB3 device connected to black socket, +it will be detected on USB2 hub `1` or `3`. +Regardless of USB2/USB3 connection type, blue sockets are always port `1`, +and black sockets are always port `2`. + + Each of 4 USB onboard hubs advertises as supporting per-port power switching, but this is not true. +In reality, Raspberry Pi 5 all 4 ports are ganged together in one group, +despite belonging to 4 different logical USB hubs. + +To turn off VBUS power it has to be disabled across all onboard hubs and ports with: + + ``` + uhubctl -l 1 -a 0 + uhubctl -l 3 -a 0 + ``` + +To turn it back on: + + ``` + uhubctl -l 1 -a 1 + uhubctl -l 3 -a 1 + ``` +Note that VBUS power goes down only if all ports are off - +enabling any single port enables VBUS back for all 4 ports. Notable projects using uhubctl ============================== -| Project | Description | -|:---------------------------------------------------------|:------------------------------------------------------| -| [Morse code USB light](https://git.io/fj1F4) | Flash a message in Morse code with USB light | -| [Webcam USB light](https://git.io/fj1FB) | Turn on/off LED when webcam is turned on/off | -| [Cinema Lightbox](https://goo.gl/fjCvkz) | Turn on/off Cinema Lightbox from iOS Home app | -| [Build Status Light](https://goo.gl/3GA82o) | Create a build status light in under 10 minutes | -| [Buildenlights](https://git.io/fj1FC) | GitLab/GitHub project build status as green/red light | -| [Weather Station](https://goo.gl/3b1FzC) | Reset Weather Station when it freezes | -| [sysmoQMOD](https://bit.ly/2VtWrVt) | Reset cellular modems when necessary | -| [Smog Sensor](https://bit.ly/2EMwgCk) | Raspberry Pi based smog sensor power reset | -| [Terrible Cluster](https://goo.gl/XjiXFu) | Power on/off Raspberry Pi cluster nodes as needed | -| [Ideal Music Server](https://bit.ly/39MeVFQ) | Turn off unused USB ports to improve audio quality | -| [USB drives with no phantom load](https://goo.gl/qfrmGK) | Power USB drives only when needed to save power | -| [USB drive data recovery](https://goo.gl/4MddLr) | Recover data from failing USB hard drive | -| [Control power to 3D printer](https://git.io/fh5Tr) | OctoPrint web plugin for USB power control | -| [USB fan for Raspberry Pi](https://bit.ly/2TRV6sM) | Control USB fan to avoid Raspberry Pi overheating | -| [Raspberry Pi Reboot Router](https://bit.ly/3aNbQqs) | Automatically reboot router if internet isn't working | -| [Control USB Lamp With Voice](https://bit.ly/2VtW2SX) | Voice Control of USB Lamp using Siri and Raspberry Pi | -| [Control USB LED Strip](https://bit.ly/3oVWfeZ) | Controlling USB powered LED Light Strip | -| [Brew beer with Raspberry Pi](https://git.io/JtbLd) | Automated beer brewing system using Raspberry Pi | -| [Webcam On-Air Sign](https://bit.ly/3witNsa) | Automatically light up a sign when webcam is in use | -| [Do it yourself PPPS](https://git.io/J3lHs) | Solder wires in your USB hub to support uhubctl | -| [Python Wrapper for uhubctl](https://github.com/nbuchwitz/python3-uhubctl) | Module to use uhubctl with Python | +| Project | Description | +|:---------------------------------------------------------|:--------------------------------------------------------| +| [Morse code USB light](https://git.io/fj1F4) | Flash a message in Morse code with USB light | +| [Webcam USB light](https://git.io/fj1FB) | Turn on/off LED when webcam is turned on/off | +| [Cinema Lightbox](https://goo.gl/fjCvkz) | Turn on/off Cinema Lightbox from iOS Home app | +| [Build Status Light](https://goo.gl/3GA82o) | Create a build status light in under 10 minutes | +| [Buildenlights](https://git.io/fj1FC) | GitLab/GitHub project build status as green/red light | +| [Weather Station](https://goo.gl/3b1FzC) | Reset Weather Station when it freezes | +| [sysmoQMOD](https://bit.ly/2VtWrVt) | Reset cellular modems when necessary | +| [Smog Sensor](https://bit.ly/2EMwgCk) | Raspberry Pi based smog sensor power reset | +| [Terrible Cluster](https://goo.gl/XjiXFu) | Power on/off Raspberry Pi cluster nodes as needed | +| [Ideal Music Server](https://bit.ly/39MeVFQ) | Turn off unused USB ports to improve audio quality | +| [USB drives with no phantom load](https://goo.gl/qfrmGK) | Power USB drives only when needed to save power | +| [USB drive data recovery](https://goo.gl/4MddLr) | Recover data from failing USB hard drive | +| [Control power to 3D printer](https://git.io/fh5Tr) | OctoPrint web plugin for USB power control | +| [USB fan for Raspberry Pi](https://bit.ly/2TRV6sM) | Control USB fan to avoid Raspberry Pi overheating | +| [Raspberry Pi Reboot Router](https://bit.ly/3aNbQqs) | Automatically reboot router if internet isn't working | +| [Control USB Lamp With Voice](https://bit.ly/2VtW2SX) | Voice Control of USB Lamp using Siri and Raspberry Pi | +| [Control USB LED Strip](https://bit.ly/3oVWfeZ) | Controlling USB powered LED Light Strip | +| [Brew beer with Raspberry Pi](https://git.io/JtbLd) | Automated beer brewing system using Raspberry Pi | +| [Webcam On-Air Sign](https://bit.ly/3witNsa) | Automatically light up a sign when webcam is in use | +| [Do it yourself PPPS](https://git.io/J3lHs) | Solder wires in your USB hub to support uhubctl | +| [Open source PPPS hub](https://tinyurl.com/yckhystt) | Open source hardware project for uhubctl compatible hub | +| [Python Wrapper for uhubctl](https://github.com/nbuchwitz/python3-uhubctl) | Module to use uhubctl with Python | +| [labgrid](https://github.com/labgrid-project/labgrid) | Framework for testing embedded Linux on hardware | Copyright ========= -Copyright (C) 2009-2022 Vadim Mikhailov +Copyright (C) 2009-2024 Vadim Mikhailov This file can be distributed under the terms and conditions of the GNU General Public License version 2. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uhubctl-2.5.0/VERSION new/uhubctl-2.6.0/VERSION --- old/uhubctl-2.5.0/VERSION 2022-11-02 04:26:08.000000000 +0100 +++ new/uhubctl-2.6.0/VERSION 2024-09-01 01:30:35.000000000 +0200 @@ -1 +1 @@ -2.5.0 +2.6.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uhubctl-2.5.0/udev/rules.d/52-usb.rules new/uhubctl-2.6.0/udev/rules.d/52-usb.rules --- old/uhubctl-2.5.0/udev/rules.d/52-usb.rules 2022-11-02 04:26:08.000000000 +0100 +++ new/uhubctl-2.6.0/udev/rules.d/52-usb.rules 2024-09-01 01:30:35.000000000 +0200 @@ -1,6 +1,6 @@ # uhubctl â USB hub per-port power control https://github.com/mvp/uhubctl # -# Copyright (c) 2009-2022, Vadim Mikhailov +# Copyright (c) 2009-2024, Vadim Mikhailov # # This file can be distributed under the terms and conditions of the # GNU General Public License version 2. @@ -16,9 +16,9 @@ # sudo usermod -a -G dialout $USER # This is for Linux before 6.0: -SUBSYSTEM=="usb", DRIVER=="hub", MODE="0664", GROUP="dialout" +SUBSYSTEM=="usb", DRIVER=="usb", MODE="0664", GROUP="dialout" # This is for Linux 6.0 or later (ok to keep this block present for older Linux kernels): -SUBSYSTEM=="usb", DRIVER=="hub", \ +SUBSYSTEM=="usb", DRIVER=="usb", \ RUN+="/bin/sh -c \"chown -f root:dialout $sys$devpath/*-port*/disable || true\"" \ RUN+="/bin/sh -c \"chmod -f 660 $sys$devpath/*-port*/disable || true\"" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uhubctl-2.5.0/uhubctl.c new/uhubctl-2.6.0/uhubctl.c --- old/uhubctl-2.5.0/uhubctl.c 2022-11-02 04:26:08.000000000 +0100 +++ new/uhubctl-2.6.0/uhubctl.c 2024-09-01 01:30:35.000000000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2022 Vadim Mikhailov + * Copyright (c) 2009-2024 Vadim Mikhailov * * Utility to turn USB port power on/off * for USB hubs that support per-port power switching. @@ -29,7 +29,7 @@ #include <unistd.h> #endif -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(_WIN32) +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(_WIN32) #include <libusb.h> #else #include <libusb-1.0/libusb.h> @@ -47,7 +47,7 @@ #include <time.h> /* for nanosleep */ #endif -#ifdef __gnu_linux__ +#if defined(__gnu_linux__) || defined(__linux__) #include <fcntl.h> /* for open() / O_WRONLY */ #endif @@ -80,6 +80,7 @@ #define POWER_ON 1 #define POWER_CYCLE 2 #define POWER_TOGGLE 3 +#define POWER_FLASH 4 #define MAX_HUB_CHAIN 8 /* Per USB 3.0 spec max hub chain is 7 */ @@ -226,14 +227,14 @@ static int opt_reset = 0; /* reset hub after operation(s) */ static int opt_force = 0; /* force operation even on unsupported hubs */ static int opt_nodesc = 0; /* skip querying device description */ -#ifdef __gnu_linux__ +#if defined(__gnu_linux__) || defined(__linux__) static int opt_nosysfs = 0; /* don't use the Linux sysfs port disable interface, even if available */ #endif static const char short_options[] = "l:L:n:a:p:d:r:w:s:hvefRN" -#ifdef __gnu_linux__ +#if defined(__gnu_linux__) || defined(__linux__) "S" #endif ; @@ -251,7 +252,7 @@ { "exact", no_argument, NULL, 'e' }, { "force", no_argument, NULL, 'f' }, { "nodesc", no_argument, NULL, 'N' }, -#ifdef __gnu_linux__ +#if defined(__gnu_linux__) || defined(__linux__) { "nosysfs", no_argument, NULL, 'S' }, #endif { "reset", no_argument, NULL, 'R' }, @@ -261,7 +262,7 @@ }; -static int print_usage() +static int print_usage(void) { printf( "uhubctl: utility to control USB port power for smart hubs.\n" @@ -269,18 +270,18 @@ "Without options, show status for all smart hubs.\n" "\n" "Options [defaults in brackets]:\n" - "--action, -a - action to off/on/cycle/toggle (0/1/2/3) for affected ports.\n" + "--action, -a - action to off/on/cycle/toggle/flash (0/1/2/3/4) for affected ports.\n" "--ports, -p - ports to operate on [all hub ports].\n" "--location, -l - limit hub by location [all smart hubs].\n" "--level -L - limit hub by location level (e.g. a-b.c is level 3).\n" "--vendor, -n - limit hub by vendor id [%s] (partial ok).\n" "--search, -s - limit hub by attached device description.\n" - "--delay, -d - delay for cycle action [%g sec].\n" + "--delay, -d - delay for cycle/flash action [%g sec].\n" "--repeat, -r - repeat power off count [%d] (some devices need it to turn off).\n" "--exact, -e - exact location (no USB3 duality handling).\n" "--force, -f - force operation even on unsupported hubs.\n" "--nodesc, -N - do not query device description (helpful for unresponsive devices).\n" -#ifdef __gnu_linux__ +#if defined(__gnu_linux__) || defined(__linux__) "--nosysfs, -S - do not use the Linux sysfs port disable interface.\n" #endif "--reset, -R - reset hub after each power-on action, causing all devices to reassociate.\n" @@ -404,7 +405,7 @@ return rc; if (desc.bDeviceClass != LIBUSB_CLASS_HUB) return LIBUSB_ERROR_INVALID_PARAM; - int bcd_usb = libusb_le16_to_cpu(desc.bcdUSB); + int bcd_usb = desc.bcdUSB; int desc_type = bcd_usb >= USB_SS_BCD ? LIBUSB_DT_SUPERSPEED_HUB : LIBUSB_DT_HUB; rc = libusb_open(dev, &devh); @@ -427,8 +428,8 @@ snprintf( info->vendor, sizeof(info->vendor), "%04x:%04x", - libusb_le16_to_cpu(desc.idVendor), - libusb_le16_to_cpu(desc.idProduct) + desc.idVendor, + desc.idProduct ); /* Convert bus and ports array into USB location string */ @@ -490,6 +491,32 @@ lpsm = HUB_CHAR_INDV_PORT_LPSM; } info->lpsm = lpsm; + + /* Raspberry Pi 5 hack */ + + /* TODO: make this hack more reliable by querying Raspberry Pi model */ + + if (strlen(info->container_id)==0 && + info->lpsm==HUB_CHAR_INDV_PORT_LPSM && + info->pn_len==0) + { + /* USB2 */ + if (strcasecmp(info->vendor, "1d6b:0002")==0 && + info->nports==2 && + !info->super_speed && + (info->bus==1 || info->bus==3)) + { + strcpy(info->container_id, "Raspberry Pi 5 Fake Container Id"); + } + /* USB3 */ + if (strcasecmp(info->vendor, "1d6b:0003")==0 && + info->nports==1 && + info->super_speed && + (info->bus==2 || info->bus==4)) + { + strcpy(info->container_id, "Raspberry Pi 5 Fake Container Id"); + } + } rc = 0; } else { rc = len; @@ -524,11 +551,11 @@ if (rc < 0) { return rc; } - return ust.wPortStatus; + return libusb_le16_to_cpu(ust.wPortStatus); } -#ifdef __gnu_linux__ +#if defined(__gnu_linux__) || defined(__linux__) /* * Try to use the Linux sysfs interface to power a port off/on. * Returns 0 on success. @@ -548,10 +575,17 @@ * The "disable" sysfs interface is available only starting with kernel version 6.0. * For earlier kernel versions the open() call will fail and we fall back to using libusb. */ - snprintf(disable_path, PATH_MAX, - "/sys/bus/usb/devices/%s:%d.0/%s-port%i/disable", - hub->location, configuration, hub->location, port - ); + if (hub->pn_len == 0) { + snprintf(disable_path, PATH_MAX, + "/sys/bus/usb/devices/%s-0:%d.0/usb%s-port%i/disable", + hub->location, configuration, hub->location, port + ); + } else { + snprintf(disable_path, PATH_MAX, + "/sys/bus/usb/devices/%s:%d.0/%s-port%i/disable", + hub->location, configuration, hub->location, port + ); + } int disable_fd = open(disable_path, O_WRONLY); if (disable_fd >= 0) { @@ -621,7 +655,7 @@ static int set_port_status(struct libusb_device_handle *devh, struct hub_info *hub, int port, int on) { -#ifdef __gnu_linux__ +#if defined(__gnu_linux__) || defined(__linux__) if (!opt_nosysfs) { if (set_port_status_linux(devh, hub, port, on) == 0) { return 0; @@ -662,8 +696,8 @@ if (rc) return rc; bzero(ds, sizeof(*ds)); - id_vendor = libusb_le16_to_cpu(desc.idVendor); - id_product = libusb_le16_to_cpu(desc.idProduct); + id_vendor = desc.idVendor; + id_product = desc.idProduct; rc = libusb_open(dev, &devh); if (rc == 0) { if (!opt_nodesc) { @@ -685,6 +719,7 @@ } if (desc.bDeviceClass == LIBUSB_CLASS_HUB) { struct hub_info info; + bzero(&info, sizeof(info)); rc = get_hub_info(dev, &info); if (rc == 0) { const char * lpsm_type; @@ -823,7 +858,7 @@ * In case of error returns negative error code. */ -static int usb_find_hubs() +static int usb_find_hubs(void) { struct libusb_device *dev; int perm_ok = 1; @@ -1011,7 +1046,7 @@ } } if (perm_ok == 0 && hub_phys_count == 0) { -#ifdef __gnu_linux__ +#if defined(__gnu_linux__) || defined(__linux__) if (geteuid() != 0) { fprintf(stderr, "There were permission problems while accessing USB.\n" @@ -1078,6 +1113,9 @@ if (!strcasecmp(optarg, "toggle") || !strcasecmp(optarg, "3")) { opt_action = POWER_TOGGLE; } + if (!strcasecmp(optarg, "flash") || !strcasecmp(optarg, "4")) { + opt_action = POWER_FLASH; + } break; case 'd': opt_delay = atof(optarg); @@ -1091,7 +1129,7 @@ case 'N': opt_nodesc = 1; break; -#ifdef __gnu_linux__ +#if defined(__gnu_linux__) || defined(__linux__) case 'S': opt_nosysfs = 1; break; @@ -1193,6 +1231,9 @@ /* will operate on these ports */ int ports = ((1 << hubs[i].nports) - 1) & opt_ports; int should_be_on = k; + if (opt_action == POWER_FLASH) { + should_be_on = !should_be_on; + } int port; for (port=1; port <= hubs[i].nports; port++) { @@ -1232,7 +1273,7 @@ } libusb_close(devh); } - if (k == 0 && opt_action == POWER_CYCLE) + if (k == 0 && (opt_action == POWER_CYCLE || opt_action == POWER_FLASH)) sleep_ms((int)(opt_delay * 1000)); } rc = 0;
