Skip to content

Commit

Permalink
Fix losing USB events
Browse files Browse the repository at this point in the history
  • Loading branch information
hikalium committed Aug 24, 2024
1 parent cd5790b commit 0282da6
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 135 deletions.
50 changes: 23 additions & 27 deletions os/src/ax88179.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,35 +312,31 @@ pub async fn attach_usb_device(mut ddc: UsbDeviceDriverContext) -> Result<()> {
)
.await;
match event_trb {
Ok(trbs) => {
for trb in trbs {
println!(
"slot = {}, dci = {}, length = {}",
ddc.slot(),
trb.dci(),
trb.transfer_length()
);
if trb.dci() != 1 {
if let Some(ref mut tring) = ddc.ep_ring(trb.dci())?.as_ref() {
let cmd = tring.current();
let data = unsafe {
Mmio::<[u8; 8]>::from_raw(
*(cmd.data() as *const usize) as *mut [u8; 8],
)
};
hexdump(data.as_ref());
let transfer_trb_ptr = trb.data() as usize;
tring.dequeue_trb(transfer_trb_ptr)?;
println!("{:#018X}", transfer_trb_ptr);
ddc.xhci().notify_ep(ddc.slot(), trb.dci())?;
println!("{:?}", tring)
}
Ok(trb) => {
println!(
"slot = {}, dci = {}, length = {}",
ddc.slot(),
trb.dci(),
trb.transfer_length()
);
if trb.dci() != 1 {
if let Some(ref mut tring) = ddc.ep_ring(trb.dci())?.as_ref() {
let cmd = tring.current();
let data = unsafe {
Mmio::<[u8; 8]>::from_raw(*(cmd.data() as *const usize) as *mut [u8; 8])
};
hexdump(data.as_ref());
let transfer_trb_ptr = trb.data() as usize;
tring.dequeue_trb(transfer_trb_ptr)?;
println!("{:#018X}", transfer_trb_ptr);
ddc.xhci().notify_ep(ddc.slot(), trb.dci())?;
println!("{:?}", tring)
}
let status = read_mac_reg_u16(&mut ddc, MAC_REG_MEDIUM_STATUS_MODE).await?;
println!("status: {:#06X}", status);
let gmii_phy_status = read_phy_reg(&mut ddc, GMII_PHY_PHYSR).await?;
println!("gmii_phys_link: {:#04X}", gmii_phy_status);
}
let status = read_mac_reg_u16(&mut ddc, MAC_REG_MEDIUM_STATUS_MODE).await?;
println!("status: {:#06X}", status);
let gmii_phy_status = read_phy_reg(&mut ddc, GMII_PHY_PHYSR).await?;
println!("gmii_phys_link: {:#04X}", gmii_phy_status);
}
Err(e) => {
println!("Error: {:?}", e);
Expand Down
75 changes: 36 additions & 39 deletions os/src/usb_hid_keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,52 +103,49 @@ pub async fn usb_hid_keyboard_mainloop(ddc: UsbDeviceDriverContext) -> Result<()
let xhci = ddc.xhci();
let portsc = xhci.portsc(port)?.upgrade().ok_or("PORTSC was invalid")?;
let mut prev_pressed_keys = BitSet::<32>::new();
let event_trb = EventFuture::new_transfer_event_on_slot(xhci.primary_event_ring(), slot);
loop {
let event_trb =
EventFuture::new_transfer_event_on_slot(xhci.primary_event_ring(), slot).await;
let event_trb = event_trb.clone().await;
match event_trb {
Ok(trbs) => {
info!("kbd trbs: {trbs:?}");
for trb in trbs {
let transfer_trb_ptr = trb.data() as usize;
let mut report = [0u8; 8];
report.copy_from_slice(
unsafe {
Mmio::<[u8; 8]>::from_raw(
*(transfer_trb_ptr as *const usize) as *mut [u8; 8],
)
}
.as_ref(),
);
if let Some(ref mut tring) = ddc.ep_ring(trb.dci())?.as_ref() {
tring.dequeue_trb(transfer_trb_ptr)?;
xhci.notify_ep(slot, trb.dci())?;
}
let mut next_pressed_keys = BitSet::<32>::new();
// First two bytes are modifiers, so skip them
let keycodes = report.iter().skip(2);
for value in keycodes {
next_pressed_keys.insert(*value as usize).unwrap();
Ok(trb) => {
let transfer_trb_ptr = trb.data() as usize;
let mut report = [0u8; 8];
report.copy_from_slice(
unsafe {
Mmio::<[u8; 8]>::from_raw(
*(transfer_trb_ptr as *const usize) as *mut [u8; 8],
)
}
let change = prev_pressed_keys.symmetric_difference(&next_pressed_keys);
for id in change.iter() {
let c = usage_id_to_char(id as u8);
if let Ok(c) = c {
if !prev_pressed_keys.get(id).unwrap_or(false) {
// the key state was changed from released to pressed
if c == KeyEvent::None {
continue;
}
if let Some(c) = c.to_char() {
InputManager::take().push_input(c);
}
.as_ref(),
);
if let Some(ref mut tring) = ddc.ep_ring(trb.dci())?.as_ref() {
tring.dequeue_trb(transfer_trb_ptr)?;
xhci.notify_ep(slot, trb.dci())?;
}
let mut next_pressed_keys = BitSet::<32>::new();
// First two bytes are modifiers, so skip them
let keycodes = report.iter().skip(2);
for value in keycodes {
next_pressed_keys.insert(*value as usize).unwrap();
}
let change = prev_pressed_keys.symmetric_difference(&next_pressed_keys);
for id in change.iter() {
let c = usage_id_to_char(id as u8);
if let Ok(c) = c {
if !prev_pressed_keys.get(id).unwrap_or(false) {
// the key state was changed from released to pressed
if c == KeyEvent::None {
continue;
}
if let Some(c) = c.to_char() {
InputManager::take().push_input(c);
}
} else {
error!("{c:?}");
}
} else {
error!("{c:?}");
}
prev_pressed_keys = next_pressed_keys;
}
prev_pressed_keys = next_pressed_keys;
}
Err(e) => {
error!("e: {:?}", e);
Expand Down
73 changes: 35 additions & 38 deletions os/src/usb_hid_tablet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,50 +93,47 @@ pub async fn attach_usb_device(mut ddc: UsbDeviceDriverContext) -> Result<()> {
let max_x = w - 1.0;
let max_y = h - 1.0;

let event_trb = EventFuture::new_transfer_event_on_slot(xhci.primary_event_ring(), slot);
loop {
let event_trb =
EventFuture::new_transfer_event_on_slot(xhci.primary_event_ring(), slot).await;
let event_trb = event_trb.clone().await;
match event_trb {
Ok(trbs) => {
for trb in trbs {
let transfer_trb_ptr = trb.data() as usize;
let mut report = [0u8; 8];
report.copy_from_slice(
unsafe {
Mmio::<[u8; 8]>::from_raw(
*(transfer_trb_ptr as *const usize) as *mut [u8; 8],
)
}
.as_ref(),
);
if let Some(ref mut tring) = ddc.ep_ring(trb.dci())?.as_ref() {
tring.dequeue_trb(transfer_trb_ptr)?;
xhci.notify_ep(slot, trb.dci())?;
Ok(trb) => {
let transfer_trb_ptr = trb.data() as usize;
let mut report = [0u8; 8];
report.copy_from_slice(
unsafe {
Mmio::<[u8; 8]>::from_raw(
*(transfer_trb_ptr as *const usize) as *mut [u8; 8],
)
}
.as_ref(),
);
if let Some(ref mut tring) = ddc.ep_ring(trb.dci())?.as_ref() {
tring.dequeue_trb(transfer_trb_ptr)?;
xhci.notify_ep(slot, trb.dci())?;
}

let b = report[0];
let l = b & 1 != 0;
let r = b & 2 != 0;
let c = b & 4 != 0;
let button = MouseButtonState::from_lcr(l, c, r);
let b = report[0];
let l = b & 1 != 0;
let r = b & 2 != 0;
let c = b & 4 != 0;
let button = MouseButtonState::from_lcr(l, c, r);

// 0~32767, top left origin (on QEMU)
let px = [report[1], report[2]];
let py = [report[3], report[4]];
let px = u16::from_le_bytes(px);
let py = u16::from_le_bytes(py);
let px = px as f64 / 32768f64;
let py = py as f64 / 32768f64;
// convert to the screen corrdinates
let px = px * w;
let py = py * h;
let px = unsafe { px.clamp(0.0, max_x).to_int_unchecked() };
let py = unsafe { py.clamp(0.0, max_y).to_int_unchecked() };
let position = PointerPosition::from_xy(px, py);
// 0~32767, top left origin (on QEMU)
let px = [report[1], report[2]];
let py = [report[3], report[4]];
let px = u16::from_le_bytes(px);
let py = u16::from_le_bytes(py);
let px = px as f64 / 32768f64;
let py = py as f64 / 32768f64;
// convert to the screen corrdinates
let px = px * w;
let py = py * h;
let px = unsafe { px.clamp(0.0, max_x).to_int_unchecked() };
let py = unsafe { py.clamp(0.0, max_y).to_int_unchecked() };
let position = PointerPosition::from_xy(px, py);

InputManager::take()
.push_cursor_input_absolute(MouseEvent { button, position });
}
InputManager::take().push_cursor_input_absolute(MouseEvent { button, position });
}
Err(e) => {
error!("e: {:?}", e);
Expand Down
16 changes: 1 addition & 15 deletions os/src/xhci/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,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();
EventFuture::new_on_trb(&self.primary_event_ring, cmd_ptr)
.await?
.get(0)
.cloned()
.ok_or(Error::Failed("Timed out"))
EventFuture::new_on_trb(&self.primary_event_ring, cmd_ptr).await
}
pub async fn request_initial_device_descriptor(
&self,
Expand Down Expand Up @@ -219,8 +215,6 @@ impl Controller {
self.notify_ep(slot, 1)?;
EventFuture::new_on_trb(&self.primary_event_ring, trb_ptr_waiting)
.await?
.get(0)
.ok_or(Error::Failed("Timed out"))?
.completed()
}
pub async fn request_set_interface(
Expand All @@ -244,8 +238,6 @@ impl Controller {
self.notify_ep(slot, 1)?;
EventFuture::new_on_trb(&self.primary_event_ring, trb_ptr_waiting)
.await?
.get(0)
.ok_or(Error::Failed("Timed out"))?
.completed()
}
pub async fn request_set_protocol(
Expand All @@ -272,8 +264,6 @@ impl Controller {
self.notify_ep(slot, 1)?;
EventFuture::new_on_trb(&self.primary_event_ring, trb_ptr_waiting)
.await?
.get(0)
.ok_or(Error::Failed("Timed out"))?
.completed()
}
pub async fn request_report_bytes(
Expand All @@ -300,8 +290,6 @@ impl Controller {
self.notify_ep(slot, 1)?;
EventFuture::new_on_trb(&self.primary_event_ring, trb_ptr_waiting)
.await?
.get(0)
.ok_or(Error::Failed("Timed out"))?
.completed()
}
async fn request_descriptor<T: Sized>(
Expand All @@ -328,8 +316,6 @@ impl Controller {
self.notify_ep(slot, 1)?;
EventFuture::new_on_trb(&self.primary_event_ring, trb_ptr_waiting)
.await?
.get(0)
.ok_or(Error::Failed("Timed out"))?
.completed()
}
pub async fn request_config_descriptor_and_rest(
Expand Down
3 changes: 0 additions & 3 deletions os/src/xhci/device.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
extern crate alloc;

use crate::error::Error;
use crate::error::Result;
use crate::usb::descriptor::EndpointDescriptor;
use crate::usb::descriptor::InterfaceDescriptor;
Expand Down Expand Up @@ -155,8 +154,6 @@ impl UsbDeviceDriverContext {
pub async fn wait_transfer_event(&mut self) -> Result<()> {
EventFuture::new_on_slot_with_timeout(self.xhci.primary_event_ring(), self.slot, 10 * 1000)
.await?
.get(0)
.ok_or(Error::Failed("Timed out"))?
.completed()
}
}
Loading

0 comments on commit 0282da6

Please sign in to comment.