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