Skip to content

Commit 2282cba

Browse files
committed
rust: device_id: add macro for alias generation
For modpost to work, we need the device id table to be named as follow: __mod_{type}__{name}_device_table In C, this is done by calling MODULE_DEVICE_TABLE(type, name), which declares a new symbol that aliases to `name`. As far as I know it is not possible to create such aliases in Rust, so here we instead create a new static variable which contains a copy of the device_id tables, but without the extra `id_infos` used on the Rust side. Signed-off-by: Fabien Parent <[email protected]>
1 parent eae8e61 commit 2282cba

File tree

1 file changed

+31
-5
lines changed

1 file changed

+31
-5
lines changed

rust/kernel/device_id.rs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,25 @@ pub unsafe trait RawDeviceId {
4040
const DRIVER_DATA_OFFSET: usize;
4141
}
4242

43-
/// A zero-terminated device id array, followed by context data.
43+
/// A zero-terminated device id array.
4444
#[repr(C)]
45-
pub struct IdArray<T: RawDeviceId, U, const N: usize> {
45+
pub struct RawIdArray<T: RawDeviceId, const N: usize> {
4646
ids: [T::RawType; N],
4747
sentinel: MaybeUninit<T::RawType>,
48+
}
49+
50+
impl<T: RawDeviceId, const N: usize> RawIdArray<T, N> {
51+
#[doc(hidden)]
52+
pub const fn len(&self) -> usize {
53+
(N + 1) * core::mem::size_of::<T>()
54+
}
55+
}
56+
57+
/// A zero-terminated device id array, followed by context data.
58+
#[repr(C)]
59+
pub struct IdArray<T: RawDeviceId, U, const N: usize> {
60+
#[doc(hidden)]
61+
pub raw_ids: RawIdArray<T, N>,
4862
id_infos: [U; N],
4963
}
5064

@@ -83,8 +97,10 @@ impl<T: RawDeviceId, U, const N: usize> IdArray<T, U, N> {
8397
// SAFETY: this is effectively `array_assume_init`, which is unstable, so we use
8498
// `transmute_copy` instead. We have initialized all elements of `raw_ids` so this
8599
// `array_assume_init` is safe.
86-
ids: unsafe { core::mem::transmute_copy(&raw_ids) },
87-
sentinel: MaybeUninit::zeroed(),
100+
raw_ids: RawIdArray {
101+
ids: unsafe { core::mem::transmute_copy(&raw_ids) },
102+
sentinel: MaybeUninit::zeroed(),
103+
},
88104
// SAFETY: We have initialized all elements of `infos` so this `array_assume_init` is
89105
// safe.
90106
id_infos: unsafe { core::mem::transmute_copy(&infos) },
@@ -117,10 +133,20 @@ impl<T: RawDeviceId, U, const N: usize> IdTable<T, U> for IdArray<T, U, N> {
117133
}
118134

119135
fn id(&self, index: usize) -> &T::RawType {
120-
&self.ids[index]
136+
&self.raw_ids.ids[index]
121137
}
122138

123139
fn info(&self, index: usize) -> &U {
124140
&self.id_infos[index]
125141
}
126142
}
143+
144+
/// Create device table alias for modpost.
145+
#[macro_export]
146+
macro_rules! module_device_table {
147+
($table_type: literal, $module_table_name:ident, $table_name:ident) => {
148+
#[export_name = concat!("__mod_", $table_type, "__", stringify!($table_name), "_device_table")]
149+
static $module_table_name: [u8; $table_name.raw_ids.len()] =
150+
unsafe { core::mem::transmute_copy(&$table_name.raw_ids) };
151+
};
152+
}

0 commit comments

Comments
 (0)