diff --git a/xhcid/src/xhci/mod.rs b/xhcid/src/xhci/mod.rs index fbf75bff59..fe633432db 100644 --- a/xhcid/src/xhci/mod.rs +++ b/xhcid/src/xhci/mod.rs @@ -465,12 +465,12 @@ impl Xhci { pub fn init(&mut self, max_slots: u8) -> Result<()> { // Set run/stop to 0 debug!("Stopping xHC."); - self.op.get_mut().unwrap().usb_cmd.writef(1, false); + self.op.get_mut().unwrap().usb_cmd.writef(USB_CMD_RS, false); // Warm reset debug!("Reset xHC"); - self.op.get_mut().unwrap().usb_cmd.writef(1 << 1, true); - while self.op.get_mut().unwrap().usb_cmd.readf(1 << 1) { + self.op.get_mut().unwrap().usb_cmd.writef(USB_CMD_HCRST, true); + while self.op.get_mut().unwrap().usb_cmd.readf(USB_CMD_HCRST) { thread::yield_now(); } @@ -531,18 +531,18 @@ impl Xhci { debug!("Enabling Primary Interrupter."); int.iman.writef(1 << 1 | 1, true); } - self.op.get_mut().unwrap().usb_cmd.writef(1 << 2, true); + self.op.get_mut().unwrap().usb_cmd.writef(USB_CMD_INTE, true); // Setup the scratchpad buffers that are required for the xHC to function. self.setup_scratchpads()?; // Set run/stop to 1 debug!("Starting xHC."); - self.op.get_mut().unwrap().usb_cmd.writef(1, true); + self.op.get_mut().unwrap().usb_cmd.writef(USB_CMD_RS, true); // Wait until controller is running debug!("Waiting for start request to complete."); - while self.op.get_mut().unwrap().usb_sts.readf(1) { + while self.op.get_mut().unwrap().usb_sts.readf(USB_STS_HCH) { trace!("Waiting for XHCI to report running status."); } @@ -796,7 +796,7 @@ impl Xhci { info!("Attempting to address the device"); let mut ring = match self - .address_device(&mut input, port_id, slot_ty, slot, protocol_speed) + .address_device(&mut input, port_id, slot_ty, slot, protocol_speed, speed) .await { Ok(device_ring) => device_ring, @@ -1012,6 +1012,7 @@ impl Xhci { slot_ty: u8, slot: u8, protocol_speed: &ProtocolSpeed, + speed: u8, ) -> Result { // Collect MTT, parent port number, parent slot ID let mut mtt = false; @@ -1057,6 +1058,7 @@ impl Xhci { assert_eq!(route_string & 0x000F_FFFF, route_string); slot_ctx.a.write( route_string + | (u32::from(speed) << 20) | (u32::from(mtt) << 25) | (u32::from(hub) << 26) | (u32::from(context_entries) << 27), @@ -1087,16 +1089,12 @@ impl Xhci { let max_error_count = 3u8; // recommended value according to the XHCI spec let ep_ty = 4u8; // control endpoint, bidirectional - let max_packet_size: u32 = if protocol_speed.is_lowspeed() { - 8 // only valid value - } else if protocol_speed.is_fullspeed() { - 64 // valid values are 8, 16, 32, 64 + let max_packet_size: u32 = if protocol_speed.is_lowspeed() || protocol_speed.is_fullspeed() { + 8 } else if protocol_speed.is_highspeed() { - 64 // only valid value - } else if protocol_speed.is_superspeed_gen_x() { - 512 // only valid value + 64 } else { - unreachable!() + 512 }; let host_initiate_disable = false; // only applies to streams let max_burst_size = 0u8; // TODO @@ -1110,9 +1108,14 @@ impl Xhci { | (u32::from(max_packet_size) << 16), ); + let dequeue_cycle_state = true; let tr = ring.register(); endp_ctx.trh.write((tr >> 32) as u32); - endp_ctx.trl.write(tr as u32); + endp_ctx.trl.write((tr as u32) | u32::from(dequeue_cycle_state)); + + // The default control pipe can always use 8 bytes + let avg_trb_len = 8u8; + endp_ctx.c.write(u32::from(avg_trb_len)); } let input_context_physical = input_context.physical(); diff --git a/xhcid/src/xhci/operational.rs b/xhcid/src/xhci/operational.rs index 4ac6549179..12be477296 100644 --- a/xhcid/src/xhci/operational.rs +++ b/xhcid/src/xhci/operational.rs @@ -80,6 +80,8 @@ pub struct OperationalRegs { pub const USB_CMD_RS: u32 = 1 << 0; /// Host controller reset pub const USB_CMD_HCRST: u32 = 1 << 1; +// Interrupter enable +pub const USB_CMD_INTE: u32 = 1 << 2; /// Host controller halted pub const USB_STS_HCH: u32 = 1 << 0;