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