usb: check for port partner Thunderbolt capability

Query the port partner's SVIDs when the DisplayPort driver sysfs
is not recognized so that the USB HAL can identify whether or not
the port partner supports Thunderbolt.

Test: manual verification on device - test to see that cableStatus
is set to NOT_CAPABLE on hub that supports Thunderbolt but not
DisplayPort Alt Mode. Then verify that device not capable of being
a DisplayPort sink but does support Thunderbolt does not trigger
this status.
Bug: 288150501
Change-Id: Iaba60ecc5510acecee1e1d3241611906c738a263
Signed-off-by: RD Babiera <rdbabiera@google.com>
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:873766c6f0c668ba526eaefe18ecc5e51ce87d67)
This commit is contained in:
RD Babiera 2023-08-23 22:42:35 +00:00
parent f6c07adcd9
commit e1a03c3dd0
2 changed files with 49 additions and 9 deletions

View file

@ -868,6 +868,29 @@ AltModeData::DisplayPortAltModeData constructAltModeData(string hpd, string pin_
return dpData; return dpData;
} }
Status queryPartnerSvids(std::vector<string> *svids) {
DIR *dp;
dp = opendir(kDisplayPortUsbPath);
if (dp != NULL) {
struct dirent *ep;
// Iterate through directories for Alt Mode SVIDs
while ((ep = readdir(dp))) {
if (ep->d_type == DT_DIR) {
string svid;
string portPartnerPath = string(kDisplayPortUsbPath) + string(ep->d_name) + "/svid";
if (ReadFileToString(portPartnerPath, &svid)) {
(*svids).push_back(Trim(svid));
}
}
}
closedir(dp);
} else {
return Status::ERROR;
}
return Status::SUCCESS;
}
/* DisplayPort Helper Functions End */ /* DisplayPort Helper Functions End */
// Only care about first port which must support DisplayPortAltMode // Only care about first port which must support DisplayPortAltMode
@ -877,18 +900,32 @@ Status queryDisplayPortStatus(android::hardware::usb::Usb *usb,
string path; string path;
AltModeData::DisplayPortAltModeData dpData; AltModeData::DisplayPortAltModeData dpData;
/*
* We check if the DisplayPort Alt Mode sysfs nodes exist. If they don't, then it means that the
* device has not entered Alt Mode with the port partner because of a source/sink role
* incompatibility, pin assignment incompatibility, etc. So, we then check to see if the partner
* supports Thunderbolt and DisplayPort SVIDs. If it supports DisplayPort, then we assume that
* it must be a source device and Thunderbolt should operate similarly; we don't populate the
* DisplayPortAltModeStatus. If it only supports Thunderbolt, then we cannot determine if it is
* sink or source capable, and need to notify the user.
*/
if (usb->getDisplayPortUsbPathHelper(&path) == Status::ERROR) { if (usb->getDisplayPortUsbPathHelper(&path) == Status::ERROR) {
(*currentPortStatus)[0].supportedAltModes.push_back(dpData); std::vector<string> svids;
return Status::SUCCESS; if (queryPartnerSvids(&svids) == Status::SUCCESS) {
if (std::count(svids.begin(), svids.end(), SVID_THUNDERBOLT) &&
!std::count(svids.begin(), svids.end(), SVID_DISPLAYPORT)) {
dpData.cableStatus = DisplayPortAltModeStatus::NOT_CAPABLE;
}
}
} else {
usb->readDisplayPortAttribute("hpd", path, &hpd);
usb->readDisplayPortAttribute("pin_assignment", path, &pinAssign);
usb->readDisplayPortAttribute("vdo", path, &vdo);
usb->readDisplayPortAttribute("link_status", path, &linkStatus);
dpData = constructAltModeData(hpd, pinAssign, linkStatus, vdo);
} }
usb->readDisplayPortAttribute("hpd", path, &hpd);
usb->readDisplayPortAttribute("pin_assignment", path, &pinAssign);
usb->readDisplayPortAttribute("vdo", path, &vdo);
usb->readDisplayPortAttribute("link_status", path, &linkStatus);
// Set DisplayPortAltModeInfo
dpData = constructAltModeData(hpd, pinAssign, linkStatus, vdo);
(*currentPortStatus)[0].supportedAltModes.push_back(dpData); (*currentPortStatus)[0].supportedAltModes.push_back(dpData);
return Status::SUCCESS; return Status::SUCCESS;

View file

@ -70,6 +70,9 @@ constexpr char kGadgetName[] = "11210000.dwc3";
#define DISPLAYPORT_POLL_WAIT_MS 100 #define DISPLAYPORT_POLL_WAIT_MS 100
#define SVID_DISPLAYPORT "ff01"
#define SVID_THUNDERBOLT "8087"
struct Usb : public BnUsb { struct Usb : public BnUsb {
Usb(); Usb();