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.
65pub struct PlatformDeviceInfo {
66    name: &'static str,
67    id: usize,
68    compatible: Vec<&'static str>,
69    resources: Vec<PlatformDeviceResource>,
70}
71
72/// Information about a platform device.
73///
74/// This structure holds the basic identifying information for platform devices,
75/// including a name, unique identifier, compatibility strings, and resources.
76///
77/// # Fields
78/// - `name`: A static string representing the name of the device
79/// - `id`: A unique identifier for the device
80/// - `compatible`: A list of compatibility strings that describe compatible drivers
81/// - `resources`: A list of resources associated with the device
82///
83/// # Examples
84///
85/// ```
86/// let device_info = PlatformDeviceInfo::new(
87///     "uart0",
88///     0,
89///     vec!["ns16550a", "uart"],
90///     Vec::new() // Add resources as an empty vector
91/// );
92///
93impl PlatformDeviceInfo {
94    /// Creates a new `PlatformDeviceInfo` instance.
95    ///
96    /// # Arguments
97    ///
98    /// * `name` - Static string identifier for the device
99    /// * `id` - Unique identifier number
100    /// * `compatible` - List of compatible device identifiers
101    ///
102    /// # Returns
103    ///
104    /// A new `PlatformDeviceInfo` instance with the provided values.
105    pub fn new(name: &'static str, id: usize, compatible: Vec<&'static str>, resources: Vec<PlatformDeviceResource>) -> Self {
106        Self {
107            name,
108            id,
109            compatible,
110            resources,
111        }
112    }
113
114    /// Get the `PlatformDeviceResource` associated with the device.
115    /// 
116    /// # Returns
117    /// 
118    /// A reference to a vector of `PlatformDeviceResource` objects.
119    /// 
120    pub fn get_resources(&self) -> &Vec<PlatformDeviceResource> {
121        &self.resources
122    }
123}
124
125impl DeviceInfo for PlatformDeviceInfo {
126    fn name(&self) -> &'static str {
127        self.name
128    }
129
130    fn id(&self) -> usize {
131        self.id
132    }
133
134    fn compatible(&self) -> Vec<&'static str> {
135        self.compatible.clone()
136    }
137
138    fn as_any(&self) -> &dyn Any {
139        self
140    }
141}
142
143pub struct PlatformDeviceDriver {
144    name: &'static str,
145    probe_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
146    remove_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
147    compatible: Vec<&'static str>, // Change to Vec<&'static str>
148}
149
150impl PlatformDeviceDriver {
151    pub fn new(
152        name: &'static str,
153        probe_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
154        remove_fn: fn(&PlatformDeviceInfo) -> Result<(), &'static str>,
155        compatible: Vec<&'static str>,
156    ) -> Self {
157        Self {
158            name,
159            probe_fn,           
160            remove_fn,
161            compatible,
162        }
163    }
164}
165
166impl DeviceDriver for PlatformDeviceDriver {
167    fn name(&self) -> &'static str {
168        self.name
169    }
170
171    fn match_table(&self) -> Vec<&'static str> {
172        self.compatible.clone()
173    }
174
175    fn probe(&self, device: &dyn DeviceInfo) -> Result<(), &'static str> {
176        // Downcast the device to a `PlatformDeviceInfo`
177        let platform_device_info = device.as_any()
178            .downcast_ref::<PlatformDeviceInfo>()
179            .ok_or("Failed to downcast to PlatformDeviceInfo")?;
180        // Call the probe function
181        (self.probe_fn)(platform_device_info)
182    }
183
184    fn remove(&self, _device: &dyn DeviceInfo) -> Result<(), &'static str> {
185        Ok(())
186    }
187}
188
189
190#[cfg(test)]
191mod tests {
192    use alloc::vec;
193
194    use super::*;
195
196    #[test_case]
197    fn test_probe_success() {
198        let device = PlatformDeviceInfo::new("test_device", 1, vec!["test,compatible"], vec![]);
199        let driver = PlatformDeviceDriver::new(
200            "test_driver",
201            |device_info| {
202                assert_eq!(device_info.name(), "test_device");
203                Ok(())
204            },
205            |_device| Ok(()),
206            vec!["test,compatible"],
207        );
208
209        let result = driver.probe(&device);
210        assert!(result.is_ok());
211    }
212
213    #[test_case]
214    fn test_probe_failure() {
215        struct DummyDevice;
216        impl DeviceInfo for DummyDevice {
217            fn name(&self) -> &'static str { "dummy" }
218            fn id(&self) -> usize { 0 }
219            fn compatible(&self) -> Vec<&'static str> { vec![] }
220            fn as_any(&self) -> &dyn Any { self }
221        }
222
223        let device = DummyDevice;
224        let driver = PlatformDeviceDriver::new(
225            "test_driver",
226            |_device| Ok(()),
227            |_device| Ok(()),
228            vec!["test,compatible"],
229        );
230
231        let result = driver.probe(&device);
232        assert!(result.is_err());
233    }
234}