Add a simple dma coherent allocator rust abstraction. Based on
Andreas Hindborg's dma abstractions from the rnvme driver, which
was also based on earlier work by Wedson Almeida Filho.
Nacked-by: Christoph Hellwig <hch@xxxxxx>
Signed-off-by: Abdiel Janulgue <abdiel.janulgue@xxxxxxxxx>
---
rust/bindings/bindings_helper.h | 1 +
rust/helpers/dma.c | 13 +
rust/helpers/helpers.c | 1 +
rust/kernel/dma.rs | 421 ++++++++++++++++++++++++++++++++
rust/kernel/lib.rs | 1 +
5 files changed, 437 insertions(+)
create mode 100644 rust/helpers/dma.c
create mode 100644 rust/kernel/dma.rs
diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index 55354e4dec14..f69b05025e52 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -11,6 +11,7 @@
#include <linux/blk_types.h>
#include <linux/blkdev.h>
#include <linux/cred.h>
+#include <linux/dma-mapping.h>
#include <linux/errname.h>
#include <linux/ethtool.h>
#include <linux/file.h>
diff --git a/rust/helpers/dma.c b/rust/helpers/dma.c
new file mode 100644
index 000000000000..30da079d366c
--- /dev/null
+++ b/rust/helpers/dma.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/dma-mapping.h>
+
+int rust_helper_dma_set_mask_and_coherent(struct device *dev, u64 mask)
+{
+ return dma_set_mask_and_coherent(dev, mask);
+}
+
+int rust_helper_dma_set_mask(struct device *dev, u64 mask)
+{
+ return dma_set_mask(dev, mask);
+}
diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
index 0640b7e115be..8f3808c8b7fe 100644
--- a/rust/helpers/helpers.c
+++ b/rust/helpers/helpers.c
@@ -13,6 +13,7 @@
#include "build_bug.c"
#include "cred.c"
#include "device.c"
+#include "dma.c"
#include "err.c"
#include "fs.c"
#include "io.c"
diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs
new file mode 100644
index 000000000000..b4dd5d411711
--- /dev/null
+++ b/rust/kernel/dma.rs
@@ -0,0 +1,421 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Direct memory access (DMA).
+//!
+//! C header: [`include/linux/dma-mapping.h`](srctree/include/linux/dma-mapping.h)
+
+use crate::{
+ bindings, build_assert,
+ device::Device,
+ error::code::*,
+ error::Result,
+ transmute::{AsBytes, FromBytes},
+ types::ARef,
+};
+
+/// Inform the kernel about the device's DMA addressing capabilities. This will set the mask for
+/// both streaming and coherent APIs together.
+pub fn dma_set_mask_and_coherent(dev: &Device, mask: u64) -> i32 {
+ // SAFETY: device pointer is guaranteed as valid by invariant on `Device`.
+ unsafe { bindings::dma_set_mask_and_coherent(dev.as_raw(), mask) }
+}
+
+/// Same as `dma_set_mask_and_coherent`, but set the mask only for streaming mappings.
+pub fn dma_set_mask(dev: &Device, mask: u64) -> i32 {
+ // SAFETY: device pointer is guaranteed as valid by invariant on `Device`.
+ unsafe { bindings::dma_set_mask(dev.as_raw(), mask) }
+}