|
2 | 2 |
|
3 | 3 | //! Generic support for drivers of different buses (e.g., PCI, Platform, Amba, etc.).
|
4 | 4 | //!
|
5 |
| -//! Each bus / subsystem is expected to implement [`RegistrationOps`], which allows drivers to |
6 |
| -//! register using the [`Registration`] class. |
| 5 | +//! This documentation describes how to implement a bus specific driver API and how to align it with |
| 6 | +//! the design of (bus specific) devices. |
| 7 | +//! |
| 8 | +//! Note: Readers are expected to know the content of the documentation of [`Device`] and |
| 9 | +//! [`DeviceContext`]. |
| 10 | +//! |
| 11 | +//! # Driver Trait |
| 12 | +//! |
| 13 | +//! The main driver interface is defined by a bus specific driver trait. For instance: |
| 14 | +//! |
| 15 | +//! ```ignore |
| 16 | +//! pub trait Driver: Send { |
| 17 | +//! /// The type holding information about each device ID supported by the driver. |
| 18 | +//! type IdInfo: 'static; |
| 19 | +//! |
| 20 | +//! /// The table of OF device ids supported by the driver. |
| 21 | +//! const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None; |
| 22 | +//! |
| 23 | +//! /// The table of ACPI device ids supported by the driver. |
| 24 | +//! const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = None; |
| 25 | +//! |
| 26 | +//! /// Driver probe. |
| 27 | +//! fn probe(dev: &Device<device::Core>, id_info: &Self::IdInfo) -> Result<Pin<KBox<Self>>>; |
| 28 | +//! |
| 29 | +//! /// Driver unbind (optional). |
| 30 | +//! fn unbind(dev: &Device<device::Core>, this: Pin<&Self>) { |
| 31 | +//! let _ = (dev, this); |
| 32 | +//! } |
| 33 | +//! } |
| 34 | +//! ``` |
| 35 | +//! |
| 36 | +//! For specific examples see [`auxiliary::Driver`], [`pci::Driver`] and [`platform::Driver`]. |
| 37 | +//! |
| 38 | +//! The `probe()` callback should return a `Result<Pin<KBox<Self>>>`, i.e. the driver's private |
| 39 | +//! data. The bus abstraction should store the pointer in the corresponding bus device. The generic |
| 40 | +//! [`Device`] infrastructure provides common helpers for this purpose on its |
| 41 | +//! [`Device<CoreInternal>`] implementation. |
| 42 | +//! |
| 43 | +//! All driver callbacks should provide a reference to the driver's private data. Once the driver |
| 44 | +//! is unbound from the device, the bus abstraction should take back the ownership of the driver's |
| 45 | +//! private data from the corresponding [`Device`] and [`drop`] it. |
| 46 | +//! |
| 47 | +//! All driver callbacks should provide a [`Device<Core>`] reference (see also [`device::Core`]). |
| 48 | +//! |
| 49 | +//! # Adapter |
| 50 | +//! |
| 51 | +//! The adapter implementation of a bus represents the abstraction layer between the C bus |
| 52 | +//! callbacks and the Rust bus callbacks. It therefore has to be generic over an implementation of |
| 53 | +//! the [driver trait](#driver-trait). |
| 54 | +//! |
| 55 | +//! ```ignore |
| 56 | +//! pub struct Adapter<T: Driver>; |
| 57 | +//! ``` |
| 58 | +//! |
| 59 | +//! There's a common [`Adapter`] trait that can be implemented to inherit common driver |
| 60 | +//! infrastructure, such as finding the ID info from an [`of::IdTable`] or [`acpi::IdTable`]. |
| 61 | +//! |
| 62 | +//! # Driver Registration |
| 63 | +//! |
| 64 | +//! In order to register C driver types (such as `struct platform_driver`) the [adapter](#adapter) |
| 65 | +//! should implement the [`RegistrationOps`] trait. |
| 66 | +//! |
| 67 | +//! This trait implementation can be used to create the actual registration with the common |
| 68 | +//! [`Registration`] type. |
| 69 | +//! |
| 70 | +//! Typically, bus abstractions want to provide a bus specific `module_bus_driver!` macro, which |
| 71 | +//! creates a kernel module with exactly one [`Registration`] for the bus specific adapter. |
| 72 | +//! |
| 73 | +//! The generic driver infrastructure provides a helper for this with the [`module_driver`] macro. |
| 74 | +//! |
| 75 | +//! # Device IDs |
| 76 | +//! |
| 77 | +//! Besides the common device ID types, such as [`of::DeviceId`] and [`acpi::DeviceId`], most buses |
| 78 | +//! may need to implement their own device ID types. |
| 79 | +//! |
| 80 | +//! For this purpose the generic infrastructure in [`device_id`] should be used. |
| 81 | +//! |
| 82 | +//! [`auxiliary::Driver`]: kernel::auxiliary::Driver |
| 83 | +//! [`Core`]: device::Core |
| 84 | +//! [`Device`]: device::Device |
| 85 | +//! [`Device<Core>`]: device::Device<device::Core> |
| 86 | +//! [`Device<CoreInternal>`]: device::Device<device::CoreInternal> |
| 87 | +//! [`DeviceContext`]: device::DeviceContext |
| 88 | +//! [`device_id`]: kernel::device_id |
| 89 | +//! [`module_driver`]: kernel::module_driver |
| 90 | +//! [`pci::Driver`]: kernel::pci::Driver |
| 91 | +//! [`platform::Driver`]: kernel::platform::Driver |
7 | 92 |
|
8 | 93 | use crate::error::{Error, Result};
|
9 | 94 | use crate::{acpi, device, of, str::CStr, try_pin_init, types::Opaque, ThisModule};
|
|
0 commit comments