summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Brockus <dbrockus@google.com>2020-09-17 11:02:48 -0600
committerCommit Bot <commit-bot@chromium.org>2020-09-19 00:40:16 +0000
commit4cb55a8a12a56a9ad19545541cf604d597b705c4 (patch)
treed1b92f0b4d242013ede6d8d898490559d8a85f37
parentf6b2316d9a42d6b11cbb1a1c449cc0a6d649fa24 (diff)
downloadchrome-ec-4cb55a8a12a56a9ad19545541cf604d597b705c4.tar.gz
USB-PD: Continue mode discovery after failure
pd_get_next_mode was searching the svid_mode_data looking for the next entry to discover, if there are any. Failed and needs discovery were handled the same way, return that entry. So if you had a discovery entry that fails that gets returned and causes the entry to stop, over and over again This issue was found using an ikling hub with attached AC connected to Morphius the SVID discovery finds two SVIDs, DP and Nintendo. The Nintendo fails and this caused the alt-mode to not enter for the valid DP mode. The change is to continue discovery even if there is a failure discovered. If any of the modes succeeded then it will be considered success if there are no new modes to discover. This is the order of returned values: no entries -> successful. an entry that need to be discovered -> return discovery entry. everything discovered properly in the list -> successful. discovered some good and some failed -> successful. all discovered fail -> return first fail. BUG=b:168804124 BRANCH=none TEST=verify morphius monitor when attached ikling powered hub Signed-off-by: Denis Brockus <dbrockus@google.com> Change-Id: Id2064079614c276f3d2054c5bcb194cdb997514c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2416990 Tested-by: Denis Brockus <dbrockus@chromium.org> Reviewed-by: Denis Brockus <dbrockus@chromium.org> Commit-Queue: Denis Brockus <dbrockus@chromium.org> Auto-Submit: Denis Brockus <dbrockus@chromium.org>
-rw-r--r--common/usb_pd_alt_mode_dfp.c23
-rw-r--r--include/usb_pd.h24
2 files changed, 35 insertions, 12 deletions
diff --git a/common/usb_pd_alt_mode_dfp.c b/common/usb_pd_alt_mode_dfp.c
index 737b4e2a76..75d7744597 100644
--- a/common/usb_pd_alt_mode_dfp.c
+++ b/common/usb_pd_alt_mode_dfp.c
@@ -590,17 +590,34 @@ struct svid_mode_data *pd_get_next_mode(int port,
enum tcpm_transmit_type type)
{
struct pd_discovery *disc = pd_get_am_discovery(port, type);
+ struct svid_mode_data *failed_mode_data = NULL;
+ bool svid_good_discovery = false;
int svid_idx;
+ /* Walk through all of the discovery mode entries */
for (svid_idx = 0; svid_idx < disc->svid_cnt; ++svid_idx) {
struct svid_mode_data *mode_data = &disc->svids[svid_idx];
- if (mode_data->discovery == PD_DISC_COMPLETE)
- continue;
+ /* Discovery is needed, so send this one back now */
+ if (mode_data->discovery == PD_DISC_NEEDED)
+ return mode_data;
- return mode_data;
+ /* Discovery already succeeded, save that it was seen */
+ if (mode_data->discovery == PD_DISC_COMPLETE)
+ svid_good_discovery = true;
+ /* Discovery already failed, save first failure */
+ else if (!failed_mode_data)
+ failed_mode_data = mode_data;
}
+ /* If no good entries were located, then return last failed */
+ if (!svid_good_discovery)
+ return failed_mode_data;
+
+ /*
+ * Mode discovery has been attempted for every discovered SVID (if
+ * any exist)
+ */
return NULL;
}
diff --git a/include/usb_pd.h b/include/usb_pd.h
index 0aa2df2621..806df4d396 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -1761,13 +1761,16 @@ void pd_set_modes_discovery(int port, enum tcpm_transmit_type type,
/**
* Get Modes discovery state for this port and SOP* type. Modes discover is
- * considered complete for a port and type when modes have been discovered for
- * all discovered SVIDs. Mode discovery is failed if mode discovery for any SVID
- * failed.
+ * considered NEEDED if there are any discovered SVIDs that still need to be
+ * discovered. Modes discover is considered COMPLETE when no discovered SVIDs
+ * need to go through discovery and at least one mode has been considered
+ * complete or if there are no discovered SVIDs. Modes discovery is
+ * considered FAIL if mode discovery for all SVIDs are failed.
*
* @param port USB-C port number
* @param type SOP* type to retrieve
- * @return Current discovery state (failed or complete)
+ * @return Current discovery state (PD_DISC_NEEDED, PD_DISC_COMPLETE,
+ * PD_DISC_FAIL)
*/
enum pd_discovery_state pd_get_modes_discovery(int port,
enum tcpm_transmit_type type);
@@ -1788,14 +1791,17 @@ int pd_get_mode_vdo_for_svid(int port, enum tcpm_transmit_type type,
uint16_t svid, uint32_t *vdo_out);
/**
- * Get a pointer to mode data for the next SVID with undiscovered modes. This
- * data may indicate that discovery failed.
+ * Get a pointer to mode data for the next SVID that needs to be discovered.
+ * This data may indicate that discovery failed.
*
* @param port USB-C port number
* @param type SOP* type to retrieve
- * @return Pointer to the first SVID-mode structure with undiscovered mode;
- * discovery may be needed or failed; returns NULL if all SVIDs have
- * discovered modes
+ * @return In order of precedence:
+ * Pointer to the first SVID-mode structure with needs discovered
+ * mode, if any exist;
+ * Pointer to the first SVID-mode structure with discovery failed
+ * mode, if any exist and no modes succeeded in discovery;
+ * NULL, otherwise
*/
struct svid_mode_data *pd_get_next_mode(int port, enum tcpm_transmit_type type);