Use an event queue in the IRQ reactor.

This commit is contained in:
4lDO2
2020-03-28 12:30:32 +01:00
parent 9e34ed3fbf
commit e58245b280
+22 -8
View File
@@ -5,12 +5,16 @@ use std::io::prelude::*;
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use std::sync::atomic::{self, AtomicUsize};
use std::{mem, task, thread};
use std::{io, mem, task, thread};
use std::os::unix::io::AsRawFd;
use crossbeam_channel::{Sender, Receiver};
use futures::Stream;
use syscall::Io;
use event::EventQueue;
use super::Xhci;
use super::ring::Ring;
use super::trb::{Trb, TrbCompletionCode, TrbType};
@@ -126,18 +130,26 @@ impl IrqReactor {
}
fn run_with_irq_file(mut self) {
let hci_clone = Arc::clone(&self.hci);
let mut event_queue = EventQueue::<()>::new().expect("xhcid irq_reactor: failed to create IRQ event queue");
let irq_fd = self.irq_file.as_ref().unwrap().as_raw_fd();
'event_loop: loop {
self.handle_requests();
event_queue.add(irq_fd, move |_| -> io::Result<Option<()>> {
let mut buffer = [0u8; 8];
let bytes_read = self.irq_file.as_mut().unwrap().read(&mut buffer).expect("Failed to read from irq scheme");
self.handle_requests();
if bytes_read < mem::size_of::<usize>() {
panic!("wrong number of bytes read from `irq:`: expected {}, got {}", mem::size_of::<usize>(), bytes_read);
// continue the loop when the next IRQ arrives
return Ok(None);
}
if !self.hci.received_irq() {
continue;
// continue only when an IRQ to this device was received
return Ok(None);
}
let _ = self.irq_file.as_mut().unwrap().write(&buffer);
@@ -153,18 +165,20 @@ impl IrqReactor {
if trb.completion_code() == TrbCompletionCode::Invalid as u8 {
if count == 0 { println!("xhci: Received interrupt, but no event was found in the event ring. Ignoring interrupt.") }
continue 'event_loop;
// no more events were found, continue the loop
return Ok(None);
} else { count += 1 }
if self.check_event_ring_full(trb.clone()) {
continue 'trb_loop;
return Ok(None);
}
self.acknowledge(trb.clone());
trb.reserved(false);
self.update_erdp();
}
}
}).expect("xhcid: failed to catch irq events");
event_queue.run().expect("xhcid: failed to run IRQ event queue");
}
fn update_erdp(&self) {
let dequeue_pointer_and_dcs = self.hci.primary_event_ring.lock().unwrap().erdp();