Re: [RFC PATCH v5 2/3] rust: add minimal IIO subsystem abstractions
Muchamad Coirul Anwar <[email protected]>
| Newsgroups | org.kernel.vger.linux-iio,org.kernel.vger.linux-i2c,org.kernel.vger.linux-kernel,org.kernel.vger.rust-for-linux |
|---|---|
| Message-ID | <CAO26r3RLnX4HXrKDF6akmG722Q2CvDU-uJ40Yfuu_wwJdGgA9g@mail.gmail.com> |
Hi Jonathan, On Mon, 24 Aug 2026 at 07:07, Jonathan Cameron <[email protected]> wrote: > This looks fine to me subject to a few little things - see inline. > > However I didn't take the time to decode every line of rust today so there were bits > I simply didn't understand yet. So for this to be able to move forward I'm going > to need reviews from rust experts! Thanks for the review. I'll add an explicit review request to Danilo and Igor in the v6 cover letter. Brandon Saint-John has been CC'd since v2 and reviewed the series at v3. If he has time to look at it again, a Reviewed-by from him on the Rust abstractions would be welcome. > > > diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs > > index a56ba6309594..5dc917d92151 100644 > > --- a/rust/kernel/error.rs > > +++ b/rust/kernel/error.rs > > @@ -86,6 +86,7 @@ macro_rules! declare_err { > > declare_err!(EIOCBQUEUED, "iocb queued, will get completion event."); > > declare_err!(ERECALLCONFLICT, "Conflict with recalled state."); > > declare_err!(ENOGRACE, "NFS file lock reclaim refused."); > > + declare_err!(ENODATA, "No data available."); > > Do we have something says there must be a user in the same patch? > A really generic thing like this in C would definitely be a patch on its > own so that folk who care about maintaining a given file can easily see > it without reviewing the rest of the series. > > So unless you can't do otherwise, break this out as a precursor patch. I'll break it out as its own patch. The patch will note that the first user is the AS5600 driver, which returns ENODATA when the magnet is absent. > > } > > > > /// Generic integer kernel error. > > diff --git a/rust/kernel/iio.rs b/rust/kernel/iio.rs > > new file mode 100644 > > index 000000000000..f1638160fed1 > > --- /dev/null > > +++ b/rust/kernel/iio.rs > ... > > > + > > +build_iio_enum! { > > + /// Raw unprocessed value from the channel (`IIO_CHAN_INFO_RAW`). > > + /// > > + /// For sensors, this is typically the ADC reading or register value > > + /// before any scaling or offset correction. > > + Raw = iio_chan_info_enum_IIO_CHAN_INFO_RAW, > > I guess there may be a rust convention for this but from a human trying to > read the code point of view this need a blank line here and in similar places > where you have docs / thing documented repeated back to back. Fair point. I'll add blank lines between the variant doc blocks and audit the rest of iio.rs for the same pattern. > > + /// Scale factor to convert raw values to SI units (`IIO_CHAN_INFO_SCALE`). > > + /// > > + /// The processed value is `raw * scale`. The unit depends on the channel > > + /// type (e.g. V for voltage, m/s² for acceleration, rad for angle). > > + Scale = iio_chan_info_enum_IIO_CHAN_INFO_SCALE, > > +} > > > > + > > +/// C-compatible trampoline for the `iio_info.read_raw` callback. > > +/// > > +/// # Safety > > +/// > > +/// This function is only called by the IIO core via the `read_raw` function > > +/// pointer in `iio_info`. The IIO core guarantees: > > +/// - `indio_dev` is a valid `iio_dev` allocated by `iio_device_alloc`. > > +/// - `chan` points to a valid channel spec from the device's channel array. > > +/// - `val` is a valid non-null pointer to a writable `int`. > > +/// - `val2` is a valid non-null pointer to a writable `int`. The IIO core > > +/// always passes stack-allocated storage for both, regardless of whether > > +/// the driver uses `val2` (e.g. `IIO_VAL_INT` only writes `val`; `val2` > > That val2 is always a valid pointer smells a bit like the c interface leaking > into the rust. I'm not necessarily against that being a constraint we take > on but I'm not sure how we document that. Probably add something to the C docs. > Any C driver relying on this today is probably buggy for other reasons. As you suggested, I'll add a note to the C-side iio_info.read_raw documentation in include/linux/iio/iio.h. The IIO core always passes stack-allocated storage for both val and val2 regardless of which IIO_VAL_* type the driver returns, so the assumption holds, it just isn't written down anywhere. I'll also note it in the SAFETY block of read_raw_callback. > > + Ok(IioVal::Fractional(v, v2)) => { > > + // SAFETY: both `val` and `val2` are valid per the Safety contract. > > + unsafe { > > + *val = v; > > + *val2 = v2.get(); > > Why get in some places and not others? May well be a gap in my really limited > rust knowledge. This came up in v3 and I answered it then but forgot to add the comment as I said I would. IioVal::Fractional holds a NonZeroI32 denominator to prevent division-by-zero in iio_format_value(). NonZeroI32 is a newtype wrapper over i32, so .get() is needed to extract the inner i32. The other variants hold plain i32 and don't need it. I'll add an inline comment in v6.