1 use alloc::{ 2 string::{String, ToString}, 3 sync::{Arc, Weak}, 4 }; 5 use intertrait::cast::CastArc; 6 use system_error::SystemError; 7 8 use crate::{ 9 driver::base::{ 10 device::{ 11 bus::{bus_register, Bus}, 12 device_register, 13 driver::Driver, 14 sys_devices_kset, Device, 15 }, 16 kobject::KObject, 17 subsys::SubSysPrivate, 18 }, 19 filesystem::sysfs::AttributeGroup, 20 }; 21 22 use super::{ 23 device::{PciBusDevice, PciDevice}, 24 driver::PciDriver, 25 test::pt_init, 26 }; 27 28 static mut PCI_BUS_DEVICE: Option<Arc<PciBusDevice>> = None; 29 static mut PCI_BUS: Option<Arc<PciBus>> = None; 30 31 pub(super) fn set_pci_bus_device(device: Arc<PciBusDevice>) { 32 unsafe { 33 PCI_BUS_DEVICE = Some(device); 34 } 35 } 36 37 pub(super) fn set_pci_bus(bus: Arc<PciBus>) { 38 unsafe { 39 PCI_BUS = Some(bus); 40 } 41 } 42 43 pub fn pci_bus_device() -> Arc<PciBusDevice> { 44 unsafe { 45 return PCI_BUS_DEVICE.clone().unwrap(); 46 } 47 } 48 49 pub fn pci_bus() -> Arc<PciBus> { 50 unsafe { 51 return PCI_BUS.clone().unwrap(); 52 } 53 } 54 55 /// # 结构功能 56 /// 该结构为Pci总线,由于总线也属于设备,故设此结构; 57 /// 此结构对应/sys/bus/pci 58 #[derive(Debug)] 59 pub struct PciBus { 60 private: SubSysPrivate, 61 } 62 63 impl PciBus { 64 pub fn new() -> Arc<Self> { 65 let w: Weak<Self> = Weak::new(); 66 let private = SubSysPrivate::new("pci".to_string(), Some(w), None, &[]); 67 let bus = Arc::new(Self { private }); 68 bus 69 } 70 } 71 72 impl Bus for PciBus { 73 fn name(&self) -> String { 74 return "pci".to_string(); 75 } 76 77 fn dev_name(&self) -> String { 78 return self.name(); 79 } 80 81 fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] { 82 return &[&PciDeviceAttrGroup]; 83 } 84 85 fn subsystem(&self) -> &SubSysPrivate { 86 return &self.private; 87 } 88 89 fn probe(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> { 90 let drv = device.driver().ok_or(SystemError::EINVAL)?; 91 let pci_drv = drv.cast::<dyn PciDriver>().map_err(|_| { 92 kerror!( 93 "PciBus::probe() failed: device.driver() is not a PciDriver. Device: '{:?}'", 94 device.name() 95 ); 96 SystemError::EINVAL 97 })?; 98 let pci_dev = device.clone().cast::<dyn PciDevice>().map_err(|_| { 99 kerror!( 100 "PciBus::probe() failed: device is not a PciDevice. Device: '{:?}'", 101 device.name() 102 ); 103 SystemError::EINVAL 104 })?; 105 //见https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/pci/pci-driver.c#324 106 let id = pci_drv.match_dev(&pci_dev).ok_or(SystemError::EINVAL)?; 107 pci_drv.probe(&pci_dev, &id) 108 } 109 110 fn remove(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> { 111 todo!() 112 } 113 114 fn sync_state(&self, _device: &Arc<dyn Device>) { 115 todo!() 116 } 117 118 fn shutdown(&self, _device: &Arc<dyn Device>) { 119 todo!() 120 } 121 122 fn resume(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> { 123 todo!() 124 } 125 126 fn match_device( 127 &self, 128 device: &Arc<dyn Device>, 129 driver: &Arc<dyn Driver>, 130 ) -> Result<bool, SystemError> { 131 //首先将设备和驱动映射为pci设备和pci驱动 132 let pci_driver = driver.clone().cast::<dyn PciDriver>().map_err(|_| { 133 return SystemError::EINVAL; 134 })?; 135 let pci_dev = device.clone().cast::<dyn PciDevice>().map_err(|_| { 136 return SystemError::EINVAL; 137 })?; 138 //pci_driver需要实现一个match_dev函数,即driver需要识别是否支持给定的pci设备 139 //这是主要的match方式 140 if pci_driver.match_dev(&pci_dev).is_some() { 141 return Ok(true); 142 } 143 144 //todo:这里似乎需要一个driver_override_only的支持,但是目前不清楚driver_override_only 的用途,故暂时参考platform总线的match方法 145 //override_only相关代码在 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/pci/pci-driver.c#159 146 if let Some(driver_id_table) = driver.id_table() { 147 if driver_id_table.name().eq(&pci_dev.name()) { 148 return Ok(true); 149 } 150 }; 151 return Ok(pci_dev.name().eq(&pci_driver.name())); 152 } 153 } 154 155 #[derive(Debug)] 156 pub struct PciDeviceAttrGroup; 157 158 impl AttributeGroup for PciDeviceAttrGroup { 159 fn name(&self) -> Option<&str> { 160 return None; 161 } 162 163 fn attrs(&self) -> &[&'static dyn crate::filesystem::sysfs::Attribute] { 164 return &[]; 165 } 166 167 fn is_visible( 168 &self, 169 _kobj: Arc<dyn crate::driver::base::kobject::KObject>, 170 attr: &'static dyn crate::filesystem::sysfs::Attribute, 171 ) -> Option<crate::filesystem::vfs::syscall::ModeType> { 172 return Some(attr.mode()); 173 } 174 } 175 176 pub(super) fn pci_bus_subsys_init() -> Result<(), SystemError> { 177 let pci_bus_device: Arc<PciBusDevice> = PciBusDevice::new(Some(Arc::downgrade( 178 &(sys_devices_kset() as Arc<dyn KObject>), 179 ))); 180 181 set_pci_bus_device(pci_bus_device.clone()); 182 183 device_register(pci_bus_device.clone())?; 184 let pci_bus = PciBus::new(); 185 186 set_pci_bus(pci_bus.clone()); 187 let r = bus_register(pci_bus.clone() as Arc<dyn Bus>); 188 pt_init()?; 189 return r; 190 } 191