From: "Danilo Krummrich" <dakr@kernel.org>
To: "Gladyshev Ilya" <foxido@foxido.dev>
Cc: "foxido @ foxido . dev-cc= Rafael J. Wysocki" <rafael@kernel.org>,
"Len Brown" <lenb@kernel.org>, "Miguel Ojeda" <ojeda@kernel.org>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Tamir Duberstein" <tamird@gmail.com>,
"Armin Wolf" <W_Armin@gmx.de>,
platform-driver-x86@vger.kernel.org,
linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
linux-acpi@vger.kernel.org
Subject: Re: [RFC PATCH 1/3] rust: implement wrapper for acpi_object
Date: Mon, 22 Dec 2025 12:35:08 +0100 [thread overview]
Message-ID: <DF4PPPGQBPNA.13TJNSRSRUW0A@kernel.org> (raw)
In-Reply-To: <a28e83201e1413091333509628274807e50ec170.1766331321.git.foxido@foxido.dev>
On Sun Dec 21, 2025 at 7:22 PM CET, Gladyshev Ilya wrote:
> +/// An ACPI object.
> +///
> +/// This structure represents the Rust abstraction for a C [`struct acpi_object`].
> +/// You probably want to convert it into actual object type.
I think this is a good place to link the corresponding types.
> +///
> +/// # Example
> +/// ```
> +/// # use kernel::prelude::*
> +/// use kernel::acpi::{AcpiObject};
Braces not needed.
> +///
> +/// fn read_first_acpi_byte(obj: &AcpiObject) -> Result<u8> {
> +/// if obj.type_id() != AcpiBuffer::ACPI_TYPE {
> +/// return Err(EINVAL);
> +/// }
Given the try_into() conversion below this check is unnecessary.
> +/// let obj: &AcpiBuffer = obj.try_into()?;
> +///
> +/// Ok(obj.payload()[0])
> +/// }
> +/// ```
> +#[repr(transparent)]
> +pub struct AcpiObject(bindings::acpi_object);
> +
> +impl AcpiObject {
> + /// Returns object type (see `acpitypes.h`)
> + pub fn type_id(&self) -> u32 {
> + // SAFETY: `type` field is valid in all union variants
Here and in a lot of other places, please end with a period.
> + unsafe { self.0.type_ }
> + }
> +}
> +
> +/// Generate AcpiObject subtype
> +///
> +/// For given subtype implements
> +/// - `TryFrom<&AcpiObject> for &SubType` trait
> +/// - unsafe try_from_unchecked() with same semantics, but without type check
> +macro_rules! acpi_object_subtype {
> + ($subtype_name:ident <- ($acpi_type:ident, $field_name:ident, $union_type:ty)) => {
> + /// Wraps `acpi_object` subtype
> + #[repr(transparent)]
> + pub struct $subtype_name($union_type);
> +
> + impl TryFrom<&AcpiObject> for &$subtype_name {
> + type Error = Error;
> +
> + fn try_from(value: &AcpiObject) -> core::result::Result<Self, Self::Error> {
> + // SAFETY: type_ field present in all union types and is always valid
> + let real_type = unsafe { value.0.type_ };
> +
> + if (real_type != $subtype_name::ACPI_TYPE) {
> + return Err(EINVAL);
> + }
This should just be
if (value.type_id() != $subtype_name::ACPI_TYPE) {
return Err(EINVAL);
}
> +
> + // SAFETY: We validated union subtype
When writing safety comments, please read the safety documentation of the
corresponding function and try to cover all requirements listed as bullet
points.
> + Ok(unsafe {
> + ::core::mem::transmute::<&$union_type, &$subtype_name>(&value.0.$field_name)
> + })
> + }
> + }
> +
> + impl $subtype_name {
> + /// This ACPI type int value (see `acpitypes.h`)
> + pub const ACPI_TYPE: u32 = bindings::$acpi_type;
> +
> + /// Converts AcpiObject reference into exact ACPI type wrapper
> + ///
> + /// # Safety
> + ///
> + /// Assumes that value is correct (`Self`) subtype
> + pub unsafe fn try_from_unchecked(value: &AcpiObject) -> &Self {
The name try_from_unchecked() implies that the function is fallible, but it
isn't. I suggest calling it something along the lines of cast_unchecked().
> + // SAFETY: Only unsafety comes from unchecked transformation and
> + // we transfered
> + unsafe {
> + ::core::mem::transmute::<&$union_type, &$subtype_name>(&value.0.$field_name)
> + }
> + }
> + }
> + };
> +}
> +
> +acpi_object_subtype!(AcpiInteger
> + <- (ACPI_TYPE_INTEGER, integer, bindings::acpi_object__bindgen_ty_1));
> +acpi_object_subtype!(AcpiString
> + <- (ACPI_TYPE_STRING, string, bindings::acpi_object__bindgen_ty_2));
> +acpi_object_subtype!(AcpiBuffer
> + <- (ACPI_TYPE_BUFFER, buffer, bindings::acpi_object__bindgen_ty_3));
> +acpi_object_subtype!(AcpiPackage
> + <- (ACPI_TYPE_PACKAGE, package, bindings::acpi_object__bindgen_ty_4));
> +acpi_object_subtype!(AcpiReference
> + <- (ACPI_TYPE_LOCAL_REFERENCE, reference, bindings::acpi_object__bindgen_ty_5));
> +acpi_object_subtype!(AcpiProcessor
> + <- (ACPI_TYPE_PROCESSOR, processor, bindings::acpi_object__bindgen_ty_6));
> +acpi_object_subtype!(AcpiPowerResource
> + <- (ACPI_TYPE_POWER, power_resource, bindings::acpi_object__bindgen_ty_7));
> +
> +impl AcpiBuffer {
> + /// Get Buffer's content
> + pub fn payload(&self) -> &[u8] {
> + // SAFETY: (pointer, length) indeed represents byte slice
> + unsafe { ::core::slice::from_raw_parts(self.0.pointer, self.0.length as usize) }
> + }
> +}
What about the values of the other types? How are they accessed?
Also, I think it would be better to use a Deref impl rather than a method.
next prev parent reply other threads:[~2025-12-22 11:35 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-21 18:22 [RFC PATCH 0/3] rust: WMI abstractions Gladyshev Ilya
2025-12-21 18:22 ` [RFC PATCH 1/3] rust: implement wrapper for acpi_object Gladyshev Ilya
2025-12-22 11:35 ` Danilo Krummrich [this message]
2025-12-22 21:47 ` Gladyshev Ilya
2025-12-22 22:44 ` Danilo Krummrich
2025-12-23 15:02 ` Gladyshev Ilya
2025-12-22 19:32 ` Rafael J. Wysocki
2025-12-23 16:36 ` Gladyshev Ilya
2025-12-24 21:43 ` kernel test robot
2025-12-21 18:22 ` [RFC PATCH 2/3] rust: introduce WMI abstractions Gladyshev Ilya
2025-12-22 11:50 ` Danilo Krummrich
2025-12-25 18:06 ` Armin Wolf
2025-12-25 20:37 ` Gladyshev Ilya
2025-12-28 21:02 ` Armin Wolf
2025-12-21 18:22 ` [RFC PATCH 3/3] rust: sample driver for WMI demonstrations Gladyshev Ilya
2025-12-24 15:09 ` kernel test robot
2025-12-22 11:52 ` [RFC PATCH 0/3] rust: WMI abstractions Danilo Krummrich
2025-12-22 21:30 ` Gladyshev Ilya
2025-12-25 17:56 ` Armin Wolf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DF4PPPGQBPNA.13TJNSRSRUW0A@kernel.org \
--to=dakr@kernel.org \
--cc=W_Armin@gmx.de \
--cc=a.hindborg@kernel.org \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=foxido@foxido.dev \
--cc=gary@garyguo.net \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
--cc=rafael@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tamird@gmail.com \
--cc=tmgross@umich.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.