From mboxrd@z Thu Jan 1 00:00:00 1970 From: Claude Code Review Bot To: dri-devel-reviews@example.com Subject: Claude review: rust: add basic serial device bus abstractions Date: Sun, 12 Apr 2026 08:55:16 +1000 Message-ID: In-Reply-To: <20260411-rust_serdev-v4-3-845e960c6627@posteo.de> References: <20260411-rust_serdev-v4-0-845e960c6627@posteo.de> <20260411-rust_serdev-v4-3-845e960c6627@posteo.de> X-Mailer: Claude Code Patch Reviewer Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit MIME-Version: 1.0 Patch Review This is the main patch. Several issues found: **Bug -- `Timeout::into_jiffies` overflow handling**: ```rust + fn into_jiffies(self) -> isize { + match self { + Self::Jiffies(value) => value.get().try_into().unwrap_or_default(), + Self::Milliseconds(value) => { + msecs_to_jiffies(value.get()).try_into().unwrap_or_default() + } + Self::Max => 0, + } + } ``` `unwrap_or_default()` produces `0isize` on overflow, which in the C code maps to `MAX_SCHEDULE_TIMEOUT` (infinite wait). A timeout that's too large to represent silently becomes an infinite wait rather than the longest representable finite timeout. This should use `unwrap_or(isize::MAX)` or saturating conversion instead. **Typo in doc comment**: ```rust + /// Even partiy. + Even = bindings::serdev_parity_SERDEV_PARITY_EVEN, ``` "partiy" should be "parity". **Broken intra-doc links** (two instances): ```rust + /// Note that any accepted data has only been buffered by the controller. Use + /// [ Device::wait_until_sent`] to make sure the controller write buffer has actually been ``` The space after `[` breaks the rustdoc link. Should be `` [`Device::wait_until_sent`] `` (no space after `[`). This appears on both `write_all` and `write` methods. **`write_all` cast concern**: ```rust + let ret = unsafe { + bindings::serdev_device_write( + self.as_raw(), + data.as_ptr(), + data.len(), + timeout.into_jiffies(), + ) + }; + // CAST: negative return values are guaranteed to be between `-MAX_ERRNO` and `-1`, + // which always fit into a `i32`. + to_result(ret as i32).map(|()| ret.unsigned_abs()) ``` The CAST comment only addresses negative values, but `ret` is `ssize_t` (i64 on 64-bit). If the positive return value (bytes written) exceeds `i32::MAX` (~2GB), the `as i32` cast would produce a negative value, causing `to_result` to return a spurious error. For serial devices, writes of >2GB are effectively impossible, but the comment should acknowledge this assumption or the code should use a safe conversion. A more robust approach would be to check sign on the original `isize` value before casting. **Probe/receive synchronization -- `UnsafeCell`**: ```rust +#[pin_data] +struct PrivateData { + #[pin] + probe_complete: Completion, + error: UnsafeCell, +} ``` The use of `UnsafeCell` for `error` relies on the `Completion` providing memory ordering (write barrier from `complete_all`, read barrier from `wait_for_completion`). This is correct but worth a comment explaining the synchronization invariant, since `UnsafeCell` without an atomic or lock is unusual and will attract questions from reviewers. **`receive_buf_callback` on probe error before `complete_all`**: The callback path through the `from_result` closure is carefully ordered: `devres::register` -> `set_client_ops` -> `devm_serdev_device_open` -> `T::probe` -> `set error` -> `complete_all`. If any step before `set_client_ops` fails, no callback can fire. If `devm_serdev_device_open` fails, the device isn't open so no receives. If `T::probe` fails (via `set_drvdata`), `error` is set and `complete_all` is called before returning the error. The devres LIFO order then closes the device before freeing PrivateData. This analysis shows the design is correct but should be documented in a comment block for future maintainers. **`set_baudrate` return type**: ```rust + pub fn set_baudrate(&self, speed: u32) -> Result<(), u32> { ``` Returning `Result<(), u32>` where `Err(actual_speed)` means the requested speed wasn't matched exactly is a usable API, but it's worth noting that many callers in the C world accept approximate baudrates (e.g., requesting 115200 and getting 115384). The current API forces exact-match semantics. Consider documenting this or providing a method that returns the actual rate. **Methods on `Device` only**: All device operation methods (`set_baudrate`, `set_flow_control`, `set_parity`, `write_all`, `write`, `write_flush`, `wait_until_sent`) are on `impl Device`. This works from probe via `Core` -> `Bound` deref coercion, which is the correct kernel Rust pattern. --- Generated by Claude Code Patch Reviewer