FILE
ioctl.rs
File preview with syntax highlighting.
linux-6.19.14/rust/kernel/drm/ioctl.rs
1// SPDX-License-Identifier: GPL-2.0 OR MIT 2 3//! DRM IOCTL definitions. 4//! 5//! C header: [`include/drm/drm_ioctl.h`](srctree/include/drm/drm_ioctl.h) 6 7use crate::ioctl; 8 9const 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)] 14pub 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)] 21pub 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)] 28pub 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)] 35pub 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. 40pub 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. 44pub 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. 51pub 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. 59pub 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. 65pub 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)] 69pub 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: &mut 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] 101macro_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::from_raw(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 // The `ioctl` argument is exclusively owned by the handler 142 // and guaranteed by the C implementation (`drm_ioctl()`) to remain 143 // valid for the entire lifetime of the reference taken here. 144 // There is no concurrent access or aliasing; no other references 145 // to this object exist during this call. 146 let data = unsafe { &mut *(raw_data.cast::<$crate::uapi::$struct>()) }; 147 // SAFETY: This is just the DRM file structure 148 let file = unsafe { $crate::drm::File::from_raw(raw_file) }; 149 150 match $func(dev, data, file) { 151 Err(e) => e.to_errno(), 152 Ok(i) => i.try_into() 153 .unwrap_or($crate::error::code::ERANGE.to_errno()), 154 } 155 } 156 Some($cmd) 157 }, 158 flags: $flags, 159 name: $crate::str::as_char_ptr_in_const_context( 160 $crate::c_str!(::core::stringify!($cmd)), 161 ), 162 } 163 ),*]; 164 ioctls 165 }; 166 }; 167}
~/
Read-only file preview.