0

TLDR; I want to disable the USB hub on a RPi4 until boot is complete.

Hi, I am trying to solve a problem that I have not seen posted about.

I have a RPi4 with multiple RPiZs plugged into it acting as ethernet gadgets. The RPiZs connect to different interfaces (usb1:usb4) based on udev rules and interfaces set up in the /etc/dhcpcd.conf which match the set ups on the individual RPiZ.

When I plug a RPiZ into the RPi4 via USB, it powers up and connects via ethernet over usb. The RPi4 assigns the corresponding interface and IP address perfectly.

However, an issue occurs if the entire system is powered on at the same time. The ethernet over usb connection is made before the rules are established and the RPiZ is assigned to interface usb0 and given a random ip-address.

I have a simple script (see below) based on this question: How do I reset a USB device using a script?

The script resets USB hub which resets the network which fixes the interfaces and IP addresses. However, for automation reasons, it is important that connections are right on the first try.

I suspect the problem would be solved if I could disable the USB hub (either power or just data) until the boot is complete. I have seen a lot of threads about disabling USB after boot, but none about disabling before boot. I would appreciate any help I can get. Thanks.

# /etc/udev/rules.d/90-usbpi.rules
SUBSYSTEM=="net", ATTR{address}=="00:22:82:ff:ff:01", NAME="usb1"
SUBSYSTEM=="net", ATTR{address}=="00:22:82:ff:ff:02", NAME="usb2"
SUBSYSTEM=="net", ATTR{address}=="00:22:82:ff:ff:03", NAME="usb3"
SUBSYSTEM=="net", ATTR{address}=="00:22:82:ff:ff:04", NAME="usb4"
# added to /etc/dhcpcd.conf.
interface usb1
static ip_address=10.0.11.1/24
    
interface usb2
static ip_address=10.0.12.1/24
    
interface usb3
static ip_address=10.0.13.1/24

interface usb4
static ip_address=10.0.14.1/24
#!/bin/bash


ID=0525:a4a2

logger "Searching for $ID"
devPath=`lsusb | grep $ID | sed -r 's/Bus ([0-9]{3}) Device ([0-9]{3}).*/bus\/usb\/\1\/\2/g;'`
logger "Found $ID @ $devPath"
logger "Searching for sysPath"
for sysPath in /sys/bus/usb/devices/*; do
    logger "$sysPath/uevent"
    devName=`cat "$sysPath/uevent" | grep $devPath`
    #logger devName=$devName
    if [ ! -z $devName ] 
    then
        break
    fi
done
if [ ! -z  $devName ] 
then
    logger "Found $ID @ $sysPath, Resetting"
    logger "echo 0 > $sysPath/authorized"
    echo 0 > $sysPath/authorized
    logger "echo 1 > $sysPath/authorized"
    echo 1 > $sysPath/authorized
else
    logger "Could not find $ID"
fi
1
  • you say the RPiZ is assigned to interface usb0 but you have 4 x RPiZ, what happens to the other 3 RPiZ's? May 8, 2023 at 0:43

1 Answer 1

1

AFAIK it is not possible to "disable the USB hub" but this would be a kludge in any event.

Relying on automatic enumeration of attached devices is unpredictable.

You should explore predictable network interface names which is the normal solution to the problem of multiple interfaces.
Network interfaces will have names formed from a prefix en — Ethernet or wl — wlan followed by x indicating MAC and the MAC e.g. enxb827eb123456 or wlx00c140123456. The onboard WiFi of the Pi4, Pi3 and PIZeroW which is connected over sdio will continue to use the name wlan0

I am not sure if this would work with ethernet gadgets but you could give it a try.

In any event it you do want to allocate using udev rules you should avoid names which conflict with automatic enumeration names.

Another suggestion is that you avoid IP addresses (I don't care what IP my multiple machines are allocated). I give each a unique hostname and connect using hostname.local.

2
  • Thanks. This might be the answer, but I'll have to set up a test. When I originally set this up (maybe pre stretch release), I had an issue with the dynamic addresses. While the each RPiZ had different interfaces, they were all on the same subnet. As a result all traffic was sent down the first interface rather than being assigned to the correct interface. It took me a while to figure that out, and manually assigning everything fixed it. If I'm reading you right, that issue may not exist anymore? FYI, I also modified the ethernet address for each RPiZ.
    – Rusty
    May 10, 2023 at 23:42
  • I just tried on a Pi Zero (actually a Pi Zero W with broken WiFI). hostname.local worked
    – Milliways
    May 11, 2023 at 2:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.