xref: /DragonOS/kernel/src/driver/pci/device.rs (revision 69715438f21c9a4da5198b92aee5c27aa8c44543)
1 use alloc::{
2     string::{String, ToString},
3     sync::{Arc, Weak},
4 };
5 use system_error::SystemError;
6 
7 use crate::{
8     driver::base::{
9         device::{
10             bus::Bus, device_manager, driver::Driver, Device, DeviceCommonData, DeviceType, IdTable,
11         },
12         kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
13         kset::KSet,
14     },
15     filesystem::kernfs::KernFSInode,
16     libs::{
17         rwlock::{RwLock, RwLockWriteGuard},
18         spinlock::{SpinLock, SpinLockGuard},
19     },
20 };
21 
22 use super::{
23     dev_id::PciDeviceID,
24     pci_irq::IrqType,
25     subsys::{pci_bus, pci_bus_device},
26 };
27 
28 /// # 结构功能
29 /// 该结构为Pci设备的管理器,使用该结构可以将pci设备添加到sysfs中
30 pub struct PciDeviceManager;
31 
pci_device_manager() -> &'static PciDeviceManager32 pub fn pci_device_manager() -> &'static PciDeviceManager {
33     &PciDeviceManager
34 }
35 
36 impl PciDeviceManager {
37     /// #函数的功能
38     /// 将pci设备注册到sysfs中
39     ///
40     /// ## 参数:
41     /// - 'pci_dev':需要添加的pci设备
42     ///
43     /// ## 返回值:
44     /// - OK(()) :表示成功
45     /// - Err(e) :失败原因
device_add(&self, pci_dev: Arc<dyn PciDevice>) -> Result<(), SystemError>46     pub fn device_add(&self, pci_dev: Arc<dyn PciDevice>) -> Result<(), SystemError> {
47         // pci设备一般放置在/sys/device/pci:xxxx下
48         if pci_dev.dev_parent().is_none() {
49             pci_dev.set_dev_parent(Some(Arc::downgrade(&(pci_bus_device() as Arc<dyn Device>))));
50         }
51         // 设置设备的总线
52         pci_dev.set_bus(Some(Arc::downgrade(&(pci_bus() as Arc<dyn Bus>))));
53         // 对设备进行默认的初始化
54         device_manager().device_default_initialize(&(pci_dev.clone() as Arc<dyn Device>));
55         // 使用设备管理器注册设备,当设备被注册后,会根据它的总线字段,在对应的总线上扫描驱动,并尝试进行匹配
56         let r = device_manager().add_device(pci_dev.clone() as Arc<dyn Device>);
57 
58         if r.is_ok() {
59             //todo:这里可能还要处理一些设置成功后设备状态的变化
60             return Ok(());
61         } else {
62             //todo:这里可能有一些添加失败的处理
63             return r;
64         }
65     }
66 }
67 
68 /// #trait功能
69 /// 要进入sysfs的Pci设备应当实现的trait
70 pub trait PciDevice: Device {
71     /// # 函数的功能
72     /// 返回本设备的PciDeviceID,该ID用于driver和device之间的匹配
73     ///
74     /// ## 返回值
75     /// - 'PciDeviceID' :本设备的PciDeviceID
dynid(&self) -> PciDeviceID76     fn dynid(&self) -> PciDeviceID;
77 
78     /// # 函数的功能
79     /// 返回本设备的供应商(vendor)ID
80     ///
81     /// ## 返回值
82     /// - u16 :表示供应商ID
vendor(&self) -> u1683     fn vendor(&self) -> u16;
device_id(&self) -> u1684     fn device_id(&self) -> u16;
subsystem_vendor(&self) -> u1685     fn subsystem_vendor(&self) -> u16;
subsystem_device(&self) -> u1686     fn subsystem_device(&self) -> u16;
revision(&self) -> u887     fn revision(&self) -> u8;
class_code(&self) -> u888     fn class_code(&self) -> u8;
irq_type(&self) -> &RwLock<IrqType>89     fn irq_type(&self) -> &RwLock<IrqType>;
irq_line(&self) -> u890     fn irq_line(&self) -> u8;
subclass(&self) -> u891     fn subclass(&self) -> u8;
interface_code(&self) -> u892     fn interface_code(&self) -> u8;
93 }
94 
95 /// #结构功能
96 /// 由于Pci总线本身就属于一个设备,故该结构代表Pci总线(控制器)本身
97 /// 它对应/sys/device/pci
98 #[derive(Debug)]
99 #[cast_to([sync] Device)]
100 pub struct PciBusDevice {
101     inner: SpinLock<InnerPciBusDevice>,
102     kobj_state: LockedKObjectState,
103     name: String,
104 }
105 
106 impl PciBusDevice {
new(parent: Option<Weak<dyn KObject>>) -> Arc<Self>107     pub fn new(parent: Option<Weak<dyn KObject>>) -> Arc<Self> {
108         let bus_device = Self {
109             inner: SpinLock::new(InnerPciBusDevice {
110                 kobject_common: KObjectCommonData::default(),
111                 device_common: DeviceCommonData::default(),
112             }),
113             kobj_state: LockedKObjectState::new(None),
114             name: "pci".to_string(),
115         };
116         bus_device.set_parent(parent);
117         return Arc::new(bus_device);
118     }
119 
inner(&self) -> SpinLockGuard<InnerPciBusDevice>120     fn inner(&self) -> SpinLockGuard<InnerPciBusDevice> {
121         self.inner.lock()
122     }
123 }
124 
125 #[derive(Debug)]
126 struct InnerPciBusDevice {
127     kobject_common: KObjectCommonData,
128     device_common: DeviceCommonData,
129 }
130 
131 impl KObject for PciBusDevice {
as_any_ref(&self) -> &dyn core::any::Any132     fn as_any_ref(&self) -> &dyn core::any::Any {
133         self
134     }
135 
parent(&self) -> Option<alloc::sync::Weak<dyn KObject>>136     fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
137         self.inner().kobject_common.parent.clone()
138     }
139 
inode(&self) -> Option<Arc<KernFSInode>>140     fn inode(&self) -> Option<Arc<KernFSInode>> {
141         self.inner().kobject_common.kern_inode.clone()
142     }
143 
set_inode(&self, inode: Option<Arc<KernFSInode>>)144     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
145         self.inner().kobject_common.kern_inode = inode;
146     }
147 
kobj_type(&self) -> Option<&'static dyn KObjType>148     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
149         self.inner().kobject_common.kobj_type
150     }
151 
set_kobj_type(&self, ktype: Option<&'static dyn KObjType>)152     fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
153         self.inner().kobject_common.kobj_type = ktype
154     }
155 
kset(&self) -> Option<Arc<KSet>>156     fn kset(&self) -> Option<Arc<KSet>> {
157         self.inner().kobject_common.kset.clone()
158     }
159 
kobj_state( &self, ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState>160     fn kobj_state(
161         &self,
162     ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> {
163         self.kobj_state.read()
164     }
165 
kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>166     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
167         self.kobj_state.write()
168     }
169 
set_kobj_state(&self, state: KObjectState)170     fn set_kobj_state(&self, state: KObjectState) {
171         *self.kobj_state.write() = state;
172     }
173 
name(&self) -> String174     fn name(&self) -> String {
175         self.name.clone()
176     }
177 
set_name(&self, _name: String)178     fn set_name(&self, _name: String) {
179         //do nothing; it's not supposed to change this struct's name
180     }
181 
set_kset(&self, kset: Option<Arc<KSet>>)182     fn set_kset(&self, kset: Option<Arc<KSet>>) {
183         self.inner().kobject_common.kset = kset;
184     }
185 
set_parent(&self, parent: Option<Weak<dyn KObject>>)186     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
187         self.inner().kobject_common.parent = parent;
188     }
189 }
190 
191 impl Device for PciBusDevice {
dev_type(&self) -> DeviceType192     fn dev_type(&self) -> DeviceType {
193         return DeviceType::Bus;
194     }
195 
id_table(&self) -> IdTable196     fn id_table(&self) -> IdTable {
197         IdTable::new("pci".to_string(), None)
198     }
199 
bus(&self) -> Option<Weak<dyn Bus>>200     fn bus(&self) -> Option<Weak<dyn Bus>> {
201         self.inner().device_common.bus.clone()
202     }
203 
set_bus(&self, bus: Option<alloc::sync::Weak<dyn Bus>>)204     fn set_bus(&self, bus: Option<alloc::sync::Weak<dyn Bus>>) {
205         self.inner().device_common.bus = bus
206     }
207 
driver(&self) -> Option<Arc<dyn Driver>>208     fn driver(&self) -> Option<Arc<dyn Driver>> {
209         self.inner().device_common.driver.clone()?.upgrade()
210     }
211 
is_dead(&self) -> bool212     fn is_dead(&self) -> bool {
213         false
214     }
215 
set_driver(&self, driver: Option<alloc::sync::Weak<dyn Driver>>)216     fn set_driver(&self, driver: Option<alloc::sync::Weak<dyn Driver>>) {
217         self.inner().device_common.driver = driver;
218     }
219 
can_match(&self) -> bool220     fn can_match(&self) -> bool {
221         todo!()
222     }
223 
set_can_match(&self, _can_match: bool)224     fn set_can_match(&self, _can_match: bool) {
225         todo!()
226     }
227 
set_class(&self, _class: Option<alloc::sync::Weak<dyn crate::driver::base::class::Class>>)228     fn set_class(&self, _class: Option<alloc::sync::Weak<dyn crate::driver::base::class::Class>>) {
229         todo!()
230     }
231 
state_synced(&self) -> bool232     fn state_synced(&self) -> bool {
233         todo!()
234     }
235 
dev_parent(&self) -> Option<alloc::sync::Weak<dyn Device>>236     fn dev_parent(&self) -> Option<alloc::sync::Weak<dyn Device>> {
237         self.inner().device_common.get_parent_weak_or_clear()
238     }
239 
set_dev_parent(&self, dev_parent: Option<alloc::sync::Weak<dyn Device>>)240     fn set_dev_parent(&self, dev_parent: Option<alloc::sync::Weak<dyn Device>>) {
241         self.inner().device_common.parent = dev_parent;
242     }
243 }
244