xhcid: remove transfer states on dead rings
This commit is contained in:
+2
-18
@@ -63,10 +63,6 @@ pub mod driver_interface;
|
||||
mod usb;
|
||||
mod xhci;
|
||||
|
||||
async fn handle_packet(hci: Arc<Xhci>, 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::<Packet>::new()));
|
||||
//let todo_futures = Arc::new(Mutex::new(Vec::<Pin<Box<dyn Future<Output = usize> + 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::<Packet>::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,
|
||||
|
||||
@@ -34,6 +34,14 @@ pub struct State {
|
||||
is_isoch_or_vf: bool,
|
||||
}
|
||||
|
||||
impl State {
|
||||
fn finish(self, message: Option<NextEventTrb>) {
|
||||
*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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user