forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request torvalds#558 from wedsonaf/device
rust: add an abstraction for devices.
- Loading branch information
Showing
3 changed files
with
70 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
|
||
//! Generic devices that are part of the kernel's driver model. | ||
//! | ||
//! C header: [`include/linux/device.h`](../../../../include/linux/device.h) | ||
use crate::bindings; | ||
|
||
/// A raw device. | ||
/// | ||
/// # Safety | ||
/// | ||
/// Implementers must ensure that the `*mut device` returned by [`RawDevice::raw_device`] is | ||
/// related to `self`, that is, actions on it will affect `self`. For example, if one calls | ||
/// `get_device`, then the refcount on the device represented by `self` will be incremented. | ||
pub unsafe trait RawDevice { | ||
/// Returns the raw `struct device` related to `self`. | ||
fn raw_device(&self) -> *mut bindings::device; | ||
} | ||
|
||
/// A ref-counted device. | ||
/// | ||
/// # Invariants | ||
/// | ||
/// `ptr` is valid, non-null, and has a non-zero reference count. One of the references is owned by | ||
/// `self`, and will be decremented when `self` is dropped. | ||
pub struct Device { | ||
pub(crate) ptr: *mut bindings::device, | ||
} | ||
|
||
impl Device { | ||
/// Creates a new device instance. | ||
/// | ||
/// # Safety | ||
/// | ||
/// Callers must ensure that `ptr` is valid, non-null, and has a non-zero reference count. | ||
pub unsafe fn new(ptr: *mut bindings::device) -> Self { | ||
// SAFETY: By the safety requiments, ptr is valid and its refcounted will be incremented. | ||
unsafe { bindings::get_device(ptr) }; | ||
// INVARIANT: The safety requirements satisfy all but one invariant, which is that `self` | ||
// owns a reference. This is satisfied by the call to `get_device` above. | ||
Self { ptr } | ||
} | ||
|
||
/// Creates a new device instance from an existing [`RawDevice`] instance. | ||
pub fn from_dev(dev: &dyn RawDevice) -> Self { | ||
// SAFETY: The requirements are satisfied by the existence of `RawDevice` and its safety | ||
// requirements. | ||
unsafe { Self::new(dev.raw_device()) } | ||
} | ||
} | ||
|
||
impl Drop for Device { | ||
fn drop(&mut self) { | ||
// SAFETY: By the type invariants, we know that `self` owns a reference, so it is safe to | ||
// relinquish it now. | ||
unsafe { bindings::put_device(self.ptr) }; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters