// SPDX-License-Identifier: GPL-2.0 use kernel::uapi; // TODO Work out some common infrastructure to avoid boilerplate code for uAPI abstractions. macro_rules! define_uapi_abstraction { ($name:ident <= $inner:ty) => { #[repr(transparent)] pub struct $name(::kernel::types::Opaque<$inner>); impl ::core::convert::From<&::kernel::types::Opaque<$inner>> for &$name { fn from(value: &::kernel::types::Opaque<$inner>) -> Self { // SAFETY: `Self` is a transparent wrapper of `$inner`. unsafe { ::core::mem::transmute(value) } } } }; } define_uapi_abstraction!(Getparam <= uapi::drm_nova_getparam); impl Getparam { pub fn param(&self) -> u64 { // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_getparam`. unsafe { (*self.0.get()).param } } pub fn set_value(&self, v: u64) { // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_getparam`. unsafe { (*self.0.get()).value = v }; } } define_uapi_abstraction!(GemCreate <= uapi::drm_nova_gem_create); impl GemCreate { pub fn size(&self) -> u64 { // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_create`. unsafe { (*self.0.get()).size } } pub fn set_handle(&self, handle: u32) { // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_create`. unsafe { (*self.0.get()).handle = handle }; } } define_uapi_abstraction!(GemInfo <= uapi::drm_nova_gem_info); impl GemInfo { pub fn handle(&self) -> u32 { // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_info`. unsafe { (*self.0.get()).handle } } pub fn set_size(&self, size: u64) { // SAFETY: `self.get()` is a valid pointer to a `struct drm_nova_gem_info`. unsafe { (*self.0.get()).size = size }; } }