>_ DevTrendsen

Language

Home

Languages

Sections

Frontend Backend Mobile DevOps AI / ML GameDev Blockchain Embedded Security
C

How to Programmatically Cut Power to a Stuck USB Device Using uhubctl

Imagine a common situation: a 4G modem has frozen on a remote server, a dacha router, or a test bench. Or a Raspberry Pi board has switched to an abnormal mode, and a 3D printer controller has stopped responding to commands. A regular OS reboot doesn't help because power continues to be supplied to the USB ports. The only option is to drive to the site and manually unplug the cable.

If you don't want to work as a "walking administrator," the uhubctl utility will come in handy. Vadim Mikhaylov wrote this tool in C back in 2015, and the project is still active. The main purpose of the program is to send low-level USB commands to the hub controller so that it physically removes VBUS voltage from a specific port.

How It Works and the Hardware Catch

uhubctl doesn't perform miracles out of thin air. It only works with hubs where the manufacturer has implemented hardware support for per-port power switching (PPPS). According to USB 2.0 and USB 3.0 standards, this specification has existed for a long time, but cost-cutting on power components means many cheap hubs combine the power of all ports into a single line.

Nevertheless, there are enough compatible devices on the market. The repository maintains a detailed table with dozens of verified models:

  • Built-in hubs in Dell, LG, BenQ, and Acer monitors.
  • Raspberry Pi single-board computers (on models 3B+ and 4B, you can disable power, though with some nuances).
  • External hubs from Anker, D-Link, Rosonway, and Plugable.
  • Asus motherboards and KUNBUS RevPi industrial controllers.

Under the Hood

uhubctl communicates with the hub via the libusb library or directly through Linux kernel interfaces. Linux kernel 6.0 introduced a standard mechanism for disabling ports through sysfs. The utility tries this first, and if you're running an older system or macOS, it switches to libusb.

There's one nuance with USB 3.0. When you connect a modern hub to a USB 3.0 port, the system sees it as two separate logical devices: a virtual USB 2.0 hub and a virtual USB 3.0 hub. If you cut power to the port on only one branch, the connected device may simply switch to the other speed and continue working. uhubctl handles this routine for you and performs a synchronous disconnect on both virtual hubs.

Installation and Quick Start

In most Linux distributions, the utility is already available in the standard repositories:

sudo apt install uhubctl

For macOS, installation goes through Homebrew:

brew install uhubctl

If your distribution has an outdated version, compiling from Git sources is straightforward. You'll need libusb-1.0 and make:

git clone https://github.com/mvp/uhubctl
cd uhubctl
make
sudo make install

First, you should run the utility without parameters to see a list of available hubs and devices connected to them:

sudo uhubctl

The command will output the bus topology, hub addresses in 1-1 or 2-3.1 format, and the state of each port.

Command Examples

To cut power to the second port on the default hub, run:

sudo uhubctl -a off -p 2

Instead of off and on, you can pass the cycle action. It disables power, waits a short pause, and turns it back on. This is suitable for a hard reset of frozen equipment:

sudo uhubctl -a cycle -p 2 -d 3

The -d 3 parameter sets a 3-second delay before restoring power. If you need to reset several ports at once, specify them separated by commas or a dash: -p 1,3,4 or -p 1-4.

Configuring Access Rights in Linux

By default, working directly with USB devices requires root privileges. To avoid running scripts through sudo, add udev rules to the /etc/udev/rules.d/52-usb.rules file:

SUBSYSTEM=="usb", DRIVER=="hub|usb", MODE="0666" SUBSYSTEM=="usb", DRIVER=="hub|usb", RUN="/bin/sh -c \"chmod -f 666 $sys$devpath/*port*/disable || true\""

After that, run sudo udevadm trigger --attr-match=subsystem=usb, and the permissions will update.

Practical Use Cases

Developers and system administrators use uhubctl in a wide variety of tasks:

  • Automatic reset of frozen LTE modems and routers in monitoring farms.
  • Control of external LED indicators, fans, or webcams.
  • Safe disconnection of external hard drives to eliminate phantom load and save energy.
  • Integration with OctoPrint for remotely turning a 3D printer on and off.
  • Hardware testing in CI/CD pipelines when you need to physically reconnect a debug board to the test bench.

Limitations and Hardware Specifics

Before embedding the utility into your scripts, you should check the hardware specifics of your system. For example, on some Raspberry Pi models, the power lines of all four ports are connected in parallel. When trying to turn off one port, the system will cut power to all four at once.

Additionally, some USB-powered gadgets continue to draw charging current even if the data signal lines are disconnected. In this case, only testing the specific hub with a multimeter or load resistor will help.

If you're building an autonomous test bench, a smart home, or managing servers with connected peripherals, uhubctl is one of those compact tools that save you from long trips to stranded hardware. The program is distributed under the GPLv2 license and solves its task without unnecessary complexity. The main thing before starting is to make sure your USB hub supports power management.

Related projects