1use crate::{
8 bindings,
9 device,
10 devres,
11 drm,
12 error::to_result,
13 prelude::*,
14 sync::aref::ARef, };
16
17pub(crate) const FEAT_GEM: u32 = bindings::drm_driver_feature_DRIVER_GEM;
19
20pub struct DriverInfo {
22 pub major: i32,
24 pub minor: i32,
26 pub patchlevel: i32,
28 pub name: &'static CStr,
30 pub desc: &'static CStr,
32}
33
34pub struct AllocOps {
36 pub(crate) gem_create_object: Option<
37 unsafe extern "C" fn(
38 dev: *mut bindings::drm_device,
39 size: usize,
40 ) -> *mut bindings::drm_gem_object,
41 >,
42 pub(crate) prime_handle_to_fd: Option<
43 unsafe extern "C" fn(
44 dev: *mut bindings::drm_device,
45 file_priv: *mut bindings::drm_file,
46 handle: u32,
47 flags: u32,
48 prime_fd: *mut core::ffi::c_int,
49 ) -> core::ffi::c_int,
50 >,
51 pub(crate) prime_fd_to_handle: Option<
52 unsafe extern "C" fn(
53 dev: *mut bindings::drm_device,
54 file_priv: *mut bindings::drm_file,
55 prime_fd: core::ffi::c_int,
56 handle: *mut u32,
57 ) -> core::ffi::c_int,
58 >,
59 pub(crate) gem_prime_import: Option<
60 unsafe extern "C" fn(
61 dev: *mut bindings::drm_device,
62 dma_buf: *mut bindings::dma_buf,
63 ) -> *mut bindings::drm_gem_object,
64 >,
65 pub(crate) gem_prime_import_sg_table: Option<
66 unsafe extern "C" fn(
67 dev: *mut bindings::drm_device,
68 attach: *mut bindings::dma_buf_attachment,
69 sgt: *mut bindings::sg_table,
70 ) -> *mut bindings::drm_gem_object,
71 >,
72 pub(crate) dumb_create: Option<
73 unsafe extern "C" fn(
74 file_priv: *mut bindings::drm_file,
75 dev: *mut bindings::drm_device,
76 args: *mut bindings::drm_mode_create_dumb,
77 ) -> core::ffi::c_int,
78 >,
79 pub(crate) dumb_map_offset: Option<
80 unsafe extern "C" fn(
81 file_priv: *mut bindings::drm_file,
82 dev: *mut bindings::drm_device,
83 handle: u32,
84 offset: *mut u64,
85 ) -> core::ffi::c_int,
86 >,
87}
88
89pub trait AllocImpl: super::private::Sealed + drm::gem::IntoGEMObject {
91 type Driver: drm::Driver;
93
94 const ALLOC_OPS: AllocOps;
96}
97
98#[vtable]
103pub trait Driver {
104 type Data: Sync + Send;
106
107 type Object: AllocImpl;
109
110 type File: drm::file::DriverFile;
112
113 const INFO: DriverInfo;
115
116 const IOCTLS: &'static [drm::ioctl::DrmIoctlDescriptor];
118}
119
120pub struct Registration<T: Driver>(ARef<drm::Device<T>>);
124
125impl<T: Driver> Registration<T> {
126 fn new(drm: &drm::Device<T>, flags: usize) -> Result<Self> {
127 to_result(unsafe { bindings::drm_dev_register(drm.as_raw(), flags) })?;
129
130 Ok(Self(drm.into()))
131 }
132
133 pub fn new_foreign_owned(
137 drm: &drm::Device<T>,
138 dev: &device::Device<device::Bound>,
139 flags: usize,
140 ) -> Result
141 where
142 T: 'static,
143 {
144 if drm.as_ref().as_raw() != dev.as_raw() {
145 return Err(EINVAL);
146 }
147
148 let reg = Registration::<T>::new(drm, flags)?;
149
150 devres::register(dev, reg, GFP_KERNEL)
151 }
152
153 pub fn device(&self) -> &drm::Device<T> {
155 &self.0
156 }
157}
158
159unsafe impl<T: Driver> Sync for Registration<T> {}
162
163unsafe impl<T: Driver> Send for Registration<T> {}
165
166impl<T: Driver> Drop for Registration<T> {
167 fn drop(&mut self) {
168 unsafe { bindings::drm_dev_unregister(self.0.as_raw()) };
171 }
172}