usbhubd/xhcid: fix reading descriptor on USB 3 hubs

This commit is contained in:
Jeremy Soller
2025-03-28 18:27:29 -06:00
parent ba0ca4ce05
commit cbbcbc9ec3
2 changed files with 78 additions and 17 deletions
+32 -16
View File
@@ -58,19 +58,35 @@ fn main() {
.expect("Failed to find suitable configuration");
// Read hub descriptor
let mut hub_desc = usb::HubDescriptor::default();
handle
.device_request(
PortReqTy::Class,
PortReqRecipient::Device,
usb::SetupReq::GetDescriptor as u8,
// 0x29 is USB 2.0 hub descriptor
// TODO: suppot reading USB 3.0 descriptor?
0x29_00,
0,
DeviceReqData::In(unsafe { plain::as_mut_bytes(&mut hub_desc) }),
)
.expect("Failed to read hub descriptor");
let ports = if desc.major_version() >= 3 {
// USB 3.0 hubs
let mut hub_desc = usb::HubDescriptor3::default();
handle
.device_request(
PortReqTy::Class,
PortReqRecipient::Device,
usb::SetupReq::GetDescriptor as u8,
u16::from(usb::HubDescriptor3::DESCRIPTOR_KIND) << 8,
0,
DeviceReqData::In(unsafe { plain::as_mut_bytes(&mut hub_desc) }),
)
.expect("Failed to read hub descriptor");
hub_desc.ports
} else {
// USB 2.0 and earlier hubs
let mut hub_desc = usb::HubDescriptor::default();
handle
.device_request(
PortReqTy::Class,
PortReqRecipient::Device,
usb::SetupReq::GetDescriptor as u8,
u16::from(usb::HubDescriptor::DESCRIPTOR_KIND) << 8,
0,
DeviceReqData::In(unsafe { plain::as_mut_bytes(&mut hub_desc) }),
)
.expect("Failed to read hub descriptor");
hub_desc.ports
};
// Configure as hub device
handle
@@ -78,7 +94,7 @@ fn main() {
config_desc: conf_desc.configuration_value,
interface_desc: Some(interface_num),
alternate_setting: Some(if_desc.alternate_setting),
hub_ports: Some(hub_desc.ports),
hub_ports: Some(ports),
})
.expect("Failed to configure endpoints after reading hub descriptor");
@@ -120,7 +136,7 @@ fn main() {
}
let mut states = Vec::new();
for port in 1..=hub_desc.ports {
for port in 1..=ports {
let child_port_id = port_id.child(port).expect("Cannot get child port ID");
states.push(PortState {
port_id: child_port_id,
@@ -132,7 +148,7 @@ fn main() {
//TODO: use change flags?
loop {
for port in 1..=hub_desc.ports {
for port in 1..=ports {
let port_idx: usize = port.checked_sub(1).unwrap().into();
let mut state = states.get_mut(port_idx).unwrap();
+46 -1
View File
@@ -2,7 +2,6 @@
#[derive(Clone, Copy, Debug)]
pub struct HubDescriptor {
pub length: u8,
// 0x29 for USB 2, 0x2A for USB 3
pub kind: u8,
pub ports: u8,
pub characteristics: u16,
@@ -17,6 +16,10 @@ pub struct HubDescriptor {
unsafe impl plain::Plain for HubDescriptor {}
impl HubDescriptor {
pub const DESCRIPTOR_KIND: u8 = 0x29;
}
impl Default for HubDescriptor {
fn default() -> Self {
Self {
@@ -33,6 +36,48 @@ impl Default for HubDescriptor {
}
}
#[repr(C, packed)]
#[derive(Clone, Copy, Debug)]
pub struct HubDescriptor3 {
pub length: u8,
pub kind: u8,
pub ports: u8,
pub characteristics: u16,
pub power_on_good: u8,
pub current: u8,
pub decode_latency: u8,
pub delay: u16,
/*TODO: USB 2 and 3 disagree on the descriptor, so some fields are disabled
// device_removable: bitmap of ports, maximum of 256 bits (32 bytes)
// power_control_mask: bitmap of ports, maximum of 256 bits (32 bytes)
bitmaps: [u8; 64],
*/
}
unsafe impl plain::Plain for HubDescriptor3 {}
impl HubDescriptor3 {
pub const DESCRIPTOR_KIND: u8 = 0x2A;
}
impl Default for HubDescriptor3 {
fn default() -> Self {
Self {
length: 0,
kind: 0,
ports: 0,
characteristics: 0,
power_on_good: 0,
current: 0,
decode_latency: 0,
delay: 0,
/*
bitmaps: [0; 64],
*/
}
}
}
#[derive(Clone, Copy, Debug)]
#[repr(u8)]
pub enum HubFeature {