Skip to content

Commit 59bff0e

Browse files
committed
platform: move get_id_info from platform.rs to public
Signed-off-by: Li Hongyu <[email protected]>
1 parent f42f82c commit 59bff0e

File tree

2 files changed

+79
-27
lines changed

2 files changed

+79
-27
lines changed

rust/kernel/driver.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,3 +440,81 @@ macro_rules! module_driver {
440440
}
441441
}
442442
}
443+
444+
/// Implements a `get_id_info` function for drivers.
445+
///
446+
/// Some kinds of drivers, e.g. platform drivers, need to get info from `of_id`.
447+
/// This macro implements a function to do so with signature:
448+
///
449+
/// ```ignore
450+
/// fn get_id_info(dev: &Device) -> Option<&'static T::IdInfo>;
451+
/// ```
452+
///
453+
/// It should be called from inside an `impl<T: Driver> Adapter<T> {}` item.
454+
///
455+
/// # Examples
456+
///
457+
/// ```ignore
458+
/// use crate::{
459+
/// bindings,
460+
/// device::{self, RawDevice},
461+
/// driver,
462+
/// of,
463+
/// };
464+
///
465+
/// pub trait Driver {
466+
/// type IdInfo: 'static = ();
467+
/// const OF_DEVICE_ID_TABLE: Option<driver::IdTable<'static, of::DeviceId, Self::IdInfo>> = None;
468+
/// }
469+
///
470+
/// pub struct Device {
471+
/// ptr: *mut bindings::bar_device,
472+
/// }
473+
///
474+
/// // SAFETY: The device returned by `raw_device` is the raw bar device.
475+
/// unsafe impl device::RawDevice for Device {
476+
/// fn raw_device(&self) -> *mut bindings::device {
477+
/// // SAFETY: By the type invariants, we know that `self.ptr` is non-null and valid.
478+
/// unsafe { &mut (*self.ptr).dev }
479+
/// }
480+
/// }
481+
///
482+
/// pub struct Foo<T: Driver>(T);
483+
///
484+
/// impl<T: Driver> Adapter<T> {
485+
/// // Implements a `get_id_info` function
486+
/// crate::get_id_info!()
487+
/// }
488+
/// ```
489+
#[macro_export]
490+
macro_rules! get_id_info {
491+
() => {
492+
fn get_id_info(dev: &Device) -> Option<&'static T::IdInfo> {
493+
let table = T::OF_DEVICE_ID_TABLE?;
494+
495+
// SAFETY: `table` has static lifetime, so it is valid for read. `dev` is guaranteed to be
496+
// valid while it's alive, so is the raw device returned by it.
497+
let id = unsafe { bindings::of_match_device(table.as_ref(), dev.raw_device()) };
498+
if id.is_null() {
499+
return None;
500+
}
501+
502+
// SAFETY: `id` is a pointer within the static table, so it's always valid.
503+
let offset = unsafe { (*id).data };
504+
if offset.is_null() {
505+
return None;
506+
}
507+
508+
// SAFETY: The offset comes from a previous call to `offset_from` in `IdArray::new`, which
509+
// guarantees that the resulting pointer is within the table.
510+
let ptr = unsafe {
511+
id.cast::<u8>()
512+
.offset(offset as _)
513+
.cast::<Option<T::IdInfo>>()
514+
};
515+
516+
// SAFETY: The id table has a static lifetime, so `ptr` is guaranteed to be valid for read.
517+
unsafe { (&*ptr).as_ref() }
518+
}
519+
};
520+
}

rust/kernel/platform.rs

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -61,33 +61,7 @@ impl<T: Driver> driver::DriverOps for Adapter<T> {
6161
}
6262

6363
impl<T: Driver> Adapter<T> {
64-
fn get_id_info(dev: &Device) -> Option<&'static T::IdInfo> {
65-
let table = T::OF_DEVICE_ID_TABLE?;
66-
67-
// SAFETY: `table` has static lifetime, so it is valid for read. `dev` is guaranteed to be
68-
// valid while it's alive, so is the raw device returned by it.
69-
let id = unsafe { bindings::of_match_device(table.as_ref(), dev.raw_device()) };
70-
if id.is_null() {
71-
return None;
72-
}
73-
74-
// SAFETY: `id` is a pointer within the static table, so it's always valid.
75-
let offset = unsafe { (*id).data };
76-
if offset.is_null() {
77-
return None;
78-
}
79-
80-
// SAFETY: The offset comes from a previous call to `offset_from` in `IdArray::new`, which
81-
// guarantees that the resulting pointer is within the table.
82-
let ptr = unsafe {
83-
id.cast::<u8>()
84-
.offset(offset as _)
85-
.cast::<Option<T::IdInfo>>()
86-
};
87-
88-
// SAFETY: The id table has a static lifetime, so `ptr` is guaranteed to be valid for read.
89-
unsafe { (&*ptr).as_ref() }
90-
}
64+
crate::get_id_info!();
9165

9266
extern "C" fn probe_callback(pdev: *mut bindings::platform_device) -> core::ffi::c_int {
9367
from_kernel_result! {

0 commit comments

Comments
 (0)