1use crate::{
8 bindings, device, devres, drm,
9 error::{to_result, Result},
10 prelude::*,
11 str::CStr,
12 types::ARef,
13};
14use macros::vtable;
15
16pub(crate) const FEAT_GEM: u32 = bindings::drm_driver_feature_DRIVER_GEM;
18
19pub struct DriverInfo {
21 pub major: i32,
23 pub minor: i32,
25 pub patchlevel: i32,
27 pub name: &'static CStr,
29 pub desc: &'static CStr,
31}
32
33pub struct AllocOps {
35 pub(crate) gem_create_object: Option<
36 unsafe extern "C" fn(
37 dev: *mut bindings::drm_device,
38 size: usize,
39 ) -> *mut bindings::drm_gem_object,
40 >,
41 pub(crate) prime_handle_to_fd: Option<
42 unsafe extern "C" fn(
43 dev: *mut bindings::drm_device,
44 file_priv: *mut bindings::drm_file,
45 handle: u32,
46 flags: u32,
47 prime_fd: *mut core::ffi::c_int,
48 ) -> core::ffi::c_int,
49 >,
50 pub(crate) prime_fd_to_handle: Option<
51 unsafe extern "C" fn(
52 dev: *mut bindings::drm_device,
53 file_priv: *mut bindings::drm_file,
54 prime_fd: core::ffi::c_int,
55 handle: *mut u32,
56 ) -> core::ffi::c_int,
57 >,
58 pub(crate) gem_prime_import: Option<
59 unsafe extern "C" fn(
60 dev: *mut bindings::drm_device,
61 dma_buf: *mut bindings::dma_buf,
62 ) -> *mut bindings::drm_gem_object,
63 >,
64 pub(crate) gem_prime_import_sg_table: Option<
65 unsafe extern "C" fn(
66 dev: *mut bindings::drm_device,
67 attach: *mut bindings::dma_buf_attachment,
68 sgt: *mut bindings::sg_table,
69 ) -> *mut bindings::drm_gem_object,
70 >,
71 pub(crate) dumb_create: Option<
72 unsafe extern "C" fn(
73 file_priv: *mut bindings::drm_file,
74 dev: *mut bindings::drm_device,
75 args: *mut bindings::drm_mode_create_dumb,
76 ) -> core::ffi::c_int,
77 >,
78 pub(crate) dumb_map_offset: Option<
79 unsafe extern "C" fn(
80 file_priv: *mut bindings::drm_file,
81 dev: *mut bindings::drm_device,
82 handle: u32,
83 offset: *mut u64,
84 ) -> core::ffi::c_int,
85 >,
86}
87
88pub trait AllocImpl: super::private::Sealed + drm::gem::IntoGEMObject {
90 const ALLOC_OPS: AllocOps;
92}
93
94#[vtable]
99pub trait Driver {
100 type Data: Sync + Send;
102
103 type Object: AllocImpl;
105
106 type File: drm::file::DriverFile;
108
109 const INFO: DriverInfo;
111
112 const IOCTLS: &'static [drm::ioctl::DrmIoctlDescriptor];
114}
115
116pub struct Registration<T: Driver>(ARef<drm::Device<T>>);
120
121impl<T: Driver> Registration<T> {
122 fn new(drm: &drm::Device<T>, flags: usize) -> Result<Self> {
124 to_result(unsafe { bindings::drm_dev_register(drm.as_raw(), flags) })?;
126
127 Ok(Self(drm.into()))
128 }
129
130 pub fn new_foreign_owned(
133 drm: &drm::Device<T>,
134 dev: &device::Device<device::Bound>,
135 flags: usize,
136 ) -> Result
137 where
138 T: 'static,
139 {
140 if drm.as_ref().as_raw() != dev.as_raw() {
141 return Err(EINVAL);
142 }
143
144 let reg = Registration::<T>::new(drm, flags)?;
145
146 devres::register(dev, reg, GFP_KERNEL)
147 }
148
149 pub fn device(&self) -> &drm::Device<T> {
151 &self.0
152 }
153}
154
155unsafe impl<T: Driver> Sync for Registration<T> {}
158
159unsafe impl<T: Driver> Send for Registration<T> {}
161
162impl<T: Driver> Drop for Registration<T> {
163 fn drop(&mut self) {
164 unsafe { bindings::drm_dev_unregister(self.0.as_raw()) };
167 }
168}