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
  */