axdriver_block/
bcm2835sdhci.rs1use axdriver_base::{BaseDriverOps, DevError, DevResult, DeviceType};
4use bcm2835_sdhci::{
5 Bcm2835SDhci::{BLOCK_SIZE, EmmcCtl},
6 SDHCIError,
7};
8
9use crate::BlockDriverOps;
10
11pub struct SDHCIDriver(EmmcCtl);
13
14impl SDHCIDriver {
15 pub fn try_new() -> DevResult<SDHCIDriver> {
17 let mut ctrl = EmmcCtl::new();
18 if ctrl.init() == 0 {
19 log::info!("BCM2835 sdhci: successfully initialized");
20 Ok(SDHCIDriver(ctrl))
21 } else {
22 log::warn!("BCM2835 sdhci: init failed");
23 Err(DevError::Io)
24 }
25 }
26}
27
28fn deal_sdhci_err(err: SDHCIError) -> DevError {
29 match err {
30 SDHCIError::Io => DevError::Io,
31 SDHCIError::AlreadyExists => DevError::AlreadyExists,
32 SDHCIError::Again => DevError::Again,
33 SDHCIError::BadState => DevError::BadState,
34 SDHCIError::InvalidParam => DevError::InvalidParam,
35 SDHCIError::NoMemory => DevError::NoMemory,
36 SDHCIError::ResourceBusy => DevError::ResourceBusy,
37 SDHCIError::Unsupported => DevError::Unsupported,
38 }
39}
40
41impl BaseDriverOps for SDHCIDriver {
42 fn device_type(&self) -> DeviceType {
43 DeviceType::Block
44 }
45
46 fn device_name(&self) -> &str {
47 "bcm2835_sdhci"
48 }
49}
50
51impl BlockDriverOps for SDHCIDriver {
52 fn read_block(&mut self, block_id: u64, buf: &mut [u8]) -> DevResult {
53 if buf.len() < BLOCK_SIZE {
54 return Err(DevError::InvalidParam);
55 }
56 let (prefix, aligned_buf, suffix) = unsafe { buf.align_to_mut::<u32>() };
57 if !prefix.is_empty() || !suffix.is_empty() {
58 return Err(DevError::InvalidParam);
59 }
60 self.0
61 .read_block(block_id as u32, 1, aligned_buf)
62 .map_err(deal_sdhci_err)
63 }
64
65 fn write_block(&mut self, block_id: u64, buf: &[u8]) -> DevResult {
66 if buf.len() < BLOCK_SIZE {
67 return Err(DevError::Io);
68 }
69 let (prefix, aligned_buf, suffix) = unsafe { buf.align_to::<u32>() };
70 if !prefix.is_empty() || !suffix.is_empty() {
71 return Err(DevError::InvalidParam);
72 }
73 self.0
74 .write_block(block_id as u32, 1, aligned_buf)
75 .map_err(deal_sdhci_err)
76 }
77 fn flush(&mut self) -> DevResult {
78 Ok(())
79 }
80
81 #[inline]
82 fn num_blocks(&self) -> u64 {
83 self.0.get_block_num()
84 }
85
86 #[inline]
87 fn block_size(&self) -> usize {
88 self.0.get_block_size()
89 }
90}