aboutsummaryrefslogtreecommitdiffstats
path: root/meta-oe/dynamic-layers/selinux/recipes-devtool/android-tools/android-tools/0003-Update-usage-of-usbdevfs_urb-to-match-new-kernel-UAP.patch
blob: 7ea040c68a1f34e8653fd5d249ab7747da54c85f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
From 02b6b6977d80af4b9b806054fadb5a06cedf011d Mon Sep 17 00:00:00 2001
From: Etienne Cordonnier <ecordonnier@snap.com>
Date: Tue, 14 Mar 2023 11:33:50 +0100
Subject: [PATCH] Update usage of usbdevfs_urb to match new kernel UAPI
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Linux kernel API has been changed by commit 94dfc73e7cf4 ("treewide: uapi: Replace zero-length arrays with flexible-array members")
where zero-length array iso_frame_desc in struct usbdevfs_urb was replaced with a proper flexible-array member.

Current USB API usage causes a compilation error at Linux 6.0:

In file included from /home/mae/.cache/kiss/proc/121205/build/android-tools/vendor/adb/client/usb_linux.cpp:28:
/usr/include/linux/usbdevice_fs.h:134:41: error: flexible array member ‘usbdevfs_urb::iso_frame_desc’ not at end of ‘struct usb_handle’
  134 |         struct usbdevfs_iso_packet_desc iso_frame_desc[];
      |                                         ^~~~~~~~~~~~~~
/home/mae/.cache/kiss/proc/121205/build/android-tools/vendor/adb/client/usb_linux.cpp:76:18: note: next member ‘usbdevfs_urb usb_handle::urb_out’ declared here
   76 |     usbdevfs_urb urb_out;
      |                  ^~~~~~~
/home/mae/.cache/kiss/proc/121205/build/android-tools/vendor/adb/client/usb_linux.cpp:61:8: note: in the definition of ‘struct usb_handle’
   61 | struct usb_handle {
      |        ^~~~~~~~~~

Fix it by using pointers to a struct with flexible-array members.
Current fix works both with the old and the new API.

See https://github.com/nmeum/android-tools/issues/74 for more context.

Tested: built on Linux against kernel 5.19 and 6.0; 'adb shell' over USB
cable
Acked-by: Gustavo A. R. Silva gustavoars@kernel.org
Change-Id: I7f0f7b35d9a3ab980d3520b541b60c7857a6b101
Signed-off-by: Anatol Pomozov <anatol.pomozov@gmail.com>

[Backported on version 10]
Signed-off-by: Etienne Cordonnier <ecordonnier@snap.com>

---
 system/core/adb/client/usb_linux.cpp | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/system/core/adb/client/usb_linux.cpp b/system/core/adb/client/usb_linux.cpp
index 343e7b59..6a4479f3 100644
--- a/system/core/adb/client/usb_linux.cpp
+++ b/system/core/adb/client/usb_linux.cpp
@@ -71,8 +71,8 @@ struct usb_handle : public ::usb_handle {
     unsigned zero_mask;
     unsigned writeable = 1;
 
-    usbdevfs_urb urb_in;
-    usbdevfs_urb urb_out;
+    usbdevfs_urb *urb_in;
+    usbdevfs_urb *urb_out;
 
     bool urb_in_busy = false;
     bool urb_out_busy = false;
@@ -305,7 +305,7 @@ static int usb_bulk_write(usb_handle* h, const void* data, int len) {
     std::unique_lock<std::mutex> lock(h->mutex);
     D("++ usb_bulk_write ++");
 
-    usbdevfs_urb* urb = &h->urb_out;
+    usbdevfs_urb* urb = h->urb_out;
     memset(urb, 0, sizeof(*urb));
     urb->type = USBDEVFS_URB_TYPE_BULK;
     urb->endpoint = h->ep_out;
@@ -344,7 +344,7 @@ static int usb_bulk_read(usb_handle* h, void* data, int len) {
     std::unique_lock<std::mutex> lock(h->mutex);
     D("++ usb_bulk_read ++");
 
-    usbdevfs_urb* urb = &h->urb_in;
+    usbdevfs_urb* urb = h->urb_in;
     memset(urb, 0, sizeof(*urb));
     urb->type = USBDEVFS_URB_TYPE_BULK;
     urb->endpoint = h->ep_in;
@@ -389,7 +389,7 @@ static int usb_bulk_read(usb_handle* h, void* data, int len) {
         }
         D("[ urb @%p status = %d, actual = %d ]", out, out->status, out->actual_length);
 
-        if (out == &h->urb_in) {
+        if (out == h->urb_in) {
             D("[ reap urb - IN complete ]");
             h->urb_in_busy = false;
             if (urb->status != 0) {
@@ -398,7 +398,7 @@ static int usb_bulk_read(usb_handle* h, void* data, int len) {
             }
             return urb->actual_length;
         }
-        if (out == &h->urb_out) {
+        if (out == h->urb_out) {
             D("[ reap urb - OUT compelete ]");
             h->urb_out_busy = false;
             h->cv.notify_all();
@@ -502,10 +502,10 @@ void usb_kick(usb_handle* h) {
             ** but this ensures that a reader blocked on REAPURB
             ** will get unblocked
             */
-            ioctl(h->fd, USBDEVFS_DISCARDURB, &h->urb_in);
-            ioctl(h->fd, USBDEVFS_DISCARDURB, &h->urb_out);
-            h->urb_in.status = -ENODEV;
-            h->urb_out.status = -ENODEV;
+            ioctl(h->fd, USBDEVFS_DISCARDURB, h->urb_in);
+            ioctl(h->fd, USBDEVFS_DISCARDURB, h->urb_out);
+            h->urb_in->status = -ENODEV;
+            h->urb_out->status = -ENODEV;
             h->urb_in_busy = false;
             h->urb_out_busy = false;
             h->cv.notify_all();
@@ -521,6 +521,8 @@ int usb_close(usb_handle* h) {
 
     D("-- usb close %p (fd = %d) --", h, h->fd);
 
+    delete h->urb_in;
+    delete h->urb_out;
     delete h;
 
     return 0;
@@ -556,6 +558,8 @@ static void register_device(const char* dev_name, const char* dev_path, unsigned
     usb->ep_out = ep_out;
     usb->zero_mask = zero_mask;
     usb->max_packet_size = max_packet_size;
+    usb->urb_in = new usbdevfs_urb;
+    usb->urb_out = new usbdevfs_urb;
 
     // Initialize mark so we don't get garbage collected after the device scan.
     usb->mark = true;