Skip to content

Commit b7810d6

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 6b07c73 commit b7810d6

6 files changed

Lines changed: 65 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
@@ -18,6 +18,8 @@
1818
#include <linux/file.h>
1919
#include <linux/firmware.h>
2020
#include <linux/fs.h>
21+
#include <linux/iio/iio.h>
22+
#include <linux/iio/types.h>
2123
#include <linux/ioport.h>
2224
#include <linux/jiffies.h>
2325
#include <linux/jump_label.h>
@@ -46,6 +48,9 @@
4648
#include <linux/wait.h>
4749
#include <linux/workqueue.h>
4850
#include <linux/xarray.h>
51+
#include <sound/core.h>
52+
#include <sound/dmaengine_pcm.h>
53+
#include <sound/pcm.h>
4954
#include <trace/events/rust_sample.h>
5055

5156
/* `bindgen` gets confused at certain things. */
@@ -75,3 +80,10 @@ const xa_mark_t BINDINGS_XA_MARK_2 = XA_MARK_2;
7580
const xa_mark_t BINDINGS_XA_PRESENT = XA_PRESENT;
7681
const xa_mark_t BINDINGS_XA_MARK_MAX = XA_MARK_MAX;
7782
const xa_mark_t BINDINGS_XA_FREE_MARK = XA_FREE_MARK;
83+
84+
const u64 BINDINGS_SNDRV_PCM_FMTBIT_FLOAT_LE = SNDRV_PCM_FMTBIT_FLOAT_LE;
85+
86+
const u32 BINDINGS_IIO_CHAN_INFO_RAW = IIO_CHAN_INFO_RAW;
87+
const u32 BINDINGS_IIO_CHAN_INFO_PROCESSED = IIO_CHAN_INFO_PROCESSED;
88+
const u32 BINDINGS_IIO_ANGL = IIO_ANGL;
89+
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: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,22 @@ impl<'a> Property<'a> {
390390
pub fn is_empty(&self) -> bool {
391391
self.len() == 0
392392
}
393+
394+
pub fn copy_to_slice<T: PropertyUnit>(&self, target: &mut [T]) -> Result<()> {
395+
if self.len() % T::UNIT_SIZE != 0 {
396+
return Err(EINVAL);
397+
}
398+
399+
if self.len() / T::UNIT_SIZE != target.len() {
400+
return Err(EINVAL);
401+
}
402+
403+
let val = self.value();
404+
for (i, off) in (0..self.len()).step_by(T::UNIT_SIZE).enumerate() {
405+
target[i] = T::from_bytes(&val[off..off + T::UNIT_SIZE])?
406+
}
407+
Ok(())
408+
}
393409
}
394410

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

0 commit comments

Comments
 (0)