mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
board/common: fix authorization cascade for internal USB hubs
Two related problems prevented devices behind an intermediate hub (e.g.
the VIA Labs hub on the RPi 400's VL805 xHCI) from being authorized
when confd unlocks a USB bus:
1. Cascade ordering: usb_authorize() ran nftw() with FTW_DEPTH, which
visits children before the root-hub entry. The hub was authorized
while authorized_default was still 2, so when the kernel probed the
hub's children it immediately denied them. Fix: write
authorized_default=1 on the bus before entering nftw.
2. Slow/async probe: hub port enumeration is asynchronous — devices
behind a hub may appear in sysfs after nftw has already finished.
Fix: add a udev rule that catches usb_device add events on buses
where authorized_default=1 is already set on any ancestor root hub
and authorizes them immediately.
The ATTRS{} matcher in udev walks the full sysfs parent chain, so
authorized_default=1 on the root hub is visible even for devices several
hubs deep. Buses still locked at authorized_default=0 are left alone.
Also expand the docstring in generic_usb_ports() to document the
design: each root hub gets its own uniquely-named entry (USB, or USB1/
USB2/... when multiple) so buses can be individually controlled, and
boards needing finer control should use DT usb-ports annotations.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -78,6 +78,17 @@ static bool usb_authorize(struct json_t *root, const char *name, int enabled)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Set authorized_default=1 on the bus BEFORE nftw
|
||||
* authorizes individual devices. With FTW_DEPTH,
|
||||
* nftw visits children before the root-hub entry, so
|
||||
* without this a hub would be authorized first while
|
||||
* authorized_default is still 2. Setting it here
|
||||
* ensures devices appearing behind an intermediate
|
||||
* hub are auto-authorized by the kernel as they probe.
|
||||
*/
|
||||
if (fexist(apath))
|
||||
writedf(1, "w", "%s", apath);
|
||||
if (realpath(path, apath))
|
||||
nftw(apath, dir_cb, 20, FTW_DEPTH | FTW_PHYS);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user