Thread (6 messages) 6 messages, 3 authors, 2021-08-20

Re: [RFC v2] soc: qcom: socinfo.rs: Add Rust Socinfo Driver implementation

From: Miguel Ojeda <hidden>
Date: 2021-08-20 22:18:45

Hi Antonio,

Thanks again for working on this.

On Fri, Aug 20, 2021 at 9:39 PM Antonio Martorana
[off-list ref] wrote:
V2: Addressed formating issues, added conditional compilation to debug_fs
variables, fixed Kconfig, and still working on removing references to bindings::
by abstracting FFI functions through rust/ .
Normally the changelog goes outside the commit message, i.e. after `---`.
+/// SoC version type with major number in the upper 16 bits and minor
+/// number in the lower 16 bits.
+
+const fn socinfo_major(ver: u32) -> u32 {
Doc comments should "touch" the function they document. But using
`///` like shown here would document only `socinfo_major`, and what
the comment says is not really the function documentation. What I
meant in v1 is that perhaps you can find a better way to document all
of them, or none.

Given `socinfo_version` is not used, I would remove that one, and put
"// The upper 16 bits are the major." and "// The lower 16 bits are
the minor." as normal comments inside the function body. Even better,
you could create a `SocInfoVersion` type.
+    ///
+    /// SMEM Image table indices
+    ///
No empty comment lines before/after, please. In addition, `///` is a
doc comment, not a normal comment. You are trying to give a heading
for a set of `const`s, not document the first one.

We should add a lint for the former, and probably we could also try
one for the latter, too...
+#[cfg(CONFIG_DEBUG_FS)]
+const PMIC_MODELS: [&str; 37] = [
This is fine, but since you have created a `config_debug_fs` module,
perhaps you could move everything inside it.

Related: perhaps the name for that module could be something simpler,
like `debugfs`.
+    unsafe {
+        let ref_mut_seq_priv = seq_private.as_mut().unwrap();
+    }
The `// SAFETY: ` comments in several places are missing.
+fn qcom_show_pmic_model(seq: &mut bindings::seq_file, p: &mut c_types::c_void) -> Result {
Several of these functions cannot fail -- so why `Result`?

...ah, I see, you are panicking now -- but then you don't need the
`Result`. If this was userspace and you were not expecting a failure,
then yes, panic might have been a good idea. However, here we are
supposed to return the error like you did in v1. When I mentioned you
should use `Result`, it means you should return the `EINVAL` as such
(using the pre-defined error constants we have in
`rust/kernel/error.rs`, which are in the prelude for ease-of-use, see
e.g. https://rust-for-linux.github.io/docs/kernel/prelude/struct.Error.html).
+    // SAFETY: `socinfo` is guaranteed to be:
+    // - A valid (and instalized), non-null pointer
+    // - Is properly aligned
+    // - Adheres to aliasing rules
The `// SAFETY: ` comment should explain why the callee's
preconditions hold, not just state them (which does not help much a
future reader searching for UB).
+    unsafe {
+        let mut_socinfo = socinfo.as_mut().unwrap();
As mentioned in v1, `unsafe` blocks should be split and reduced as
much as possible.
+        let test_model = socinfo_minor((*socinfo).pmic_model);
+        model = test_model;
Why is `test_model` there?
+    let mut check_valid_model: bool = false;
+    if !PMIC_MODELS[model as usize].is_empty() {
+        check_valid_model = true;
+    }
Try to avoid mutability where possible, e.g.:

    let valid_model = !PMIC_MODELS[model as usize].is_empty();
+    if model < PMIC_MODELS.len() as u32 && check_valid_model {
Something looks odd -- we are checking whether the model is within
`PMIC_MODELS`, but you already used it to index (which is safe, but
because it will panic if wrong -- which we do not want!).
+#[cfg(CONFIG_DEBUG_FS)]
+fn qcom_show_pmic_model_array(seq: &mut bindings::seq_file, p: &mut c_types::c_void) -> Result {
+    Ok(())
+}
+
+#[cfg(CONFIG_DEBUG_FS)]
+fn qcom_show_pmic_die_revision(seq: &mut bindings::seq_file, p: &mut c_types::c_void) -> Result {
+    Ok(())
+}
+
+#[cfg(CONFIG_DEBUG_FS)]
+fn qcom_show_chip_id(seq: &mut bindings::seq_file, p: &mut c_types::c_void) -> Result {
+    Ok(())
+}
Even if not commented out, this is still dead code -- it is best to
remove it until you implement them.
+    fmt: bindings::__le32,
Same thing about `bindings::` from v1 etc. -- if this were not a proof
of concept, it should be properly abstracted.
+const SOC_ID: [SocId; 105] = [
For lots of data, it is usually better to use `static` to have a
single instance somewhere in memory (vs. e.g. inlining).
+    SocId {
+        id: 87,
+        name: c_str!("MSM8960"),
+    },
For repetitive things like this (and especially if the automatic
formatting makes it look bad!), a local "macro by example" is usually
a good approach, e.g.:

    soc_ids!(3,
         87 "MSM8960"
        109 "APQ8064"
        122 "MSM8660A etc etc"
    );

or any other syntax you like for the particular case. It looks much
better, and separates the details of the type from the data table.

The macro can be something like:

    macro_rules! soc_ids(
        ($length:literal, $($id:literal $name:literal)*) => {
            static SOC_ID: [SocID; $length] = [
                $(SocID { id: $id, name: $name },)*
            ];
        }
    );

https://godbolt.org/z/dWofxYn19 to play with it.
+struct SocId {
+    id: u32,
+    name: &'static str::CStr,
+}
Even if Rust allows otherwise, I would still try to put declarations
before they are used.
+fn socinfo_machine(id: &u32) -> Option<&'static str::CStr> {
It is simpler to pass an integer as-is, rather than a pointer to it.
+    for idx in SOC_ID {
You probably want `&SOC_ID` here (see the `static` vs. `const`
discussion above).
+        if idx.id == *id {
+            return Some(idx.name);
+        }
+    }
+    None
Loops like this are good candidates for a functional style -- something like:

    SOC_ID.iter().find(|x| x.id == id).map(|x| x.name)

Whether this looks better or not, of course, is up for debate ;)
+        Ok(drv_data)
+    }
+    fn remove(device_id: i32, _drv_data: Self::DrvData) -> Result {
Newline between functions, please.

Normally we only prefix by underscore if unused.

Cheers,
Miguel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help