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