19a695706SAsahi Lina // SPDX-License-Identifier: GPL-2.0 OR MIT 29a695706SAsahi Lina 39a695706SAsahi Lina //! DRM IOCTL definitions. 49a695706SAsahi Lina //! 59a695706SAsahi Lina //! C header: [`include/linux/drm/drm_ioctl.h`](srctree/include/linux/drm/drm_ioctl.h) 69a695706SAsahi Lina 79a695706SAsahi Lina use crate::ioctl; 89a695706SAsahi Lina 99a695706SAsahi Lina const BASE: u32 = uapi::DRM_IOCTL_BASE as u32; 109a695706SAsahi Lina 119a695706SAsahi Lina /// Construct a DRM ioctl number with no argument. 129a695706SAsahi Lina #[allow(non_snake_case)] 139a695706SAsahi Lina #[inline(always)] 149a695706SAsahi Lina pub const fn IO(nr: u32) -> u32 { 159a695706SAsahi Lina ioctl::_IO(BASE, nr) 169a695706SAsahi Lina } 179a695706SAsahi Lina 189a695706SAsahi Lina /// Construct a DRM ioctl number with a read-only argument. 199a695706SAsahi Lina #[allow(non_snake_case)] 209a695706SAsahi Lina #[inline(always)] 219a695706SAsahi Lina pub const fn IOR<T>(nr: u32) -> u32 { 229a695706SAsahi Lina ioctl::_IOR::<T>(BASE, nr) 239a695706SAsahi Lina } 249a695706SAsahi Lina 259a695706SAsahi Lina /// Construct a DRM ioctl number with a write-only argument. 269a695706SAsahi Lina #[allow(non_snake_case)] 279a695706SAsahi Lina #[inline(always)] 289a695706SAsahi Lina pub const fn IOW<T>(nr: u32) -> u32 { 299a695706SAsahi Lina ioctl::_IOW::<T>(BASE, nr) 309a695706SAsahi Lina } 319a695706SAsahi Lina 329a695706SAsahi Lina /// Construct a DRM ioctl number with a read-write argument. 339a695706SAsahi Lina #[allow(non_snake_case)] 349a695706SAsahi Lina #[inline(always)] 359a695706SAsahi Lina pub const fn IOWR<T>(nr: u32) -> u32 { 369a695706SAsahi Lina ioctl::_IOWR::<T>(BASE, nr) 379a695706SAsahi Lina } 389a695706SAsahi Lina 399a695706SAsahi Lina /// Descriptor type for DRM ioctls. Use the `declare_drm_ioctls!{}` macro to construct them. 409a695706SAsahi Lina pub type DrmIoctlDescriptor = bindings::drm_ioctl_desc; 419a695706SAsahi Lina 429a695706SAsahi Lina /// This is for ioctl which are used for rendering, and require that the file descriptor is either 439a695706SAsahi Lina /// for a render node, or if it’s a legacy/primary node, then it must be authenticated. 449a695706SAsahi Lina pub const AUTH: u32 = bindings::drm_ioctl_flags_DRM_AUTH; 459a695706SAsahi Lina 469a695706SAsahi Lina /// This must be set for any ioctl which can change the modeset or display state. Userspace must 479a695706SAsahi Lina /// call the ioctl through a primary node, while it is the active master. 489a695706SAsahi Lina /// 499a695706SAsahi Lina /// Note that read-only modeset ioctl can also be called by unauthenticated clients, or when a 509a695706SAsahi Lina /// master is not the currently active one. 519a695706SAsahi Lina pub const MASTER: u32 = bindings::drm_ioctl_flags_DRM_MASTER; 529a695706SAsahi Lina 539a695706SAsahi Lina /// Anything that could potentially wreak a master file descriptor needs to have this flag set. 549a695706SAsahi Lina /// 559a695706SAsahi Lina /// Current that’s only for the SETMASTER and DROPMASTER ioctl, which e.g. logind can call to 569a695706SAsahi Lina /// force a non-behaving master (display compositor) into compliance. 579a695706SAsahi Lina /// 589a695706SAsahi Lina /// This is equivalent to callers with the SYSADMIN capability. 599a695706SAsahi Lina pub const ROOT_ONLY: u32 = bindings::drm_ioctl_flags_DRM_ROOT_ONLY; 609a695706SAsahi Lina 619a695706SAsahi Lina /// This is used for all ioctl needed for rendering only, for drivers which support render nodes. 629a695706SAsahi Lina /// This should be all new render drivers, and hence it should be always set for any ioctl with 639a695706SAsahi Lina /// `AUTH` set. Note though that read-only query ioctl might have this set, but have not set 649a695706SAsahi Lina /// DRM_AUTH because they do not require authentication. 659a695706SAsahi Lina pub const RENDER_ALLOW: u32 = bindings::drm_ioctl_flags_DRM_RENDER_ALLOW; 669a695706SAsahi Lina 679a695706SAsahi Lina /// Internal structures used by the `declare_drm_ioctls!{}` macro. Do not use directly. 689a695706SAsahi Lina #[doc(hidden)] 699a695706SAsahi Lina pub mod internal { 709a695706SAsahi Lina pub use bindings::drm_device; 719a695706SAsahi Lina pub use bindings::drm_file; 729a695706SAsahi Lina pub use bindings::drm_ioctl_desc; 739a695706SAsahi Lina } 749a695706SAsahi Lina 759a695706SAsahi Lina /// Declare the DRM ioctls for a driver. 769a695706SAsahi Lina /// 779a695706SAsahi Lina /// Each entry in the list should have the form: 789a695706SAsahi Lina /// 799a695706SAsahi Lina /// `(ioctl_number, argument_type, flags, user_callback),` 809a695706SAsahi Lina /// 819a695706SAsahi Lina /// `argument_type` is the type name within the `bindings` crate. 829a695706SAsahi Lina /// `user_callback` should have the following prototype: 839a695706SAsahi Lina /// 849a695706SAsahi Lina /// ```ignore 859a695706SAsahi Lina /// fn foo(device: &kernel::drm::Device<Self>, 869a695706SAsahi Lina /// data: &Opaque<uapi::argument_type>, 879a695706SAsahi Lina /// file: &kernel::drm::File<Self::File>, 889a695706SAsahi Lina /// ) -> Result<u32> 899a695706SAsahi Lina /// ``` 909a695706SAsahi Lina /// where `Self` is the drm::drv::Driver implementation these ioctls are being declared within. 919a695706SAsahi Lina /// 929a695706SAsahi Lina /// # Examples 939a695706SAsahi Lina /// 949a695706SAsahi Lina /// ```ignore 959a695706SAsahi Lina /// kernel::declare_drm_ioctls! { 969a695706SAsahi Lina /// (FOO_GET_PARAM, drm_foo_get_param, ioctl::RENDER_ALLOW, my_get_param_handler), 979a695706SAsahi Lina /// } 989a695706SAsahi Lina /// ``` 999a695706SAsahi Lina /// 1009a695706SAsahi Lina #[macro_export] 1019a695706SAsahi Lina macro_rules! declare_drm_ioctls { 1029a695706SAsahi Lina ( $(($cmd:ident, $struct:ident, $flags:expr, $func:expr)),* $(,)? ) => { 1039a695706SAsahi Lina const IOCTLS: &'static [$crate::drm::ioctl::DrmIoctlDescriptor] = { 1049a695706SAsahi Lina use $crate::uapi::*; 1059a695706SAsahi Lina const _:() = { 1069a695706SAsahi Lina let i: u32 = $crate::uapi::DRM_COMMAND_BASE; 1079a695706SAsahi Lina // Assert that all the IOCTLs are in the right order and there are no gaps, 1089a695706SAsahi Lina // and that the size of the specified type is correct. 1099a695706SAsahi Lina $( 1109a695706SAsahi Lina let cmd: u32 = $crate::macros::concat_idents!(DRM_IOCTL_, $cmd); 1119a695706SAsahi Lina ::core::assert!(i == $crate::ioctl::_IOC_NR(cmd)); 1129a695706SAsahi Lina ::core::assert!(core::mem::size_of::<$crate::uapi::$struct>() == 1139a695706SAsahi Lina $crate::ioctl::_IOC_SIZE(cmd)); 1149a695706SAsahi Lina let i: u32 = i + 1; 1159a695706SAsahi Lina )* 1169a695706SAsahi Lina }; 1179a695706SAsahi Lina 1189a695706SAsahi Lina let ioctls = &[$( 1199a695706SAsahi Lina $crate::drm::ioctl::internal::drm_ioctl_desc { 1209a695706SAsahi Lina cmd: $crate::macros::concat_idents!(DRM_IOCTL_, $cmd) as u32, 1219a695706SAsahi Lina func: { 1229a695706SAsahi Lina #[allow(non_snake_case)] 1239a695706SAsahi Lina unsafe extern "C" fn $cmd( 1249a695706SAsahi Lina raw_dev: *mut $crate::drm::ioctl::internal::drm_device, 1259a695706SAsahi Lina raw_data: *mut ::core::ffi::c_void, 1269a695706SAsahi Lina raw_file: *mut $crate::drm::ioctl::internal::drm_file, 1279a695706SAsahi Lina ) -> core::ffi::c_int { 1289a695706SAsahi Lina // SAFETY: 1299a695706SAsahi Lina // - The DRM core ensures the device lives while callbacks are being 1309a695706SAsahi Lina // called. 1319a695706SAsahi Lina // - The DRM device must have been registered when we're called through 1329a695706SAsahi Lina // an IOCTL. 1339a695706SAsahi Lina // 1349a695706SAsahi Lina // FIXME: Currently there is nothing enforcing that the types of the 1359a695706SAsahi Lina // dev/file match the current driver these ioctls are being declared 1369a695706SAsahi Lina // for, and it's not clear how to enforce this within the type system. 137*917b10d9SAlice Ryhl let dev = $crate::drm::device::Device::from_raw(raw_dev); 1389a695706SAsahi Lina // SAFETY: The ioctl argument has size `_IOC_SIZE(cmd)`, which we 1399a695706SAsahi Lina // asserted above matches the size of this type, and all bit patterns of 1409a695706SAsahi Lina // UAPI structs must be valid. 1419a695706SAsahi Lina let data = unsafe { 1429a695706SAsahi Lina &*(raw_data as *const $crate::types::Opaque<$crate::uapi::$struct>) 1439a695706SAsahi Lina }; 1449a695706SAsahi Lina // SAFETY: This is just the DRM file structure 145*917b10d9SAlice Ryhl let file = unsafe { $crate::drm::File::from_raw(raw_file) }; 1469a695706SAsahi Lina 1479a695706SAsahi Lina match $func(dev, data, file) { 1489a695706SAsahi Lina Err(e) => e.to_errno(), 1499a695706SAsahi Lina Ok(i) => i.try_into() 1509a695706SAsahi Lina .unwrap_or($crate::error::code::ERANGE.to_errno()), 1519a695706SAsahi Lina } 1529a695706SAsahi Lina } 1539a695706SAsahi Lina Some($cmd) 1549a695706SAsahi Lina }, 1559a695706SAsahi Lina flags: $flags, 1569a695706SAsahi Lina name: $crate::c_str!(::core::stringify!($cmd)).as_char_ptr(), 1579a695706SAsahi Lina } 1589a695706SAsahi Lina ),*]; 1599a695706SAsahi Lina ioctls 1609a695706SAsahi Lina }; 1619a695706SAsahi Lina }; 1629a695706SAsahi Lina } 163