New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 810568 link

Starred by 2 users

Issue metadata

Status: Untriaged
Owner: ----
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Chrome
Pri: 3
Type: Feature



Sign in to add a comment

usbpd stack : handle REJECT cases more gracefully

Project Member Reported by bleung@chromium.org, Feb 8 2018

Issue description

Aseda and I were talking and I  told him that I noticed that there were more than a few cases where the Chrome OS EC's PD implementation does not handle REJECT cases gracefully.

Specifically, REJECTS that come as a part of negotiation of an initial PD contract are very troublesome. Right now, we do nothing in a lot of cases, not retrying the REQUEST, so the charger is at liberty to  hard reset the port.

We if we get a reject on a request as a part of contract negotiation, we should try very hard to make the source happy so that hard reset doesn't happen.
 
Cc: -bleung@google.com mdhayter@chromium.org vpalatin@chromium.org dnschn...@chromium.org shu...@chromium.org
+others for opinion on this idea.
Agreed.  As more creative implementations of Type-C appear, we'll likely be encountering an increased incidence of REJECT.
Cc: bleung@google.com
Cc: tbroch@chromium.org groeck@chromium.org
Just to document a case that came to mind:
https://issuetracker.google.com/37476637

Our PD stack would mistake PD 3.0 APDOs for PD 2.0 PDOs, and would select one of those APDOs using a PD 2.0 request.

The PD 3.0 PPS charger would reject the request because it was a malformed PD 3.0 request, but our PD stack appeared to assume everything went ok.

We should have known something was wrong from the REJECT, but based on the power supply state on the Chromebook, it seemed to think it actually succeeded in getting a PD contract.

+todd who helped fix the APDO bug.

+groeck, since this should be applied in his tcpm implementation too.
So I assume this bug discusses specifically the REJECT to the REQUEST message not all the other possible REJECTs.

> We should have known something was wrong from the REJECT, 
> but based on the power supply state on the Chromebook, 
> it seemed to think it actually succeeded in getting a PD contract.

No, in this case, it actually decides its a pure type-C source which is not willing to give an explicit PD contract,
and continue using it as a valid type-C source.

>  if we get a reject on a request as a part of contract negotiation, we should try very hard to make the source happy 

But retries don't seem a terribly good idea either, most of the time the REJECT means 'you send me an invalid request', so doing it again in an infinite loop will seldom have a positive outcome (the example by Benson in #4 is the typical example where this would have ended up badly ...)
The only case were the retry is interesting would be the not-so-common case where the source change its mind about how power it has available (admitting this becomes something real on future multi-port PD sources). Then to do something robust, we would need to ask again the SNK caps and retries from the beginning IFF they have changed.
It's a bit of work to do this cleanly but feasible.
Hmm... My reading of the PD spec leads me to a little different interpretation.

Based on 2.6.1 Source Operation, the moment that a GoodCRC is sent by
a sink in response to a Source Capabilities, both sides are part of a
PD connection, and Type-C source rules for current no longer apply.
From that point forward, an Explicit Contract is required. See the
definition of the term "Explicit Contract" which says: "All Port pairs
are required to make an Explicit Contract"

In the case where the source REJECTs a REQUEST from the sink, there is
no Explicit Contract in place, and the sink is on borrowed time.

I've seen power sources that issue a Hard Reset when they get into the
state where they detect a PD connection (GoodCRC sent from sink after
SourceCap), but receive something in the Request they don't like, and
then Reject. After a few hundred milliseconds, they hard reset.

Something that I and our friends in Cupertino have seen in the
ecosystem has been that some power supplies balk and send REJECT when
they see CapMismatch bit set in the REQUEST and a higher Max Current
in the request than the source advertised in the Source Cap.

Recall https://issuetracker.google.com/issues/65032711, that Zinger
would send REJECTs when max current was higher than 3.0A and cap
mismatch was set.

One possible mitigation would be if we see a reject and we have either
cap mismatch set or a bigger than the source is expecting max current,
we could back off on those and craft a more conservative REQUEST
(without the bit set) for the retry.

Ultimately yes, rejecting for these reasons is a not a good idea and
may not be spec compliant, but there are power sources in the
ecosystem that do this already, and we may have to deal with these.

Devices in the ecosystem already possibly run into cases where we hard
reset loop without an explicit contract. By retrying with a less
"weird" REQUEST, we may be able to break the cycle before it starts.
By the way, according to our friends in Cupertino, Zinger (at least with early firmwares) would reject a valid REQUEST, and then shortly thereafter issue a soft reset. Other chargers in our chromebook ecosystem (Asus charger and an HP charger) would issue a hard reset instead.
Components: OS>Kernel>Power

Comment 9 by tbroch@chromium.org, Feb 23 2018

Components: -OS>Kernel>Power OS>Firmware>EC
Labels: -Pri-2 Pri-3
Status: Untriaged (was: Unconfirmed)

Sign in to add a comment