1 // SPDX-License-Identifier: GPL-2.0 OR MIT 2 3 //! DRM IOCTL definitions. 4 //! 5 //! C header: [`include/linux/drm/drm_ioctl.h`](srctree/include/linux/drm/drm_ioctl.h) 6 7 use crate::ioctl; 8 9 const BASE: u32 = uapi::DRM_IOCTL_BASE as u32; 10 11 /// Construct a DRM ioctl number with no argument. 12 #[allow(non_snake_case)] 13 #[inline(always)] 14 pub const fn IO(nr: u32) -> u32 { 15 ioctl::_IO(BASE, nr) 16 } 17 18 /// Construct a DRM ioctl number with a read-only argument. 19 #[allow(non_snake_case)] 20 #[inline(always)] 21 pub const fn IOR<T>(nr: u32) -> u32 { 22 ioctl::_IOR::<T>(BASE, nr) 23 } 24 25 /// Construct a DRM ioctl number with a write-only argument. 26 #[allow(non_snake_case)] 27 #[inline(always)] 28 pub const fn IOW<T>(nr: u32) -> u32 { 29 ioctl::_IOW::<T>(BASE, nr) 30 } 31 32 /// Construct a DRM ioctl number with a read-write argument. 33 #[allow(non_snake_case)] 34 #[inline(always)] 35 pub const fn IOWR<T>(nr: u32) -> u32 { 36 ioctl::_IOWR::<T>(BASE, nr) 37 } 38 39 /// Descriptor type for DRM ioctls. Use the `declare_drm_ioctls!{}` macro to construct them. 40 pub type DrmIoctlDescriptor = bindings::drm_ioctl_desc; 41 42 /// This is for ioctl which are used for rendering, and require that the file descriptor is either 43 /// for a render node, or if it’s a legacy/primary node, then it must be authenticated. 44 pub const AUTH: u32 = bindings::drm_ioctl_flags_DRM_AUTH; 45 46 /// This must be set for any ioctl which can change the modeset or display state. Userspace must 47 /// call the ioctl through a primary node, while it is the active master. 48 /// 49 /// Note that read-only modeset ioctl can also be called by unauthenticated clients, or when a 50 /// master is not the currently active one. 51 pub const MASTER: u32 = bindings::drm_ioctl_flags_DRM_MASTER; 52 53 /// Anything that could potentially wreak a master file descriptor needs to have this flag set. 54 /// 55 /// Current that’s only for the SETMASTER and DROPMASTER ioctl, which e.g. logind can call to 56 /// force a non-behaving master (display compositor) into compliance. 57 /// 58 /// This is equivalent to callers with the SYSADMIN capability. 59 pub const ROOT_ONLY: u32 = bindings::drm_ioctl_flags_DRM_ROOT_ONLY; 60 61 /// This is used for all ioctl needed for rendering only, for drivers which support render nodes. 62 /// This should be all new render drivers, and hence it should be always set for any ioctl with 63 /// `AUTH` set. Note though that read-only query ioctl might have this set, but have not set 64 /// DRM_AUTH because they do not require authentication. 65 pub const RENDER_ALLOW: u32 = bindings::drm_ioctl_flags_DRM_RENDER_ALLOW; 66 67 /// Internal structures used by the `declare_drm_ioctls!{}` macro. Do not use directly. 68 #[doc(hidden)] 69 pub mod internal { 70 pub use bindings::drm_device; 71 pub use bindings::drm_file; 72 pub use bindings::drm_ioctl_desc; 73 } 74 75 /// Declare the DRM ioctls for a driver. 76 /// 77 /// Each entry in the list should have the form: 78 /// 79 /// `(ioctl_number, argument_type, flags, user_callback),` 80 /// 81 /// `argument_type` is the type name within the `bindings` crate. 82 /// `user_callback` should have the following prototype: 83 /// 84 /// ```ignore 85 /// fn foo(device: &kernel::drm::Device<Self>, 86 /// data: &Opaque<uapi::argument_type>, 87 /// file: &kernel::drm::File<Self::File>, 88 /// ) -> Result<u32> 89 /// ``` 90 /// where `Self` is the drm::drv::Driver implementation these ioctls are being declared within. 91 /// 92 /// # Examples 93 /// 94 /// ```ignore 95 /// kernel::declare_drm_ioctls! { 96 /// (FOO_GET_PARAM, drm_foo_get_param, ioctl::RENDER_ALLOW, my_get_param_handler), 97 /// } 98 /// ``` 99 /// 100 #[macro_export] 101 macro_rules! declare_drm_ioctls { 102 ( $(($cmd:ident, $struct:ident, $flags:expr, $func:expr)),* $(,)? ) => { 103 const IOCTLS: &'static [$crate::drm::ioctl::DrmIoctlDescriptor] = { 104 use $crate::uapi::*; 105 const _:() = { 106 let i: u32 = $crate::uapi::DRM_COMMAND_BASE; 107 // Assert that all the IOCTLs are in the right order and there are no gaps, 108 // and that the size of the specified type is correct. 109 $( 110 let cmd: u32 = $crate::macros::concat_idents!(DRM_IOCTL_, $cmd); 111 ::core::assert!(i == $crate::ioctl::_IOC_NR(cmd)); 112 ::core::assert!(core::mem::size_of::<$crate::uapi::$struct>() == 113 $crate::ioctl::_IOC_SIZE(cmd)); 114 let i: u32 = i + 1; 115 )* 116 }; 117 118 let ioctls = &[$( 119 $crate::drm::ioctl::internal::drm_ioctl_desc { 120 cmd: $crate::macros::concat_idents!(DRM_IOCTL_, $cmd) as u32, 121 func: { 122 #[allow(non_snake_case)] 123 unsafe extern "C" fn $cmd( 124 raw_dev: *mut $crate::drm::ioctl::internal::drm_device, 125 raw_data: *mut ::core::ffi::c_void, 126 raw_file: *mut $crate::drm::ioctl::internal::drm_file, 127 ) -> core::ffi::c_int { 128 // SAFETY: 129 // - The DRM core ensures the device lives while callbacks are being 130 // called. 131 // - The DRM device must have been registered when we're called through 132 // an IOCTL. 133 // 134 // FIXME: Currently there is nothing enforcing that the types of the 135 // dev/file match the current driver these ioctls are being declared 136 // for, and it's not clear how to enforce this within the type system. 137 let dev = $crate::drm::device::Device::as_ref(raw_dev); 138 // SAFETY: The ioctl argument has size `_IOC_SIZE(cmd)`, which we 139 // asserted above matches the size of this type, and all bit patterns of 140 // UAPI structs must be valid. 141 let data = unsafe { 142 &*(raw_data as *const $crate::types::Opaque<$crate::uapi::$struct>) 143 }; 144 // SAFETY: This is just the DRM file structure 145 let file = unsafe { $crate::drm::File::as_ref(raw_file) }; 146 147 match $func(dev, data, file) { 148 Err(e) => e.to_errno(), 149 Ok(i) => i.try_into() 150 .unwrap_or($crate::error::code::ERANGE.to_errno()), 151 } 152 } 153 Some($cmd) 154 }, 155 flags: $flags, 156 name: $crate::c_str!(::core::stringify!($cmd)).as_char_ptr(), 157 } 158 ),*]; 159 ioctls 160 }; 161 }; 162 } 163