diff --git a/usbhubd/src/main.rs b/usbhubd/src/main.rs index 2dcb6f14e5..98d7798b3e 100644 --- a/usbhubd/src/main.rs +++ b/usbhubd/src/main.rs @@ -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(); diff --git a/xhcid/src/usb/hub.rs b/xhcid/src/usb/hub.rs index 2eeff3ab3d..acc9d0c75e 100644 --- a/xhcid/src/usb/hub.rs +++ b/xhcid/src/usb/hub.rs @@ -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 {