1use crate::{
8 bindings, device,
9 devres::Devres,
10 drm,
11 error::{to_result, Result},
12 prelude::*,
13 types::ARef,
14};
15use macros::vtable;
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 const ALLOC_OPS: AllocOps;
93}
94
95#[vtable]
100pub trait Driver {
101 type Data: Sync + Send;
103
104 type Object: AllocImpl;
106
107 type File: drm::file::DriverFile;
109
110 const INFO: DriverInfo;
112
113 const IOCTLS: &'static [drm::ioctl::DrmIoctlDescriptor];
115}
116
117pub struct Registration<T: Driver>(ARef<drm::Device<T>>);
121
122impl<T: Driver> Registration<T> {
123 fn new(drm: &drm::Device<T>, flags: usize) -> Result<Self> {
125 to_result(unsafe { bindings::drm_dev_register(drm.as_raw(), flags) })?;
127
128 Ok(Self(drm.into()))
129 }
130
131 pub fn new_foreign_owned(
134 drm: &drm::Device<T>,
135 dev: &device::Device<device::Bound>,
136 flags: usize,
137 ) -> Result {
138 if drm.as_ref().as_raw() != dev.as_raw() {
139 return Err(EINVAL);
140 }
141
142 let reg = Registration::<T>::new(drm, flags)?;
143 Devres::new_foreign_owned(dev, reg, GFP_KERNEL)
144 }
145
146 pub fn device(&self) -> &drm::Device<T> {
148 &self.0
149 }
150}
151
152unsafe impl<T: Driver> Sync for Registration<T> {}
155
156unsafe impl<T: Driver> Send for Registration<T> {}
158
159impl<T: Driver> Drop for Registration<T> {
160 fn drop(&mut self) {
161 unsafe { bindings::drm_dev_unregister(self.0.as_raw()) };
164 }
165}