usb/
error.rs

1// SPDX-FileCopyrightText: 2024 Foundation Devices, Inc. <hello@foundation.xyz>
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4pub use ehci::EhciError;
5use server::{AsScalar, FromScalar};
6
7#[derive(Debug, Clone, Copy, thiserror::Error, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
8pub enum UsbError {
9    #[error("OS error: {:?}", xous::Error::from_usize(*.0))]
10    XousError(usize),
11    #[error("EHCI error: {0:?}")]
12    EhciError(EhciError),
13    #[error("Other Usb error")]
14    Other,
15    #[error("Usb device not found")]
16    NotFound,
17    #[error("Device was not claimed")]
18    NotClaimed,
19    #[error("Data buffer was too large")]
20    DataTooLarge,
21    #[error("An interface was already registered")]
22    AlreadyRegistered,
23    #[error("An endpoint operation was attempted in the wrong direction (e.g. read on an IN endpoint)")]
24    WrongDirection,
25    #[error("The endpoint already has a queued operation")]
26    Busy,
27    #[error("The usb host has disconnected")]
28    HostDisconnected,
29    #[error("One of the parameters had a wrong value")]
30    InvalidParameter,
31    #[error("The USB interface is disabled")]
32    InterfaceDisabled,
33}
34
35impl From<xous::Error> for UsbError {
36    fn from(value: xous::Error) -> Self { UsbError::XousError(value.to_usize()) }
37}
38
39impl From<EhciError> for UsbError {
40    fn from(value: EhciError) -> Self { UsbError::EhciError(value) }
41}
42
43impl AsScalar<2> for UsbError {
44    fn as_scalar(&self) -> [u32; 2] {
45        match self {
46            UsbError::XousError(e) => [1, *e as u32],
47            UsbError::EhciError(e) => [
48                2,
49                match e {
50                    EhciError::InvalidCapsLen => 1,
51                    EhciError::EndpointNotOpen => 2,
52                    EhciError::InvalidAddress => 3,
53                    EhciError::Disconnected => 4,
54                    EhciError::DescriptorError => 5,
55                    EhciError::OutOfPoolItems => 6,
56                    EhciError::SetupUnsuccessful => 7,
57                    EhciError::Stalled => 8,
58                    EhciError::ControllerDisabled => 9,
59                },
60            ],
61            UsbError::Other => [3, 0],
62            UsbError::NotFound => [4, 0],
63            UsbError::NotClaimed => [5, 0],
64            UsbError::DataTooLarge => [6, 0],
65            UsbError::AlreadyRegistered => [7, 0],
66            UsbError::WrongDirection => [8, 0],
67            UsbError::Busy => [9, 0],
68            UsbError::HostDisconnected => [10, 0],
69            UsbError::InvalidParameter => [11, 0],
70            UsbError::InterfaceDisabled => [12, 0],
71        }
72    }
73}
74
75impl FromScalar<2> for UsbError {
76    fn from_scalar(value: [u32; 2]) -> Self {
77        match value[0] {
78            1 => UsbError::XousError(value[1] as usize),
79            2 => UsbError::EhciError(match value[1] {
80                1 => EhciError::InvalidCapsLen,
81                2 => EhciError::EndpointNotOpen,
82                3 => EhciError::InvalidAddress,
83                4 => EhciError::Disconnected,
84                5 => EhciError::DescriptorError,
85                6 => EhciError::OutOfPoolItems,
86                7 => EhciError::SetupUnsuccessful,
87                8 => EhciError::Stalled,
88                9 => EhciError::ControllerDisabled,
89                _ => EhciError::Disconnected,
90            }),
91            3 => UsbError::Other,
92            4 => UsbError::NotFound,
93            5 => UsbError::NotClaimed,
94            6 => UsbError::DataTooLarge,
95            7 => UsbError::AlreadyRegistered,
96            8 => UsbError::WrongDirection,
97            9 => UsbError::Busy,
98            10 => UsbError::HostDisconnected,
99            11 => UsbError::InvalidParameter,
100            12 => UsbError::InterfaceDisabled,
101            _ => UsbError::Other,
102        }
103    }
104}
105
106impl From<usize> for UsbError {
107    fn from(value: usize) -> Self { Self::from_scalar([value as u32, 0]) }
108}
109
110impl From<UsbError> for usize {
111    fn from(value: UsbError) -> Self { server::AsScalar::<2>::as_scalar(&value)[0] as usize }
112}