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