use core::fmt;
use sdmmc_protocol::Error as ProtocolError;
use crate::{AicError, ChipVariant};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct AicSdioIdentity {
pub manufacturer_id: Option<u16>,
pub product_id: Option<u16>,
}
impl AicSdioIdentity {
pub(crate) fn complete(self) -> Option<(u16, u16)> {
self.manufacturer_id.zip(self.product_id)
}
}
impl fmt::Display for AicSdioIdentity {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match (self.manufacturer_id, self.product_id) {
(Some(manufacturer_id), Some(product_id)) => {
write!(formatter, "{manufacturer_id:04x}:{product_id:04x}")
}
(Some(manufacturer_id), None) => {
write!(formatter, "{manufacturer_id:04x}:missing")
}
(None, Some(product_id)) => write!(formatter, "missing:{product_id:04x}"),
(None, None) => formatter.write_str("missing"),
}
}
}
#[derive(Debug, thiserror::Error)]
pub enum AicRdifError {
#[error("SDIO protocol failed: {0}")]
Protocol(#[from] ProtocolError),
#[error("AIC core failed: {0}")]
Core(#[from] AicError),
#[error(
"unsupported AIC SDIO identity: detected {detected:?}, function1={function1}, \
common={common}, io_functions={io_functions}"
)]
UnsupportedCardIdentity {
detected: ChipVariant,
io_functions: u8,
function1: AicSdioIdentity,
common: AicSdioIdentity,
},
#[error("AIC core is unavailable before SDIO card identification")]
CoreUnavailable,
#[error(
"AIC startup timed out: enumeration_started={enumeration_started}, \
card_protocol_ready={card_protocol_ready}, irq_sequence={irq_sequence}, \
irq_pending={irq_pending}, completion_pending={completion_pending:?}"
)]
StartupTimeout {
enumeration_started: bool,
card_protocol_ready: bool,
irq_sequence: u64,
irq_pending: bool,
completion_pending: Option<bool>,
},
#[error("SDIO host DMA capability is unavailable")]
DmaUnavailable,
#[error("bounded AIC ownership queue is unavailable")]
QueueUnavailable,
#[error("AIC adapter is stopped")]
Stopped,
}
impl From<AicRdifError> for rdif_eth::NetError {
fn from(error: AicRdifError) -> Self {
match error {
AicRdifError::QueueUnavailable => Self::Retry,
AicRdifError::Stopped => Self::Stopped,
AicRdifError::DmaUnavailable => Self::InvalidParts,
other => Self::Other(alloc::boxed::Box::new(other)),
}
}
}
impl From<dma_api::DmaError> for AicRdifError {
fn from(_: dma_api::DmaError) -> Self {
Self::DmaUnavailable
}
}