type-c-service/wrapper: Add recovery logic to set_max_sink_voltage#907
Draft
RobertZ2011 wants to merge 1 commit into
Draft
Conversation
Since the PD controller is responsible for picking a contract, we can't determine if a renegotiation will actually happen. The current behavior can cause a failure to consume power if no renegotiation happens. Start a sink ready timeout when limiting the maximum sink voltage to allow us to recover in cases where no renegotiation happens.
02252ce to
03804ac
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds a recovery mechanism to set_max_sink_voltage in the Type‑C controller wrapper by starting a “sink ready” timeout when the max sink voltage is changed. The motivation is that the PD controller’s internal contract selection logic may not actually renegotiate after a max-voltage limit is set, which can otherwise leave the system failing to consume power. The change reuses the existing sink-ready-timeout infrastructure (which already broadcasts a sink-ready event on timeout) by ensuring a deadline is set even when no “new contract” event ever occurs.
Changes:
- Factor the sink-ready timeout calculation into a helper (
check_sink_ready_timeout_duration) and reuse it for both contract transitions and the new max-voltage recovery path. - Update
set_max_sink_voltage/process_set_max_sink_voltageto take a mutablePortStateso it can armsink_ready_deadlineafter disabling the sink path and before requesting renegotiation. - Adjust the
SetMaxSinkVoltagecontroller-command path to plumbPortStateintoprocess_set_max_sink_voltage.
Step-by-step review guide
-
Shared timeout computation
- Introduces
check_sink_ready_timeout_duration(is_epr)and uses it insidecheck_sink_ready_timeout. - Matters because the new recovery logic needs to arm the same timeout with consistent timing (SPR vs EPR).
- Introduces
-
Recovery logic in
set_max_sink_voltageset_max_sink_voltagenow locks wrapper state and obtains&mut PortStateso it can setsink_ready_deadline.- In
process_set_max_sink_voltage, after disabling the sink path (and before requesting renegotiation), it armssink_ready_deadlineif not already set. This is the key behavioral change: it ensures a future timeout-driven “sink ready” event can fire even if renegotiation never produces a new-contract indication.
-
Command path plumbing
- The
SetMaxSinkVoltagearm inprocess_port_commandnow fetches the per-portPortStateand passes it toprocess_set_max_sink_voltage. - Matters because this path runs through the generic PD command handler, so it must be able to mutate the same per-port deadline used by the timeout event loop.
- The
Potential issues
| # | Severity | File | Description | Code |
|---|---|---|---|---|
| 1 | 🟢 Low | type-c-service/src/wrapper/pd.rs:315-331 |
The SetMaxSinkVoltage match arm redundantly re-runs lookup_local_port(command.port) even though local_port was already validated earlier in process_port_command, adding avoidable nesting/duplication. |
match self.registration.pd_controller.lookup_local_port(command.port) { ... } |
Comment on lines
315
to
331
| controller::PortCommandData::SetMaxSinkVoltage(voltage_mv) => { | ||
| match self.registration.pd_controller.lookup_local_port(command.port) { | ||
| Ok(local_port) => { | ||
| self.process_set_max_sink_voltage(controller, local_port, voltage_mv) | ||
| .await | ||
| match state | ||
| .port_states_mut() | ||
| .get_mut(local_port.0 as usize) | ||
| .ok_or(PdError::InvalidPort) | ||
| { | ||
| Ok(port_state) => { | ||
| self.process_set_max_sink_voltage(controller, port_state, local_port, voltage_mv) | ||
| .await | ||
| } | ||
| Err(e) => Err(e), | ||
| } | ||
| } | ||
| Err(e) => Err(e), | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Since the PD controller is responsible for picking a contract, we can't determine if a renegotiation will actually happen. The current behavior can cause a failure to consume power if no renegotiation happens. Start a sink ready timeout when limiting the maximum sink voltage to allow us to recover in cases where no renegotiation happens.