1
1
// SPDX-License-Identifier: GPL-2.0
2
+ //
2
3
3
4
//! Generic devices that are part of the kernel's driver model.
4
5
//!
5
6
//! C header: [`include/linux/device.h`](../../../../include/linux/device.h)
6
7
7
- use crate :: { bindings, str:: CStr } ;
8
+ use crate :: { bindings, prelude :: * , str:: CStr } ;
8
9
9
10
/// A raw device.
10
11
///
@@ -34,6 +35,51 @@ pub unsafe trait RawDevice {
34
35
// by the compiler because of their lifetimes).
35
36
unsafe { CStr :: from_char_ptr ( name) }
36
37
}
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
+ }
37
83
}
38
84
39
85
/// A ref-counted device.
@@ -43,7 +89,8 @@ pub unsafe trait RawDevice {
43
89
/// `ptr` is valid, non-null, and has a non-zero reference count. One of the references is owned by
44
90
/// `self`, and will be decremented when `self` is dropped.
45
91
pub struct Device {
46
- pub ( crate ) ptr : * mut bindings:: device ,
92
+ // TODO: Make this pub(crate).
93
+ pub ptr : * mut bindings:: device ,
47
94
}
48
95
49
96
// 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 {
73
120
// requirements.
74
121
unsafe { Self :: new ( dev. raw_device ( ) ) }
75
122
}
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
+ }
76
133
}
77
134
78
135
// SAFETY: The device returned by `raw_device` is the one for which we hold a reference.
0 commit comments