summaryrefslogtreecommitdiff
path: root/samples/rust
diff options
context:
space:
mode:
Diffstat (limited to 'samples/rust')
-rw-r--r--samples/rust/Kconfig34
-rw-r--r--samples/rust/Makefile3
-rw-r--r--samples/rust/rust_configfs.rs192
-rw-r--r--samples/rust/rust_dma.rs97
-rw-r--r--samples/rust/rust_driver_auxiliary.rs120
-rw-r--r--samples/rust/rust_driver_faux.rs4
-rw-r--r--samples/rust/rust_driver_pci.rs27
-rw-r--r--samples/rust/rust_driver_platform.rs13
-rw-r--r--samples/rust/rust_minimal.rs2
-rw-r--r--samples/rust/rust_misc_device.rs183
-rw-r--r--samples/rust/rust_print_main.rs2
11 files changed, 563 insertions, 114 deletions
diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig
index 3b6eae84b297..7f7371a004ee 100644
--- a/samples/rust/Kconfig
+++ b/samples/rust/Kconfig
@@ -10,6 +10,17 @@ menuconfig SAMPLES_RUST
if SAMPLES_RUST
+config SAMPLE_RUST_CONFIGFS
+ tristate "Configfs sample"
+ depends on CONFIGFS_FS
+ help
+ This option builds the Rust configfs sample.
+
+ To compile this as a module, choose M here:
+ the module will be called rust_configfs.
+
+ If unsure, say N.
+
config SAMPLE_RUST_MINIMAL
tristate "Minimal"
help
@@ -40,6 +51,17 @@ config SAMPLE_RUST_PRINT
If unsure, say N.
+config SAMPLE_RUST_DMA
+ tristate "DMA Test Driver"
+ depends on PCI
+ help
+ This option builds the Rust DMA Test driver sample.
+
+ To compile this as a module, choose M here:
+ the module will be called rust_dma.
+
+ If unsure, say N.
+
config SAMPLE_RUST_DRIVER_PCI
tristate "PCI Driver"
depends on PCI
@@ -71,6 +93,18 @@ config SAMPLE_RUST_DRIVER_FAUX
If unsure, say N.
+config SAMPLE_RUST_DRIVER_AUXILIARY
+ tristate "Auxiliary Driver"
+ depends on PCI
+ select AUXILIARY_BUS
+ help
+ This option builds the Rust auxiliary driver sample.
+
+ To compile this as a module, choose M here:
+ the module will be called rust_driver_auxiliary.
+
+ If unsure, say N.
+
config SAMPLE_RUST_HOSTPROGS
bool "Host programs"
help
diff --git a/samples/rust/Makefile b/samples/rust/Makefile
index 0dbc6d90f1ef..bd2faad63b4f 100644
--- a/samples/rust/Makefile
+++ b/samples/rust/Makefile
@@ -4,9 +4,12 @@ ccflags-y += -I$(src) # needed for trace events
obj-$(CONFIG_SAMPLE_RUST_MINIMAL) += rust_minimal.o
obj-$(CONFIG_SAMPLE_RUST_MISC_DEVICE) += rust_misc_device.o
obj-$(CONFIG_SAMPLE_RUST_PRINT) += rust_print.o
+obj-$(CONFIG_SAMPLE_RUST_DMA) += rust_dma.o
obj-$(CONFIG_SAMPLE_RUST_DRIVER_PCI) += rust_driver_pci.o
obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) += rust_driver_platform.o
obj-$(CONFIG_SAMPLE_RUST_DRIVER_FAUX) += rust_driver_faux.o
+obj-$(CONFIG_SAMPLE_RUST_DRIVER_AUXILIARY) += rust_driver_auxiliary.o
+obj-$(CONFIG_SAMPLE_RUST_CONFIGFS) += rust_configfs.o
rust_print-y := rust_print_main.o rust_print_events.o
diff --git a/samples/rust/rust_configfs.rs b/samples/rust/rust_configfs.rs
new file mode 100644
index 000000000000..60ddbe62cda3
--- /dev/null
+++ b/samples/rust/rust_configfs.rs
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust configfs sample.
+
+use kernel::alloc::flags;
+use kernel::c_str;
+use kernel::configfs;
+use kernel::configfs_attrs;
+use kernel::new_mutex;
+use kernel::page::PAGE_SIZE;
+use kernel::prelude::*;
+use kernel::sync::Mutex;
+
+module! {
+ type: RustConfigfs,
+ name: "rust_configfs",
+ author: "Rust for Linux Contributors",
+ description: "Rust configfs sample",
+ license: "GPL",
+}
+
+#[pin_data]
+struct RustConfigfs {
+ #[pin]
+ config: configfs::Subsystem<Configuration>,
+}
+
+#[pin_data]
+struct Configuration {
+ message: &'static CStr,
+ #[pin]
+ bar: Mutex<(KBox<[u8; PAGE_SIZE]>, usize)>,
+}
+
+impl Configuration {
+ fn new() -> impl PinInit<Self, Error> {
+ try_pin_init!(Self {
+ message: c_str!("Hello World\n"),
+ bar <- new_mutex!((KBox::new([0; PAGE_SIZE], flags::GFP_KERNEL)?, 0)),
+ })
+ }
+}
+
+impl kernel::InPlaceModule for RustConfigfs {
+ fn init(_module: &'static ThisModule) -> impl PinInit<Self, Error> {
+ pr_info!("Rust configfs sample (init)\n");
+
+ // Define a subsystem with the data type `Configuration`, two
+ // attributes, `message` and `bar` and child group type `Child`. `mkdir`
+ // in the directory representing this subsystem will create directories
+ // backed by the `Child` type.
+ let item_type = configfs_attrs! {
+ container: configfs::Subsystem<Configuration>,
+ data: Configuration,
+ child: Child,
+ attributes: [
+ message: 0,
+ bar: 1,
+ ],
+ };
+
+ try_pin_init!(Self {
+ config <- configfs::Subsystem::new(
+ c_str!("rust_configfs"), item_type, Configuration::new()
+ ),
+ })
+ }
+}
+
+#[vtable]
+impl configfs::GroupOperations for Configuration {
+ type Child = Child;
+
+ fn make_group(&self, name: &CStr) -> Result<impl PinInit<configfs::Group<Child>, Error>> {
+ // Define a group with data type `Child`, one attribute `baz` and child
+ // group type `GrandChild`. `mkdir` in the directory representing this
+ // group will create directories backed by the `GrandChild` type.
+ let tpe = configfs_attrs! {
+ container: configfs::Group<Child>,
+ data: Child,
+ child: GrandChild,
+ attributes: [
+ baz: 0,
+ ],
+ };
+
+ Ok(configfs::Group::new(name.try_into()?, tpe, Child::new()))
+ }
+}
+
+#[vtable]
+impl configfs::AttributeOperations<0> for Configuration {
+ type Data = Configuration;
+
+ fn show(container: &Configuration, page: &mut [u8; PAGE_SIZE]) -> Result<usize> {
+ pr_info!("Show message\n");
+ let data = container.message;
+ page[0..data.len()].copy_from_slice(data);
+ Ok(data.len())
+ }
+}
+
+#[vtable]
+impl configfs::AttributeOperations<1> for Configuration {
+ type Data = Configuration;
+
+ fn show(container: &Configuration, page: &mut [u8; PAGE_SIZE]) -> Result<usize> {
+ pr_info!("Show bar\n");
+ let guard = container.bar.lock();
+ let data = guard.0.as_slice();
+ let len = guard.1;
+ page[0..len].copy_from_slice(&data[0..len]);
+ Ok(len)
+ }
+
+ fn store(container: &Configuration, page: &[u8]) -> Result {
+ pr_info!("Store bar\n");
+ let mut guard = container.bar.lock();
+ guard.0[0..page.len()].copy_from_slice(page);
+ guard.1 = page.len();
+ Ok(())
+ }
+}
+
+// `pin_data` cannot handle structs without braces.
+#[pin_data]
+struct Child {}
+
+impl Child {
+ fn new() -> impl PinInit<Self, Error> {
+ try_pin_init!(Self {})
+ }
+}
+
+#[vtable]
+impl configfs::GroupOperations for Child {
+ type Child = GrandChild;
+
+ fn make_group(&self, name: &CStr) -> Result<impl PinInit<configfs::Group<GrandChild>, Error>> {
+ // Define a group with data type `GrandChild`, one attribute `gc`. As no
+ // child type is specified, it will not be possible to create subgroups
+ // in this group, and `mkdir`in the directory representing this group
+ // will return an error.
+ let tpe = configfs_attrs! {
+ container: configfs::Group<GrandChild>,
+ data: GrandChild,
+ attributes: [
+ gc: 0,
+ ],
+ };
+
+ Ok(configfs::Group::new(
+ name.try_into()?,
+ tpe,
+ GrandChild::new(),
+ ))
+ }
+}
+
+#[vtable]
+impl configfs::AttributeOperations<0> for Child {
+ type Data = Child;
+
+ fn show(_container: &Child, page: &mut [u8; PAGE_SIZE]) -> Result<usize> {
+ pr_info!("Show baz\n");
+ let data = c"Hello Baz\n".to_bytes();
+ page[0..data.len()].copy_from_slice(data);
+ Ok(data.len())
+ }
+}
+
+// `pin_data` cannot handle structs without braces.
+#[pin_data]
+struct GrandChild {}
+
+impl GrandChild {
+ fn new() -> impl PinInit<Self, Error> {
+ try_pin_init!(Self {})
+ }
+}
+
+#[vtable]
+impl configfs::AttributeOperations<0> for GrandChild {
+ type Data = GrandChild;
+
+ fn show(_container: &GrandChild, page: &mut [u8; PAGE_SIZE]) -> Result<usize> {
+ pr_info!("Show grand child\n");
+ let data = c"Hello GC\n".to_bytes();
+ page[0..data.len()].copy_from_slice(data);
+ Ok(data.len())
+ }
+}
diff --git a/samples/rust/rust_dma.rs b/samples/rust/rust_dma.rs
new file mode 100644
index 000000000000..874c2c964afa
--- /dev/null
+++ b/samples/rust/rust_dma.rs
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust DMA api test (based on QEMU's `pci-testdev`).
+//!
+//! To make this driver probe, QEMU must be run with `-device pci-testdev`.
+
+use kernel::{bindings, device::Core, dma::CoherentAllocation, pci, prelude::*, types::ARef};
+
+struct DmaSampleDriver {
+ pdev: ARef<pci::Device>,
+ ca: CoherentAllocation<MyStruct>,
+}
+
+const TEST_VALUES: [(u32, u32); 5] = [
+ (0xa, 0xb),
+ (0xc, 0xd),
+ (0xe, 0xf),
+ (0xab, 0xba),
+ (0xcd, 0xef),
+];
+
+struct MyStruct {
+ h: u32,
+ b: u32,
+}
+
+impl MyStruct {
+ fn new(h: u32, b: u32) -> Self {
+ Self { h, b }
+ }
+}
+// SAFETY: All bit patterns are acceptable values for `MyStruct`.
+unsafe impl kernel::transmute::AsBytes for MyStruct {}
+// SAFETY: Instances of `MyStruct` have no uninitialized portions.
+unsafe impl kernel::transmute::FromBytes for MyStruct {}
+
+kernel::pci_device_table!(
+ PCI_TABLE,
+ MODULE_PCI_TABLE,
+ <DmaSampleDriver as pci::Driver>::IdInfo,
+ [(
+ pci::DeviceId::from_id(bindings::PCI_VENDOR_ID_REDHAT, 0x5),
+ ()
+ )]
+);
+
+impl pci::Driver for DmaSampleDriver {
+ type IdInfo = ();
+ const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
+
+ fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
+ dev_info!(pdev.as_ref(), "Probe DMA test driver.\n");
+
+ let ca: CoherentAllocation<MyStruct> =
+ CoherentAllocation::alloc_coherent(pdev.as_ref(), TEST_VALUES.len(), GFP_KERNEL)?;
+
+ || -> Result {
+ for (i, value) in TEST_VALUES.into_iter().enumerate() {
+ kernel::dma_write!(ca[i] = MyStruct::new(value.0, value.1));
+ }
+
+ Ok(())
+ }()?;
+
+ let drvdata = KBox::new(
+ Self {
+ pdev: pdev.into(),
+ ca,
+ },
+ GFP_KERNEL,
+ )?;
+
+ Ok(drvdata.into())
+ }
+}
+
+impl Drop for DmaSampleDriver {
+ fn drop(&mut self) {
+ dev_info!(self.pdev.as_ref(), "Unload DMA test driver.\n");
+
+ let _ = || -> Result {
+ for (i, value) in TEST_VALUES.into_iter().enumerate() {
+ assert_eq!(kernel::dma_read!(self.ca[i].h), value.0);
+ assert_eq!(kernel::dma_read!(self.ca[i].b), value.1);
+ }
+ Ok(())
+ }();
+ }
+}
+
+kernel::module_pci_driver! {
+ type: DmaSampleDriver,
+ name: "rust_dma",
+ authors: ["Abdiel Janulgue"],
+ description: "Rust DMA test",
+ license: "GPL v2",
+}
diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driver_auxiliary.rs
new file mode 100644
index 000000000000..3e15e6d002bb
--- /dev/null
+++ b/samples/rust/rust_driver_auxiliary.rs
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Rust auxiliary driver sample (based on a PCI driver for QEMU's `pci-testdev`).
+//!
+//! To make this driver probe, QEMU must be run with `-device pci-testdev`.
+
+use kernel::{
+ auxiliary, bindings, c_str, device::Core, driver, error::Error, pci, prelude::*, str::CStr,
+ InPlaceModule,
+};
+
+use pin_init::PinInit;
+
+const MODULE_NAME: &CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
+const AUXILIARY_NAME: &CStr = c_str!("auxiliary");
+
+struct AuxiliaryDriver;
+
+kernel::auxiliary_device_table!(
+ AUX_TABLE,
+ MODULE_AUX_TABLE,
+ <AuxiliaryDriver as auxiliary::Driver>::IdInfo,
+ [(auxiliary::DeviceId::new(MODULE_NAME, AUXILIARY_NAME), ())]
+);
+
+impl auxiliary::Driver for AuxiliaryDriver {
+ type IdInfo = ();
+
+ const ID_TABLE: auxiliary::IdTable<Self::IdInfo> = &AUX_TABLE;
+
+ fn probe(adev: &auxiliary::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
+ dev_info!(
+ adev.as_ref(),
+ "Probing auxiliary driver for auxiliary device with id={}\n",
+ adev.id()
+ );
+
+ ParentDriver::connect(adev)?;
+
+ let this = KBox::new(Self, GFP_KERNEL)?;
+
+ Ok(this.into())
+ }
+}
+
+struct ParentDriver {
+ _reg: [auxiliary::Registration; 2],
+}
+
+kernel::pci_device_table!(
+ PCI_TABLE,
+ MODULE_PCI_TABLE,
+ <ParentDriver as pci::Driver>::IdInfo,
+ [(
+ pci::DeviceId::from_id(bindings::PCI_VENDOR_ID_REDHAT, 0x5),
+ ()
+ )]
+);
+
+impl pci::Driver for ParentDriver {
+ type IdInfo = ();
+
+ const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
+
+ fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
+ let this = KBox::new(
+ Self {
+ _reg: [
+ auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 0, MODULE_NAME)?,
+ auxiliary::Registration::new(pdev.as_ref(), AUXILIARY_NAME, 1, MODULE_NAME)?,
+ ],
+ },
+ GFP_KERNEL,
+ )?;
+
+ Ok(this.into())
+ }
+}
+
+impl ParentDriver {
+ fn connect(adev: &auxiliary::Device) -> Result<()> {
+ let parent = adev.parent().ok_or(EINVAL)?;
+ let pdev: &pci::Device = parent.try_into()?;
+
+ dev_info!(
+ adev.as_ref(),
+ "Connect auxiliary {} with parent: VendorID={:#x}, DeviceID={:#x}\n",
+ adev.id(),
+ pdev.vendor_id(),
+ pdev.device_id()
+ );
+
+ Ok(())
+ }
+}
+
+#[pin_data]
+struct SampleModule {
+ #[pin]
+ _pci_driver: driver::Registration<pci::Adapter<ParentDriver>>,
+ #[pin]
+ _aux_driver: driver::Registration<auxiliary::Adapter<AuxiliaryDriver>>,
+}
+
+impl InPlaceModule for SampleModule {
+ fn init(module: &'static kernel::ThisModule) -> impl PinInit<Self, Error> {
+ try_pin_init!(Self {
+ _pci_driver <- driver::Registration::new(MODULE_NAME, module),
+ _aux_driver <- driver::Registration::new(MODULE_NAME, module),
+ })
+ }
+}
+
+module! {
+ type: SampleModule,
+ name: "rust_driver_auxiliary",
+ author: "Danilo Krummrich",
+ description: "Rust auxiliary driver",
+ license: "GPL v2",
+}
diff --git a/samples/rust/rust_driver_faux.rs b/samples/rust/rust_driver_faux.rs
index 048c6cb98b29..ecc9fd378cbd 100644
--- a/samples/rust/rust_driver_faux.rs
+++ b/samples/rust/rust_driver_faux.rs
@@ -7,7 +7,7 @@ use kernel::{c_str, faux, prelude::*, Module};
module! {
type: SampleModule,
name: "rust_faux_driver",
- author: "Lyude Paul",
+ authors: ["Lyude Paul"],
description: "Rust faux device sample",
license: "GPL",
}
@@ -20,7 +20,7 @@ impl Module for SampleModule {
fn init(_module: &'static ThisModule) -> Result<Self> {
pr_info!("Initialising Rust Faux Device Sample\n");
- let reg = faux::Registration::new(c_str!("rust-faux-sample-device"))?;
+ let reg = faux::Registration::new(c_str!("rust-faux-sample-device"), None)?;
dev_info!(reg.as_ref(), "Hello from faux device!\n");
diff --git a/samples/rust/rust_driver_pci.rs b/samples/rust/rust_driver_pci.rs
index 1fb6e44f3395..15147e4401b2 100644
--- a/samples/rust/rust_driver_pci.rs
+++ b/samples/rust/rust_driver_pci.rs
@@ -4,7 +4,7 @@
//!
//! To make this driver probe, QEMU must be run with `-device pci-testdev`.
-use kernel::{bindings, c_str, devres::Devres, pci, prelude::*};
+use kernel::{bindings, c_str, device::Core, devres::Devres, pci, prelude::*, types::ARef};
struct Regs;
@@ -26,7 +26,7 @@ impl TestIndex {
}
struct SampleDriver {
- pdev: pci::Device,
+ pdev: ARef<pci::Device>,
bar: Devres<Bar0>,
}
@@ -43,17 +43,17 @@ kernel::pci_device_table!(
impl SampleDriver {
fn testdev(index: &TestIndex, bar: &Bar0) -> Result<u32> {
// Select the test.
- bar.writeb(index.0, Regs::TEST);
+ bar.write8(index.0, Regs::TEST);
- let offset = u32::from_le(bar.readl(Regs::OFFSET)) as usize;
- let data = bar.readb(Regs::DATA);
+ let offset = u32::from_le(bar.read32(Regs::OFFSET)) as usize;
+ let data = bar.read8(Regs::DATA);
// Write `data` to `offset` to increase `count` by one.
//
- // Note that we need `try_writeb`, since `offset` can't be checked at compile-time.
- bar.try_writeb(data, offset)?;
+ // Note that we need `try_write8`, since `offset` can't be checked at compile-time.
+ bar.try_write8(data, offset)?;
- Ok(bar.readl(Regs::COUNT))
+ Ok(bar.read32(Regs::COUNT))
}
}
@@ -62,7 +62,7 @@ impl pci::Driver for SampleDriver {
const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE;
- fn probe(pdev: &mut pci::Device, info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
+ fn probe(pdev: &pci::Device<Core>, info: &Self::IdInfo) -> Result<Pin<KBox<Self>>> {
dev_dbg!(
pdev.as_ref(),
"Probe Rust PCI driver sample (PCI ID: 0x{:x}, 0x{:x}).\n",
@@ -77,18 +77,17 @@ impl pci::Driver for SampleDriver {
let drvdata = KBox::new(
Self {
- pdev: pdev.clone(),
+ pdev: pdev.into(),
bar,
},
GFP_KERNEL,
)?;
- let bar = drvdata.bar.try_access().ok_or(ENXIO)?;
-
+ let bar = drvdata.bar.access(pdev.as_ref())?;
dev_info!(
pdev.as_ref(),
"pci-testdev data-match count: {}\n",
- Self::testdev(info, &bar)?
+ Self::testdev(info, bar)?
);
Ok(drvdata.into())
@@ -104,7 +103,7 @@ impl Drop for SampleDriver {
kernel::module_pci_driver! {
type: SampleDriver,
name: "rust_driver_pci",
- author: "Danilo Krummrich",
+ authors: ["Danilo Krummrich"],
description: "Rust PCI driver",
license: "GPL v2",
}
diff --git a/samples/rust/rust_driver_platform.rs b/samples/rust/rust_driver_platform.rs
index 8120609e2940..8b42b3cfb363 100644
--- a/samples/rust/rust_driver_platform.rs
+++ b/samples/rust/rust_driver_platform.rs
@@ -2,10 +2,10 @@
//! Rust Platform driver sample.
-use kernel::{c_str, of, platform, prelude::*};
+use kernel::{c_str, device::Core, of, platform, prelude::*, types::ARef};
struct SampleDriver {
- pdev: platform::Device,
+ pdev: ARef<platform::Device>,
}
struct Info(u32);
@@ -21,14 +21,17 @@ impl platform::Driver for SampleDriver {
type IdInfo = Info;
const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE);
- fn probe(pdev: &mut platform::Device, info: Option<&Self::IdInfo>) -> Result<Pin<KBox<Self>>> {
+ fn probe(
+ pdev: &platform::Device<Core>,
+ info: Option<&Self::IdInfo>,
+ ) -> Result<Pin<KBox<Self>>> {
dev_dbg!(pdev.as_ref(), "Probe Rust Platform driver sample.\n");
if let Some(info) = info {
dev_info!(pdev.as_ref(), "Probed with info: '{}'.\n", info.0);
}
- let drvdata = KBox::new(Self { pdev: pdev.clone() }, GFP_KERNEL)?;
+ let drvdata = KBox::new(Self { pdev: pdev.into() }, GFP_KERNEL)?;
Ok(drvdata.into())
}
@@ -43,7 +46,7 @@ impl Drop for SampleDriver {
kernel::module_platform_driver! {
type: SampleDriver,
name: "rust_driver_platform",
- author: "Danilo Krummrich",
+ authors: ["Danilo Krummrich"],
description: "Rust Platform driver",
license: "GPL v2",
}
diff --git a/samples/rust/rust_minimal.rs b/samples/rust/rust_minimal.rs
index 4aaf117bf8e3..1fc7a1be6b6d 100644
--- a/samples/rust/rust_minimal.rs
+++ b/samples/rust/rust_minimal.rs
@@ -7,7 +7,7 @@ use kernel::prelude::*;
module! {
type: RustMinimal,
name: "rust_minimal",
- author: "Rust for Linux Contributors",
+ authors: ["Rust for Linux Contributors"],
description: "Rust minimal sample",
license: "GPL",
}
diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_device.rs
index 40ad7266c225..c881fd6dbd08 100644
--- a/samples/rust/rust_misc_device.rs
+++ b/samples/rust/rust_misc_device.rs
@@ -3,97 +3,98 @@
// Copyright (C) 2024 Google LLC.
//! Rust misc device sample.
+//!
+//! Below is an example userspace C program that exercises this sample's functionality.
+//!
+//! ```c
+//! #include <stdio.h>
+//! #include <stdlib.h>
+//! #include <errno.h>
+//! #include <fcntl.h>
+//! #include <unistd.h>
+//! #include <sys/ioctl.h>
+//!
+//! #define RUST_MISC_DEV_FAIL _IO('|', 0)
+//! #define RUST_MISC_DEV_HELLO _IO('|', 0x80)
+//! #define RUST_MISC_DEV_GET_VALUE _IOR('|', 0x81, int)
+//! #define RUST_MISC_DEV_SET_VALUE _IOW('|', 0x82, int)
+//!
+//! int main() {
+//! int value, new_value;
+//! int fd, ret;
+//!
+//! // Open the device file
+//! printf("Opening /dev/rust-misc-device for reading and writing\n");
+//! fd = open("/dev/rust-misc-device", O_RDWR);
+//! if (fd < 0) {
+//! perror("open");
+//! return errno;
+//! }
+//!
+//! // Make call into driver to say "hello"
+//! printf("Calling Hello\n");
+//! ret = ioctl(fd, RUST_MISC_DEV_HELLO, NULL);
+//! if (ret < 0) {
+//! perror("ioctl: Failed to call into Hello");
+//! close(fd);
+//! return errno;
+//! }
+//!
+//! // Get initial value
+//! printf("Fetching initial value\n");
+//! ret = ioctl(fd, RUST_MISC_DEV_GET_VALUE, &value);
+//! if (ret < 0) {
+//! perror("ioctl: Failed to fetch the initial value");
+//! close(fd);
+//! return errno;
+//! }
+//!
+//! value++;
+//!
+//! // Set value to something different
+//! printf("Submitting new value (%d)\n", value);
+//! ret = ioctl(fd, RUST_MISC_DEV_SET_VALUE, &value);
+//! if (ret < 0) {
+//! perror("ioctl: Failed to submit new value");
+//! close(fd);
+//! return errno;
+//! }
+//!
+//! // Ensure new value was applied
+//! printf("Fetching new value\n");
+//! ret = ioctl(fd, RUST_MISC_DEV_GET_VALUE, &new_value);
+//! if (ret < 0) {
+//! perror("ioctl: Failed to fetch the new value");
+//! close(fd);
+//! return errno;
+//! }
+//!
+//! if (value != new_value) {
+//! printf("Failed: Committed and retrieved values are different (%d - %d)\n", value, new_value);
+//! close(fd);
+//! return -1;
+//! }
+//!
+//! // Call the unsuccessful ioctl
+//! printf("Attempting to call in to an non-existent IOCTL\n");
+//! ret = ioctl(fd, RUST_MISC_DEV_FAIL, NULL);
+//! if (ret < 0) {
+//! perror("ioctl: Succeeded to fail - this was expected");
+//! } else {
+//! printf("ioctl: Failed to fail\n");
+//! close(fd);
+//! return -1;
+//! }
+//!
+//! // Close the device file
+//! printf("Closing /dev/rust-misc-device\n");
+//! close(fd);
+//!
+//! printf("Success\n");
+//! return 0;
+//! }
+//! ```
-/// Below is an example userspace C program that exercises this sample's functionality.
-///
-/// ```c
-/// #include <stdio.h>
-/// #include <stdlib.h>
-/// #include <errno.h>
-/// #include <fcntl.h>
-/// #include <unistd.h>
-/// #include <sys/ioctl.h>
-///
-/// #define RUST_MISC_DEV_FAIL _IO('|', 0)
-/// #define RUST_MISC_DEV_HELLO _IO('|', 0x80)
-/// #define RUST_MISC_DEV_GET_VALUE _IOR('|', 0x81, int)
-/// #define RUST_MISC_DEV_SET_VALUE _IOW('|', 0x82, int)
-///
-/// int main() {
-/// int value, new_value;
-/// int fd, ret;
-///
-/// // Open the device file
-/// printf("Opening /dev/rust-misc-device for reading and writing\n");
-/// fd = open("/dev/rust-misc-device", O_RDWR);
-/// if (fd < 0) {
-/// perror("open");
-/// return errno;
-/// }
-///
-/// // Make call into driver to say "hello"
-/// printf("Calling Hello\n");
-/// ret = ioctl(fd, RUST_MISC_DEV_HELLO, NULL);
-/// if (ret < 0) {
-/// perror("ioctl: Failed to call into Hello");
-/// close(fd);
-/// return errno;
-/// }
-///
-/// // Get initial value
-/// printf("Fetching initial value\n");
-/// ret = ioctl(fd, RUST_MISC_DEV_GET_VALUE, &value);
-/// if (ret < 0) {
-/// perror("ioctl: Failed to fetch the initial value");
-/// close(fd);
-/// return errno;
-/// }
-///
-/// value++;
-///
-/// // Set value to something different
-/// printf("Submitting new value (%d)\n", value);
-/// ret = ioctl(fd, RUST_MISC_DEV_SET_VALUE, &value);
-/// if (ret < 0) {
-/// perror("ioctl: Failed to submit new value");
-/// close(fd);
-/// return errno;
-/// }
-///
-/// // Ensure new value was applied
-/// printf("Fetching new value\n");
-/// ret = ioctl(fd, RUST_MISC_DEV_GET_VALUE, &new_value);
-/// if (ret < 0) {
-/// perror("ioctl: Failed to fetch the new value");
-/// close(fd);
-/// return errno;
-/// }
-///
-/// if (value != new_value) {
-/// printf("Failed: Committed and retrieved values are different (%d - %d)\n", value, new_value);
-/// close(fd);
-/// return -1;
-/// }
-///
-/// // Call the unsuccessful ioctl
-/// printf("Attempting to call in to an non-existent IOCTL\n");
-/// ret = ioctl(fd, RUST_MISC_DEV_FAIL, NULL);
-/// if (ret < 0) {
-/// perror("ioctl: Succeeded to fail - this was expected");
-/// } else {
-/// printf("ioctl: Failed to fail\n");
-/// close(fd);
-/// return -1;
-/// }
-///
-/// // Close the device file
-/// printf("Closing /dev/rust-misc-device\n");
-/// close(fd);
-///
-/// printf("Success\n");
-/// return 0;
-/// }
-/// ```
use core::pin::Pin;
use kernel::{
@@ -116,7 +117,7 @@ const RUST_MISC_DEV_SET_VALUE: u32 = _IOW::<i32>('|' as u32, 0x82);
module! {
type: RustMiscDeviceModule,
name: "rust_misc_device",
- author: "Lee Jones",
+ authors: ["Lee Jones"],
description: "Rust misc device sample",
license: "GPL",
}
diff --git a/samples/rust/rust_print_main.rs b/samples/rust/rust_print_main.rs
index 7e8af5f176a3..8ea95e8c2f36 100644
--- a/samples/rust/rust_print_main.rs
+++ b/samples/rust/rust_print_main.rs
@@ -8,7 +8,7 @@ use kernel::prelude::*;
module! {
type: RustPrint,
name: "rust_print",
- author: "Rust for Linux Contributors",
+ authors: ["Rust for Linux Contributors"],
description: "Rust printing macros sample",
license: "GPL",
}