Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/rust/kernel/faux.rs
29266 views
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::{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
pub struct Registration(NonNull<bindings::faux_device>);
23
24
impl Registration {
25
/// Create and register a new faux device with the given name.
26
#[inline]
27
pub fn new(name: &CStr, parent: Option<&device::Device>) -> 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
// - `parent` can be either NULL or a pointer to a `struct device`, and `faux_device_create`
32
// will take a reference to `parent` using `device_add` - ensuring that it remains valid
33
// for the lifetime of the faux device.
34
let dev = unsafe {
35
bindings::faux_device_create(
36
name.as_char_ptr(),
37
parent.map_or(null_mut(), |p| p.as_raw()),
38
null(),
39
)
40
};
41
42
// The above function will return either a valid device, or NULL on failure
43
// INVARIANT: The device will remain registered until faux_device_destroy() is called, which
44
// happens in our Drop implementation.
45
Ok(Self(NonNull::new(dev).ok_or(ENODEV)?))
46
}
47
48
fn as_raw(&self) -> *mut bindings::faux_device {
49
self.0.as_ptr()
50
}
51
}
52
53
impl AsRef<device::Device> for Registration {
54
fn as_ref(&self) -> &device::Device {
55
// SAFETY: The underlying `device` in `faux_device` is guaranteed by the C API to be
56
// a valid initialized `device`.
57
unsafe { device::Device::from_raw(addr_of_mut!((*self.as_raw()).dev)) }
58
}
59
}
60
61
impl Drop for Registration {
62
#[inline]
63
fn drop(&mut self) {
64
// SAFETY: `self.0` is a valid registered faux_device via our type invariants.
65
unsafe { bindings::faux_device_destroy(self.as_raw()) }
66
}
67
}
68
69
// SAFETY: The faux device API is thread-safe as guaranteed by the device core, as long as
70
// faux_device_destroy() is guaranteed to only be called once - which is guaranteed by our type not
71
// having Copy/Clone.
72
unsafe impl Send for Registration {}
73
74
// SAFETY: The faux device API is thread-safe as guaranteed by the device core, as long as
75
// faux_device_destroy() is guaranteed to only be called once - which is guaranteed by our type not
76
// having Copy/Clone.
77
unsafe impl Sync for Registration {}
78
79