1 // SPDX-License-Identifier: GPL-2.0-only 2 3 //! Abstractions for the faux bus. 4 //! 5 //! This module provides bindings for working with faux devices in kernel modules. 6 //! 7 //! C header: [`include/linux/device/faux.h`] 8 9 use crate::{bindings, device, error::code::*, prelude::*}; 10 use core::ptr::{addr_of_mut, null, null_mut, NonNull}; 11 12 /// The registration of a faux device. 13 /// 14 /// This type represents the registration of a [`struct faux_device`]. When an instance of this type 15 /// is dropped, its respective faux device will be unregistered from the system. 16 /// 17 /// # Invariants 18 /// 19 /// `self.0` always holds a valid pointer to an initialized and registered [`struct faux_device`]. 20 /// 21 /// [`struct faux_device`]: srctree/include/linux/device/faux.h 22 #[repr(transparent)] 23 pub struct Registration(NonNull<bindings::faux_device>); 24 25 impl Registration { 26 /// Create and register a new faux device with the given name. new(name: &CStr) -> Result<Self>27 pub fn new(name: &CStr) -> Result<Self> { 28 // SAFETY: 29 // - `name` is copied by this function into its own storage 30 // - `faux_ops` is safe to leave NULL according to the C API 31 let dev = unsafe { bindings::faux_device_create(name.as_char_ptr(), null_mut(), null()) }; 32 33 // The above function will return either a valid device, or NULL on failure 34 // INVARIANT: The device will remain registered until faux_device_destroy() is called, which 35 // happens in our Drop implementation. 36 Ok(Self(NonNull::new(dev).ok_or(ENODEV)?)) 37 } 38 as_raw(&self) -> *mut bindings::faux_device39 fn as_raw(&self) -> *mut bindings::faux_device { 40 self.0.as_ptr() 41 } 42 } 43 44 impl AsRef<device::Device> for Registration { as_ref(&self) -> &device::Device45 fn as_ref(&self) -> &device::Device { 46 // SAFETY: The underlying `device` in `faux_device` is guaranteed by the C API to be 47 // a valid initialized `device`. 48 unsafe { device::Device::as_ref(addr_of_mut!((*self.as_raw()).dev)) } 49 } 50 } 51 52 impl Drop for Registration { drop(&mut self)53 fn drop(&mut self) { 54 // SAFETY: `self.0` is a valid registered faux_device via our type invariants. 55 unsafe { bindings::faux_device_destroy(self.as_raw()) } 56 } 57 } 58 59 // SAFETY: The faux device API is thread-safe as guaranteed by the device core, as long as 60 // faux_device_destroy() is guaranteed to only be called once - which is guaranteed by our type not 61 // having Copy/Clone. 62 unsafe impl Send for Registration {} 63 64 // SAFETY: The faux device API is thread-safe as guaranteed by the device core, as long as 65 // faux_device_destroy() is guaranteed to only be called once - which is guaranteed by our type not 66 // having Copy/Clone. 67 unsafe impl Sync for Registration {} 68