uhubctl
uhubctl è una utility per controllare l'alimentazione USB per porta su hub USB intelligenti.
Un hub intelligente è definito come uno che implementa la commutazione dell'alimentazione per porta.
L'idea originale per questo codice è stata ispirata da hub-ctrl.c di Niibe Yutaka:
https://www.gniibe.org/development/ac-power-control-by-USB-hub
Hub USB compatibili
Nota che non molti hub USB supportano correttamente la commutazione dell'alimentazione per porta.
Alcuni di essi non sono più in produzione e possono essere difficili da trovare.
Questa è la lista degli hub USB compatibili noti:
| Produttore | Prodotto | Porte | USB | VID:PID | Rilascio | EOL |
|---|
| Acer | monitor BE270U (vedi) | 4 | 3.0 | 2109:2811 | 2016 | |
| AmazonBasics | HU3641V1 (problema RPi) | 4 | 3.0 | 2109:2811 | 2013 | |
| AmazonBasics | HU3770V1 (problema RPi) | 7 | 3.0 | 2109:2811 | 2013 | |
| AmazonBasics | HU9003V1EBL, HUC9003V1EBL | 7 | 3.1 | 2109:2817 | 2018 | |
| AmazonBasics | HU9002V1SBL, HU9002V1EBL, HU9002V1ESL, HHU9002V1EZPR01 (nota) | 10 | 3.1 | 2109:2817 | 2018 | |
| AmazonBasics | HUC9002V1SBL, HUC9002V1EBL, HUC9002V1ESL | 10 | 3.1 | 2109:2817 | 2018 | |
| AmazonBasics | U3-7HUB (funziona solo con 1 porta di ricarica) | 7 | 3.0 | 2109:2813 | 2020 | |
| Anker | AK-68ANHUB-BV7A-0004 (nota) | 7 | 3.0 | |
Questa tabella non è affatto completa.
Se il tuo hub funziona con uhubctl, ma non è elencato sopra, segnalalo
aprendo una nuova issue su https://github.com/mvp/uhubctl/issues,
così possiamo aggiungerlo alla tabella dei supportati. Nel tuo report, fornisci
il modello esatto del prodotto e aggiungi l'output di uhubctl
e testa il supporto per lo spegnimento della VBUS come descritto di seguito nelle FAQ.
Nota che diverse schede madri moderne hanno hub root integrati che
supportano questa funzione: potresti non aver nemmeno bisogno di comprare un hub esterno.
Nota sulla dualità USB 3.0
Se hai un hub USB 3.0 collegato a una porta upstream USB3, verrà rilevato
come 2 hub virtuali indipendenti: USB2 e USB3, e i tuoi dispositivi USB verranno collegati
all'hub virtuale USB2 o USB3 a seconda delle loro capacità e della velocità di connessione.
Per controllare l'alimentazione di tali hub, è necessario spegnere/accendere l'alimentazione su entrambi gli hub virtuali
USB2 e USB3 affinché le modifiche di spegnimento/accensione abbiano effetto. uhubctl proverà a farlo automaticamente
(a meno che non si disabiliti questo comportamento con l'opzione -e).
Sfortunatamente, mentre la maggior parte degli hub interromperà la connessione dati USB, alcuni potrebbero non interrompere la VBUS verso la porta,
il che significa che il telefono collegato potrebbe continuare a caricarsi dalla porta che è stata spenta da uhubctl.
Installazione
Per Linux e MacOS, uhubctl è disponibile nei gestori di pacchetti standard
e può essere installato con i seguenti comandi:
- MacOS:
brew install uhubctl oppure sudo port install uhubctl
- ⚠️ MacOS 26+ richiede libusb 1.0.30 o successivo!
- Ubuntu/Debian/Raspbian:
sudo apt install uhubctl
- Redhat/EPEL/Fedora/CentOS:
sudo yum install uhubctl
- OpenSUSE:
sudo zypper install uhubctl
- FreeBSD:
cd /usr/ports/sysutils/uhubctl && sudo make install
Tuttavia, la versione di uhubctl installata dal gestore di pacchetti standard potrebbe non
essere necessariamente l'ultima versione, o addirittura essere molto indietro rispetto alla versione corrente.
Se la ultima versione pubblicata di uhubctl
è più nuova di quella offerta dal tuo gestore di pacchetti, potresti dover compilare e installare
dal sorgente come descritto di seguito.
Compilazione
Questa utility è stata testata per la compilazione e il funzionamento su Linux (Ubuntu/Debian/Raspbian,
Redhat/EPEL/Fedora/CentOS, Arch Linux, Gentoo, openSUSE, Buildroot),
FreeBSD, NetBSD, SunOS e MacOS.
Mentre uhubctl compila su Windows, la commutazione dell'alimentazione USB non funziona su Windows perché libusb
usa il driver winusb.sys, che secondo Microsoft non supporta
le necessarie richieste di controllo USB.
Questo potrebbe essere risolto se libusb iniziasse a supportare un driver diverso su Windows.
Nota che è altamente raccomandato avere installata l'utility pkgconf (o pkg-config)
(spesso è installata di default).
Prima di tutto, devi installare la libreria libusb-1.0 (è richiesta la versione 1.0.13 o successiva,
è consigliata la 1.0.23 o successiva):
- Ubuntu:
sudo apt-get install libusb-1.0-0-dev pkgconf
- Redhat:
sudo yum install libusb1-devel pkgconf
- OpenSUSE:
sudo zypper install libusb-1_0-devel pkgconf
- MacOS:
brew install libusb pkgconf, oppure sudo port install libusb-devel pkgconf
- FreeBSD:
pkg install gmake pkgconf (libusb è incluso di default)
- NetBSD:
sudo pkgin install libusb1 gmake pkgconf
- Windows: TBD?
Per scaricare il sorgente di uhubctl e compilarlo:
git clone https://github.com/mvp/uhubctl
cd uhubctl
make
Questo dovrebbe generare il binario uhubctl.
Puoi installarlo nel tuo sistema come /usr/sbin/uhubctl usando:
Nota che su alcuni sistemi operativi (es. FreeBSD/NetBSD) devi usare gmake per compilare.
Utilizzo
⚠️ Su Linux, usa sudo o configura i permessi USB come descritto di seguito!
Per elencare tutti gli hub supportati:
Puoi controllare l'alimentazione su una o più porte USB in questo modo:
Ciò significa agire sull'hub intelligente predefinito e spegnere l'alimentazione (-a off, oppure -a 0)
sulla porta 2 (-p 2). Le azioni supportate sono off/on/cycle/toggle (oppure 0/1/2/3).
cycle significa spegnere l'alimentazione, attendere un certo ritardo (configurabile con -d) e riaccenderla.
Le porte possono essere un elenco separato da virgole e possono usare - per gli intervalli, es. 2, oppure , oppure , oppure .> ⚠️ La disattivazione delle porte USB integrate potrebbe scollegare tastiera o mouse,
quindi fai attenzione a quali porte stai disattivando!
Se hai più di uno smart USB hub collegato, dovresti scegliere
l'hub specifico da controllare usando il parametro -l (posizione).
Per trovare le posizioni degli hub, esegui semplicemente uhubctl senza parametri.
Le posizioni degli hub sono nel formato b-x.y.z, dove b è il numero del bus USB, e x, y, z...
sono i numeri di porta per tutti gli hub nella catena, a partire dall'hub root per un dato bus USB.
Questo indirizzo è semi-stabile: non cambia se scolleghi/ricolleghi (o spegni/accendi)
un dispositivo USB nella stessa porta fisica USB (questo metodo è usato anche nel kernel Linux).
Permessi USB su Linux
Su Linux, dovresti configurare i permessi USB di udev (altrimenti dovrai eseguirlo come root usando sudo uhubctl).
A partire dal kernel Linux 6.0 esiste un'interfaccia standard per accendere o spegnere le porte degli hub USB,
e uhubctl proverà a usarla (invece di libusb) per impostare lo stato delle porte.
È per questo che ci sono regole aggiuntive per i kernel 6.0+.
Non c'è alcun danno nell'avere queste regole su sistemi che eseguono versioni precedenti del kernel.
Per correggere i permessi USB, esegui prima sudo uhubctl e annota tutti i vid:pid per gli hub che devi controllare.
Quindi, aggiungi regole udev come quelle sotto al file /etc/udev/rules.d/52-usb.rules
(sostituisci 2001 con il tuo vendor id dell'hub, oppure rimuovi completamente il filtro ATTR{idVendor} per consentire l'accesso a qualsiasi hub USB):
SUBSYSTEM=="usb", DRIVER=="hub|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|usb", \
RUN="/bin/sh -c \"chmod -f 666 $sys$devpath/*port*/disable || true\""
Nota che per gli hub USB3, alcuni hub usano un vendor ID diverso per i componenti USB2 rispetto a USB3 dello stesso chip,
ed entrambi necessitano dei permessi per far funzionare correttamente uhubctl.
Ad esempio, per Raspberry Pi 4B, devi aggiungere queste 2 righe (o rimuovere il filtro idVendor):
SUBSYSTEM=="usb", DRIVER=="hub|usb", MODE="0666", ATTR{idVendor}=="2109"
SUBSYSTEM=="usb", DRIVER=="hub|usb", MODE="0666", ATTR{idVendor}=="1d6b"
Se non ti piace la modalità completamente aperta 0666, puoi limitare l'accesso per gruppo in questo modo:
SUBSYSTEM=="usb", DRIVER=="hub|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|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\""
e poi aggiungi gli utenti autorizzati al gruppo dialout:
sudo usermod -a -G dialout $USER
Affinché le modifiche alle regole udev abbiano effetto, riavvia o esegui:
sudo udevadm trigger --attr-match=subsystem=usb
Per tua comodità, una regola udev pronta all'uso è fornita qui.
FAQ
Cos'è la commutazione di alimentazione per-porta USB?
Secondo la specifica USB 2.0, gli hub USB possono dichiarare nessuna commutazione di alimentazione,
commutazione di alimentazione di gruppo (tutte le porte contemporaneamente) o commutazione di alimentazione per-porta (individuale).
Nota che di default uhubctl rileva solo gli hub USB che supportano la commutazione di alimentazione per-porta
(ma puoi forzarlo a provare a operare su hub non supportati con l'opzione -f).
Puoi scoprire che tipo di commutazione di alimentazione supporta il tuo hardware usando sudo lsusb -v:
Nessuna commutazione di alimentazione:
wHubCharacteristic 0x000a
No power switching (usb 1.0)
Per-port overcurrent protection
Commutazione di alimentazione di gruppo:
wHubCharacteristic 0x0008
Ganged power switching
Per-port overcurrent protection
Commutazione di alimentazione per-porta:
wHubCharacteristic 0x0009
Per-port power switching
Per-port overcurrent protection
Come faccio a verificare se il mio hub USB è supportato da uhubctl?
- Esegui
sudo uhubctl. Se il tuo hub non è elencato, non è supportato.
In alternativa, puoi eseguire sudo lsusb -v e cercare
Per-port power switching - se non vedi questa riga nell'output di lsusb,
l'hub non è supportato.
- Verifica il supporto per lo spegnimento di VBUS (tensione): collega un telefono, una luce USB
o una ventola USB alla porta USB del tuo hub.
Prova a usare
uhubctl per spegnere l'alimentazione su quella porta e verifica
che il telefono smetta di caricarsi, la luce USB smetta di illuminare o la ventola USB smetta di girare.
Se VBUS non si spegne, il produttore del tuo hub non ha incluso il circuito
per tagliare effettivamente l'alimentazione. Un tale hub funzionerebbe comunque
per interrompere la connessione dati USB, ma non può spegnere l'alimentazione,
e non lo consideriamo un dispositivo supportato.
- Se i test sopra sono riusciti, segnala il tuo hub
aprendo una nuova issue su https://github.com/mvp/uhubctl/issues,
così possiamo aggiungerlo all'elenco dei dispositivi supportati.
Per favore non segnalare hub non supportati, a meno che non sia una revisione
hardware diversa di un modello supportato già elencato.
I dispositivi USB non vengono rimossi dopo lo spegnimento dell'alimentazione della porta su Linux
Dopo lo spegnimento della porta USB, udev non riceve alcun evento, quindi mantiene i file di dispositivo.
Tuttavia, tentare di accedere ai file di dispositivo causerà un errore di I/O.
Questo è un problema del kernel Linux ed è risolto
dalla versione uhubctl 2.5.0 per i sistemi con kernel Linux 6.0 o successivo.
Se stai ancora usando Linux 5.x o precedente, puoi usare questa soluzione alternativa per questo problema:
sudo uhubctl -a off -l ${location} -p ${port}
sudo udevadm trigger --action=remove /sys/bus/usb/devices/${location}.${port}/
Il file di dispositivo verrà rimosso da udev, ma il dispositivo USB sarà ancora visibile in lsusb.
Nota che il percorso /sys/bus/usb/devices/${location}.${port} esiste solo se il dispositivo è stato rilevato su quella porta.
Quando riattivi l'alimentazione, il dispositivo dovrebbe ri-enumerarsi correttamente (non c'è bisogno di chiamare di nuovo udevadm).
L'alimentazione si riaccende dopo pochi secondi su Linux
Alcuni driver di dispositivo nel kernel vengono sorpresi dallo spegnimento del dispositivo USB e provano automaticamente a riaccenderlo.
Questo è un problema del kernel Linux ed è risolto
dalla versione uhubctl 2.5.0 per i sistemi con kernel Linux 6.0 o successivo.
Se stai ancora usando Linux 5.x o precedente:
Puoi usare l'opzione -r N, dove N è un numero da 10 a 1000, per risolvere questo problema -
uhubctl proverà a spegnere l'alimentazione molte volte in rapida successione, e dovrebbe sopprimerlo.
Disabilitare l'autorizzazione USB per il dispositivo in questione prima di spegnere l'alimentazione con uhubctl dovrebbe aiutare:
echo 0 > sudo tee /sys/bus/usb/devices/${location}.${port}/authorized
Se il tuo dispositivo è un'unità di archiviazione di massa USB, invocare udisksctl prima di chiamare uhubctl dovrebbe aiutare anche in questo caso:
sudo udisksctl power-off --block-device /dev/disk/...`
sudo uhubctl -a off ...
Vengono rilevati più hub a 4 porte, ma ho solo un hub a 7 porte collegato
Molti produttori di hub costruiscono i loro hub USB usando chip USB di base a 4 porte.
Ad esempio, per realizzare un hub a 7 porte, collegano in cascata due hub a 4 porte - 1 porta è persa per il collegamento in cascata,
quindi si ottiene un hub a 4+4-1=7 porte. Allo stesso modo, un hub a 10 porte potrebbe essere costruito come 3 hub a 4 porte
collegati in cascata tra loro, che danno 4+4+4-2=10 porte utilizzabili.
Nota che non dovresti mai provare a cambiare lo stato di alimentazione per le porte usate per collegare in cascata gli hub interni.
Farlo confonderà il circuito dell'hub interno e causerà un comportamento imprevedibile.
Raspberry Pi spegne l'alimentazione su tutte le porte, non solo su quella specificata
Questa è una limitazione del design hardware di Raspberry Pi.
Come soluzione alternativa, puoi comprare un hub USB esterno dalla lista dei supportati qui sopra,
collegarlo a qualsiasi porta USB di Raspberry Pi e controllare l'alimentazione sulle sue porte in modo indipendente.
Inoltre, ci sono hub supportati progettati specificamente per Raspberry Pi, ad es. UUGear MEGA4.
Per riferimento, i modelli di Raspberry Pi supportati hanno la seguente topologia USB interna:
Raspberry Pi B+,2B,3B
-
Hub singolo 1-1, porte 2-5 raggruppate, tutte controllate dalla porta 2:
Tentare di controllare le porte 3,4,5 non farà nulla.
La porta 1 controlla l'alimentazione per Ethernet+WiFi.
Raspberry Pi 3B+
-
Hub principale 1-1, tutte le 4 porte raggruppate, controllate dalla porta 2 (spegne anche le porte dell'hub secondario).
La porta 1 collega l'hub 1-1.1 sotto, le porte 2 e 3 sono cablate all'esterno, la porta 4 non è cablata.
-
Hub secondario 1-1.1 (collegato in cascata al principale): 3 porte,
la porta 1 è usata per Ethernet+WiFi, e le porte 2 e 3 sono cablate all'esterno.
Raspberry Pi 4B
⚠️ Se il firmware VL805 è più vecchio di 00137ad (controlla con sudo rpi-eeprom-update),
devi aggiornare il firmware
per far funzionare la commutazione di alimentazione su RPi 4B.
-
Hub USB2 1, 1 porta, collega solo l'hub 1-1 sotto.
-
Hub USB2 1-1, 4 porte raggruppate, duale dell'hub USB3 2 sotto:
-
Hub USB3 2, 4 porte raggruppate, duale dell'hub USB2 1-1 sopra:
-
Hub USB2 3, 1 porta, controller OTG. La commutazione di alimentazione non è supportata.
Raspberry Pi 5
Raspberry Pi 5 ha due porte USB2 e due porte USB3 (4 in totale).
Queste porte sono collegate a 4 hub USB distinti 1,2,3,4 in una configurazione davvero strana
(ma a seconda del sistema operativo e della revisione hardware, gli hub di interesse possono essere 2,3,4,5).
Se un dispositivo USB3 è collegato a una presa blu, verrà rilevato sull'hub USB3 2 o 4.
Se un dispositivo USB2 è collegato a una qualsiasi presa o un dispositivo USB3 è collegato a una presa nera,
verrà rilevato sull'hub USB2 1 o 3.
Indipendentemente dal tipo di connessione USB2/USB3, le prese blu sono sempre la porta 1,
e le prese nere sono sempre la porta 2.
Ciascuno dei 4 hub USB integrati dichiara di supportare la commutazione di alimentazione per-porta, ma non è vero.
In realtà, su Raspberry Pi 5 tutte le 4 porte sono raggruppate insieme in un unico gruppo,
nonostante appartengano a 4 hub USB logici diversi.
Per spegnere l'alimentazione VBUS, deve essere disattivata su tutti gli hub e le porte integrati con: ```
uhubctl -l 2 -a 0
uhubctl -l 4 -a 0
Per riattivarlo: ```
uhubctl -l 2 -a 1
uhubctl -l 4 -a 1
Nota: l'alimentazione VBUS si spegne solo se tutte le porte sono spente - abilitare una qualsiasi porta riattiva la VBUS per tutte e 4 le porte.
Progetti notevoli che utilizzano uhubctl
Copyright
Copyright (C) 2009-2026 Vadim Mikhailov
Questo file può essere distribuito secondo i termini e le condizioni della GNU General Public License versione 2.