Merge "usb: Enable USB configurations for trinket"
diff --git a/hal/Usb.cpp b/hal/Usb.cpp
index 0310d0a..418f43c 100644
--- a/hal/Usb.cpp
+++ b/hal/Usb.cpp
@@ -15,6 +15,10 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
+ *
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
*/
#define LOG_TAG "android.hardware.usb@1.2-service-qti"
@@ -54,20 +58,14 @@
// Set by the signal handler to destroy the thread
volatile bool destroyThread;
-
-volatile bool armResetRecovery = false;
-std::string audioDev = "";
-volatile int monDisconnect = 0;
-pthread_t mDisMon;
+// USB bus reset recovery active
+int usbResetRecov;
static void checkUsbWakeupSupport(struct Usb *usb);
static void checkUsbInHostMode(struct Usb *usb);
static void checkUsbDeviceAutoSuspend(const std::string& devicePath);
static bool checkUsbInterfaceAutoSuspend(const std::string& devicePath,
const std::string &intf);
-static bool isAudioClass(const std::string& devicePath,
- const std::string &intf);
-static bool isRootHub(const std::string& devicePath);
static int32_t readFile(const std::string &filename, std::string *contents) {
FILE *fp;
@@ -736,27 +734,9 @@
}
}
-// USB audio device disconnect monitor
-void *disconnectMon(void *param) {
- std::string *devicePath = (std::string *)param;
- int timeout = 300;
-
- while (!destroyThread && monDisconnect) {
- if (!timeout) {
- ALOGI("disconnectMon timed out, deauthorizing");
- writeFile(*devicePath + "/../authorized", "0");
- break;
- }
- timeout--;
- usleep(1000);
- }
-
- return NULL;
-}
-
static void uevent_event(uint32_t /*epevents*/, struct data *payload) {
char msg[UEVENT_MSG_LEN + 2];
- int n;
+ int n, ret;
std::string gadgetName = GetProperty(USB_CONTROLLER_PROP, "");
static std::regex add_regex("add@(/devices/platform/soc/.*dwc3/xhci-hcd\\.\\d\\.auto/"
"usb\\d/\\d-\\d(?:/[\\d\\.-]+)*)");
@@ -764,7 +744,7 @@
"usb\\d)/\\d-\\d(?:/[\\d\\.-]+)*)");
static std::regex bind_regex("bind@(/devices/platform/soc/.*dwc3/xhci-hcd\\.\\d\\.auto/"
"usb\\d/\\d-\\d(?:/[\\d\\.-]+)*)/([^/]*:[^/]*)");
- static std::regex unbind_regex("unbind@(/devices/platform/soc/.*dwc3/xhci-hcd\\.\\d\\.auto/"
+ static std::regex bus_reset_regex("change@(/devices/platform/soc/.*dwc3/xhci-hcd\\.\\d\\.auto/"
"usb\\d/\\d-\\d(?:/[\\d\\.-]+)*)/([^/]*:[^/]*)");
static std::regex udc_regex("(add|remove)@/devices/platform/soc/.*/" + gadgetName +
"/udc/" + gadgetName);
@@ -788,23 +768,36 @@
std::csub_match submatch = match[1];
checkUsbDeviceAutoSuspend("/sys" + submatch.str());
}
- } else if (std::regex_match(msg, match, bind_regex)) {
+ } else if (!payload->usb->mIgnoreWakeup && std::regex_match(msg, match, bind_regex)) {
+ if (match.size() == 3) {
+ std::csub_match devpath = match[1];
+ std::csub_match intfpath = match[2];
+ checkUsbInterfaceAutoSuspend("/sys" + devpath.str(), intfpath.str());
+ }
+ } else if (std::regex_match(msg, match, bus_reset_regex)) {
std::csub_match devpath = match[1];
std::csub_match intfpath = match[2];
- std::string dpath;
- if (!payload->usb->mIgnoreWakeup) {
- if (match.size() == 3) {
- checkUsbInterfaceAutoSuspend("/sys" + devpath.str(), intfpath.str());
- }
- }
+ ALOGI("Handling USB bus reset recovery");
- dpath.assign("/sys" + devpath.str());
- // Limit the audio path recovery to devices directly connected to the root hub.
- // Save the device path to the audio device, which will trigger the recovery.
- if (audioDev == "" && isAudioClass(dpath, intfpath.str()) && isRootHub(dpath)) {
- audioDev.assign(dpath);
- armResetRecovery = true;
+ // Limit the recovery to when an audio device is connected directly to
+ // the roothub. A path reference is needed so other non-audio class
+ // related devices don't trigger the disconnectMon. (unbind uevent occurs
+ // after sysfs files are cleaned, can't check bInterfaceClass)
+ usbResetRecov = 1;
+ ret = writeFile("/sys" + devpath.str() + "/../authorized", "0");
+ if (ret < 0)
+ ALOGI("unable to deauthorize device");
+ } else if (std::regex_match(msg, match, remove_regex)) {
+ std::csub_match devpath = match[1];
+ std::csub_match parentpath = match[2];
+
+ ALOGI("Disconnect received");
+ if (usbResetRecov) {
+ usbResetRecov = 0;
+ //Allow interfaces to disconnect
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ writeFile("/sys" + parentpath.str() + "/authorized", "1");
}
} else if (std::regex_match(msg, match, udc_regex)) {
if (!strncmp(msg, "add", 3)) {
@@ -817,6 +810,7 @@
ALOGI("Binding UDC %s to ConfigFS", gadgetName.c_str());
writeFile("/config/usb_gadget/g1/UDC", gadgetName);
}
+
} else {
// When the UDC is removed, the ConfigFS gadget will no longer be
// bound. If ADBD is running it would keep opening/writing to its
@@ -826,40 +820,6 @@
// Setting this property stops ADBD from proceeding with the retry.
SetProperty(VENDOR_USB_ADB_DISABLED_PROP, "1");
}
- } else if (std::regex_match(msg, match, unbind_regex)) {
- std::csub_match devpath = match[1];
- std::csub_match intfpath = match[2];
- std::string dpath;
-
- dpath.assign("/sys" + devpath.str());
- // Limit the recovery to when an audio device is connected directly to
- // the roothub. A path reference is needed so other non-audio class
- // related devices don't trigger the disconnectMon. (unbind uevent occurs
- // after sysfs files are cleaned, can't check bInterfaceClass)
- if (armResetRecovery && audioDev == dpath) {
- monDisconnect = 1;
- armResetRecovery = false;
- if (pthread_create(&mDisMon, NULL, disconnectMon, &audioDev)) {
- ALOGE("pthread creation failed %d", errno);
- }
- }
- } else if (std::regex_match(msg, match, remove_regex)) {
- std::csub_match devpath = match[1];
- std::csub_match parentpath = match[2];
- std::string dpath;
-
- dpath.assign("/sys" + devpath.str());
- ALOGI("Disconnect received");
- if (monDisconnect) {
- monDisconnect = 0;
- if (!pthread_kill(mDisMon, 0)) {
- pthread_join(mDisMon, NULL);
- }
- writeFile("/sys" + parentpath.str() + "/authorized", "1");
- }
- if (audioDev == dpath)
- audioDev = "";
- armResetRecovery = false;
}
}
@@ -1098,27 +1058,6 @@
}
}
-static bool isRootHub(const std::string& devicePath) {
- std::string devpath;
- int path;
-
- readFile(devicePath + "/../devpath", &devpath);
- path = std::stoi(devpath, 0, 16);
-
- return !path;
-}
-
-static bool isAudioClass(const std::string& devicePath,
- const std::string &intf) {
- std::string bInterfaceClass;
- int interfaceClass, ret = -1;
-
- readFile(devicePath + "/" + intf + "/bInterfaceClass", &bInterfaceClass);
- interfaceClass = std::stoi(bInterfaceClass, 0, 16);
-
- return (interfaceClass == USB_CLASS_AUDIO);
-}
-
/*
* allow specific USB device idProduct and idVendor to auto suspend
*/