summaryrefslogtreecommitdiff
path: root/usb
diff options
context:
space:
mode:
authorBadhri Jagan Sridharan <badhri@google.com>2018-07-18 18:03:44 -0700
committerThierry Strudel <tstrudel@google.com>2018-07-20 16:44:32 +0000
commit6aa47331376378baec051ccb846d28e85dee5f69 (patch)
tree47e314a581493565557d9746b587b9260a395365 /usb
parent9d2d028b64c90e52c5044c1b66608a112c1eb5ae (diff)
UsbGadget: Fix switching functions
Sleep only when time elapsed since the last disconnect is less than the PULL_UP_DELAY. This ensures that the hal does not miss the 2 second timeout while switching between functions. Also, enclose write within TEMP_FAILURE_RETRY to prevent being returned from EINTR. Bug: 111424620 Test: a. Switch between multiple functions. b. while true; do fastboot reboot; adb wait-for-device; adb shell getprop ro.bootmode; adb root; sleep 2; adb wait-for-device; adb reboot bootloader; done; Change-Id: Ic8c418c145e4fe070b407c22eef803e10ae41077
Diffstat (limited to 'usb')
-rw-r--r--usb/UsbGadget.cpp37
-rw-r--r--usb/UsbGadget.h2
2 files changed, 32 insertions, 7 deletions
diff --git a/usb/UsbGadget.cpp b/usb/UsbGadget.cpp
index f319f39..74afc99 100644
--- a/usb/UsbGadget.cpp
+++ b/usb/UsbGadget.cpp
@@ -95,6 +95,7 @@ static void *monitorFfs(void *param) {
char buf[BUFFER_SIZE];
bool writeUdc = true, stopMonitor = false;
struct epoll_event events[EPOLL_EVENTS];
+ steady_clock::time_point disconnect;
bool descriptorWritten = true;
for (int i = 0; i < static_cast<int>(usbGadget->mEndpointList.size()); i++) {
@@ -105,11 +106,16 @@ static void *monitorFfs(void *param) {
}
// notify here if the endpoints are already present.
- if (descriptorWritten && !!WriteStringToFile(GADGET_NAME, PULLUP_PATH)) {
- lock_guard<mutex> lock(usbGadget->mLock);
- usbGadget->mCurrentUsbFunctionsApplied = true;
- gadgetPullup = true;
- usbGadget->mCv.notify_all();
+ if (descriptorWritten) {
+ usleep(PULL_UP_DELAY);
+ if (!!WriteStringToFile(GADGET_NAME, PULLUP_PATH)) {
+ lock_guard<mutex> lock(usbGadget->mLock);
+ usbGadget->mCurrentUsbFunctionsApplied = true;
+ gadgetPullup = true;
+ writeUdc = false;
+ ALOGI("GADGET pulled up");
+ usbGadget->mCv.notify_all();
+ }
}
while (!stopMonitor) {
@@ -146,8 +152,14 @@ static void *monitorFfs(void *param) {
if (!descriptorPresent && !writeUdc) {
if (DEBUG) ALOGI("endpoints not up");
writeUdc = true;
+ disconnect = std::chrono::steady_clock::now();
} else if (descriptorPresent && writeUdc) {
- usleep(PULL_UP_DELAY);
+ steady_clock::time_point temp = steady_clock::now();
+
+ if (std::chrono::duration_cast<microseconds>(temp - disconnect).count()
+ < PULL_UP_DELAY)
+ usleep(PULL_UP_DELAY);
+
if(!!WriteStringToFile(GADGET_NAME, PULLUP_PATH)) {
lock_guard<mutex> lock(usbGadget->mLock);
usbGadget->mCurrentUsbFunctionsApplied = true;
@@ -246,8 +258,17 @@ V1_0::Status UsbGadget::tearDownGadget() {
if (mMonitorCreated) {
uint64_t flag = 100;
+ unsigned long ret;
+
// Stop the monitor thread by writing into signal fd.
- write(mEventFd, &flag, sizeof(flag));
+ ret = TEMP_FAILURE_RETRY(write(mEventFd, &flag, sizeof(flag)));
+ if (ret < 0) {
+ ALOGE("Error writing errno=%d", errno);
+ } else if (ret < sizeof(flag)) {
+ ALOGE("Short write length=%zd", ret);
+ }
+
+ ALOGI("mMonitor signalled to exit");
mMonitor->join();
mMonitorCreated = false;
ALOGI("mMonitor destroyed");
@@ -583,6 +604,8 @@ Return<void> UsbGadget::setCurrentUsbFunctions(
goto error;
}
+ ALOGI("Returned from tearDown gadget");
+
// Leave the gadget pulled down to give time for the host to sense disconnect.
usleep(DISCONNECT_WAIT_US);
diff --git a/usb/UsbGadget.h b/usb/UsbGadget.h
index 9a2c4dd..a0aa42b 100644
--- a/usb/UsbGadget.h
+++ b/usb/UsbGadget.h
@@ -50,6 +50,7 @@ using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
+using ::std::chrono::steady_clock;
using ::std::lock_guard;
using ::std::move;
using ::std::mutex;
@@ -57,6 +58,7 @@ using ::std::string;
using ::std::thread;
using ::std::unique_ptr;
using ::std::vector;
+using namespace std::chrono;
using namespace std::chrono_literals;
struct UsbGadget : public IUsbGadget {