Skip to content

platform: move get_id_info from platform.rs to public #864

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: rust
Choose a base branch
from

Conversation

Richardhongyu
Copy link

Signed-off-by: Li Hongyu [email protected]

@Richardhongyu
Copy link
Author

In this PR, @wedsonaf suggests to move get_id_info function into public. I write a macro to implement this function for drivers that need to have info from of_id.

Copy link
Member

@bjorn3 bjorn3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two other options to consider:

  1. Create a standalone function that can be used by any adapter.
  2. Create a bang macro used inside the impl. So for example impl<T: Driver> Adapter<T> { impl_get_id_info!(); /* ... */ }.

I think I prefer the first option.


format!(
"
impl<T: Driver> {name}<T> {{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#[derive(Foo)] generally implements a trait called Foo for the respective type. Not sure if we should introduce a trait GetIdInfo, or not.

@wedsonaf
Copy link

wedsonaf commented Aug 9, 2022

@Richardhongyu thanks for doing this. What I had in mind, however, was similar to what @bjorn3 said: a function that other adapters can call.

Is there a reason why you think such an option wouldn't work?

@Richardhongyu
Copy link
Author

I tried this before. But the get_id_info function needs to use Driver and Device, which belong to each file, e.g. foo.rs, bar.rs. I think it's hard to use them in the get_id_info when moving get_id_info into a public file.

@bjorn3
Copy link
Member

bjorn3 commented Aug 9, 2022

Then option 2

Create a bang macro used inside the impl. So for example impl<T: Driver> Adapter<T> { impl_get_id_info!(); /* ... */ }.

Should work.

@Richardhongyu
Copy link
Author

Option 2 looks easier to read. I will change to this style.

@Richardhongyu
Copy link
Author

The new commit uses Option 2.

@Richardhongyu
Copy link
Author

@bjorn3 Thanks for reviewing and helping improve the code!

@Richardhongyu
Copy link
Author

I pushed a new version to apply the above changes.

@wedsonaf
Copy link

wedsonaf commented Aug 9, 2022

I tried this before. But the get_id_info function needs to use Driver and Device, which belong to each file, e.g. foo.rs, bar.rs. I think it's hard to use them in the get_id_info when moving get_id_info into a public file.

Why can't these be passed in as arguments?

@wedsonaf
Copy link

wedsonaf commented Aug 9, 2022

Here's a working version (just the first few lines are different, the rest is exactly the same):

fn get_id_info<T>(
    dev: &impl RawDevice,
    table: Option<driver::IdTable<'static, of::DeviceId, T>>,
) -> Option<&'static T> {
    let table = table?;

    // SAFETY: `table` has static lifetime, so it is valid for read. `dev` is guaranteed to be
    // valid while it's alive, so is the raw device returned by it.
    let id = unsafe { bindings::of_match_device(table.as_ref(), dev.raw_device()) };
    if id.is_null() {
        return None;
    }

    // SAFETY: `id` is a pointer within the static table, so it's always valid.
    let offset = unsafe { (*id).data };
    if offset.is_null() {
        return None;
    }

    // SAFETY: The offset comes from a previous call to `offset_from` in `IdArray::new`, which
    // guarantees that the resulting pointer is within the table.
    let ptr = unsafe { id.cast::<u8>().offset(offset as _).cast::<Option<T>>() };

    // SAFETY: The id table has a static lifetime, so `ptr` is guaranteed to be valid for read.
    unsafe { (&*ptr).as_ref() }
}

probe_callback (and similar functions for other buses) would call the above function as follows:

let info = get_id_info(&dev, T::OF_DEVICE_ID_TABLE);

Do you see a reason why this wouldn't work?

@Richardhongyu Richardhongyu force-pushed the rust_get_id_info branch 2 times, most recently from 93551a0 to 260a52f Compare August 10, 2022 09:59
@Richardhongyu
Copy link
Author

Richardhongyu commented Aug 10, 2022

@wedsonaf This is really cool! Thanks for your help!

I didn't think of passing IdTable in the arguments. I learn a lot from your design. Thanks again for reviewing and correcting me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants