Skip to content

Commit 9fe1c8c

Browse files
committed
rust: device: add dma map functions
Based on wedsonaf@02541e6
1 parent 15040ff commit 9fe1c8c

File tree

1 file changed

+59
-2
lines changed

1 file changed

+59
-2
lines changed

rust/kernel/device.rs

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// SPDX-License-Identifier: GPL-2.0
2+
//
23

34
//! Generic devices that are part of the kernel's driver model.
45
//!
56
//! C header: [`include/linux/device.h`](../../../../include/linux/device.h)
67
7-
use crate::{bindings, str::CStr};
8+
use crate::{bindings, prelude::*, str::CStr};
89

910
/// A raw device.
1011
///
@@ -34,6 +35,51 @@ pub unsafe trait RawDevice {
3435
// by the compiler because of their lifetimes).
3536
unsafe { CStr::from_char_ptr(name) }
3637
}
38+
39+
fn dma_set_mask(&self, mask: u64) -> Result {
40+
let dev = self.raw_device();
41+
let ret = unsafe { bindings::dma_set_mask(dev as _, mask) };
42+
if ret != 0 {
43+
Err(Error::from_errno(ret))
44+
} else {
45+
Ok(())
46+
}
47+
}
48+
49+
fn dma_set_coherent_mask(&self, mask: u64) -> Result {
50+
let dev = self.raw_device();
51+
let ret = unsafe { bindings::dma_set_coherent_mask(dev as _, mask) };
52+
if ret != 0 {
53+
Err(Error::from_errno(ret))
54+
} else {
55+
Ok(())
56+
}
57+
}
58+
59+
fn dma_map_sg(&self, sglist: &mut [bindings::scatterlist], dir: u32) -> Result {
60+
let dev = self.raw_device();
61+
let count = sglist.len().try_into()?;
62+
let ret = unsafe {
63+
bindings::dma_map_sg_attrs(
64+
dev,
65+
&mut sglist[0],
66+
count,
67+
dir,
68+
bindings::DMA_ATTR_NO_WARN.into(),
69+
)
70+
};
71+
// TODO: It may map fewer than what was requested. What happens then?
72+
if ret == 0 {
73+
return Err(EIO);
74+
}
75+
Ok(())
76+
}
77+
78+
fn dma_unmap_sg(&self, sglist: &mut [bindings::scatterlist], dir: u32) {
79+
let dev = self.raw_device();
80+
let count = sglist.len() as _;
81+
unsafe { bindings::dma_unmap_sg_attrs(dev, &mut sglist[0], count, dir, 0) };
82+
}
3783
}
3884

3985
/// A ref-counted device.
@@ -43,7 +89,8 @@ pub unsafe trait RawDevice {
4389
/// `ptr` is valid, non-null, and has a non-zero reference count. One of the references is owned by
4490
/// `self`, and will be decremented when `self` is dropped.
4591
pub struct Device {
46-
pub(crate) ptr: *mut bindings::device,
92+
// TODO: Make this pub(crate).
93+
pub ptr: *mut bindings::device,
4794
}
4895

4996
// SAFETY: `Device` only holds a pointer to a C device, which is safe to be used from any thread.
@@ -73,6 +120,16 @@ impl Device {
73120
// requirements.
74121
unsafe { Self::new(dev.raw_device()) }
75122
}
123+
124+
// TODO: Review how this is used.
125+
/// Creates a new `DeviceRef` from a device whose reference count has already been incremented.
126+
/// The returned object takes over the reference, that is, the reference will be decremented
127+
/// when the `DeviceRef` instance goes out of scope.
128+
pub fn from_dev_no_reference(dev: &dyn RawDevice) -> Self {
129+
Self {
130+
ptr: dev.raw_device() as _,
131+
}
132+
}
76133
}
77134

78135
// SAFETY: The device returned by `raw_device` is the one for which we hold a reference.

0 commit comments

Comments
 (0)