xref: /DragonOS/kernel/src/driver/block/virtio_blk.rs (revision bd70d2d1f490aabd570a5301b858bd5eb04149fa)
1 use core::{any::Any, fmt::Debug};
2 
3 use alloc::{
4     string::{String, ToString},
5     sync::{Arc, Weak},
6     vec::Vec,
7 };
8 use log::{debug, error};
9 use system_error::SystemError;
10 use unified_init::macros::unified_init;
11 use virtio_drivers::device::blk::VirtIOBlk;
12 
13 use crate::{
14     driver::{
15         base::{
16             block::{
17                 block_device::{BlockDevice, BlockId, LBA_SIZE},
18                 disk_info::Partition,
19             },
20             class::Class,
21             device::{
22                 bus::Bus,
23                 driver::{Driver, DriverCommonData},
24                 Device, DeviceCommonData, DeviceId, DeviceType, IdTable,
25             },
26             kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
27             kset::KSet,
28         },
29         virtio::{
30             sysfs::{virtio_bus, virtio_device_manager, virtio_driver_manager},
31             transport::VirtIOTransport,
32             virtio_impl::HalImpl,
33             VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_VENDOR_ID,
34         },
35     },
36     exception::{irqdesc::IrqReturn, IrqNumber},
37     filesystem::{kernfs::KernFSInode, mbr::MbrDiskPartionTable},
38     init::initcall::INITCALL_POSTCORE,
39     libs::{
40         rwlock::{RwLockReadGuard, RwLockWriteGuard},
41         spinlock::{SpinLock, SpinLockGuard},
42     },
43 };
44 
45 const VIRTIO_BLK_BASENAME: &str = "virtio_blk";
46 
47 static mut VIRTIO_BLK_DRIVER: Option<Arc<VirtIOBlkDriver>> = None;
48 
49 #[inline(always)]
50 fn virtio_blk_driver() -> Arc<VirtIOBlkDriver> {
51     unsafe { VIRTIO_BLK_DRIVER.as_ref().unwrap().clone() }
52 }
53 
54 /// Get the first virtio block device
55 #[allow(dead_code)]
56 pub fn virtio_blk_0() -> Option<Arc<VirtIOBlkDevice>> {
57     virtio_blk_driver()
58         .devices()
59         .first()
60         .cloned()
61         .map(|dev| dev.arc_any().downcast().unwrap())
62 }
63 
64 pub fn virtio_blk(transport: VirtIOTransport, dev_id: Arc<DeviceId>) {
65     let device = VirtIOBlkDevice::new(transport, dev_id);
66     if let Some(device) = device {
67         debug!("VirtIOBlkDevice '{:?}' created", device.dev_id);
68         virtio_device_manager()
69             .device_add(device.clone() as Arc<dyn VirtIODevice>)
70             .expect("Add virtio blk failed");
71     }
72 }
73 
74 /// virtio block device
75 #[derive(Debug)]
76 #[cast_to([sync] VirtIODevice)]
77 #[cast_to([sync] Device)]
78 pub struct VirtIOBlkDevice {
79     dev_id: Arc<DeviceId>,
80     inner: SpinLock<InnerVirtIOBlkDevice>,
81     locked_kobj_state: LockedKObjectState,
82     self_ref: Weak<Self>,
83 }
84 
85 unsafe impl Send for VirtIOBlkDevice {}
86 unsafe impl Sync for VirtIOBlkDevice {}
87 
88 impl VirtIOBlkDevice {
89     pub fn new(transport: VirtIOTransport, dev_id: Arc<DeviceId>) -> Option<Arc<Self>> {
90         let irq = transport.irq().map(|irq| IrqNumber::new(irq.data()));
91         let device_inner = VirtIOBlk::<HalImpl, VirtIOTransport>::new(transport);
92         if let Err(e) = device_inner {
93             error!("VirtIOBlkDevice '{dev_id:?}' create failed: {:?}", e);
94             return None;
95         }
96 
97         let mut device_inner: VirtIOBlk<HalImpl, VirtIOTransport> = device_inner.unwrap();
98         device_inner.enable_interrupts();
99         let dev = Arc::new_cyclic(|self_ref| Self {
100             self_ref: self_ref.clone(),
101             dev_id,
102             locked_kobj_state: LockedKObjectState::default(),
103             inner: SpinLock::new(InnerVirtIOBlkDevice {
104                 device_inner,
105                 name: None,
106                 virtio_index: None,
107                 device_common: DeviceCommonData::default(),
108                 kobject_common: KObjectCommonData::default(),
109                 irq,
110             }),
111         });
112 
113         dev.set_driver(Some(Arc::downgrade(
114             &(virtio_blk_driver() as Arc<dyn Driver>),
115         )));
116 
117         Some(dev)
118     }
119 
120     fn inner(&self) -> SpinLockGuard<InnerVirtIOBlkDevice> {
121         self.inner.lock()
122     }
123 }
124 
125 impl BlockDevice for VirtIOBlkDevice {
126     fn read_at_sync(
127         &self,
128         lba_id_start: BlockId,
129         count: usize,
130         buf: &mut [u8],
131     ) -> Result<usize, SystemError> {
132         let mut inner = self.inner();
133 
134         inner
135             .device_inner
136             .read_blocks(lba_id_start, &mut buf[..count * LBA_SIZE])
137             .map_err(|e| {
138                 error!(
139                     "VirtIOBlkDevice '{:?}' read_at_sync failed: {:?}",
140                     self.dev_id, e
141                 );
142                 SystemError::EIO
143             })?;
144 
145         Ok(count)
146     }
147 
148     fn write_at_sync(
149         &self,
150         lba_id_start: BlockId,
151         count: usize,
152         buf: &[u8],
153     ) -> Result<usize, SystemError> {
154         self.inner()
155             .device_inner
156             .write_blocks(lba_id_start, &buf[..count * LBA_SIZE])
157             .map_err(|_| SystemError::EIO)?;
158         Ok(count)
159     }
160 
161     fn sync(&self) -> Result<(), SystemError> {
162         Ok(())
163     }
164 
165     fn blk_size_log2(&self) -> u8 {
166         9
167     }
168 
169     fn as_any_ref(&self) -> &dyn Any {
170         self
171     }
172 
173     fn device(&self) -> Arc<dyn Device> {
174         self.self_ref.upgrade().unwrap()
175     }
176 
177     fn block_size(&self) -> usize {
178         todo!()
179     }
180 
181     fn partitions(&self) -> Vec<Arc<Partition>> {
182         let device = self.self_ref.upgrade().unwrap() as Arc<dyn BlockDevice>;
183         let mbr_table = MbrDiskPartionTable::from_disk(device.clone())
184             .expect("Failed to get MBR partition table");
185         mbr_table.partitions(Arc::downgrade(&device))
186     }
187 }
188 
189 struct InnerVirtIOBlkDevice {
190     device_inner: VirtIOBlk<HalImpl, VirtIOTransport>,
191     name: Option<String>,
192     virtio_index: Option<VirtIODeviceIndex>,
193     device_common: DeviceCommonData,
194     kobject_common: KObjectCommonData,
195     irq: Option<IrqNumber>,
196 }
197 
198 impl Debug for InnerVirtIOBlkDevice {
199     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
200         f.debug_struct("InnerVirtIOBlkDevice").finish()
201     }
202 }
203 
204 impl VirtIODevice for VirtIOBlkDevice {
205     fn irq(&self) -> Option<IrqNumber> {
206         self.inner().irq
207     }
208 
209     fn handle_irq(
210         &self,
211         _irq: crate::exception::IrqNumber,
212     ) -> Result<IrqReturn, system_error::SystemError> {
213         // todo: handle virtio blk irq
214         Ok(crate::exception::irqdesc::IrqReturn::Handled)
215     }
216 
217     fn dev_id(&self) -> &Arc<DeviceId> {
218         &self.dev_id
219     }
220 
221     fn set_device_name(&self, name: String) {
222         self.inner().name = Some(name);
223     }
224 
225     fn device_name(&self) -> String {
226         self.inner()
227             .name
228             .clone()
229             .unwrap_or_else(|| VIRTIO_BLK_BASENAME.to_string())
230     }
231 
232     fn set_virtio_device_index(&self, index: VirtIODeviceIndex) {
233         self.inner().virtio_index = Some(index);
234     }
235 
236     fn virtio_device_index(&self) -> Option<VirtIODeviceIndex> {
237         self.inner().virtio_index
238     }
239 
240     fn device_type_id(&self) -> u32 {
241         virtio_drivers::transport::DeviceType::Block as u32
242     }
243 
244     fn vendor(&self) -> u32 {
245         VIRTIO_VENDOR_ID.into()
246     }
247 }
248 
249 impl Device for VirtIOBlkDevice {
250     fn dev_type(&self) -> DeviceType {
251         DeviceType::Net
252     }
253 
254     fn id_table(&self) -> IdTable {
255         IdTable::new(VIRTIO_BLK_BASENAME.to_string(), None)
256     }
257 
258     fn bus(&self) -> Option<Weak<dyn Bus>> {
259         self.inner().device_common.bus.clone()
260     }
261 
262     fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
263         self.inner().device_common.bus = bus;
264     }
265 
266     fn class(&self) -> Option<Arc<dyn Class>> {
267         let mut guard = self.inner();
268         let r = guard.device_common.class.clone()?.upgrade();
269         if r.is_none() {
270             guard.device_common.class = None;
271         }
272 
273         return r;
274     }
275 
276     fn set_class(&self, class: Option<Weak<dyn Class>>) {
277         self.inner().device_common.class = class;
278     }
279 
280     fn driver(&self) -> Option<Arc<dyn Driver>> {
281         let r = self.inner().device_common.driver.clone()?.upgrade();
282         if r.is_none() {
283             self.inner().device_common.driver = None;
284         }
285 
286         return r;
287     }
288 
289     fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
290         self.inner().device_common.driver = driver;
291     }
292 
293     fn is_dead(&self) -> bool {
294         false
295     }
296 
297     fn can_match(&self) -> bool {
298         self.inner().device_common.can_match
299     }
300 
301     fn set_can_match(&self, can_match: bool) {
302         self.inner().device_common.can_match = can_match;
303     }
304 
305     fn state_synced(&self) -> bool {
306         true
307     }
308 }
309 
310 impl KObject for VirtIOBlkDevice {
311     fn as_any_ref(&self) -> &dyn Any {
312         self
313     }
314 
315     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
316         self.inner().kobject_common.kern_inode = inode;
317     }
318 
319     fn inode(&self) -> Option<Arc<KernFSInode>> {
320         self.inner().kobject_common.kern_inode.clone()
321     }
322 
323     fn parent(&self) -> Option<Weak<dyn KObject>> {
324         self.inner().kobject_common.parent.clone()
325     }
326 
327     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
328         self.inner().kobject_common.parent = parent;
329     }
330 
331     fn kset(&self) -> Option<Arc<KSet>> {
332         self.inner().kobject_common.kset.clone()
333     }
334 
335     fn set_kset(&self, kset: Option<Arc<KSet>>) {
336         self.inner().kobject_common.kset = kset;
337     }
338 
339     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
340         self.inner().kobject_common.kobj_type
341     }
342 
343     fn name(&self) -> String {
344         self.device_name()
345     }
346 
347     fn set_name(&self, _name: String) {
348         // do nothing
349     }
350 
351     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
352         self.locked_kobj_state.read()
353     }
354 
355     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
356         self.locked_kobj_state.write()
357     }
358 
359     fn set_kobj_state(&self, state: KObjectState) {
360         *self.locked_kobj_state.write() = state;
361     }
362 
363     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
364         self.inner().kobject_common.kobj_type = ktype;
365     }
366 }
367 
368 #[unified_init(INITCALL_POSTCORE)]
369 fn virtio_blk_driver_init() -> Result<(), SystemError> {
370     let driver = VirtIOBlkDriver::new();
371     virtio_driver_manager()
372         .register(driver.clone() as Arc<dyn VirtIODriver>)
373         .expect("Add virtio net driver failed");
374     unsafe {
375         VIRTIO_BLK_DRIVER = Some(driver);
376     }
377 
378     return Ok(());
379 }
380 
381 #[derive(Debug)]
382 #[cast_to([sync] VirtIODriver)]
383 #[cast_to([sync] Driver)]
384 struct VirtIOBlkDriver {
385     inner: SpinLock<InnerVirtIOBlkDriver>,
386     kobj_state: LockedKObjectState,
387 }
388 
389 impl VirtIOBlkDriver {
390     pub fn new() -> Arc<Self> {
391         let inner = InnerVirtIOBlkDriver {
392             driver_common: DriverCommonData::default(),
393             kobj_common: KObjectCommonData::default(),
394         };
395         Arc::new(VirtIOBlkDriver {
396             inner: SpinLock::new(inner),
397             kobj_state: LockedKObjectState::default(),
398         })
399     }
400 
401     fn inner(&self) -> SpinLockGuard<InnerVirtIOBlkDriver> {
402         return self.inner.lock();
403     }
404 }
405 
406 #[derive(Debug)]
407 struct InnerVirtIOBlkDriver {
408     driver_common: DriverCommonData,
409     kobj_common: KObjectCommonData,
410 }
411 
412 impl VirtIODriver for VirtIOBlkDriver {
413     fn probe(&self, device: &Arc<dyn VirtIODevice>) -> Result<(), SystemError> {
414         let _dev = device
415             .clone()
416             .arc_any()
417             .downcast::<VirtIOBlkDevice>()
418             .map_err(|_| {
419                 error!(
420                 "VirtIOBlkDriver::probe() failed: device is not a VirtIO block device. Device: '{:?}'",
421                 device.name()
422             );
423                 SystemError::EINVAL
424             })?;
425 
426         return Ok(());
427     }
428 }
429 
430 impl Driver for VirtIOBlkDriver {
431     fn id_table(&self) -> Option<IdTable> {
432         Some(IdTable::new(VIRTIO_BLK_BASENAME.to_string(), None))
433     }
434 
435     fn add_device(&self, device: Arc<dyn Device>) {
436         let iface = device
437             .arc_any()
438             .downcast::<VirtIOBlkDevice>()
439             .expect("VirtIOBlkDriver::add_device() failed: device is not a VirtIOBlkDevice");
440 
441         self.inner()
442             .driver_common
443             .devices
444             .push(iface as Arc<dyn Device>);
445     }
446 
447     fn delete_device(&self, device: &Arc<dyn Device>) {
448         let _iface = device
449             .clone()
450             .arc_any()
451             .downcast::<VirtIOBlkDevice>()
452             .expect("VirtIOBlkDriver::delete_device() failed: device is not a VirtIOBlkDevice");
453 
454         let mut guard = self.inner();
455         let index = guard
456             .driver_common
457             .devices
458             .iter()
459             .position(|dev| Arc::ptr_eq(device, dev))
460             .expect("VirtIOBlkDriver::delete_device() failed: device not found");
461 
462         guard.driver_common.devices.remove(index);
463     }
464 
465     fn devices(&self) -> Vec<Arc<dyn Device>> {
466         self.inner().driver_common.devices.clone()
467     }
468 
469     fn bus(&self) -> Option<Weak<dyn Bus>> {
470         Some(Arc::downgrade(&virtio_bus()) as Weak<dyn Bus>)
471     }
472 
473     fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
474         // do nothing
475     }
476 }
477 
478 impl KObject for VirtIOBlkDriver {
479     fn as_any_ref(&self) -> &dyn Any {
480         self
481     }
482 
483     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
484         self.inner().kobj_common.kern_inode = inode;
485     }
486 
487     fn inode(&self) -> Option<Arc<KernFSInode>> {
488         self.inner().kobj_common.kern_inode.clone()
489     }
490 
491     fn parent(&self) -> Option<Weak<dyn KObject>> {
492         self.inner().kobj_common.parent.clone()
493     }
494 
495     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
496         self.inner().kobj_common.parent = parent;
497     }
498 
499     fn kset(&self) -> Option<Arc<KSet>> {
500         self.inner().kobj_common.kset.clone()
501     }
502 
503     fn set_kset(&self, kset: Option<Arc<KSet>>) {
504         self.inner().kobj_common.kset = kset;
505     }
506 
507     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
508         self.inner().kobj_common.kobj_type
509     }
510 
511     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
512         self.inner().kobj_common.kobj_type = ktype;
513     }
514 
515     fn name(&self) -> String {
516         VIRTIO_BLK_BASENAME.to_string()
517     }
518 
519     fn set_name(&self, _name: String) {
520         // do nothing
521     }
522 
523     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
524         self.kobj_state.read()
525     }
526 
527     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
528         self.kobj_state.write()
529     }
530 
531     fn set_kobj_state(&self, state: KObjectState) {
532         *self.kobj_state.write() = state;
533     }
534 }
535