starnix_core/device/
block.rs1use crate::device::DeviceMode;
6use crate::device::kobject::DeviceMetadata;
7use crate::fs::sysfs::{BlockDeviceInfo, build_block_device_directory};
8use crate::task::{CurrentTask, Kernel};
9use crate::vfs::{FileOps, FsString, NamespaceNode};
10use starnix_logging::track_stub;
11use starnix_sync::{FileOpsCore, Locked, Unlocked};
12use starnix_uapi::device_id::DeviceId;
13use starnix_uapi::errors::Errno;
14use starnix_uapi::open_flags::OpenFlags;
15use starnix_uapi::user_address::ArchSpecific;
16use starnix_uapi::{errno, uapi};
17use std::sync::Arc;
18
19pub fn canonicalize_ioctl_request(current_task: &CurrentTask, request: u32) -> u32 {
20 if current_task.is_arch32() {
21 match request {
22 uapi::arch32::BLKGETSIZE64 => uapi::BLKGETSIZE64,
23 _ => request,
24 }
25 } else {
26 request
27 }
28}
29
30pub struct MmcBlockDevice;
31
32impl BlockDeviceInfo for MmcBlockDevice {
33 fn size(&self) -> Result<usize, Errno> {
34 track_stub!(TODO("https://fxbug.dev/488067251"), "mmcblk query size");
35 Err(errno!(ENOTSUP))
36 }
37}
38
39fn open_mmc_block_device(
40 _locked: &mut Locked<FileOpsCore>,
41 _current_task: &CurrentTask,
42 _id: DeviceId,
43 _node: &NamespaceNode,
44 _flags: OpenFlags,
45) -> Result<Box<dyn FileOps>, Errno> {
46 track_stub!(TODO("https://fxbug.dev/488067251"), "mmcblk open device");
47 Err(errno!(ENOTSUP))
48}
49
50pub fn add_mmc_block_device(
53 locked: &mut Locked<Unlocked>,
54 kernel: &Kernel,
55) -> Result<Arc<MmcBlockDevice>, Errno> {
56 let name = FsString::from("mmcblk0");
57 let class = kernel.device_registry.objects.virtual_block_class();
58 let device = Arc::new(MmcBlockDevice);
59 let device_weak = Arc::downgrade(&device);
60 kernel.device_registry.register_device_with_dir(
61 locked,
62 kernel,
63 name.as_ref(),
64 DeviceMetadata::new(name.clone(), DeviceId::MMCBLK0, DeviceMode::Block),
65 class,
66 |device, dir| build_block_device_directory(device, device_weak, dir),
67 open_mmc_block_device,
68 )?;
69 Ok(device)
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 use crate::testing::{anon_test_file, spawn_kernel_and_run};
76 use crate::vfs::VecOutputBuffer;
77 use starnix_uapi::open_flags::OpenFlags;
78
79 #[::fuchsia::test]
80 async fn test_mmc_block_device() {
81 spawn_kernel_and_run(async |locked, current_task| {
82 let _device = add_mmc_block_device(locked, current_task.kernel()).unwrap();
83 let class = current_task.kernel().device_registry.objects.virtual_block_class();
84 assert!(class.dir.lookup(b"mmcblk0/holders".into()).is_some());
86 let size_node = class.dir.lookup(b"mmcblk0/size".into()).unwrap();
89 let file_ops =
90 size_node.create_file_ops(locked, ¤t_task, OpenFlags::RDONLY).unwrap();
91 let file = anon_test_file(locked, ¤t_task, file_ops, OpenFlags::RDONLY);
92 let mut buf = VecOutputBuffer::new(10);
93 assert_eq!(file.read(locked, ¤t_task, &mut buf).unwrap_err(), errno!(ENOTSUP));
94 })
95 .await;
96 }
97}