Skip to content

Commit b52bafa

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

File tree

2 files changed

+74
-27
lines changed

2 files changed

+74
-27
lines changed

rust/kernel/driver.rs

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

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)