Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions usb-host/src/backend/kmod/transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use core::ptr::NonNull;
use alloc::vec::Vec;
use dma_api::DmaDirection;
use usb_if::endpoint::TransferRequest;
use usb_if::err::TransferError;
use usb_if::transfer::Direction;

use crate::{
Expand All @@ -18,7 +19,7 @@ impl Transfer {
kind: TransferKind,
direction: Direction,
buff: Option<(NonNull<u8>, usize)>,
) -> Self {
) -> Result<Self, TransferError> {
let dma_direction = match direction {
Direction::In => DmaDirection::FromDevice,
Direction::Out => DmaDirection::ToDevice,
Expand All @@ -27,22 +28,25 @@ impl Transfer {
let slice = unsafe { core::slice::from_raw_parts_mut(ptr.as_ptr(), len) };
Some(
dma.map_single_array(slice, ALIGN, dma_direction)
.expect("DMA mapping failed"),
.map_err(|err| TransferError::Other(anyhow!("DMA mapping failed: {err}")))?,
)
} else {
None
};

Self {
Ok(Self {
kind,
direction,
mapping,
transfer_len: 0,
iso_packet_actual_lengths: Vec::new(),
}
})
}

pub(crate) fn from_request(dma: &Kernel, request: TransferRequest) -> Self {
pub(crate) fn from_request(
dma: &Kernel,
request: TransferRequest,
) -> Result<Self, TransferError> {
let (kind, direction, buffer) = request.into();
let buff = buffer.map(|buffer| (buffer.ptr, buffer.len));
Self::new(dma, kind, direction, buff)
Expand Down
19 changes: 17 additions & 2 deletions usb-host/src/backend/kmod/xhci/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,13 +276,28 @@ impl Endpoint {
}
Ok(())
}

fn required_trbs_for_request(request: &TransferRequest) -> usize {
match request {
TransferRequest::Control { buffer, .. } => {
if buffer.is_some_and(|buffer| buffer.len > 0) {
3
} else {
2
}
}
TransferRequest::Bulk { .. } | TransferRequest::Interrupt { .. } => 1,
TransferRequest::Isochronous { packets, .. } => packets.len().max(1),
}
}
}

impl EndpointOp for Endpoint {
fn submit_request(&mut self, request: TransferRequest) -> Result<RequestId, TransferError> {
let transfer = Transfer::from_request(&self.kernel, request);
let required_trbs = Self::required_trbs(&transfer);
let required_trbs = Self::required_trbs_for_request(&request);
self.ensure_ring_capacity(required_trbs)?;
let transfer = Transfer::from_request(&self.kernel, request)?;
debug_assert_eq!(required_trbs, Self::required_trbs(&transfer));

let mut data_bus_addr = 0;
if transfer.buffer_len() > 0 {
Expand Down
Loading