kernel/device/platform/mod.rs
1//! Platform device driver module.
2//!
3//! This module provides the implementation of platform device drivers, including
4//! device information and driver management. It defines the `PlatformDeviceInfo` and
5//! `PlatformDeviceDriver` structs, which represent the device information and driver
6//! respectively.
7//!
8//! The module implements the `Device` and `DeviceDriver` traits for platform devices,
9//! allowing them to be integrated into the device management system.
10//!
11//! # Components
12//!
13//! - `PlatformDeviceInfo`: Stores information about a platform device, including its name,
14//! ID, and compatible device strings.
15//!
16//! - `PlatformDeviceDriver`: Implements a driver for platform devices, containing resources,
17//! probe and remove functions, and compatibility information.
18//!
19//! # Submodules
20//!
21//! - `resource`: Defines platform-specific device resources.
22//!
23//! # Examples
24//!
25//! ```rust
26//! // Creating a platform device info
27//! let device_info = PlatformDeviceInfo::new(
28//! "example_device",
29//! 1,
30//! vec!["example,device-v1", "example,device-v2"],
31//! Vec::new() // Add resources as an empty vector
32//! );
33//!
34//! // Creating a platform device driver
35//! let driver = PlatformDeviceDriver::new(
36//! "example_driver",
37//! |device_info| { /* probe implementation */ Ok(()) },
38//! |device_info| { /* remove implementation */ Ok(()) },
39//! vec!["example,device-v1", "example,device-v2"]
40//! );
41//! ```
42//!
43//! # Implementation Details
44//!
45//! Platform devices are hardware components that are directly connected to the
46//! system bus or integrated into the SoC. They are typically discovered during
47//! boot time through firmware tables (like ACPI or Device Tree).
48//!
49//! The driver model allows for dynamic matching between devices and their drivers
50//! based on the compatible strings, enabling a flexible plug-and-play architecture.
51//! respectively. The module also includes the `Device` and `DeviceDriver` traits,
52//! which define the interface for device information and drivers.
53//!
54
55
56pub mod resource;
57
58extern crate alloc;
59use alloc::vec::Vec;
60
61use super::*;
62use resource::*;
63
64/// Struct representing platform device information.
65#[derive(Debug)]
66pub struct PlatformDeviceInfo {
67 name: &'static str,
68 id: usize,
69 compatible: Vec<&'static str>,
70 resources: Vec<PlatformDeviceResource>,
71}
72
73/// Information about a platform device.
74///
75/// This structure holds the basic identifying information for platform devices,
76/// including a name, unique identifier, compatibility strings, and resources.
77///
78/// # Fields
79/// - `name`: A static string representing the name of the device
80/// - `id`: A unique identifier for the device
81/// - `compatible`: A list of compatibility strings that describe compatible drivers
82/// - `resources`: A list of resources associated with the device
83///
84/// # Examples
85///
86/// ```
87/// let device_info = PlatformDeviceInfo::new(
88/// "uart0",
89/// 0,
90/// vec!["ns16550a", "uart"],
91/// Vec::new() // Add resources as an empty vector
92/// );
93///
94impl PlatformDeviceInfo {
95 /// Creates a new `PlatformDeviceInfo` instance.
96 ///
97 /// # Arguments
98 ///
99 /// * `name` - Static string identifier for the device
100 /// * `id` - Unique identifier number
101 /// * `compatible` - List of compatible device identifiers
102 ///
103 /// # Returns
104 ///
105 /// A new `PlatformDeviceInfo` instance with the provided values.
106 pub fn new(name: &'static str, id: usize, compatible: Vec<&'static str>, resources: Vec<PlatformDeviceResource>) -> Self {
107 Self {
108 name,
109 id,
110 compatible,
111 resources,
112 }
113 }
114
115 /// Get the `PlatformDeviceResource` associated with the device.
116 ///
117 /// # Returns
118 ///
119 /// A reference to a vector of `PlatformDeviceResource` objects.
120 ///
121 pub fn get_resources(&self) -> &Vec<PlatformDeviceResource> {
122 &self.resources
123 }
124}
125
126impl DeviceInfo for PlatformDeviceInfo {
127 fn name(&self) -> &'static str {
128 self.name
129 }
130
131 fn id(&self) -> usize {
132 self.id
133 }
134
135 fn compatible(&self) -> Vec<&'static str> {
136 self.compatible.clone()
137 }
138
139 fn as_any(&self) -> &dyn Any {
140 self
141 }
142}
143
144pub struct PlatformDeviceDriver {
145 name: &'static str,
146 probe_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
147 remove_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
148 compatible: Vec<&'static str>, // Change to Vec<&'static str>
149}
150
151impl PlatformDeviceDriver {
152 pub fn new(
153 name: &'static str,
154 probe_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
155 remove_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
156 compatible: Vec<&'static str>,
157 ) -> Self {
158 Self {
159 name,
160 probe_fn,
161 remove_fn,
162 compatible,
163 }
164 }
165}
166
167impl DeviceDriver for PlatformDeviceDriver {
168 fn name(&self) -> &'static str {
169 self.name
170 }
171
172 fn match_table(&self) -> Vec<&'static str> {
173 self.compatible.clone()
174 }
175
176 fn probe(&self, device: &dyn DeviceInfo) -> Result<(), &'static str> {
177 // Downcast the device to a `PlatformDeviceInfo`
178 let platform_device_info = device.as_any()
179 .downcast_ref::<PlatformDeviceInfo>()
180 .ok_or("Failed to downcast to PlatformDeviceInfo")?;
181 // Call the probe function
182 (self.probe_fn)(platform_device_info)
183 }
184
185 fn remove(&self, _device: &dyn DeviceInfo) -> Result<(), &'static str> {
186 Ok(())
187 }
188}
189
190
191#[cfg(test)]
192mod tests {
193 use alloc::vec;
194
195 use super::*;
196
197 #[test_case]
198 fn test_probe_success() {
199 let device = PlatformDeviceInfo::new("test_device", 1, vec!["test,compatible"], vec![]);
200 let driver = PlatformDeviceDriver::new(
201 "test_driver",
202 |device_info| {
203 assert_eq!(device_info.name(), "test_device");
204 Ok(())
205 },
206 |_device| Ok(()),
207 vec!["test,compatible"],
208 );
209
210 let result = driver.probe(&device);
211 assert!(result.is_ok());
212 }
213
214 #[test_case]
215 fn test_probe_failure() {
216 struct DummyDevice;
217 impl DeviceInfo for DummyDevice {
218 fn name(&self) -> &'static str { "dummy" }
219 fn id(&self) -> usize { 0 }
220 fn compatible(&self) -> Vec<&'static str> { vec![] }
221 fn as_any(&self) -> &dyn Any { self }
222 }
223
224 let device = DummyDevice;
225 let driver = PlatformDeviceDriver::new(
226 "test_driver",
227 |_device| Ok(()),
228 |_device| Ok(()),
229 vec!["test,compatible"],
230 );
231
232 let result = driver.probe(&device);
233 assert!(result.is_err());
234 }
235}