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 system_error::SystemError; 9 use unified_init::macros::unified_init; 10 use virtio_drivers::device::blk::VirtIOBlk; 11 12 use crate::{ 13 driver::{ 14 base::{ 15 block::{ 16 block_device::{BlockDevice, BlockId, LBA_SIZE}, 17 disk_info::Partition, 18 }, 19 class::Class, 20 device::{ 21 bus::Bus, 22 driver::{Driver, DriverCommonData}, 23 Device, DeviceCommonData, DeviceId, DeviceType, IdTable, 24 }, 25 kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, 26 kset::KSet, 27 }, 28 virtio::{ 29 sysfs::{virtio_bus, virtio_device_manager, virtio_driver_manager}, 30 transport::VirtIOTransport, 31 virtio_impl::HalImpl, 32 VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_VENDOR_ID, 33 }, 34 }, 35 exception::{irqdesc::IrqReturn, IrqNumber}, 36 filesystem::{kernfs::KernFSInode, mbr::MbrDiskPartionTable}, 37 init::initcall::INITCALL_POSTCORE, 38 libs::{ 39 rwlock::{RwLockReadGuard, RwLockWriteGuard}, 40 spinlock::{SpinLock, SpinLockGuard}, 41 }, 42 }; 43 44 const VIRTIO_BLK_BASENAME: &str = "virtio_blk"; 45 46 static mut VIRTIO_BLK_DRIVER: Option<Arc<VirtIOBlkDriver>> = None; 47 48 #[inline(always)] 49 fn virtio_blk_driver() -> Arc<VirtIOBlkDriver> { 50 unsafe { VIRTIO_BLK_DRIVER.as_ref().unwrap().clone() } 51 } 52 53 /// Get the first virtio block device 54 #[allow(dead_code)] 55 pub fn virtio_blk_0() -> Option<Arc<VirtIOBlkDevice>> { 56 virtio_blk_driver() 57 .devices() 58 .first() 59 .cloned() 60 .map(|dev| dev.arc_any().downcast().unwrap()) 61 } 62 63 pub fn virtio_blk(transport: VirtIOTransport, dev_id: Arc<DeviceId>) { 64 let device = VirtIOBlkDevice::new(transport, dev_id); 65 if let Some(device) = device { 66 kdebug!("VirtIOBlkDevice '{:?}' created", device.dev_id); 67 virtio_device_manager() 68 .device_add(device.clone() as Arc<dyn VirtIODevice>) 69 .expect("Add virtio blk failed"); 70 } 71 } 72 73 /// virtio block device 74 #[derive(Debug)] 75 #[cast_to([sync] VirtIODevice)] 76 #[cast_to([sync] Device)] 77 pub struct VirtIOBlkDevice { 78 dev_id: Arc<DeviceId>, 79 inner: SpinLock<InnerVirtIOBlkDevice>, 80 locked_kobj_state: LockedKObjectState, 81 self_ref: Weak<Self>, 82 } 83 84 unsafe impl Send for VirtIOBlkDevice {} 85 unsafe impl Sync for VirtIOBlkDevice {} 86 87 impl VirtIOBlkDevice { 88 pub fn new(transport: VirtIOTransport, dev_id: Arc<DeviceId>) -> Option<Arc<Self>> { 89 let irq = transport.irq().map(|irq| IrqNumber::new(irq.data())); 90 let device_inner = VirtIOBlk::<HalImpl, VirtIOTransport>::new(transport); 91 if let Err(e) = device_inner { 92 kerror!("VirtIOBlkDevice '{dev_id:?}' create failed: {:?}", e); 93 return None; 94 } 95 96 let mut device_inner: VirtIOBlk<HalImpl, VirtIOTransport> = device_inner.unwrap(); 97 device_inner.enable_interrupts(); 98 let dev = Arc::new_cyclic(|self_ref| Self { 99 self_ref: self_ref.clone(), 100 dev_id, 101 locked_kobj_state: LockedKObjectState::default(), 102 inner: SpinLock::new(InnerVirtIOBlkDevice { 103 device_inner, 104 name: None, 105 virtio_index: None, 106 device_common: DeviceCommonData::default(), 107 kobject_common: KObjectCommonData::default(), 108 irq, 109 }), 110 }); 111 112 dev.set_driver(Some(Arc::downgrade( 113 &(virtio_blk_driver() as Arc<dyn Driver>), 114 ))); 115 116 Some(dev) 117 } 118 119 fn inner(&self) -> SpinLockGuard<InnerVirtIOBlkDevice> { 120 self.inner.lock() 121 } 122 } 123 124 impl BlockDevice for VirtIOBlkDevice { 125 fn read_at_sync( 126 &self, 127 lba_id_start: BlockId, 128 count: usize, 129 buf: &mut [u8], 130 ) -> Result<usize, SystemError> { 131 let mut inner = self.inner(); 132 133 inner 134 .device_inner 135 .read_blocks(lba_id_start, &mut buf[..count * LBA_SIZE]) 136 .map_err(|e| { 137 kerror!( 138 "VirtIOBlkDevice '{:?}' read_at_sync failed: {:?}", 139 self.dev_id, 140 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 kerror!( 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