diff options
Diffstat (limited to 'samples/rust')
| -rw-r--r-- | samples/rust/Kconfig | 11 | ||||
| -rw-r--r-- | samples/rust/Makefile | 1 | ||||
| -rw-r--r-- | samples/rust/rust_debugfs.rs | 5 | ||||
| -rw-r--r-- | samples/rust/rust_debugfs_scoped.rs | 5 | ||||
| -rw-r--r-- | samples/rust/rust_dma.rs | 25 | ||||
| -rw-r--r-- | samples/rust/rust_driver_auxiliary.rs | 96 | ||||
| -rw-r--r-- | samples/rust/rust_driver_i2c.rs | 3 | ||||
| -rw-r--r-- | samples/rust/rust_driver_pci.rs | 4 | ||||
| -rw-r--r-- | samples/rust/rust_driver_platform.rs | 2 | ||||
| -rw-r--r-- | samples/rust/rust_driver_serdev.rs | 88 | ||||
| -rw-r--r-- | samples/rust/rust_driver_usb.rs | 3 | ||||
| -rw-r--r-- | samples/rust/rust_i2c_client.rs | 2 | ||||
| -rw-r--r-- | samples/rust/rust_soc.rs | 2 |
13 files changed, 195 insertions, 52 deletions
diff --git a/samples/rust/Kconfig b/samples/rust/Kconfig index c49ab9106..31d62533e 100644 --- a/samples/rust/Kconfig +++ b/samples/rust/Kconfig @@ -161,6 +161,17 @@ config SAMPLE_RUST_DRIVER_AUXILIARY If unsure, say N. +config SAMPLE_RUST_DRIVER_SERDEV + tristate "Serial Device Bus Device Driver" + select RUST_SERIAL_DEV_BUS_ABSTRACTIONS + help + This option builds the Rust serial device bus driver sample. + + To compile this as a module, choose M here: + the module will be called rust_driver_serdev. + + If unsure, say N. + config SAMPLE_RUST_SOC tristate "SoC Driver" select SOC_BUS diff --git a/samples/rust/Makefile b/samples/rust/Makefile index 6c0aaa58c..b986b681c 100644 --- a/samples/rust/Makefile +++ b/samples/rust/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_SAMPLE_RUST_DRIVER_PLATFORM) += rust_driver_platform.o obj-$(CONFIG_SAMPLE_RUST_DRIVER_USB) += rust_driver_usb.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_DRIVER_SERDEV) += rust_driver_serdev.o obj-$(CONFIG_SAMPLE_RUST_CONFIGFS) += rust_configfs.o obj-$(CONFIG_SAMPLE_RUST_SOC) += rust_soc.o diff --git a/samples/rust/rust_debugfs.rs b/samples/rust/rust_debugfs.rs index 1f59e08aa..77c19a437 100644 --- a/samples/rust/rust_debugfs.rs +++ b/samples/rust/rust_debugfs.rs @@ -110,7 +110,6 @@ impl FromStr for Inner { kernel::acpi_device_table!( ACPI_TABLE, - MODULE_ACPI_TABLE, <RustDebugFs as platform::Driver>::IdInfo, [(acpi::DeviceId::new(c"LNUXBEEF"), ())] ); @@ -147,7 +146,9 @@ impl RustDebugFs { dir.read_write_file(c"pair", new_mutex!(Inner { x: 3, y: 10 })) } - fn new<'a>(pdev: &'a platform::Device<Core<'_>>) -> impl PinInit<Self, Error> + 'a { + fn new<'a, 'b>( + pdev: &'a platform::Device<Core<'b>>, + ) -> impl PinInit<Self, Error> + use<'a, 'b> { let debugfs = Dir::new(c"sample_debugfs"); let dev = pdev.as_ref(); diff --git a/samples/rust/rust_debugfs_scoped.rs b/samples/rust/rust_debugfs_scoped.rs index 6a575a15a..ca2b154be 100644 --- a/samples/rust/rust_debugfs_scoped.rs +++ b/samples/rust/rust_debugfs_scoped.rs @@ -75,7 +75,10 @@ fn create_file_write( GFP_KERNEL, )?; } - let blob = KBox::pin_init(new_mutex!([0x42; SZ_4K]), GFP_KERNEL)?; + let blob = KBox::pin_init( + new_mutex!(pin_init::init_array_from_fn(|_| 0x42)), + GFP_KERNEL, + )?; let scope = KBox::pin_init( mod_data.device_dir.scope( diff --git a/samples/rust/rust_dma.rs b/samples/rust/rust_dma.rs index 5046b4628..bd60034de 100644 --- a/samples/rust/rust_dma.rs +++ b/samples/rust/rust_dma.rs @@ -12,10 +12,19 @@ use kernel::{ Device, DmaMask, // }, - page, pci, + io::{ + io_project, + io_read, + Io, // + }, + page, + pci, prelude::*, - scatterlist::{Owned, SGTable}, - sync::aref::ARef, + scatterlist::{ + Owned, + SGTable, // + }, + sync::aref::ARef, // }; #[pin_data(PinnedDrop)] @@ -34,6 +43,7 @@ const TEST_VALUES: [(u32, u32); 5] = [ (0xcd, 0xef), ]; +#[derive(FromBytes, IntoBytes)] struct MyStruct { h: u32, b: u32, @@ -51,7 +61,6 @@ 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(pci::Vendor::REDHAT, 0x5), ())] ); @@ -63,7 +72,7 @@ impl pci::Driver for DmaSampleDriver { fn probe<'bound>( pdev: &'bound pci::Device<Core<'_>>, - _info: &'bound Self::IdInfo, + _info: Option<&'bound Self::IdInfo>, ) -> impl PinInit<Self, Error> + 'bound { pin_init::pin_init_scope(move || { dev_info!(pdev, "Probe DMA test driver.\n"); @@ -77,7 +86,7 @@ impl pci::Driver for DmaSampleDriver { Coherent::zeroed_slice(pdev.as_ref(), TEST_VALUES.len(), GFP_KERNEL)?; for (i, value) in TEST_VALUES.into_iter().enumerate() { - kernel::dma_write!(ca, [try: i], MyStruct::new(value.0, value.1)); + io_project!(ca, [panic: i]).copy_write(MyStruct::new(value.0, value.1)); } let size = 4 * page::PAGE_SIZE; @@ -97,8 +106,8 @@ impl pci::Driver for DmaSampleDriver { impl DmaSampleDriver { fn check_dma(&self) { for (i, value) in TEST_VALUES.into_iter().enumerate() { - let val0 = kernel::dma_read!(self.ca, [panic: i].h); - let val1 = kernel::dma_read!(self.ca, [panic: i].b); + let val0 = io_read!(self.ca, [panic: i].h); + let val1 = io_read!(self.ca, [panic: i].b); assert_eq!(val0, value.0); assert_eq!(val1, value.1); diff --git a/samples/rust/rust_driver_auxiliary.rs b/samples/rust/rust_driver_auxiliary.rs index 2c1351040..0bee16fae 100644 --- a/samples/rust/rust_driver_auxiliary.rs +++ b/samples/rust/rust_driver_auxiliary.rs @@ -11,20 +11,26 @@ use kernel::{ Core, // }, driver, + new_mutex, pci, prelude::*, - types::ForLt, + sync::Mutex, + types::{ + CovariantForLt, + ForLt, // + }, InPlaceModule, // }; const MODULE_NAME: &CStr = <LocalModule as kernel::ModuleMetadata>::NAME; const AUXILIARY_NAME: &CStr = c"auxiliary"; +const COVARIANT_DEV_ID: u32 = 0; +const INVARIANT_DEV_ID: u32 = 1; struct AuxiliaryDriver; kernel::auxiliary_device_table!( AUX_TABLE, - MODULE_AUX_TABLE, <AuxiliaryDriver as auxiliary::Driver>::IdInfo, [(auxiliary::DeviceId::new(MODULE_NAME, AUXILIARY_NAME), ())] ); @@ -56,17 +62,30 @@ struct Data<'bound> { parent: &'bound pci::Device<Bound>, } +/// Registration data with interior mutability. +/// +/// `Mutex<&'bound T>` is invariant over `'bound`, so this type cannot implement +/// [`CovariantForLt`](trait@CovariantForLt). Access must go through the closure-based +/// [`auxiliary::Device::registration_data_with()`]. +#[pin_data] +struct MutexData<'bound> { + #[pin] + parent: Mutex<&'bound pci::Device<Bound>>, + index: u32, +} + struct ParentDriver; #[allow(clippy::type_complexity)] +#[pin_data] struct ParentData<'bound> { - _reg0: auxiliary::Registration<'bound, ForLt!(Data<'_>)>, - _reg1: auxiliary::Registration<'bound, ForLt!(Data<'_>)>, + _reg0: auxiliary::Registration<'bound, CovariantForLt!(Data<'_>)>, + #[pin] + _reg1: auxiliary::Registration<'bound, ForLt!(MutexData<'_>)>, } kernel::pci_device_table!( PCI_TABLE, - MODULE_PCI_TABLE, <ParentDriver as pci::Driver>::IdInfo, [(pci::DeviceId::from_id(pci::Vendor::REDHAT, 0x5), ())] ); @@ -79,19 +98,19 @@ impl pci::Driver for ParentDriver { fn probe<'bound>( pdev: &'bound pci::Device<Core<'_>>, - _info: &'bound Self::IdInfo, + _info: Option<&'bound Self::IdInfo>, ) -> impl PinInit<Self::Data<'bound>, Error> + 'bound { - Ok(ParentData { + try_pin_init!(ParentData { // SAFETY: `ParentData` is the driver's private data, which is dropped when the // device is unbound; i.e. `mem::forget()` is never called on it. _reg0: unsafe { auxiliary::Registration::new_with_lt( pdev.as_ref(), AUXILIARY_NAME, - 0, + COVARIANT_DEV_ID, MODULE_NAME, Data { - index: 0, + index: COVARIANT_DEV_ID, parent: pdev, }, )? @@ -101,12 +120,16 @@ impl pci::Driver for ParentDriver { auxiliary::Registration::new_with_lt( pdev.as_ref(), AUXILIARY_NAME, - 1, + INVARIANT_DEV_ID, MODULE_NAME, - Data { - index: 1, - parent: pdev, - }, + pin_init!(MutexData { + parent <- { + let pdev: &pci::Device<Bound> = pdev; + + new_mutex!(pdev) + }, + index: INVARIANT_DEV_ID, + }), )? }, }) @@ -115,22 +138,39 @@ impl pci::Driver for ParentDriver { impl ParentDriver { fn connect(adev: &auxiliary::Device<Bound>) -> Result { - let data = adev.registration_data::<ForLt!(Data<'_>)>()?; - let pdev = data.parent; + match adev.id() { + // CovariantForLt types can use the direct-reference accessor. + COVARIANT_DEV_ID => { + let data = adev.registration_data::<CovariantForLt!(Data<'_>)>()?; + let pdev = data.parent; - dev_info!( - pdev, - "Connect auxiliary {} with parent: VendorID={}, DeviceID={:#x}\n", - adev.id(), - pdev.vendor_id(), - pdev.device_id() - ); + dev_info!( + pdev, + "Connect auxiliary {} with parent: VendorID={}, DeviceID={:#x}\n", + adev.id(), + pdev.vendor_id(), + pdev.device_id() + ); - dev_info!( - pdev, - "Connected to auxiliary device with index {}.\n", - data.index - ); + dev_info!( + pdev, + "Connected to auxiliary device with index {}.\n", + data.index + ); + } + // Invariant ForLt types (e.g. containing a Mutex) require the closure-based accessor. + INVARIANT_DEV_ID => { + adev.registration_data_with::<ForLt!(MutexData<'_>), _>(|data| { + let pdev = *data.parent.lock(); + dev_info!( + pdev, + "Connected to auxiliary device with index {} (via Mutex).\n", + data.index + ); + })?; + } + _ => return Err(EINVAL), + } Ok(()) } diff --git a/samples/rust/rust_driver_i2c.rs b/samples/rust/rust_driver_i2c.rs index ead8263a7..a0df0c609 100644 --- a/samples/rust/rust_driver_i2c.rs +++ b/samples/rust/rust_driver_i2c.rs @@ -14,21 +14,18 @@ struct SampleDriver; kernel::acpi_device_table! { ACPI_TABLE, - MODULE_ACPI_TABLE, <SampleDriver as i2c::Driver>::IdInfo, [(acpi::DeviceId::new(c"LNUXBEEF"), 0)] } kernel::i2c_device_table! { I2C_TABLE, - MODULE_I2C_TABLE, <SampleDriver as i2c::Driver>::IdInfo, [(i2c::DeviceId::new(c"rust_driver_i2c"), 0)] } kernel::of_device_table! { OF_TABLE, - MODULE_OF_TABLE, <SampleDriver as i2c::Driver>::IdInfo, [(of::DeviceId::new(c"test,rust_driver_i2c"), 0)] } diff --git a/samples/rust/rust_driver_pci.rs b/samples/rust/rust_driver_pci.rs index 1aa8197d8..2282191e6 100644 --- a/samples/rust/rust_driver_pci.rs +++ b/samples/rust/rust_driver_pci.rs @@ -74,7 +74,6 @@ struct SampleDriver; kernel::pci_device_table!( PCI_TABLE, - MODULE_PCI_TABLE, <SampleDriver as pci::Driver>::IdInfo, [( pci::DeviceId::from_id(pci::Vendor::REDHAT, 0x5), @@ -144,7 +143,7 @@ impl pci::Driver for SampleDriver { fn probe<'bound>( pdev: &'bound pci::Device<Core<'_>>, - info: &'bound Self::IdInfo, + info: Option<&'bound Self::IdInfo>, ) -> impl PinInit<Self::Data<'bound>, Error> + 'bound { let vendor = pdev.vendor_id(); dev_dbg!( @@ -153,6 +152,7 @@ impl pci::Driver for SampleDriver { vendor, pdev.device_id() ); + let info = info.ok_or(ENODEV)?; pdev.enable_device_mem()?; pdev.set_master(); diff --git a/samples/rust/rust_driver_platform.rs b/samples/rust/rust_driver_platform.rs index ec0d6cac4..710145b36 100644 --- a/samples/rust/rust_driver_platform.rs +++ b/samples/rust/rust_driver_platform.rs @@ -87,14 +87,12 @@ struct Info(u32); kernel::of_device_table!( OF_TABLE, - MODULE_OF_TABLE, <SampleDriver as platform::Driver>::IdInfo, [(of::DeviceId::new(c"test,rust-device"), Info(42))] ); kernel::acpi_device_table!( ACPI_TABLE, - MODULE_ACPI_TABLE, <SampleDriver as platform::Driver>::IdInfo, [(acpi::DeviceId::new(c"LNUXBEEF"), Info(0))] ); diff --git a/samples/rust/rust_driver_serdev.rs b/samples/rust/rust_driver_serdev.rs new file mode 100644 index 000000000..51b4898cd --- /dev/null +++ b/samples/rust/rust_driver_serdev.rs @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Rust Serial device bus device driver sample. + +use kernel::{ + acpi, + device::{ + Bound, + Core, // + }, + of, + prelude::*, + serdev, + sync::aref::ARef, // +}; + +struct SampleDriver { + sdev: ARef<serdev::Device>, +} + +kernel::of_device_table!( + OF_TABLE, + <SampleDriver as serdev::Driver>::IdInfo, + [(of::DeviceId::new(c"test,rust_driver_serdev"), ())] +); + +kernel::acpi_device_table!( + ACPI_TABLE, + <SampleDriver as serdev::Driver>::IdInfo, + [(acpi::DeviceId::new(c"LNUXBEEF"), ())] +); + +#[vtable] +impl serdev::Driver for SampleDriver { + type IdInfo = (); + type Data<'bound> = Self; + const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = Some(&OF_TABLE); + const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE); + + fn probe<'bound>( + sdev: &'bound serdev::Device<Core<'_>>, + _info: Option<&'bound Self::IdInfo>, + ) -> impl PinInit<Self, Error> + 'bound { + let dev = sdev.as_ref(); + + dev_dbg!(dev, "Probe Rust Serial device bus device driver sample.\n"); + + if sdev + .set_baudrate( + dev.fwnode() + .and_then(|fwnode| fwnode.property_read(c"baudrate").optional()) + .unwrap_or(115200), + ) + .is_err() + { + return Err(EINVAL); + } + sdev.set_flow_control(false); + sdev.set_parity(serdev::Parity::None)?; + + Ok(Self { sdev: sdev.into() }) + } + + fn receive<'bound>( + sdev: &'bound serdev::Device<Bound>, + _this: Pin<&Self>, + data: &[u8], + ) -> usize { + sdev.write(data).unwrap_or_default() as usize + } +} + +impl Drop for SampleDriver { + fn drop(&mut self) { + dev_dbg!( + self.sdev.as_ref(), + "Remove Rust Serial device bus device driver sample.\n" + ); + } +} + +kernel::module_serdev_device_driver! { + type: SampleDriver, + name: "rust_driver_serdev", + authors: ["Markus Probst"], + description: "Rust Serial device bus device driver", + license: "GPL v2", +} diff --git a/samples/rust/rust_driver_usb.rs b/samples/rust/rust_driver_usb.rs index 02bd5085f..7ef04e177 100644 --- a/samples/rust/rust_driver_usb.rs +++ b/samples/rust/rust_driver_usb.rs @@ -19,7 +19,6 @@ struct SampleDriver { kernel::usb_device_table!( USB_TABLE, - MODULE_USB_TABLE, <SampleDriver as usb::Driver>::IdInfo, [(usb::DeviceId::from_id(0x1234, 0x5678), ()),] ); @@ -32,7 +31,7 @@ impl usb::Driver for SampleDriver { fn probe<'bound>( intf: &'bound usb::Interface<Core<'_>>, _id: &usb::DeviceId, - _info: &'bound Self::IdInfo, + _info: Option<&'bound Self::IdInfo>, ) -> impl PinInit<Self, Error> + 'bound { let dev: &device::Device<Core<'_>> = intf.as_ref(); dev_info!(dev, "Rust USB driver sample probed\n"); diff --git a/samples/rust/rust_i2c_client.rs b/samples/rust/rust_i2c_client.rs index 2d876f4e3..c8a23875e 100644 --- a/samples/rust/rust_i2c_client.rs +++ b/samples/rust/rust_i2c_client.rs @@ -87,14 +87,12 @@ struct SampleDriver { kernel::of_device_table!( OF_TABLE, - MODULE_OF_TABLE, <SampleDriver as platform::Driver>::IdInfo, [(of::DeviceId::new(c"test,rust-device"), ())] ); kernel::acpi_device_table!( ACPI_TABLE, - MODULE_ACPI_TABLE, <SampleDriver as platform::Driver>::IdInfo, [(acpi::DeviceId::new(c"LNUXBEEF"), ())] ); diff --git a/samples/rust/rust_soc.rs b/samples/rust/rust_soc.rs index 808d58200..f5e5f2f9a 100644 --- a/samples/rust/rust_soc.rs +++ b/samples/rust/rust_soc.rs @@ -23,14 +23,12 @@ struct SampleSocDriver { kernel::of_device_table!( OF_TABLE, - MODULE_OF_TABLE, <SampleSocDriver as platform::Driver>::IdInfo, [(of::DeviceId::new(c"test,rust-device"), ())] ); kernel::acpi_device_table!( ACPI_TABLE, - MODULE_ACPI_TABLE, <SampleSocDriver as platform::Driver>::IdInfo, [(acpi::DeviceId::new(c"LNUXBEEF"), ())] ); |
