Skip to content

Commit

Permalink
bcm2835_rng_rust: add support for DrvData
Browse files Browse the repository at this point in the history
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 <thesven73@gmail.com>
  • Loading branch information
Sven Van Asbroeck committed May 27, 2021
1 parent 2727379 commit fa1e44a
Showing 1 changed file with 39 additions and 7 deletions.
46 changes: 39 additions & 7 deletions drivers/char/hw_random/bcm2835_rng_rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@

use alloc::boxed::Box;
use core::pin::Pin;
use kernel::of::OfMatchTable;
use kernel::platdev::PlatformDriver;
use kernel::prelude::*;
use kernel::{c_str, platdev};
use kernel::{
file::File,
file_operations::{FileOpener, FileOperations},
io_buffer::IoBufferWriter,
miscdev,
of::OfMatchTable,
platdev::PlatformDriver,
prelude::*,
{c_str, platdev},
};

module! {
type: RngModule,
Expand All @@ -20,15 +26,41 @@ module! {
license: b"GPL v2",
}

struct RngDevice;

impl FileOpener<()> for RngDevice {
fn open(_state: &()) -> Result<Self::Wrapper> {
Ok(Box::try_new(RngDevice)?)
}
}

impl FileOperations for RngDevice {
kernel::declare_file_operations!(read);

fn read<T: IoBufferWriter>(&self, _: &File, data: &mut T, offset: u64) -> Result<usize> {
// Succeed if the caller doesn't provide a buffer or if not at the start.
if data.is_empty() || offset != 0 {
return Ok(0);
}

data.write(&0_u32)?;
Ok(4)
}
}

struct RngDriver;

impl PlatformDriver for RngDriver {
fn probe(device_id: i32) -> Result {
type DrvData = Pin<Box<miscdev::Registration<()>>>;

fn probe(device_id: i32) -> Result<Self::DrvData> {
pr_info!("probing discovered hwrng with id {}\n", device_id);
Ok(())
let drv_data =
miscdev::Registration::new_pinned::<RngDevice>(c_str!("rust_hwrng"), None, ())?;
Ok(drv_data)
}

fn remove(device_id: i32) -> Result {
fn remove(device_id: i32, _drv_data: Self::DrvData) -> Result {
pr_info!("removing hwrng with id {}\n", device_id);
Ok(())
}
Expand Down

0 comments on commit fa1e44a

Please sign in to comment.