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}