Skip to content

Commit 970f5db

Browse files
committed
dma: Refine safety requirements of buffer traits
1 parent d48a7b0 commit 970f5db

File tree

1 file changed

+24
-16
lines changed

1 file changed

+24
-16
lines changed

src/dma.rs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ impl<B, C: Channel, T> Transfer<B, C, T> {
3939
B: WriteBuffer + 'static,
4040
T: Target<C>,
4141
{
42-
let (ptr, len) = buffer.write_buffer();
42+
// NOTE(unsafe) cannot call `&mut self` methods on `buffer` because its
43+
// concrete type is unknown here
44+
let (ptr, len) = unsafe { buffer.write_buffer() };
4345

4446
channel.set_memory_address(ptr as u32, Increment::Enable);
4547
channel.set_transfer_length(len);
@@ -55,7 +57,9 @@ impl<B, C: Channel, T> Transfer<B, C, T> {
5557
B: ReadBuffer + 'static,
5658
T: Target<C>,
5759
{
58-
let (ptr, len) = buffer.read_buffer();
60+
// NOTE(unsafe) cannot call `&mut self` methods on `buffer` because its
61+
// concrete type is unknown here
62+
let (ptr, len) = unsafe { buffer.read_buffer() };
5963

6064
channel.set_memory_address(ptr as u32, Increment::Enable);
6165
channel.set_transfer_length(len);
@@ -142,7 +146,11 @@ impl<B, C: Channel, T> TransferInner<B, C, T> {
142146
/// The implementing type must be safe to use for DMA reads. This means:
143147
///
144148
/// - It must be a pointer that references the actual buffer.
145-
/// - The requirements documented on `read_buffer` must be fulfilled.
149+
/// - The following requirements must be fulfilled by `read_buffer`:
150+
/// - The function must always return the same values, if called multiple
151+
/// times.
152+
/// - The memory specified by the returned pointer and size must not be
153+
/// freed as long as `self` is not dropped.
146154
pub unsafe trait ReadBuffer {
147155
type Word;
148156

@@ -155,11 +163,9 @@ pub unsafe trait ReadBuffer {
155163
///
156164
/// # Safety
157165
///
158-
/// - This function must always return the same values, if called multiple
159-
/// times.
160-
/// - The memory specified by the returned pointer and size must not be
161-
/// freed as long as `self` is not dropped.
162-
fn read_buffer(&self) -> (*const Self::Word, usize);
166+
/// Once this method has been called, it is unsafe to call any `&mut self`
167+
/// methods on this object as long as the returned value is used (for DMA).
168+
unsafe fn read_buffer(&self) -> (*const Self::Word, usize);
163169
}
164170

165171
/// Trait for buffers that can be given to DMA for writing.
@@ -170,7 +176,11 @@ pub unsafe trait ReadBuffer {
170176
///
171177
/// - It must be a pointer that references the actual buffer.
172178
/// - `Target` must be a type that is valid for any possible byte pattern.
173-
/// - The requirements documented on `write_buffer` must be fulfilled.
179+
/// - The following requirements must be fulfilled by `write_buffer`:
180+
/// - The function must always return the same values, if called multiple
181+
/// times.
182+
/// - The memory specified by the returned pointer and size must not be
183+
/// freed as long as `self` is not dropped.
174184
pub unsafe trait WriteBuffer {
175185
type Word;
176186

@@ -183,11 +193,9 @@ pub unsafe trait WriteBuffer {
183193
///
184194
/// # Safety
185195
///
186-
/// - This function must always return the same values, if called multiple
187-
/// times.
188-
/// - The memory specified by the returned pointer and size must not be
189-
/// freed as long as `self` is not dropped.
190-
fn write_buffer(&mut self) -> (*mut Self::Word, usize);
196+
/// Once this method has been called, it is unsafe to call any `&mut self`
197+
/// methods on this object as long as the returned value is used (for DMA)..
198+
unsafe fn write_buffer(&mut self) -> (*mut Self::Word, usize);
191199
}
192200

193201
// Blanked implementations for common DMA buffer types.
@@ -199,7 +207,7 @@ where
199207
{
200208
type Word = T::Word;
201209

202-
fn read_buffer(&self) -> (*const Self::Word, usize) {
210+
unsafe fn read_buffer(&self) -> (*const Self::Word, usize) {
203211
self.as_read_buffer()
204212
}
205213
}
@@ -211,7 +219,7 @@ where
211219
{
212220
type Word = T::Word;
213221

214-
fn write_buffer(&mut self) -> (*mut Self::Word, usize) {
222+
unsafe fn write_buffer(&mut self) -> (*mut Self::Word, usize) {
215223
self.as_write_buffer()
216224
}
217225
}

0 commit comments

Comments
 (0)