summaryrefslogtreecommitdiff
path: root/usb
diff options
context:
space:
mode:
authorRoy Luo <royluo@google.com>2023-02-08 19:38:32 +0000
committerRoy Luo <royluo@google.com>2023-02-14 20:31:24 +0000
commit4e38e3b8c35ae7894fae0a0ba10f48726c6ffbdf (patch)
tree616b216ab8df27e2702f8eccabee9a5dde4cfc8e /usb
parentef2da8cce4a93b92b133dd8abb6d56a710bcd6a2 (diff)
downloadgs201-4e38e3b8c35ae7894fae0a0ba10f48726c6ffbdf.tar.gz
Add shell command to send vendor command to GL852G
Bug: 261923350 Test: adb shell cmd android.hardware.usb.IUsb/default hub-vendor-cmd <hex wValue> <hex wIndex> Change-Id: I83b56d28cfd89dfaf51fce88f97020196402f972 Signed-off-by: Roy Luo <royluo@google.com>
Diffstat (limited to 'usb')
-rw-r--r--usb/usb/Android.bp1
-rw-r--r--usb/usb/Usb.cpp115
-rw-r--r--usb/usb/Usb.h6
-rw-r--r--usb/usb/android.hardware.usb-service.rc2
4 files changed, 121 insertions, 3 deletions
diff --git a/usb/usb/Android.bp b/usb/usb/Android.bp
index 6817e87..3421a96 100644
--- a/usb/usb/Android.bp
+++ b/usb/usb/Android.bp
@@ -40,6 +40,7 @@ cc_binary {
"libbinder",
"libhidlbase",
"liblog",
+ "libusbhost",
"libutils",
"libhardware",
"android.hardware.thermal@1.0",
diff --git a/usb/usb/Usb.cpp b/usb/usb/Usb.cpp
index 8ba4a74..533aca8 100644
--- a/usb/usb/Usb.cpp
+++ b/usb/usb/Usb.cpp
@@ -22,10 +22,12 @@
#include <assert.h>
#include <cstring>
#include <dirent.h>
+#include <private/android_filesystem_config.h>
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
+#include <usbhost/usbhost.h>
#include <chrono>
#include <regex>
#include <thread>
@@ -35,6 +37,7 @@
#include <sys/epoll.h>
#include <utils/Errors.h>
#include <utils/StrongPointer.h>
+#include <utils/Vector.h>
#include "Usb.h"
@@ -48,6 +51,8 @@ using android::base::Trim;
using android::hardware::google::pixel::getStatsService;
using android::hardware::google::pixel::PixelAtoms::VendorUsbPortOverheat;
using android::hardware::google::pixel::reportUsbPortOverheat;
+using android::String8;
+using android::Vector;
namespace aidl {
namespace android {
@@ -79,6 +84,12 @@ constexpr int kSamplingIntervalSec = 5;
void queryVersionHelper(android::hardware::usb::Usb *usb,
std::vector<PortStatus> *currentPortStatus);
+#define CTRL_TRANSFER_TIMEOUT_MSEC 1000
+#define GL852G_VENDOR_ID 0x05e3
+#define GL852G_PRODUCT_ID1 0x0608
+#define GL852G_PRODUCT_ID2 0x0610
+#define GL852G_VENDOR_CMD_REQ 0xe3
+
ScopedAStatus Usb::enableUsbData(const string& in_portName, bool in_enable,
int64_t in_transactionId) {
bool result = true;
@@ -683,7 +694,7 @@ Status getPortStatusHelper(android::hardware::usb::Usb *usb,
PortRole currentRole;
currentRole.set<PortRole::powerRole>(PortPowerRole::NONE);
- if (getCurrentRoleHelper(port.first, port.second, &currentRole) == Status::SUCCESS){
+ if (getCurrentRoleHelper(port.first, port.second, &currentRole) == Status::SUCCESS) {
(*currentPortStatus)[i].currentPowerRole = currentRole.get<PortRole::powerRole>();
} else {
ALOGE("Error while retrieving portNames");
@@ -1029,6 +1040,108 @@ ScopedAStatus Usb::setCallback(const shared_ptr<IUsbCallback>& in_callback) {
return ScopedAStatus::ok();
}
+struct hub_vendor_cmd {
+ // wValue filed of standard device request
+ int value;
+ // wIndex field of standard device request
+ int index;
+ // Output pipe to shell command
+ int out;
+ // Whether the hub is found
+ bool found;
+};
+
+static int usbDeviceAdded(const char *devname, void* client_data) {
+ struct hub_vendor_cmd *cmd = (struct hub_vendor_cmd *)client_data;
+ uint16_t vendorId, productId;
+ struct usb_device *device = usb_device_open(devname);
+
+ if (!device) {
+ dprintf(cmd->out, "usb_device_open failed\n");
+ return 0;
+ }
+
+ // The vendor cmd only applies to USB Hubs of Genesys Logic, Inc.
+ // The request field of vendor cmd is fixed to 0xe3.
+ vendorId = usb_device_get_vendor_id(device);
+ productId = usb_device_get_product_id(device);
+ if (vendorId == GL852G_VENDOR_ID &&
+ (productId == GL852G_PRODUCT_ID1 || productId == GL852G_PRODUCT_ID2)) {
+ int ret = usb_device_control_transfer(
+ device, USB_DIR_OUT | USB_TYPE_VENDOR,
+ GL852G_VENDOR_CMD_REQ, cmd->value, cmd->index, NULL, 0,
+ CTRL_TRANSFER_TIMEOUT_MSEC);
+ dprintf(cmd->out, "Vendor cmd %s (wValue %x, wIndex %x, return %d)\n",
+ ret? "failed" : "succeeded", cmd->value, cmd->index, ret);
+ // Stop iterating through usb devices once the hub is found.
+ cmd->found = true;
+ return 1;
+ }
+
+ return 0;
+}
+
+static int usbDiscoveryDone(void *client_data)
+{
+ struct hub_vendor_cmd *cmd = (struct hub_vendor_cmd *)client_data;
+
+ dprintf(cmd->out, "Done USB discovery, hub %s found\n",
+ cmd->found ? "is" : "not");
+
+ return 1;
+}
+
+static status_t sendHubVendorCmd(int out, Vector<String8>& args) {
+ if (args.size() < 3) {
+ dprintf(out, "Incorrect number of argument supplied\n");
+ return ::android::UNKNOWN_ERROR;
+ }
+ struct hub_vendor_cmd cmd = {
+ .value = std::stoi(args[1].c_str(), NULL, 16),
+ .index = std::stoi(args[2].c_str(), NULL, 16),
+ .out = out,
+ .found = false
+ };
+
+ struct usb_host_context *ctx;
+ ctx = usb_host_init();
+ if (!ctx) {
+ dprintf(out, "usb_host_init failed\n");
+ return ::android::UNKNOWN_ERROR;
+ }
+
+ usb_host_run(ctx, usbDeviceAdded, NULL, usbDiscoveryDone, &cmd);
+ usb_host_cleanup(ctx);
+
+ return ::android::NO_ERROR;
+}
+
+status_t Usb::handleShellCommand(int in, int out, int err, const char** argv,
+ uint32_t argc) {
+ uid_t uid = AIBinder_getCallingUid();
+ if (uid != AID_ROOT && uid != AID_SHELL) {
+ return ::android::PERMISSION_DENIED;
+ }
+
+ Vector<String8> utf8Args;
+ utf8Args.setCapacity(argc);
+ for (uint32_t i = 0; i < argc; i++) {
+ utf8Args.push(String8(argv[i]));
+ }
+
+ if (argc >= 1) {
+ if (!utf8Args[0].compare(String8("hub-vendor-cmd"))) {
+ return sendHubVendorCmd(out, utf8Args);
+ }
+ }
+
+ dprintf(out, "usage: adb shell cmd hub-vendor-cmd VALUE INDEX\n"
+ " VALUE wValue field in hex format, e.g. f321\n"
+ " INDEX wIndex field in hex format, e.g. f321\n");
+
+ return ::android::NO_ERROR;
+}
+
} // namespace usb
} // namespace hardware
} // namespace android
diff --git a/usb/usb/Usb.h b/usb/usb/Usb.h
index d8d6d00..121694a 100644
--- a/usb/usb/Usb.h
+++ b/usb/usb/Usb.h
@@ -43,6 +43,7 @@ using ::android::hardware::google::pixel::usb::ZoneInfo;
using ::android::hardware::thermal::V2_0::TemperatureType;
using ::android::hardware::thermal::V2_0::ThrottlingSeverity;
using ::android::sp;
+using ::android::status_t;
using ::ndk::ScopedAStatus;
using ::std::shared_ptr;
using ::std::string;
@@ -68,9 +69,12 @@ struct Usb : public BnUsb {
ScopedAStatus enableUsbDataWhileDocked(const string& in_portName,
int64_t in_transactionId) override;
ScopedAStatus limitPowerTransfer(const string& in_portName, bool in_limit,
- int64_t in_transactionId) override;
+ int64_t in_transactionId) override;
ScopedAStatus resetUsbPort(const string& in_portName, int64_t in_transactionId) override;
+ status_t handleShellCommand(int in, int out, int err, const char** argv,
+ uint32_t argc) override;
+
std::shared_ptr<::aidl::android::hardware::usb::IUsbCallback> mCallback;
// Protects mCallback variable
pthread_mutex_t mLock;
diff --git a/usb/usb/android.hardware.usb-service.rc b/usb/usb/android.hardware.usb-service.rc
index 3ee952a..06cf891 100644
--- a/usb/usb/android.hardware.usb-service.rc
+++ b/usb/usb/android.hardware.usb-service.rc
@@ -1,7 +1,7 @@
service vendor.usb /vendor/bin/hw/android.hardware.usb-service
class hal
user system
- group system shell wakelock
+ group system shell wakelock usb
capabilities WAKE_ALARM BLOCK_SUSPEND
on post-fs