1use core::fmt::Display;
2
3pub use usb_if::err::{TransferError, USBError};
4use xhci::ring::trb::event::CompletionCode;
5
6pub type Result<T = ()> = core::result::Result<T, USBError>;
7
8pub trait ConvertXhciError {
9 fn to_result(self) -> core::result::Result<(), TransferError>;
10}
11
12impl ConvertXhciError for CompletionCode {
13 fn to_result(self) -> core::result::Result<(), TransferError> {
14 match self {
15 CompletionCode::Success => Ok(()),
16 CompletionCode::ShortPacket => Ok(()),
17 CompletionCode::StallError => Err(TransferError::Stall),
18 CompletionCode::MissedServiceError => {
19 Err(TransferError::Other(anyhow!(
21 "XHCI temporary error: {self:?}"
22 )))
23 }
24 _ => Err(TransferError::Other(anyhow!("XHCI error: {self:?}"))),
25 }
26 }
27}
28
29#[derive(thiserror::Error, Debug)]
30pub struct HostError(USBError);
31
32impl Display for HostError {
33 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
34 write!(f, "{}", self.0)
35 }
36}
37
38impl From<dma_api::DmaError> for HostError {
39 fn from(value: dma_api::DmaError) -> Self {
40 match value {
41 dma_api::DmaError::NoMemory => Self(USBError::NoMemory),
42 dma_api::DmaError::DmaMaskNotMatch { .. } => Self(USBError::NoMemory),
43 e => Self(USBError::Other(e.into())),
44 }
45 }
46}
47
48impl From<HostError> for USBError {
49 fn from(value: HostError) -> Self {
50 value.0
51 }
52}