1From dae9a11f3a158357966399aef97c48b5f16934d9 Mon Sep 17 00:00:00 2001
2From: Jiacheng Liu <jiacheng.liu@mediatek.com>
3Date: Sat, 24 Jul 2021 11:01:18 +0800
4Subject: [PATCH] android-tools: adb: add u3 ss descriptor support
5
6Porting u3 Superspeed descriptor support to open-embedded android-tools package.
7This patch origins from the the patch in android project [1], but has been
8modified for backporting to android-tools_5.1.1.r37.
9
10[1] https://android.googlesource.com/platform/system/core/+/d6ee9f26a5163af4121f4380264fcbd4e6851a17%5E%21
11
12Signed-off-by: Macpaul Lin <macpaul.lin@mediatek.com>
13Signed-off-by: Jiacheng Liu <jiacheng.liu@mediatek.com>
14---
15Upstream-Status: Pending
16
17 adb/usb_linux_client.c | 275 +++++++++++++++++++++++++++++++----------
18 1 file changed, 207 insertions(+), 68 deletions(-)
19
20diff --git a/adb/usb_linux_client.c b/adb/usb_linux_client.c
21index 6e8b5bb..884e85e 100644
22--- a/adb/usb_linux_client.c
23+++ b/adb/usb_linux_client.c
24@@ -31,8 +31,10 @@
25 #define   TRACE_TAG  TRACE_USB
26 #include "adb.h"
27
28+#define USB_EXT_PROP_UNICODE    1
29 #define MAX_PACKET_SIZE_FS	64
30 #define MAX_PACKET_SIZE_HS	512
31+#define MAX_PACKET_SIZE_SS	1024
32
33 #if __BYTE_ORDER == __LITTLE_ENDIAN
34 # define cpu_to_le16(x) (x)
35@@ -62,74 +64,185 @@ struct usb_handle
36     int bulk_in;  /* "in" from the host's perspective => sink for adbd */
37 };
38
39-static const struct {
40-    struct usb_functionfs_descs_head header;
41-    struct {
42-        struct usb_interface_descriptor intf;
43-        struct usb_endpoint_descriptor_no_audio source;
44-        struct usb_endpoint_descriptor_no_audio sink;
45-    } __attribute__((packed)) fs_descs, hs_descs;
46-} __attribute__((packed)) descriptors = {
47-    .header = {
48-        .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC),
49-        .length = cpu_to_le32(sizeof(descriptors)),
50-        .fs_count = 3,
51-        .hs_count = 3,
52+struct func_desc {
53+    struct usb_interface_descriptor intf;
54+    struct usb_endpoint_descriptor_no_audio source;
55+    struct usb_endpoint_descriptor_no_audio sink;
56+} __attribute__((packed));
57+
58+struct ss_func_desc {
59+    struct usb_interface_descriptor intf;
60+    struct usb_endpoint_descriptor_no_audio source;
61+    struct usb_ss_ep_comp_descriptor source_comp;
62+    struct usb_endpoint_descriptor_no_audio sink;
63+    struct usb_ss_ep_comp_descriptor sink_comp;
64+} __attribute__((packed));
65+
66+struct desc_v1 {
67+    struct usb_functionfs_descs_head_v1 {
68+        __le32 magic;
69+        __le32 length;
70+        __le32 fs_count;
71+        __le32 hs_count;
72+    } __attribute__((packed)) header;
73+    struct func_desc fs_descs, hs_descs;
74+} __attribute__((packed));
75+
76+struct usb_os_desc_ext_prop {
77+    uint32_t dwSize;
78+    uint32_t dwPropertyDataType;
79+
80+    // Property name and value are transmitted as UTF-16, but the kernel only
81+    // accepts ASCII values and performs the conversion for us.
82+    uint16_t wPropertyNameLength;
83+    char bPropertyName[20];
84+
85+    uint32_t dwPropertyDataLength;
86+    char bProperty[39];
87+} __attribute__((packed)) os_desc_guid = {
88+    .dwSize = sizeof(struct usb_os_desc_ext_prop),
89+    .dwPropertyDataType = cpu_to_le32(USB_EXT_PROP_UNICODE),
90+    .wPropertyNameLength = cpu_to_le16(20),
91+    .bPropertyName = "DeviceInterfaceGUID",
92+    .dwPropertyDataLength = cpu_to_le32(39),
93+    .bProperty = "{F72FE0D4-CBCB-407D-8814-9ED673D0DD6B}",
94+};
95+
96+struct usb_ext_prop_values {
97+    struct usb_os_desc_ext_prop guid;
98+} __attribute__((packed));
99+
100+struct desc_v2 {
101+    struct usb_functionfs_descs_head_v2 header;
102+    // The rest of the structure depends on the flags in the header.
103+    __le32 fs_count;
104+    __le32 hs_count;
105+    __le32 ss_count;
106+    __le32 os_count;
107+    struct func_desc fs_descs, hs_descs;
108+    struct ss_func_desc ss_descs;
109+    struct usb_os_desc_header os_header;
110+    struct usb_ext_compat_desc os_desc;
111+    struct usb_os_desc_header os_prop_header;
112+    struct usb_ext_prop_values os_prop_values;
113+} __attribute__((packed));
114+
115+static struct func_desc fs_descriptors = {
116+    .intf = {
117+        .bLength = sizeof(fs_descriptors.intf),
118+        .bDescriptorType = USB_DT_INTERFACE,
119+        .bInterfaceNumber = 0,
120+        .bNumEndpoints = 2,
121+        .bInterfaceClass = ADB_CLASS,
122+        .bInterfaceSubClass = ADB_SUBCLASS,
123+        .bInterfaceProtocol = ADB_PROTOCOL,
124+        .iInterface = 1, /* first string from the provided table */
125+    },
126+    .source = {
127+        .bLength = sizeof(fs_descriptors.source),
128+        .bDescriptorType = USB_DT_ENDPOINT,
129+        .bEndpointAddress = 1 | USB_DIR_OUT,
130+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
131+        .wMaxPacketSize = MAX_PACKET_SIZE_FS,
132+    },
133+    .sink = {
134+        .bLength = sizeof(fs_descriptors.sink),
135+        .bDescriptorType = USB_DT_ENDPOINT,
136+        .bEndpointAddress = 2 | USB_DIR_IN,
137+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
138+        .wMaxPacketSize = MAX_PACKET_SIZE_FS,
139+    },
140+};
141+
142+static struct func_desc hs_descriptors = {
143+    .intf = {
144+        .bLength = sizeof(hs_descriptors.intf),
145+        .bDescriptorType = USB_DT_INTERFACE,
146+        .bInterfaceNumber = 0,
147+        .bNumEndpoints = 2,
148+        .bInterfaceClass = ADB_CLASS,
149+        .bInterfaceSubClass = ADB_SUBCLASS,
150+        .bInterfaceProtocol = ADB_PROTOCOL,
151+        .iInterface = 1, /* first string from the provided table */
152+    },
153+    .source = {
154+        .bLength = sizeof(hs_descriptors.source),
155+        .bDescriptorType = USB_DT_ENDPOINT,
156+        .bEndpointAddress = 1 | USB_DIR_OUT,
157+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
158+        .wMaxPacketSize = MAX_PACKET_SIZE_HS,
159+    },
160+    .sink = {
161+        .bLength = sizeof(hs_descriptors.sink),
162+        .bDescriptorType = USB_DT_ENDPOINT,
163+        .bEndpointAddress = 2 | USB_DIR_IN,
164+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
165+        .wMaxPacketSize = MAX_PACKET_SIZE_HS,
166+    },
167+};
168+
169+static struct ss_func_desc ss_descriptors = {
170+    .intf = {
171+        .bLength = sizeof(ss_descriptors.intf),
172+        .bDescriptorType = USB_DT_INTERFACE,
173+        .bInterfaceNumber = 0,
174+        .bNumEndpoints = 2,
175+        .bInterfaceClass = ADB_CLASS,
176+        .bInterfaceSubClass = ADB_SUBCLASS,
177+        .bInterfaceProtocol = ADB_PROTOCOL,
178+        .iInterface = 1, /* first string from the provided table */
179+    },
180+    .source = {
181+        .bLength = sizeof(ss_descriptors.source),
182+        .bDescriptorType = USB_DT_ENDPOINT,
183+        .bEndpointAddress = 1 | USB_DIR_OUT,
184+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
185+        .wMaxPacketSize = MAX_PACKET_SIZE_SS,
186+    },
187+    .source_comp = {
188+        .bLength = sizeof(ss_descriptors.source_comp),
189+        .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
190+        .bMaxBurst = 4,
191     },
192-    .fs_descs = {
193-        .intf = {
194-            .bLength = sizeof(descriptors.fs_descs.intf),
195-            .bDescriptorType = USB_DT_INTERFACE,
196-            .bInterfaceNumber = 0,
197-            .bNumEndpoints = 2,
198-            .bInterfaceClass = ADB_CLASS,
199-            .bInterfaceSubClass = ADB_SUBCLASS,
200-            .bInterfaceProtocol = ADB_PROTOCOL,
201-            .iInterface = 1, /* first string from the provided table */
202-        },
203-        .source = {
204-            .bLength = sizeof(descriptors.fs_descs.source),
205-            .bDescriptorType = USB_DT_ENDPOINT,
206-            .bEndpointAddress = 1 | USB_DIR_OUT,
207-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
208-            .wMaxPacketSize = MAX_PACKET_SIZE_FS,
209-        },
210-        .sink = {
211-            .bLength = sizeof(descriptors.fs_descs.sink),
212-            .bDescriptorType = USB_DT_ENDPOINT,
213-            .bEndpointAddress = 2 | USB_DIR_IN,
214-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
215-            .wMaxPacketSize = MAX_PACKET_SIZE_FS,
216-        },
217+    .sink = {
218+        .bLength = sizeof(ss_descriptors.sink),
219+        .bDescriptorType = USB_DT_ENDPOINT,
220+        .bEndpointAddress = 2 | USB_DIR_IN,
221+        .bmAttributes = USB_ENDPOINT_XFER_BULK,
222+        .wMaxPacketSize = MAX_PACKET_SIZE_SS,
223     },
224-    .hs_descs = {
225-        .intf = {
226-            .bLength = sizeof(descriptors.hs_descs.intf),
227-            .bDescriptorType = USB_DT_INTERFACE,
228-            .bInterfaceNumber = 0,
229-            .bNumEndpoints = 2,
230-            .bInterfaceClass = ADB_CLASS,
231-            .bInterfaceSubClass = ADB_SUBCLASS,
232-            .bInterfaceProtocol = ADB_PROTOCOL,
233-            .iInterface = 1, /* first string from the provided table */
234-        },
235-        .source = {
236-            .bLength = sizeof(descriptors.hs_descs.source),
237-            .bDescriptorType = USB_DT_ENDPOINT,
238-            .bEndpointAddress = 1 | USB_DIR_OUT,
239-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
240-            .wMaxPacketSize = MAX_PACKET_SIZE_HS,
241-        },
242-        .sink = {
243-            .bLength = sizeof(descriptors.hs_descs.sink),
244-            .bDescriptorType = USB_DT_ENDPOINT,
245-            .bEndpointAddress = 2 | USB_DIR_IN,
246-            .bmAttributes = USB_ENDPOINT_XFER_BULK,
247-            .wMaxPacketSize = MAX_PACKET_SIZE_HS,
248-        },
249+    .sink_comp = {
250+        .bLength = sizeof(ss_descriptors.sink_comp),
251+        .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
252+        .bMaxBurst = 4,
253     },
254 };
255
256+struct usb_ext_compat_desc os_desc_compat = {
257+    .bFirstInterfaceNumber = 0,
258+    .Reserved1 = cpu_to_le32(1),
259+    .CompatibleID = { 'W', 'I', 'N', 'U', 'S', 'B', '\0', '\0'},
260+    .SubCompatibleID = {0},
261+    .Reserved2 = {0},
262+};
263+
264+static struct usb_os_desc_header os_desc_header = {
265+    .interface = cpu_to_le32(0),
266+    .dwLength = cpu_to_le32(sizeof(os_desc_header) + sizeof(os_desc_compat)),
267+    .bcdVersion = cpu_to_le32(1),
268+    .wIndex = cpu_to_le32(4),
269+    .bCount = cpu_to_le32(1),
270+    .Reserved = cpu_to_le32(0),
271+};
272+
273+static struct usb_os_desc_header os_prop_header = {
274+    .interface = cpu_to_le32(0),
275+    .dwLength = cpu_to_le32(sizeof(os_desc_header) + sizeof(struct usb_ext_prop_values)),
276+    .bcdVersion = cpu_to_le32(1),
277+    .wIndex = cpu_to_le32(5),
278+    .wCount = cpu_to_le16(1),
279+};
280+
281 #define STR_INTERFACE_ "ADB Interface"
282
283 static const struct {
284@@ -151,8 +264,6 @@ static const struct {
285     },
286 };
287
288-
289-
290 static void *usb_adb_open_thread(void *x)
291 {
292     struct usb_handle *usb = (struct usb_handle *)x;
293@@ -270,6 +381,24 @@ static void usb_adb_init()
294 static void init_functionfs(struct usb_handle *h)
295 {
296     ssize_t ret;
297+    struct desc_v1 v1_descriptor = {};
298+    struct desc_v2 v2_descriptor = {};
299+
300+    v2_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
301+    v2_descriptor.header.length = cpu_to_le32(sizeof(v2_descriptor));
302+    v2_descriptor.header.flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC |
303+                                 FUNCTIONFS_HAS_SS_DESC | FUNCTIONFS_HAS_MS_OS_DESC;
304+    v2_descriptor.fs_count = 3;
305+    v2_descriptor.hs_count = 3;
306+    v2_descriptor.ss_count = 5;
307+    v2_descriptor.os_count = 2;
308+    v2_descriptor.fs_descs = fs_descriptors;
309+    v2_descriptor.hs_descs = hs_descriptors;
310+    v2_descriptor.ss_descs = ss_descriptors;
311+    v2_descriptor.os_header = os_desc_header;
312+    v2_descriptor.os_desc = os_desc_compat;
313+    v2_descriptor.os_prop_header = os_prop_header;
314+    v2_descriptor.os_prop_values.guid = os_desc_guid;
315
316     if (h->control < 0) { // might have already done this before
317         D("OPENING %s\n", USB_FFS_ADB_EP0);
318@@ -279,10 +408,20 @@ static void init_functionfs(struct usb_handle *h)
319             goto err;
320         }
321
322-        ret = adb_write(h->control, &descriptors, sizeof(descriptors));
323+        ret = adb_write(h->control, &v2_descriptor, sizeof(v2_descriptor));
324         if (ret < 0) {
325-            D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno);
326-            goto err;
327+            D("[ %s: write v2_descriptor failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno);
328+            v1_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC);
329+            v1_descriptor.header.length = cpu_to_le32(sizeof(v1_descriptor));
330+            v1_descriptor.header.fs_count = 3;
331+            v1_descriptor.header.hs_count = 3;
332+            v1_descriptor.fs_descs = fs_descriptors;
333+            v1_descriptor.hs_descs = hs_descriptors;
334+	    ret = adb_write(h->control, &v1_descriptor, sizeof(v1_descriptor));
335+	    if (ret < 0) {
336+		D("[ %s: failed to write USB descriptors]\n", USB_FFS_ADB_EP0);
337+		goto err;
338+	    }
339         }
340
341         ret = adb_write(h->control, &strings, sizeof(strings));
342--
3432.18.0
344
345