Merge changes from topic "377782468_internal_hub" into main
* changes: usb: support device state monitoring with internal hub enabled usb: dump port name for usb device state update usb: clean up monitor thread in UsbDataSessionMonitor destructor
This commit is contained in:
commit
06525b3713
4 changed files with 69 additions and 14 deletions
|
@ -117,6 +117,12 @@ constexpr char kHost1StatePath[] = "/sys/bus/usb/devices/usb1/1-0:1.0/usb1-port1
|
|||
constexpr char kHost2UeventRegex[] =
|
||||
"/devices/platform/11210000.usb/11210000.dwc3/xhci-hcd-exynos.[0-9].auto/usb2/2-0:1.0";
|
||||
constexpr char kHost2StatePath[] = "/sys/bus/usb/devices/usb2/2-0:1.0/usb2-port1/state";
|
||||
constexpr char kHubHost1UeventRegex[] =
|
||||
"/devices/platform/11210000.usb/11210000.dwc3/xhci-hcd-exynos.[0-9].auto/usb1/1-1/1-1:1.0";
|
||||
constexpr char kHubHost1StatePath[] = "/sys/bus/usb/devices/usb1/1-1/1-1:1.0/1-1-port1/state";
|
||||
constexpr char kHubHost2UeventRegex[] =
|
||||
"/devices/platform/11210000.usb/11210000.dwc3/xhci-hcd-exynos.[0-9].auto/usb1/1-1/1-1:1.0";
|
||||
constexpr char kHubHost2StatePath[] = "/sys/bus/usb/devices/usb1/1-1/1-1:1.0/1-1-port2/state";
|
||||
constexpr char kDataRolePath[] = "/sys/devices/platform/11210000.usb/new_data_role";
|
||||
constexpr int kSamplingIntervalSec = 5;
|
||||
void queryVersionHelper(android::hardware::usb::Usb *usb,
|
||||
|
@ -536,10 +542,9 @@ static int getInternalHubUniqueId() {
|
|||
return internalHubUniqueId;
|
||||
}
|
||||
|
||||
static Status tuneInternalHub(const char *devname, void* client_data) {
|
||||
static Status tuneInternalHub(const char *devname, android::hardware::usb::Usb *usb) {
|
||||
uint16_t vendorId, productId;
|
||||
struct usb_device *device;
|
||||
::aidl::android::hardware::usb::Usb *usb;
|
||||
int value, index;
|
||||
|
||||
device = usb_device_open(devname);
|
||||
|
@ -548,7 +553,6 @@ static Status tuneInternalHub(const char *devname, void* client_data) {
|
|||
return Status::ERROR;
|
||||
}
|
||||
|
||||
usb = (::aidl::android::hardware::usb::Usb *)client_data;
|
||||
value = usb->mUsbHubVendorCmdValue;
|
||||
index = usb->mUsbHubVendorCmdIndex;
|
||||
|
||||
|
@ -571,20 +575,46 @@ static Status tuneInternalHub(const char *devname, void* client_data) {
|
|||
}
|
||||
|
||||
static int usbDeviceRemoved(const char *devname, void* client_data) {
|
||||
string pogoEnableHub;
|
||||
::aidl::android::hardware::usb::Usb *usb;
|
||||
|
||||
usb = (::aidl::android::hardware::usb::Usb *)client_data;
|
||||
|
||||
if (usb->mIntHubEnabled == true && ReadFileToString(kPogoEnableHub, &pogoEnableHub)
|
||||
&& Trim(pogoEnableHub) == "0") {
|
||||
ALOGI("Internal hub disabled");
|
||||
usb->mIntHubEnabled = false;
|
||||
usb->mUsbDataSessionMonitor.reset(new UsbDataSessionMonitor(kUdcUeventRegex, kUdcStatePath,
|
||||
kHost1UeventRegex, kHost1StatePath, kHost2UeventRegex,
|
||||
kHost2StatePath, kDataRolePath,
|
||||
std::bind(&updatePortStatus, usb)));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbDeviceAdded(const char *devname, void* client_data) {
|
||||
string pogoEnableHub;
|
||||
int uniqueId = 0;
|
||||
::aidl::android::hardware::usb::Usb *usb;
|
||||
|
||||
usb = (::aidl::android::hardware::usb::Usb *)client_data;
|
||||
|
||||
// Enable hub tuning when the pogo dock is connected.
|
||||
if (ReadFileToString(kPogoEnableHub, &pogoEnableHub) && Trim(pogoEnableHub) == "1") {
|
||||
// If enable_hub is set to 1, the internal hub is the first enumearted device on bus 1 and
|
||||
// port 1.
|
||||
uniqueId = usb_device_get_unique_id_from_name(devname);
|
||||
if (uniqueId == getInternalHubUniqueId())
|
||||
tuneInternalHub(devname, client_data);
|
||||
if (uniqueId == getInternalHubUniqueId()) {
|
||||
ALOGI("Internal hub enabled");
|
||||
usb->mIntHubEnabled = true;
|
||||
tuneInternalHub(devname, usb);
|
||||
usb->mUsbDataSessionMonitor.reset(new UsbDataSessionMonitor(kUdcUeventRegex,
|
||||
kUdcStatePath, kHubHost1UeventRegex,
|
||||
kHubHost1StatePath, kHubHost2UeventRegex,
|
||||
kHubHost2StatePath, kDataRolePath,
|
||||
std::bind(&updatePortStatus, usb)));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -612,9 +642,9 @@ Usb::Usb()
|
|||
mRoleSwitchLock(PTHREAD_MUTEX_INITIALIZER),
|
||||
mPartnerLock(PTHREAD_MUTEX_INITIALIZER),
|
||||
mPartnerUp(false),
|
||||
mUsbDataSessionMonitor(kUdcUeventRegex, kUdcStatePath, kHost1UeventRegex, kHost1StatePath,
|
||||
kHost2UeventRegex, kHost2StatePath, kDataRolePath,
|
||||
std::bind(&updatePortStatus, this)),
|
||||
mUsbDataSessionMonitor(new UsbDataSessionMonitor(kUdcUeventRegex, kUdcStatePath,
|
||||
kHost1UeventRegex, kHost1StatePath, kHost2UeventRegex,
|
||||
kHost2StatePath, kDataRolePath, std::bind(&updatePortStatus, this))),
|
||||
mOverheat(ZoneInfo(TemperatureType::USB_PORT, kThermalZoneForTrip,
|
||||
ThrottlingSeverity::CRITICAL),
|
||||
{ZoneInfo(TemperatureType::UNKNOWN, kThermalZoneForTempReadPrimary,
|
||||
|
@ -1200,7 +1230,7 @@ void queryUsbDataSession(android::hardware::usb::Usb *usb,
|
|||
std::vector<PortStatus> *currentPortStatus) {
|
||||
std::vector<ComplianceWarning> warnings;
|
||||
|
||||
usb->mUsbDataSessionMonitor.getComplianceWarnings(
|
||||
usb->mUsbDataSessionMonitor->getComplianceWarnings(
|
||||
(*currentPortStatus)[0].currentDataRole, &warnings);
|
||||
(*currentPortStatus)[0].complianceWarnings.insert(
|
||||
(*currentPortStatus)[0].complianceWarnings.end(),
|
||||
|
|
|
@ -126,7 +126,8 @@ struct Usb : public BnUsb {
|
|||
bool mPartnerUp;
|
||||
|
||||
// Report usb data session event and data incompliance warnings
|
||||
UsbDataSessionMonitor mUsbDataSessionMonitor;
|
||||
std::unique_ptr<UsbDataSessionMonitor> mUsbDataSessionMonitor;
|
||||
bool mIntHubEnabled;
|
||||
// Usb Overheat object for push suez event
|
||||
UsbOverheatEvent mOverheat;
|
||||
// Temperature when connected
|
||||
|
|
|
@ -102,6 +102,7 @@ UsbDataSessionMonitor::UsbDataSessionMonitor(
|
|||
const std::string &dataRolePath, std::function<void()> updatePortStatusCb) {
|
||||
struct epoll_event ev;
|
||||
std::string udc;
|
||||
int pipefds[2];
|
||||
|
||||
unique_fd epollFd(epoll_create(8));
|
||||
if (epollFd.get() == -1) {
|
||||
|
@ -133,19 +134,28 @@ UsbDataSessionMonitor::UsbDataSessionMonitor(
|
|||
abort();
|
||||
}
|
||||
|
||||
pipe(pipefds);
|
||||
mPipefd0.reset(pipefds[0]);
|
||||
mPipefd1.reset(pipefds[1]);
|
||||
if (addEpollFd(epollFd, mPipefd0))
|
||||
abort();
|
||||
|
||||
/*
|
||||
* The device state file could be absent depending on the current data role
|
||||
* and driver architecture. It's ok for addEpollFile to fail here, the file
|
||||
* will be monitored later when its presence is detected by uevent.
|
||||
*/
|
||||
mDeviceState.name = "udc";
|
||||
mDeviceState.filePath = deviceStatePath;
|
||||
mDeviceState.ueventRegex = deviceUeventRegex;
|
||||
addEpollFile(epollFd.get(), mDeviceState.filePath, mDeviceState.fd);
|
||||
|
||||
mHost1State.name = "host1";
|
||||
mHost1State.filePath = host1StatePath;
|
||||
mHost1State.ueventRegex = host1UeventRegex;
|
||||
addEpollFile(epollFd.get(), mHost1State.filePath, mHost1State.fd);
|
||||
|
||||
mHost2State.name = "host2";
|
||||
mHost2State.filePath = host2StatePath;
|
||||
mHost2State.ueventRegex = host2UeventRegex;
|
||||
addEpollFile(epollFd.get(), mHost2State.filePath, mHost2State.fd);
|
||||
|
@ -169,7 +179,15 @@ UsbDataSessionMonitor::UsbDataSessionMonitor(
|
|||
usb_flags::enable_report_usb_data_compliance_warning());
|
||||
}
|
||||
|
||||
UsbDataSessionMonitor::~UsbDataSessionMonitor() {}
|
||||
UsbDataSessionMonitor::~UsbDataSessionMonitor() {
|
||||
/*
|
||||
* Write a character to the pipe to signal the monitor thread to exit.
|
||||
* The character is not important, it can be any value.
|
||||
*/
|
||||
int c = 'q';
|
||||
write(mPipefd1, &c, 1);
|
||||
pthread_join(mMonitor, NULL);
|
||||
}
|
||||
|
||||
void UsbDataSessionMonitor::reportUsbDataSessionMetrics() {
|
||||
std::vector<VendorUsbDataSessionEvent> events;
|
||||
|
@ -307,11 +325,11 @@ void UsbDataSessionMonitor::handleDeviceStateEvent(struct usbDeviceState *device
|
|||
n = read(deviceState->fd.get(), &state, USB_STATE_MAX_LEN);
|
||||
|
||||
if (kValidStates.find(state) == kValidStates.end()) {
|
||||
ALOGE("Invalid state %s", state);
|
||||
ALOGE("Invalid state %s: %s", deviceState->name.c_str(), state);
|
||||
return;
|
||||
}
|
||||
|
||||
ALOGI("Update USB device state: %s", state);
|
||||
ALOGI("Update device state %s: %s", deviceState->name.c_str(), state);
|
||||
|
||||
deviceState->states.push_back(state);
|
||||
deviceState->timestamps.push_back(boot_clock::now());
|
||||
|
@ -484,7 +502,9 @@ void *UsbDataSessionMonitor::monitorThread(void *param) {
|
|||
}
|
||||
|
||||
for (int n = 0; n < nevents; ++n) {
|
||||
if (events[n].data.fd == monitor->mUeventFd.get()) {
|
||||
if (events[n].data.fd == monitor->mPipefd0.get()) {
|
||||
return NULL;
|
||||
} else if (events[n].data.fd == monitor->mUeventFd.get()) {
|
||||
monitor->handleUevent();
|
||||
} else if (events[n].data.fd == monitor->mTimerFd.get()) {
|
||||
monitor->handleTimerEvent();
|
||||
|
|
|
@ -64,6 +64,8 @@ class UsbDataSessionMonitor {
|
|||
|
||||
private:
|
||||
struct usbDeviceState {
|
||||
// The name of the usb device, e.g. udc, host1, host2.
|
||||
std::string name;
|
||||
unique_fd fd;
|
||||
std::string filePath;
|
||||
std::string ueventRegex;
|
||||
|
@ -86,6 +88,8 @@ class UsbDataSessionMonitor {
|
|||
void updateUdcBindStatus(const std::string &devname);
|
||||
|
||||
pthread_t mMonitor;
|
||||
unique_fd mPipefd0;
|
||||
unique_fd mPipefd1;
|
||||
unique_fd mEpollFd;
|
||||
unique_fd mUeventFd;
|
||||
unique_fd mTimerFd;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue