1use crate::{
8 bindings, device, devres, drm,
9 error::{to_result, Result},
10 prelude::*,
11 types::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 const ALLOC_OPS: AllocOps;
91}
92
93#[vtable]
98pub trait Driver {
99 type Data: Sync + Send;
101
102 type Object: AllocImpl;
104
105 type File: drm::file::DriverFile;
107
108 const INFO: DriverInfo;
110
111 const IOCTLS: &'static [drm::ioctl::DrmIoctlDescriptor];
113}
114
115pub struct Registration<T: Driver>(ARef<drm::Device<T>>);
119
120impl<T: Driver> Registration<T> {
121 fn new(drm: &drm::Device<T>, flags: usize) -> Result<Self> {
123 to_result(unsafe { bindings::drm_dev_register(drm.as_raw(), flags) })?;
125
126 Ok(Self(drm.into()))
127 }
128
129 pub fn new_foreign_owned(
132 drm: &drm::Device<T>,
133 dev: &device::Device<device::Bound>,
134 flags: usize,
135 ) -> Result
136 where
137 T: 'static,
138 {
139 if drm.as_ref().as_raw() != dev.as_raw() {
140 return Err(EINVAL);
141 }
142
143 let reg = Registration::<T>::new(drm, flags)?;
144
145 devres::register(dev, reg, GFP_KERNEL)
146 }
147
148 pub fn device(&self) -> &drm::Device<T> {
150 &self.0
151 }
152}
153
154unsafe impl<T: Driver> Sync for Registration<T> {}
157
158unsafe impl<T: Driver> Send for Registration<T> {}
160
161impl<T: Driver> Drop for Registration<T> {
162 fn drop(&mut self) {
163 unsafe { bindings::drm_dev_unregister(self.0.as_raw()) };
166 }
167}