1
+ /*
2
+ * Copyright (C) 2021-2022 The Aero Project Developers.
3
+ *
4
+ * This file is part of The Aero Project.
5
+ *
6
+ * Aero is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * Aero is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with Aero. If not, see <https://www.gnu.org/licenses/>.
18
+ */
19
+
1
20
use core:: sync:: atomic:: { AtomicUsize , Ordering } ;
2
21
3
22
use alloc:: string:: String ;
4
23
use alloc:: sync:: { Arc , Weak } ;
5
24
25
+ use crate :: fs;
6
26
use crate :: fs:: devfs;
7
27
use crate :: fs:: inode:: INodeInterface ;
8
28
use crate :: fs:: FileSystem ;
9
29
10
- trait DrmDevice : Send + Sync { }
30
+ use crate :: mem:: paging:: VirtAddr ;
31
+
32
+ use uapi:: drm:: * ;
33
+
34
+ trait DrmDevice : Send + Sync {
35
+ /// Returns a tuple containg the driver major, minor and patch level respectively.
36
+ fn driver_version ( & self ) -> ( usize , usize , usize ) ;
37
+ /// Returns a tuple contaning the driver name, desc and date respectively.
38
+ fn driver_info ( & self ) -> ( & ' static str , & ' static str , & ' static str ) ;
39
+ }
40
+
41
+ fn copy_field ( buffer : * mut u8 , buffer_size : & mut usize , value : & [ u8 ] ) {
42
+ // do not overflow the user buffer.
43
+ let mut copy_len = value. len ( ) ;
44
+
45
+ if * buffer_size > value. len ( ) {
46
+ copy_len = * buffer_size;
47
+ }
48
+
49
+ // let userspace know exact length of driver value (which could be
50
+ // larger than the userspace-supplied buffer).
51
+ * buffer_size = value. len ( ) ;
52
+
53
+ // finally, try filling in the user buffer.
54
+ if copy_len != 0 && !buffer. is_null ( ) {
55
+ unsafe {
56
+ core:: ptr:: copy_nonoverlapping ( value. as_ptr ( ) , buffer, copy_len) ;
57
+ }
58
+ }
59
+ }
11
60
12
61
static DRM_CARD_ID : AtomicUsize = AtomicUsize :: new ( 0 ) ;
13
62
@@ -34,7 +83,32 @@ impl Drm {
34
83
}
35
84
}
36
85
37
- impl INodeInterface for Drm { }
86
+ impl INodeInterface for Drm {
87
+ // The DRM is accessed using IOCTLs on a device representing a graphics
88
+ // card.
89
+ fn ioctl ( & self , command : usize , arg : usize ) -> fs:: Result < usize > {
90
+ match command {
91
+ DRM_IOCTL_VERSION => {
92
+ let struc = VirtAddr :: new ( arg as u64 ) . read_mut :: < DrmVersion > ( ) . unwrap ( ) ;
93
+
94
+ let ( major, minor, patch_level) = self . device . driver_version ( ) ;
95
+ let ( name, desc, date) = self . device . driver_info ( ) ;
96
+
97
+ struc. version_major = major as _ ;
98
+ struc. version_minor = minor as _ ;
99
+ struc. version_patch_level = patch_level as _ ;
100
+
101
+ copy_field ( struc. name , & mut struc. name_len , name. as_bytes ( ) ) ;
102
+ copy_field ( struc. desc , & mut struc. desc_len , desc. as_bytes ( ) ) ;
103
+ copy_field ( struc. date , & mut struc. date_len , date. as_bytes ( ) ) ;
104
+
105
+ Ok ( 0 )
106
+ }
107
+
108
+ _ => unimplemented ! ( ) ,
109
+ }
110
+ }
111
+ }
38
112
39
113
impl devfs:: Device for Drm {
40
114
fn device_marker ( & self ) -> usize {
@@ -52,7 +126,15 @@ impl devfs::Device for Drm {
52
126
53
127
struct RawFramebuffer { }
54
128
55
- impl DrmDevice for RawFramebuffer { }
129
+ impl DrmDevice for RawFramebuffer {
130
+ fn driver_version ( & self ) -> ( usize , usize , usize ) {
131
+ ( 0 , 0 , 1 )
132
+ }
133
+
134
+ fn driver_info ( & self ) -> ( & ' static str , & ' static str , & ' static str ) {
135
+ ( "rawfb_gpu" , "rawfb gpu" , "0" )
136
+ }
137
+ }
56
138
57
139
fn init ( ) {
58
140
let dri = devfs:: DEV_FILESYSTEM
0 commit comments