Skip to content

Commit 7fd3263

Browse files
WhatAmISupposedToPutHerejannau
authored andcommitted
rust: WIP(?): Various bits of rust glue for AOP series
Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
1 parent e9aabc9 commit 7fd3263

6 files changed

Lines changed: 68 additions & 2 deletions

File tree

rust/bindgen_parameters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212

1313
# Packed type cannot transitively contain a `#[repr(align)]` type.
1414
--opaque-type alt_instr
15+
--opaque-type snd_codec_options
16+
--opaque-type snd_codec
17+
--opaque-type snd_compr_params
1518
--opaque-type x86_msi_data
1619
--opaque-type x86_msi_addr_lo
1720

rust/bindings/bindings_helper.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include <linux/file.h>
2020
#include <linux/firmware.h>
2121
#include <linux/fs.h>
22+
#include <linux/iio/iio.h>
23+
#include <linux/iio/types.h>
2224
#include <linux/ioport.h>
2325
#include <linux/jiffies.h>
2426
#include <linux/jump_label.h>
@@ -47,6 +49,9 @@
4749
#include <linux/wait.h>
4850
#include <linux/workqueue.h>
4951
#include <linux/xarray.h>
52+
#include <sound/core.h>
53+
#include <sound/dmaengine_pcm.h>
54+
#include <sound/pcm.h>
5055
#include <trace/events/rust_sample.h>
5156

5257
#if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
@@ -81,3 +86,10 @@ const xa_mark_t BINDINGS_XA_MARK_2 = XA_MARK_2;
8186
const xa_mark_t BINDINGS_XA_PRESENT = XA_PRESENT;
8287
const xa_mark_t BINDINGS_XA_MARK_MAX = XA_MARK_MAX;
8388
const xa_mark_t BINDINGS_XA_FREE_MARK = XA_FREE_MARK;
89+
90+
const u64 BINDINGS_SNDRV_PCM_FMTBIT_FLOAT_LE = SNDRV_PCM_FMTBIT_FLOAT_LE;
91+
92+
const u32 BINDINGS_IIO_CHAN_INFO_RAW = IIO_CHAN_INFO_RAW;
93+
const u32 BINDINGS_IIO_CHAN_INFO_PROCESSED = IIO_CHAN_INFO_PROCESSED;
94+
const u32 BINDINGS_IIO_ANGL = IIO_ANGL;
95+
const u32 BINDINGS_IIO_LIGHT = IIO_LIGHT;

rust/helpers/device.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,8 @@ int rust_helper_devm_add_action(struct device *dev,
88
{
99
return devm_add_action(dev, action, data);
1010
}
11+
12+
void *rust_helper_dev_get_drvdata(struct device *dev)
13+
{
14+
return dev_get_drvdata(dev);
15+
}

rust/kernel/alloc/kvec.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ where
460460
/// If `new_len` is greater than len, the Vec is extended by the difference,
461461
/// with each additional slot filled with `value`.
462462
/// If `new_len` is less than len, the Vec is simply truncated.
463-
fn resize(&mut self, new_len: usize, value: T, flags: Flags) -> Result<(), AllocError>
463+
pub fn resize(&mut self, new_len: usize, value: T, flags: Flags) -> Result<(), AllocError>
464464
where
465465
T: Clone,
466466
{
@@ -625,6 +625,26 @@ where
625625
}
626626
}
627627
}
628+
/// Removes an element from the vector and returns it.
629+
///
630+
/// The removed element is replaced by the last element of the vector.
631+
///
632+
/// This does not preserve ordering of the remaining elements, but is *O*(1).
633+
/// If you need to preserve the element order, use [`remove`] instead.
634+
pub fn swap_remove(&mut self, index: usize) -> T {
635+
if index > self.len() {
636+
panic!("Index out of range");
637+
}
638+
// SAFETY: index is in range
639+
// self.len() - 1 is in range since at last 1 element exists
640+
unsafe {
641+
let old = ptr::read(self.as_ptr().add(index));
642+
let last = ptr::read(self.as_ptr().add(self.len() - 1));
643+
ptr::write(self.as_mut_ptr().add(index), last);
644+
self.set_len(self.len - 1);
645+
old
646+
}
647+
}
628648
}
629649

630650
impl<T: Clone, A: Allocator> Vec<T, A> {

rust/kernel/device.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl Device {
6161
}
6262

6363
/// Obtain the raw `struct device *`.
64-
pub(crate) fn as_raw(&self) -> *mut bindings::device {
64+
pub fn as_raw(&self) -> *mut bindings::device {
6565
self.0.get()
6666
}
6767

@@ -76,6 +76,13 @@ impl Device {
7676
unsafe { Some(Self::get_device(pdev)) }
7777
}
7878

79+
/// Returns the driver_data pointer.
80+
pub fn get_drvdata<T>(&self) -> *mut T {
81+
// SAFETY: dev_get_drvdata returns a field of the device,
82+
// pointer to which is valid by type invariant
83+
unsafe { bindings::dev_get_drvdata(self.as_raw()) as *mut T }
84+
}
85+
7986
/// Convert a raw C `struct device` pointer to a `&'a Device`.
8087
///
8188
/// # Safety

rust/kernel/of.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,25 @@ impl<'a> Property<'a> {
391391
pub fn is_empty(&self) -> bool {
392392
self.len() == 0
393393
}
394+
395+
/// Copy a device-tree property to a slice
396+
///
397+
/// Enforces that the length of the property is an exact match of the slice.
398+
pub fn copy_to_slice<T: PropertyUnit>(&self, target: &mut [T]) -> Result<()> {
399+
if self.len() % T::UNIT_SIZE != 0 {
400+
return Err(EINVAL);
401+
}
402+
403+
if self.len() / T::UNIT_SIZE != target.len() {
404+
return Err(EINVAL);
405+
}
406+
407+
let val = self.value();
408+
for (i, off) in (0..self.len()).step_by(T::UNIT_SIZE).enumerate() {
409+
target[i] = T::from_bytes(&val[off..off + T::UNIT_SIZE])?
410+
}
411+
Ok(())
412+
}
394413
}
395414

396415
/// A trait that represents a value decodable from a property with a fixed unit size.

0 commit comments

Comments
 (0)