xref: /DragonOS/kernel/src/driver/pci/attr.rs (revision 7c28051e8c601312d3d0fd7bcb71bc71450d10c0)
1 use alloc::sync::Arc;
2 use intertrait::cast::CastArc;
3 use log::warn;
4 use system_error::SystemError;
5 
6 use crate::{
7     driver::base::kobject::KObject,
8     filesystem::{
9         sysfs::{
10             file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport, SYSFS_ATTR_MODE_RO,
11         },
12         vfs::syscall::ModeType,
13     },
14 };
15 
16 use super::{device::PciDevice, pci_irq::IrqType};
17 #[derive(Debug)]
18 pub struct BasicPciReadOnlyAttrs;
19 
20 impl AttributeGroup for BasicPciReadOnlyAttrs {
21     fn name(&self) -> Option<&str> {
22         None
23     }
24 
25     fn attrs(&self) -> &[&'static dyn Attribute] {
26         &[
27             &Vendor,
28             &DeviceID,
29             &SubsystemVendor,
30             &SubsystemDevice,
31             &Revision,
32             &Class,
33             &Irq,
34             &Modalias,
35         ]
36     }
37 
38     fn is_visible(
39         &self,
40         _kobj: Arc<dyn KObject>,
41         attr: &'static dyn Attribute,
42     ) -> Option<ModeType> {
43         return Some(attr.mode());
44     }
45 }
46 
47 #[derive(Debug)]
48 struct Vendor;
49 
50 impl Attribute for Vendor {
51     fn mode(&self) -> ModeType {
52         SYSFS_ATTR_MODE_RO
53     }
54 
55     fn name(&self) -> &str {
56         "vendor"
57     }
58 
59     fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
60         let dev = _kobj
61             .cast::<dyn PciDevice>()
62             .map_err(|e: Arc<dyn KObject>| {
63                 warn!("device:{:?} is not a pci device!", e);
64                 SystemError::EINVAL
65             })?;
66         return sysfs_emit_str(_buf, &format!("0x{:04x}", dev.vendor()));
67     }
68 
69     fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
70         todo!()
71     }
72 
73     fn support(&self) -> SysFSOpsSupport {
74         SysFSOpsSupport::ATTR_SHOW
75     }
76 }
77 
78 #[derive(Debug)]
79 struct DeviceID;
80 
81 impl Attribute for DeviceID {
82     fn mode(&self) -> ModeType {
83         SYSFS_ATTR_MODE_RO
84     }
85 
86     fn name(&self) -> &str {
87         "device"
88     }
89 
90     fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
91         let dev = _kobj
92             .cast::<dyn PciDevice>()
93             .map_err(|e: Arc<dyn KObject>| {
94                 warn!("device:{:?} is not a pci device!", e);
95                 SystemError::EINVAL
96             })?;
97         return sysfs_emit_str(_buf, &format!("0x{:04x}", dev.device_id()));
98     }
99 
100     fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
101         todo!()
102     }
103 
104     fn support(&self) -> SysFSOpsSupport {
105         SysFSOpsSupport::ATTR_SHOW
106     }
107 }
108 
109 #[derive(Debug)]
110 struct SubsystemVendor;
111 
112 impl Attribute for SubsystemVendor {
113     fn mode(&self) -> ModeType {
114         SYSFS_ATTR_MODE_RO
115     }
116 
117     fn name(&self) -> &str {
118         "subsystem_vendor"
119     }
120 
121     fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
122         let dev = _kobj
123             .cast::<dyn PciDevice>()
124             .map_err(|e: Arc<dyn KObject>| {
125                 warn!("device:{:?} is not a pci device!", e);
126                 SystemError::EINVAL
127             })?;
128         return sysfs_emit_str(_buf, &format!("0x{:04x}", dev.subsystem_vendor()));
129     }
130 
131     fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
132         todo!()
133     }
134 
135     fn support(&self) -> SysFSOpsSupport {
136         SysFSOpsSupport::ATTR_SHOW
137     }
138 }
139 
140 #[derive(Debug)]
141 struct SubsystemDevice;
142 
143 impl Attribute for SubsystemDevice {
144     fn mode(&self) -> ModeType {
145         SYSFS_ATTR_MODE_RO
146     }
147 
148     fn name(&self) -> &str {
149         "subsystem_device"
150     }
151 
152     fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
153         let dev = _kobj
154             .cast::<dyn PciDevice>()
155             .map_err(|e: Arc<dyn KObject>| {
156                 warn!("device:{:?} is not a pci device!", e);
157                 SystemError::EINVAL
158             })?;
159         return sysfs_emit_str(_buf, &format!("0x{:04x}", dev.subsystem_device()));
160     }
161 
162     fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
163         todo!()
164     }
165 
166     fn support(&self) -> SysFSOpsSupport {
167         SysFSOpsSupport::ATTR_SHOW
168     }
169 }
170 
171 #[derive(Debug)]
172 struct Revision;
173 
174 impl Attribute for Revision {
175     fn mode(&self) -> ModeType {
176         SYSFS_ATTR_MODE_RO
177     }
178 
179     fn name(&self) -> &str {
180         "revision"
181     }
182 
183     fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
184         let dev = _kobj
185             .cast::<dyn PciDevice>()
186             .map_err(|e: Arc<dyn KObject>| {
187                 warn!("device:{:?} is not a pci device!", e);
188                 SystemError::EINVAL
189             })?;
190         return sysfs_emit_str(_buf, &format!("0x{:02x}", dev.revision()));
191     }
192 
193     fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
194         todo!()
195     }
196 
197     fn support(&self) -> SysFSOpsSupport {
198         SysFSOpsSupport::ATTR_SHOW
199     }
200 }
201 
202 #[derive(Debug)]
203 struct Class;
204 
205 impl Attribute for Class {
206     fn mode(&self) -> ModeType {
207         SYSFS_ATTR_MODE_RO
208     }
209 
210     fn name(&self) -> &str {
211         "class"
212     }
213 
214     fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
215         let dev = _kobj
216             .cast::<dyn PciDevice>()
217             .map_err(|e: Arc<dyn KObject>| {
218                 warn!("device:{:?} is not a pci device!", e);
219                 SystemError::EINVAL
220             })?;
221         return sysfs_emit_str(_buf, &format!("0x{:06x}", dev.class_code()));
222     }
223 
224     fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
225         todo!()
226     }
227 
228     fn support(&self) -> SysFSOpsSupport {
229         SysFSOpsSupport::ATTR_SHOW
230     }
231 }
232 
233 #[derive(Debug)]
234 struct Irq;
235 
236 impl Attribute for Irq {
237     fn mode(&self) -> ModeType {
238         SYSFS_ATTR_MODE_RO
239     }
240 
241     fn name(&self) -> &str {
242         "irq"
243     }
244 
245     fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
246         let dev = _kobj
247             .cast::<dyn PciDevice>()
248             .map_err(|e: Arc<dyn KObject>| {
249                 warn!("device:{:?} is not a pci device!", e);
250                 SystemError::EINVAL
251             })?;
252         if let IrqType::Msi { .. } = *dev.irq_type().read() {
253             // 见https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/pci/pci-sysfs.c#55
254             return sysfs_emit_str(_buf, "todo:sry,msi device is unimplemented now");
255         }
256         return sysfs_emit_str(_buf, &format!("{}", dev.irq_line()));
257     }
258 
259     fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
260         todo!()
261     }
262 
263     fn support(&self) -> SysFSOpsSupport {
264         SysFSOpsSupport::ATTR_SHOW
265     }
266 }
267 
268 #[derive(Debug)]
269 struct Modalias;
270 
271 impl Attribute for Modalias {
272     fn mode(&self) -> ModeType {
273         SYSFS_ATTR_MODE_RO
274     }
275 
276     fn name(&self) -> &str {
277         "modalias"
278     }
279 
280     fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
281         let dev = _kobj
282             .cast::<dyn PciDevice>()
283             .map_err(|e: Arc<dyn KObject>| {
284                 warn!("device:{:?} is not a pci device!", e);
285                 SystemError::EINVAL
286             })?;
287         return sysfs_emit_str(
288             _buf,
289             &format!(
290                 "pci:v{:08X}d{:08X}sv{:08X}sd{:08X}bc{:02X}sc{:02X}i{:02X}",
291                 dev.vendor(),
292                 dev.device_id(),
293                 dev.subsystem_vendor(),
294                 dev.subsystem_device(),
295                 dev.class_code(),
296                 dev.subclass(),
297                 dev.interface_code(),
298             ),
299         );
300     }
301 
302     fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
303         todo!()
304     }
305 
306     fn support(&self) -> SysFSOpsSupport {
307         SysFSOpsSupport::ATTR_SHOW
308     }
309 }
310