Skip to content

Commit d047266

Browse files
author
Sven Van Asbroeck
committed
bcm2835_rng_rust: add support for DrvData
To demonstrate device driver data in a non-trivial way, create a `miscdev` for each discovered device. This `miscdev` can only be opened and read. When read from userspace, it returns four zero bytes at a time. Note that `DrvData` consists of a `Pin<Box<miscdev::Registration>>`, which is a pinned structure. This demonstrates that pinned or self- referential structures may be used in `DrvData`. Signed-off-by: Sven Van Asbroeck <[email protected]>
1 parent 669248b commit d047266

File tree

1 file changed

+39
-7
lines changed

1 file changed

+39
-7
lines changed

drivers/char/hw_random/bcm2835_rng_rust.rs

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,16 @@
77

88
use alloc::boxed::Box;
99
use core::pin::Pin;
10-
use kernel::of::OfMatchTable;
11-
use kernel::platdev::PlatformDriver;
12-
use kernel::prelude::*;
13-
use kernel::{c_str, platdev};
10+
use kernel::{
11+
file::File,
12+
file_operations::{FileOpener, FileOperations},
13+
io_buffer::IoBufferWriter,
14+
miscdev,
15+
of::OfMatchTable,
16+
platdev::PlatformDriver,
17+
prelude::*,
18+
{c_str, platdev},
19+
};
1420

1521
module! {
1622
type: RngModule,
@@ -20,15 +26,41 @@ module! {
2026
license: b"GPL v2",
2127
}
2228

29+
struct RngDevice;
30+
31+
impl FileOpener<()> for RngDevice {
32+
fn open(_state: &()) -> Result<Self::Wrapper> {
33+
Ok(Box::try_new(RngDevice)?)
34+
}
35+
}
36+
37+
impl FileOperations for RngDevice {
38+
kernel::declare_file_operations!(read);
39+
40+
fn read<T: IoBufferWriter>(&self, _: &File, data: &mut T, offset: u64) -> Result<usize> {
41+
// Succeed if the caller doesn't provide a buffer or if not at the start.
42+
if data.is_empty() || offset != 0 {
43+
return Ok(0);
44+
}
45+
46+
data.write(&0_u32)?;
47+
Ok(4)
48+
}
49+
}
50+
2351
struct RngDriver;
2452

2553
impl PlatformDriver for RngDriver {
26-
fn probe(device_id: i32) -> Result {
54+
type DrvData = Pin<Box<miscdev::Registration<()>>>;
55+
56+
fn probe(device_id: i32) -> Result<Self::DrvData> {
2757
pr_info!("probing discovered hwrng with id {}\n", device_id);
28-
Ok(())
58+
let drv_data =
59+
miscdev::Registration::new_pinned::<RngDevice>(c_str!("rust_hwrng"), None, ())?;
60+
Ok(drv_data)
2961
}
3062

31-
fn remove(device_id: i32) -> Result {
63+
fn remove(device_id: i32, _drv_data: Self::DrvData) -> Result {
3264
pr_info!("removing hwrng with id {}\n", device_id);
3365
Ok(())
3466
}

0 commit comments

Comments
 (0)