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