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`](srctree/include/linux/device/faux.h) 8 9 use crate::{ 10 bindings, 11 device, 12 prelude::*, // 13 }; 14 use core::ptr::{ 15 addr_of_mut, 16 null, 17 null_mut, 18 NonNull, // 19 }; 20 21 /// The registration of a faux device. 22 /// 23 /// This type represents the registration of a [`struct faux_device`]. When an instance of this type 24 /// is dropped, its respective faux device will be unregistered from the system. 25 /// 26 /// # Invariants 27 /// 28 /// `self.0` always holds a valid pointer to an initialized and registered [`struct faux_device`]. 29 /// 30 /// [`struct faux_device`]: srctree/include/linux/device/faux.h 31 pub struct Registration(NonNull<bindings::faux_device>); 32 33 impl Registration { 34 /// Create and register a new faux device with the given name. 35 #[inline] 36 pub fn new(name: &CStr, parent: Option<&device::Device>) -> Result<Self> { 37 // SAFETY: 38 // - `name` is copied by this function into its own storage 39 // - `faux_ops` is safe to leave NULL according to the C API 40 // - `parent` can be either NULL or a pointer to a `struct device`, and `faux_device_create` 41 // will take a reference to `parent` using `device_add` - ensuring that it remains valid 42 // for the lifetime of the faux device. 43 let dev = unsafe { 44 bindings::faux_device_create( 45 name.as_char_ptr(), 46 parent.map_or(null_mut(), |p| p.as_raw()), 47 null(), 48 ) 49 }; 50 51 // The above function will return either a valid device, or NULL on failure 52 // INVARIANT: The device will remain registered until faux_device_destroy() is called, which 53 // happens in our Drop implementation. 54 Ok(Self(NonNull::new(dev).ok_or(ENODEV)?)) 55 } 56 57 fn as_raw(&self) -> *mut bindings::faux_device { 58 self.0.as_ptr() 59 } 60 } 61 62 impl AsRef<device::Device> for Registration { 63 fn as_ref(&self) -> &device::Device { 64 // SAFETY: The underlying `device` in `faux_device` is guaranteed by the C API to be 65 // a valid initialized `device`. 66 unsafe { device::Device::from_raw(addr_of_mut!((*self.as_raw()).dev)) } 67 } 68 } 69 70 impl Drop for Registration { 71 #[inline] 72 fn drop(&mut self) { 73 // SAFETY: `self.0` is a valid registered faux_device via our type invariants. 74 unsafe { bindings::faux_device_destroy(self.as_raw()) } 75 } 76 } 77 78 // SAFETY: The faux device API is thread-safe as guaranteed by the device core, as long as 79 // faux_device_destroy() is guaranteed to only be called once - which is guaranteed by our type not 80 // having Copy/Clone. 81 unsafe impl Send for Registration {} 82 83 // SAFETY: The faux device API is thread-safe as guaranteed by the device core, as long as 84 // faux_device_destroy() is guaranteed to only be called once - which is guaranteed by our type not 85 // having Copy/Clone. 86 unsafe impl Sync for Registration {} 87