xref: /DragonOS/kernel/src/driver/virtio/sysfs.rs (revision 471d65cf158c9bf741c21f5d0ab92efe7bf1c3d4)
1 use alloc::{
2     string::{String, ToString},
3     sync::{Arc, Weak},
4 };
5 use ida::IdAllocator;
6 use intertrait::cast::CastArc;
7 use system_error::SystemError;
8 use unified_init::macros::unified_init;
9 
10 use crate::{
11     driver::base::{
12         device::{
13             bus::{bus_manager, Bus},
14             device_manager,
15             driver::{driver_manager, Driver},
16             Device,
17         },
18         kobject::KObject,
19         subsys::SubSysPrivate,
20     },
21     filesystem::{
22         sysfs::{
23             file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport, SYSFS_ATTR_MODE_RO,
24         },
25         vfs::syscall::ModeType,
26     },
27     init::initcall::INITCALL_CORE,
28 };
29 
30 use super::{VirtIODevice, VirtIODeviceIndex, VirtIODriver};
31 
32 static mut VIRTIO_BUS: Option<Arc<VirtIOBus>> = None;
33 
34 #[inline(always)]
35 pub fn virtio_bus() -> Arc<VirtIOBus> {
36     unsafe { VIRTIO_BUS.as_ref().unwrap().clone() }
37 }
38 
39 #[derive(Debug)]
40 pub struct VirtIOBus {
41     private: SubSysPrivate,
42 }
43 
44 impl VirtIOBus {
45     pub fn new() -> Arc<Self> {
46         let w: Weak<Self> = Weak::new();
47         let private = SubSysPrivate::new("virtio".to_string(), Some(w), None, &[]);
48         let bus = Arc::new(Self { private });
49         bus.subsystem()
50             .set_bus(Some(Arc::downgrade(&(bus.clone() as Arc<dyn Bus>))));
51 
52         return bus;
53     }
54 }
55 
56 impl Bus for VirtIOBus {
57     fn name(&self) -> String {
58         self.private.name()
59     }
60 
61     fn dev_name(&self) -> String {
62         return self.name();
63     }
64 
65     fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
66         // todo: VirtIODeviceAttrGroup
67         return &[];
68     }
69 
70     fn subsystem(&self) -> &SubSysPrivate {
71         return &self.private;
72     }
73 
74     fn probe(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> {
75         let drv = device.driver().ok_or(SystemError::EINVAL)?;
76         let virtio_drv = drv.cast::<dyn VirtIODriver>().map_err(|_| {
77             kerror!(
78                 "VirtIOBus::probe() failed: device.driver() is not a VirtioDriver. Device: '{:?}'",
79                 device.name()
80             );
81             SystemError::EINVAL
82         })?;
83 
84         let virtio_dev = device.clone().cast::<dyn VirtIODevice>().map_err(|_| {
85             kerror!(
86                 "VirtIOBus::probe() failed: device is not a VirtIODevice. Device: '{:?}'",
87                 device.name()
88             );
89             SystemError::EINVAL
90         })?;
91 
92         return virtio_drv.probe(&virtio_dev);
93     }
94 
95     fn remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
96         todo!()
97     }
98 
99     fn sync_state(&self, _device: &Arc<dyn Device>) {
100         todo!()
101     }
102 
103     fn shutdown(&self, _device: &Arc<dyn Device>) {
104         todo!()
105     }
106 
107     fn resume(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
108         todo!()
109     }
110 
111     fn match_device(
112         &self,
113         _device: &Arc<dyn Device>,
114         _driver: &Arc<dyn Driver>,
115     ) -> Result<bool, SystemError> {
116         // todo: https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/virtio/virtio.c#85
117         todo!("VirtIOBus::match_device() is not implemented")
118     }
119 }
120 
121 #[unified_init(INITCALL_CORE)]
122 fn virtio_init() -> Result<(), SystemError> {
123     let bus = VirtIOBus::new();
124     unsafe {
125         VIRTIO_BUS = Some(bus.clone());
126     }
127     bus_manager()
128         .register(bus)
129         .expect("Failed to register virtio bus!");
130     Ok(())
131 }
132 
133 #[inline(always)]
134 pub fn virtio_driver_manager() -> &'static VirtIODriverManager {
135     &VirtIODriverManager
136 }
137 
138 pub struct VirtIODriverManager;
139 
140 impl VirtIODriverManager {
141     pub fn register(&self, driver: Arc<dyn VirtIODriver>) -> Result<(), SystemError> {
142         driver.set_bus(Some(Arc::downgrade(&(virtio_bus() as Arc<dyn Bus>))));
143         return driver_manager().register(driver as Arc<dyn Driver>);
144     }
145 
146     #[allow(dead_code)]
147     pub fn unregister(&self, driver: &Arc<dyn VirtIODriver>) {
148         driver_manager().unregister(&(driver.clone() as Arc<dyn Driver>));
149     }
150 }
151 
152 #[inline(always)]
153 pub fn virtio_device_manager() -> &'static VirtIODeviceManager {
154     &VirtIODeviceManager
155 }
156 
157 pub struct VirtIODeviceManager;
158 
159 impl VirtIODeviceManager {
160     pub fn device_add(&self, dev: Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
161         dev.set_bus(Some(Arc::downgrade(&(virtio_bus() as Arc<dyn Bus>))));
162         device_manager().device_default_initialize(&(dev.clone() as Arc<dyn Device>));
163         let drv = dev.driver().ok_or(SystemError::EINVAL)?;
164 
165         let virtio_drv = drv.cast::<dyn VirtIODriver>().map_err(|_| {
166             kerror!(
167                 "VirtIODeviceManager::device_add() failed: device.driver() is not a VirtioDriver. Device: '{:?}'",
168                 dev.name()
169             );
170             SystemError::EINVAL
171         })?;
172         let virtio_index = VIRTIO_DEVICE_INDEX_MANAGER.alloc();
173         dev.set_virtio_device_index(virtio_index);
174         dev.set_device_name(format!("virtio{}", virtio_index.data()));
175         virtio_drv.probe(&dev)?;
176 
177         device_manager().add_device(dev.clone() as Arc<dyn Device>)?;
178         device_manager().add_groups(&(dev as Arc<dyn Device>), &[&VirtIODeviceAttrGroup])
179     }
180 
181     #[allow(dead_code)]
182     pub fn device_remove(&self, dev: &Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
183         device_manager().remove(&(dev.clone() as Arc<dyn Device>));
184         return Ok(());
185     }
186 }
187 
188 static VIRTIO_DEVICE_INDEX_MANAGER: VirtIODeviceIndexManager = VirtIODeviceIndexManager::new();
189 
190 /// VirtIO设备索引管理器
191 ///
192 /// VirtIO设备索引管理器用于分配和管理VirtIO设备的唯一索引。
193 pub struct VirtIODeviceIndexManager {
194     // ID分配器
195     ///
196     /// ID分配器用于分配唯一的索引给VirtIO设备。
197     ida: IdAllocator,
198 }
199 
200 // VirtIO设备索引管理器的新建实例
201 impl VirtIODeviceIndexManager {
202     /// 创建新的VirtIO设备索引管理器实例
203     ///
204     /// 创建一个新的VirtIO设备索引管理器实例,初始时分配器从0开始,直到最大usize值。
205     const fn new() -> Self {
206         Self {
207             ida: IdAllocator::new(0, usize::MAX),
208         }
209     }
210 
211     /// 分配一个新的VirtIO设备索引
212     ///
213     /// 分配一个唯一的索引给VirtIO设备。
214     pub fn alloc(&self) -> VirtIODeviceIndex {
215         VirtIODeviceIndex(self.ida.alloc().unwrap())
216     }
217 
218     // 释放一个VirtIO设备索引
219     ///
220     /// 释放之前分配的VirtIO设备索引,使其可以被重新使用。
221     #[allow(dead_code)]
222     pub fn free(&self, index: VirtIODeviceIndex) {
223         self.ida.free(index.0);
224     }
225 }
226 
227 /// VirtIO设备属性组
228 ///
229 /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/virtio/virtio.c#64
230 #[derive(Debug)]
231 pub struct VirtIODeviceAttrGroup;
232 
233 impl AttributeGroup for VirtIODeviceAttrGroup {
234     fn name(&self) -> Option<&str> {
235         None
236     }
237 
238     fn attrs(&self) -> &[&'static dyn Attribute] {
239         &[&AttrDevice, &AttrVendor]
240     }
241 }
242 
243 #[derive(Debug)]
244 struct AttrDevice;
245 
246 impl Attribute for AttrDevice {
247     fn name(&self) -> &str {
248         "device"
249     }
250 
251     fn mode(&self) -> ModeType {
252         SYSFS_ATTR_MODE_RO
253     }
254 
255     fn support(&self) -> SysFSOpsSupport {
256         SysFSOpsSupport::ATTR_SHOW
257     }
258 
259     fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
260         let dev = kobj.cast::<dyn VirtIODevice>().map_err(|_| {
261             kerror!("AttrDevice::show() failed: kobj is not a VirtIODevice");
262             SystemError::EINVAL
263         })?;
264         let device_type_id = dev.device_type_id();
265 
266         return sysfs_emit_str(buf, &format!("0x{:04x}\n", device_type_id));
267     }
268 }
269 
270 #[derive(Debug)]
271 struct AttrVendor;
272 
273 impl Attribute for AttrVendor {
274     fn name(&self) -> &str {
275         "vendor"
276     }
277 
278     fn mode(&self) -> ModeType {
279         SYSFS_ATTR_MODE_RO
280     }
281 
282     fn support(&self) -> SysFSOpsSupport {
283         SysFSOpsSupport::ATTR_SHOW
284     }
285 
286     fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
287         let dev = kobj.cast::<dyn VirtIODevice>().map_err(|_| {
288             kerror!("AttrVendor::show() failed: kobj is not a VirtIODevice");
289             SystemError::EINVAL
290         })?;
291         let vendor = dev.vendor();
292 
293         return sysfs_emit_str(buf, &format!("0x{:04x}\n", vendor));
294     }
295 }
296