diff --git a/xhcid/src/main.rs b/xhcid/src/main.rs index ae876f9643..7f76153d7c 100644 --- a/xhcid/src/main.rs +++ b/xhcid/src/main.rs @@ -63,10 +63,6 @@ pub mod driver_interface; mod usb; mod xhci; -async fn handle_packet(hci: Arc, packet: Packet) -> Packet { - todo!() -} - #[cfg(target_arch = "x86_64")] fn get_int_method( pcid_handle: &mut PciFunctionHandle, @@ -224,7 +220,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { let socket_fd = libredox::call::open(format!(":{}", scheme_name), flag::O_RDWR | flag::O_CREAT, 0) .expect("xhcid: failed to create usb scheme"); - let socket = Arc::new(Mutex::new(unsafe { File::from_raw_fd(socket_fd as RawFd) })); + let mut socket = unsafe { File::from_raw_fd(socket_fd as RawFd) }; daemon.ready().expect("xhcid: failed to notify parent"); @@ -238,20 +234,8 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { hci.poll(); - //let event_queue = RawEventQueue::new().expect("xhcid: failed to create event queue"); - - let todo = Arc::new(Mutex::new(Vec::::new())); - //let todo_futures = Arc::new(Mutex::new(Vec:: + Send + Sync + 'static>>>::new())); - - //let socket_fd = socket.lock().unwrap().as_raw_fd(); - //event_queue.subscribe(socket_fd as usize, 0, event::EventFlags::READ).unwrap(); - - let socket_packet = socket.clone(); - + let mut todo = Vec::::new(); loop { - let mut socket = socket_packet.lock().unwrap(); - let mut todo = todo.lock().unwrap(); - let mut packet = Packet::default(); match socket.read(&mut packet) { Ok(0) => break, diff --git a/xhcid/src/xhci/irq_reactor.rs b/xhcid/src/xhci/irq_reactor.rs index 6a1bd86908..3317ee11e7 100644 --- a/xhcid/src/xhci/irq_reactor.rs +++ b/xhcid/src/xhci/irq_reactor.rs @@ -34,6 +34,14 @@ pub struct State { is_isoch_or_vf: bool, } +impl State { + fn finish(self, message: Option) { + *self.message.lock().unwrap() = message; + trace!("Waking up future with waker: {:?}", self.waker); + self.waker.wake(); + } +} + #[derive(Debug)] pub struct NextEventTrb { pub event_trb: Trb, @@ -401,13 +409,10 @@ impl IrqReactor { }; // TODO: Validate the command TRB. - *state.message.lock().unwrap() = Some(NextEventTrb { + state.finish(Some(NextEventTrb { src_trb: Some(command_trb.clone()), event_trb: trb.clone(), - }); - - trace!("Waking up future with waker: {:?}", state.waker); - state.waker.wake(); + })); return; } else if trb.completion_trb_pointer().is_none() { @@ -419,12 +424,9 @@ impl IrqReactor { first_phys_ptr, last_phys_ptr, ring_id, - } if trb.trb_type() == TrbType::Transfer as u8 => { - if let Some(src_trb) = trb - .transfer_event_trb_pointer() - .map(|ptr| self.hci.get_transfer_trb(ptr, ring_id)) - .flatten() - { + } => { + // Check if the TRB matches the transfer + if trb.trb_type() == TrbType::Transfer as u8 { match trb.transfer_event_trb_pointer() { Some(phys_ptr) => { let matches = if first_phys_ptr <= last_phys_ptr { @@ -434,13 +436,13 @@ impl IrqReactor { phys_ptr >= first_phys_ptr || phys_ptr <= last_phys_ptr }; if matches { + let src_trb = self.hci.get_transfer_trb(phys_ptr, ring_id); // Give the source transfer TRB together with the event TRB, to the future. let state = self.states.remove(index); - *state.message.lock().unwrap() = Some(NextEventTrb { - src_trb: Some(src_trb), + state.finish(Some(NextEventTrb { + src_trb: src_trb, event_trb: trb.clone(), - }); - state.waker.wake(); + })); return; } } @@ -461,11 +463,23 @@ impl IrqReactor { } } } + + // Also check if the transfer is on a dead ring + if self.hci.with_ring(ring_id, |_ring| ()).is_none() { + log::debug!("State {} is a dead transfer", index); + let state = self.states.remove(index); + state.finish(Some(NextEventTrb { + src_trb: None, + //TODO: don't send this TRB as it may not be related + event_trb: trb.clone(), + })); + continue; + } } StateKind::Other(trb_type) if trb_type as u8 == trb.trb_type() => { let state = self.states.remove(index); - state.waker.wake(); + state.finish(None); return; } @@ -493,11 +507,10 @@ impl IrqReactor { continue; } let state = self.states.remove(index); - *state.message.lock().unwrap() = Some(NextEventTrb { + state.finish(Some(NextEventTrb { event_trb: trb.clone(), src_trb: None, - }); - state.waker.wake(); + })); } } /// Checks if an event TRB is a Host Controller Event, with the completion code Event Ring diff --git a/xhcid/src/xhci/mod.rs b/xhcid/src/xhci/mod.rs index 2d26601c6a..1c32b122c0 100644 --- a/xhcid/src/xhci/mod.rs +++ b/xhcid/src/xhci/mod.rs @@ -162,7 +162,7 @@ impl Xhci { debug!("Waiting for the next transfer event TRB..."); let trbs = future.await; let event_trb = trbs.event_trb; - let status_trb = trbs.src_trb.unwrap(); + let status_trb = trbs.src_trb.ok_or(Error::new(EIO))?; trace!("Handling the transfer event TRB!"); self::scheme::handle_transfer_event_trb("GET_DESC", &event_trb, &status_trb)?; @@ -698,6 +698,7 @@ impl Xhci { Ok(event_trb.event_slot()) } pub async fn disable_port_slot(&self, slot: u8) -> Result<()> { + trace!("Disable slot {}", slot); let (event_trb, command_trb) = self .execute_command(|cmd, cycle| cmd.disable_slot(slot, cycle)) .await; diff --git a/xhcid/src/xhci/scheme.rs b/xhcid/src/xhci/scheme.rs index a2f780dce7..1fd3631b90 100644 --- a/xhcid/src/xhci/scheme.rs +++ b/xhcid/src/xhci/scheme.rs @@ -651,7 +651,7 @@ impl Xhci { let trbs = future.await; let event_trb = trbs.event_trb; - let status_trb = trbs.src_trb.unwrap(); + let status_trb = trbs.src_trb.ok_or(Error::new(EIO))?; handle_transfer_event_trb("CONTROL_TRANSFER", &event_trb, &status_trb)?; @@ -748,7 +748,7 @@ impl Xhci { let trbs = future.await; let event_trb = trbs.event_trb; - let transfer_trb = trbs.src_trb.unwrap(); + let transfer_trb = trbs.src_trb.ok_or(Error::new(EIO))?; handle_transfer_event_trb("EXECUTE_TRANSFER", &event_trb, &transfer_trb)?; @@ -1136,7 +1136,7 @@ impl Xhci { .c .write(u32::from(avg_trb_len) | (u32::from(max_esit_payload_lo) << 16)); - log::info!("INITIALIZED ENDPOINT {}", endp_num); + log::info!("initialized endpoint {}", endp_num); } {