xref: /DragonOS/kernel/src/driver/pci/subsys.rs (revision 9a0802fd2ddda39e96342997abbfc30bf65f1f0e)
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