usbhubd: gate port-indicator SetPortFeature on hub capability

SetPortFeature(PORT_INDICATOR) was issued unconditionally for every
connected+enabled port. QEMU's usb-hub does not advertise indicator
support and NAKs the request indefinitely; with no control-transfer
timeout the daemon hung before the post-enable debounce, so devices
behind the hub never attached. Gate on wHubCharacteristics bit 7
(HUB_CHAR_PORTIND, USB 2.0 Table 11-13), matching Linux hub_configure's
has_indicators check.
This commit is contained in:
Red Bear OS
2026-07-19 19:11:36 +09:00
parent ef34223201
commit 0e948dd2a7
+11 -4
View File
@@ -159,7 +159,7 @@ fn main() {
.expect("Failed to find suitable configuration");
// Read hub descriptor
let (ports, usb_3, b_pwr_on_2_pwr_good, w_hub_delay, device_removable) = if desc.major_version() >= 3 {
let (ports, usb_3, b_pwr_on_2_pwr_good, w_hub_delay, device_removable, hub_characteristics) = if desc.major_version() >= 3 {
let mut hub_desc = usb::HubDescriptorV3::default();
handle
.device_request(
@@ -179,6 +179,7 @@ fn main() {
10u8,
u16::from(hub_desc.delay),
hub_desc.device_removable,
hub_desc.characteristics,
)
} else {
let mut hub_desc = usb::HubDescriptorV2::default();
@@ -200,6 +201,7 @@ fn main() {
// USB 2.0 device_removable bitmaps are variable-length and
// not parsed (see hub.rs).
0u16,
hub_desc.characteristics,
)
};
@@ -526,9 +528,14 @@ fn main() {
continue;
}
// Linux 7.1: port indicator — set amber during reset/power-on,
// green when enabled. Helps diagnose which port is active.
if snap.connected && snap.enabled && !snap.resetting {
// Gate on wHubCharacteristics bit 7 (HUB_CHAR_PORTIND, USB 2.0
// Table 11-13; Linux hub_configure's has_indicators): a hub that
// does not advertise indicator support may NAK this request
// indefinitely, and these control transfers have no timeout.
const HUB_CHAR_PORTIND: u16 = 0x0080;
if snap.connected && snap.enabled && !snap.resetting
&& (hub_characteristics & HUB_CHAR_PORTIND) != 0
{
let _ = set_feature(&handle, port, usb::HubPortFeature::PortIndicator);
}