Skip to content

Commit

Permalink
save
Browse files Browse the repository at this point in the history
  • Loading branch information
hikalium committed Jan 17, 2024
1 parent 5588a6b commit fa5a80e
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 50 deletions.
8 changes: 4 additions & 4 deletions os/src/ax88179.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@ async fn read_from_device<T: Sized>(
ddc.push_trb_to_ctrl_ep(
SetupStageTrb::new_vendor_device_in(request, value, index, buf.len() as u16).into(),
)?;
let trb_ptr_to_wait = ddc.push_trb_to_ctrl_ep(DataStageTrb::new_in(buf).into())?;
ddc.push_trb_to_ctrl_ep(DataStageTrb::new_in(buf).into())?;
ddc.push_trb_to_ctrl_ep(StatusStageTrb::new_out().into())?;
ddc.notify_ctrl_ep()?;
ddc.wait_transfer_event(trb_ptr_to_wait).await
ddc.wait_transfer_event().await
}

async fn write_to_device<T: Sized>(
Expand All @@ -122,10 +122,10 @@ async fn write_to_device<T: Sized>(
ddc.push_trb_to_ctrl_ep(
SetupStageTrb::new_vendor_device_out(request, reg, index, buf.len() as u16).into(),
)?;
let trb_ptr_to_wait = ddc.push_trb_to_ctrl_ep(DataStageTrb::new_out(buf).into())?;
ddc.push_trb_to_ctrl_ep(DataStageTrb::new_out(buf).into())?;
ddc.push_trb_to_ctrl_ep(StatusStageTrb::new_in().into())?;
ddc.notify_ctrl_ep()?;
ddc.wait_transfer_event(trb_ptr_to_wait).await
ddc.wait_transfer_event().await
}

async fn write_phy_reg(ddc: &mut UsbDeviceDriverContext, index: u16, value: u16) -> Result<()> {
Expand Down
12 changes: 6 additions & 6 deletions os/src/xhci/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ impl Controller {
pub async fn send_command(&self, cmd: GenericTrbEntry) -> Result<GenericTrbEntry> {
let cmd_ptr = self.command_ring.lock().push(cmd)?;
self.notify_xhc();
CommandCompletionEventFuture::new(&self.primary_event_ring, cmd_ptr)
CommandCompletionEventFuture::new_on_trb(&self.primary_event_ring, cmd_ptr)
.await?
.ok_or(Error::Failed("Timed out"))
}
Expand Down Expand Up @@ -216,7 +216,7 @@ impl Controller {
)?;
let trb_ptr_waiting = ctrl_ep_ring.push(StatusStageTrb::new_in().into())?;
self.notify_ep(slot, 1)?;
TransferEventFuture::new(&self.primary_event_ring, slot, trb_ptr_waiting)
TransferEventFuture::new_on_trb(&self.primary_event_ring, trb_ptr_waiting)
.await?
.ok_or(Error::Failed("Timed out"))?
.completed()
Expand All @@ -240,7 +240,7 @@ impl Controller {
)?;
let trb_ptr_waiting = ctrl_ep_ring.push(StatusStageTrb::new_in().into())?;
self.notify_ep(slot, 1)?;
TransferEventFuture::new(&self.primary_event_ring, slot, trb_ptr_waiting)
TransferEventFuture::new_on_trb(&self.primary_event_ring, trb_ptr_waiting)
.await?
.ok_or(Error::Failed("Timed out"))?
.completed()
Expand All @@ -267,7 +267,7 @@ impl Controller {
)?;
let trb_ptr_waiting = ctrl_ep_ring.push(StatusStageTrb::new_in().into())?;
self.notify_ep(slot, 1)?;
TransferEventFuture::new(&self.primary_event_ring, slot, trb_ptr_waiting)
TransferEventFuture::new_on_trb(&self.primary_event_ring, trb_ptr_waiting)
.await?
.ok_or(Error::Failed("Timed out"))?
.completed()
Expand All @@ -294,7 +294,7 @@ impl Controller {
let trb_ptr_waiting = ctrl_ep_ring.push(DataStageTrb::new_in(buf).into())?;
ctrl_ep_ring.push(StatusStageTrb::new_out().into())?;
self.notify_ep(slot, 1)?;
TransferEventFuture::new(&self.primary_event_ring, slot, trb_ptr_waiting)
TransferEventFuture::new_on_trb(&self.primary_event_ring, trb_ptr_waiting)
.await?
.ok_or(Error::Failed("Timed out"))?
.completed()
Expand All @@ -321,7 +321,7 @@ impl Controller {
let trb_ptr_waiting = ctrl_ep_ring.push(DataStageTrb::new_in(buf).into())?;
ctrl_ep_ring.push(StatusStageTrb::new_out().into())?;
self.notify_ep(slot, 1)?;
TransferEventFuture::new(&self.primary_event_ring, slot, trb_ptr_waiting)
TransferEventFuture::new_on_trb(&self.primary_event_ring, trb_ptr_waiting)
.await?
.ok_or(Error::Failed("Timed out"))?
.completed()
Expand Down
12 changes: 8 additions & 4 deletions os/src/xhci/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,13 @@ impl UsbDeviceDriverContext {
self.xhci.notify_ep(self.slot, ep.dci())
}
pub async fn wait_transfer_event(&mut self) -> Result<()> {
TransferEventFuture::new_with_timeout(self.xhci.primary_event_ring(), self.slot, 10 * 1000)
.await?
.ok_or(Error::Failed("Timed out"))?
.completed()
TransferEventFuture::new_on_slot_with_timeout(
self.xhci.primary_event_ring(),
self.slot,
10 * 1000,
)
.await?
.ok_or(Error::Failed("Timed out"))?
.completed()
}
}
54 changes: 30 additions & 24 deletions os/src/xhci/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ pub struct EventFuture<'a, const E: TrbType> {
_pinned: PhantomPinned,
}
impl<'a, const E: TrbType> EventFuture<'a, E> {
pub fn new_with_timeout(event_ring: &'a Mutex<EventRing>, wait_ms: u64, wait_on: EventFutureWaitType) -> Self {
pub fn new_with_timeout(
event_ring: &'a Mutex<EventRing>,
wait_ms: u64,
wait_on: EventFutureWaitType,
) -> Self {
let time_out = Hpet::take().main_counter() + Hpet::take().freq() / 1000 * wait_ms;
Self {
event_ring,
Expand All @@ -32,48 +36,50 @@ impl<'a, const E: TrbType> EventFuture<'a, E> {
_pinned: PhantomPinned,
}
}
pub fn new_on_slot_with_timeout(event_ring: &'a Mutex<EventRing>, slot: u8, wait_ms: u64) -> Self {
pub fn new_on_slot_with_timeout(
event_ring: &'a Mutex<EventRing>,
slot: u8,
wait_ms: u64,
) -> Self {
Self::new_with_timeout(event_ring, 100, EventFutureWaitType::Slot(slot))
}
pub fn new_on_slot(event_ring: &'a Mutex<EventRing>, slot: u8) -> Self {
Self::new_on_slot_with_timeout(event_ring, slot, 100)
}
pub fn new_on_trb(event_ring: &'a Mutex<EventRing>, trb_addr: u8) -> Self {
Self::new_on_trb_with_timeout(event_ring, 100, EventFutureWaitType::TrbAddr(trb_addr))
pub fn new_on_trb_with_timeout(
event_ring: &'a Mutex<EventRing>,
trb_addr: u64,
wait_ms: u64,
) -> Self {
Self::new_with_timeout(event_ring, wait_ms, EventFutureWaitType::TrbAddr(trb_addr))
}
pub fn new_on_trb(event_ring: &'a Mutex<EventRing>, trb_addr: u64) -> Self {
Self::new_on_trb_with_timeout(event_ring, trb_addr, 100)
}
}
/// Event
impl<'a, const E: TrbType> Future for EventFuture<'a, E> {
type Output = Result<Option<GenericTrbEntry>>;
fn poll(self: Pin<&mut Self>, _: &mut Context) -> Poll<Result<Option<GenericTrbEntry>>> {
let time_out = self.time_out;
if self.time_out < Hpet::take().main_counter() {
return Poll::Ready(Ok(None));
}
let mut_self = unsafe { self.get_unchecked_mut() };
match mut_self.wait_on {
EventFutureWaitType::Slot(slot) => {
let event = mut_self.event_ring.lock().pop_for_slot(slot);
let event = mut_self.event_ring.lock().pop_for_slot(slot);
if let Ok(Some(_)) = event {
return Poll::Ready(event)
} else if time_out < Hpet::take().main_counter() {
return Poll::Ready(Ok(None))
return Poll::Ready(event);
} else {
return Poll::Pending
return Poll::Pending;
}
}
EventFutureWaitType::TrbAddr(trb_addr) => {
let event = mut_self.event_ring.lock().pop();
if let Some()
if event.data
match mut_self.wait_on {
EventFutureWaitType::TrbAddr(trb_addr) {
Poll::Ready(Ok(Some(trb)))
}
EventFutureWaitType::Slot(slot) {
Poll::Ready(Ok(Some(trb)))
}
_ => {
println!("Ignoring event (!= wait_on): {:?}", trb);
Poll::Pending
}
let event = mut_self.event_ring.lock().pop_for_trb(trb_addr);
if let Ok(Some(_)) = event {
return Poll::Ready(event);
} else {
return Poll::Pending;
}
}
}
Expand Down
49 changes: 37 additions & 12 deletions os/src/xhci/ring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ use crate::allocator::ALLOCATOR;
use crate::error::Error;
use crate::error::Result;
use crate::mutex::Mutex;
use crate::println;
use crate::x86_64::paging::disable_cache;
use crate::x86_64::paging::IoBox;
use crate::xhci::trb::GenericTrbEntry;
use crate::xhci::trb::NormalTrb;
use crate::xhci::trb::TrbType;
use alloc::alloc::Layout;
use alloc::collections::VecDeque;
use alloc::collections::BTreeMap;
use alloc::fmt;
use alloc::fmt::Debug;
use alloc::vec::Vec;
use core::marker::PhantomPinned;
use core::mem::size_of;
use core::ptr::null_mut;
Expand Down Expand Up @@ -281,22 +281,21 @@ pub struct EventRing {
erst: IoBox<EventRingSegmentTableEntry>,
cycle_state_ours: bool,
erdp: Option<*mut u64>,
// slot_queues[slot]
slot_queues: Vec<VecDeque<GenericTrbEntry>>,
events_per_slot: BTreeMap<u8, GenericTrbEntry>,
events_per_trb: BTreeMap<u64, GenericTrbEntry>,
}
impl EventRing {
pub fn new() -> Result<Self> {
let ring = TrbRing::new();
let erst = EventRingSegmentTableEntry::new(&ring)?;
disable_cache(&erst);
let mut slot_queues = Vec::new();
slot_queues.resize_with(256, Default::default);
Ok(Self {
ring,
erst,
cycle_state_ours: true,
erdp: None,
slot_queues,
events_per_slot: BTreeMap::new(),
events_per_trb: BTreeMap::new(),
})
}
pub fn set_erdp(&mut self, erdp: *mut u64) {
Expand All @@ -312,7 +311,7 @@ impl EventRing {
self.ring.as_ref().current().cycle_state() == self.cycle_state_ours
}
/// Non-blocking
pub fn pop(&mut self) -> Result<Option<GenericTrbEntry>> {
fn pop(&mut self) -> Result<Option<GenericTrbEntry>> {
if !self.has_next_event() {
return Ok(None);
}
Expand All @@ -331,8 +330,8 @@ impl EventRing {
/// Non-blocking
pub fn pop_for_slot(&mut self, slot: u8) -> Result<Option<GenericTrbEntry>> {
{
let sq = &mut self.slot_queues[slot as usize];
if let Some(e) = sq.pop_front() {
// If an event for a slot is already there, pop it.
if let Some(e) = self.events_per_slot.remove(&slot) {
return Ok(Some(e));
}
}
Expand All @@ -343,8 +342,34 @@ impl EventRing {
if e.slot_id() == slot {
return Ok(Some(e));
}
let sq = &mut self.slot_queues[slot as usize];
sq.push_back(e);
let slot = e.slot_id();
if let Some(e) = self.events_per_slot.get(&slot) {
println!("Warning: losing {e:?}");
}
self.events_per_slot.insert(slot, e);
}
Ok(None)
}
/// Checks new events arrived, and if an event for the specified slot is found, return it.
/// Non-blocking
pub fn pop_for_trb(&mut self, trb_addr: u64) -> Result<Option<GenericTrbEntry>> {
{
// If an event for a slot is already there, pop it.
if let Some(e) = self.events_per_trb.remove(&trb_addr) {
return Ok(Some(e));
}
}
while self.has_next_event() {
let e = self
.pop()?
.ok_or(Error::Failed("Expected some entries but it was empty"))?;
if e.data() == trb_addr {
return Ok(Some(e));
}
if let Some(e) = self.events_per_trb.get(&trb_addr) {
println!("Warning: losing {e:?}");
}
self.events_per_trb.insert(trb_addr, e);
}
Ok(None)
}
Expand Down

0 comments on commit fa5a80e

Please sign in to comment.