1From 02b6b6977d80af4b9b806054fadb5a06cedf011d Mon Sep 17 00:00:00 2001 2From: Etienne Cordonnier <ecordonnier@snap.com> 3Date: Tue, 14 Mar 2023 11:33:50 +0100 4Subject: [PATCH] Update usage of usbdevfs_urb to match new kernel UAPI 5MIME-Version: 1.0 6Content-Type: text/plain; charset=UTF-8 7Content-Transfer-Encoding: 8bit 8 9Linux kernel API has been changed by commit 94dfc73e7cf4 ("treewide: uapi: Replace zero-length arrays with flexible-array members") 10where zero-length array iso_frame_desc in struct usbdevfs_urb was replaced with a proper flexible-array member. 11 12Current USB API usage causes a compilation error at Linux 6.0: 13 14In file included from /home/mae/.cache/kiss/proc/121205/build/android-tools/vendor/adb/client/usb_linux.cpp:28: 15/usr/include/linux/usbdevice_fs.h:134:41: error: flexible array member ‘usbdevfs_urb::iso_frame_desc’ not at end of ‘struct usb_handle’ 16 134 | struct usbdevfs_iso_packet_desc iso_frame_desc[]; 17 | ^~~~~~~~~~~~~~ 18/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 19 76 | usbdevfs_urb urb_out; 20 | ^~~~~~~ 21/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’ 22 61 | struct usb_handle { 23 | ^~~~~~~~~~ 24 25Fix it by using pointers to a struct with flexible-array members. 26Current fix works both with the old and the new API. 27 28See https://github.com/nmeum/android-tools/issues/74 for more context. 29 30Tested: built on Linux against kernel 5.19 and 6.0; 'adb shell' over USB 31cable 32Acked-by: Gustavo A. R. Silva gustavoars@kernel.org 33Change-Id: I7f0f7b35d9a3ab980d3520b541b60c7857a6b101 34Signed-off-by: Anatol Pomozov <anatol.pomozov@gmail.com> 35 36[Backported on version 10] 37Signed-off-by: Etienne Cordonnier <ecordonnier@snap.com> 38 39--- 40 system/core/adb/client/usb_linux.cpp | 24 ++++++++++++++---------- 41 1 file changed, 14 insertions(+), 10 deletions(-) 42 43diff --git a/system/core/adb/client/usb_linux.cpp b/system/core/adb/client/usb_linux.cpp 44index 343e7b59..6a4479f3 100644 45--- a/system/core/adb/client/usb_linux.cpp 46+++ b/system/core/adb/client/usb_linux.cpp 47@@ -71,8 +71,8 @@ struct usb_handle : public ::usb_handle { 48 unsigned zero_mask; 49 unsigned writeable = 1; 50 51- usbdevfs_urb urb_in; 52- usbdevfs_urb urb_out; 53+ usbdevfs_urb *urb_in; 54+ usbdevfs_urb *urb_out; 55 56 bool urb_in_busy = false; 57 bool urb_out_busy = false; 58@@ -305,7 +305,7 @@ static int usb_bulk_write(usb_handle* h, const void* data, int len) { 59 std::unique_lock<std::mutex> lock(h->mutex); 60 D("++ usb_bulk_write ++"); 61 62- usbdevfs_urb* urb = &h->urb_out; 63+ usbdevfs_urb* urb = h->urb_out; 64 memset(urb, 0, sizeof(*urb)); 65 urb->type = USBDEVFS_URB_TYPE_BULK; 66 urb->endpoint = h->ep_out; 67@@ -344,7 +344,7 @@ static int usb_bulk_read(usb_handle* h, void* data, int len) { 68 std::unique_lock<std::mutex> lock(h->mutex); 69 D("++ usb_bulk_read ++"); 70 71- usbdevfs_urb* urb = &h->urb_in; 72+ usbdevfs_urb* urb = h->urb_in; 73 memset(urb, 0, sizeof(*urb)); 74 urb->type = USBDEVFS_URB_TYPE_BULK; 75 urb->endpoint = h->ep_in; 76@@ -389,7 +389,7 @@ static int usb_bulk_read(usb_handle* h, void* data, int len) { 77 } 78 D("[ urb @%p status = %d, actual = %d ]", out, out->status, out->actual_length); 79 80- if (out == &h->urb_in) { 81+ if (out == h->urb_in) { 82 D("[ reap urb - IN complete ]"); 83 h->urb_in_busy = false; 84 if (urb->status != 0) { 85@@ -398,7 +398,7 @@ static int usb_bulk_read(usb_handle* h, void* data, int len) { 86 } 87 return urb->actual_length; 88 } 89- if (out == &h->urb_out) { 90+ if (out == h->urb_out) { 91 D("[ reap urb - OUT compelete ]"); 92 h->urb_out_busy = false; 93 h->cv.notify_all(); 94@@ -502,10 +502,10 @@ void usb_kick(usb_handle* h) { 95 ** but this ensures that a reader blocked on REAPURB 96 ** will get unblocked 97 */ 98- ioctl(h->fd, USBDEVFS_DISCARDURB, &h->urb_in); 99- ioctl(h->fd, USBDEVFS_DISCARDURB, &h->urb_out); 100- h->urb_in.status = -ENODEV; 101- h->urb_out.status = -ENODEV; 102+ ioctl(h->fd, USBDEVFS_DISCARDURB, h->urb_in); 103+ ioctl(h->fd, USBDEVFS_DISCARDURB, h->urb_out); 104+ h->urb_in->status = -ENODEV; 105+ h->urb_out->status = -ENODEV; 106 h->urb_in_busy = false; 107 h->urb_out_busy = false; 108 h->cv.notify_all(); 109@@ -521,6 +521,8 @@ int usb_close(usb_handle* h) { 110 111 D("-- usb close %p (fd = %d) --", h, h->fd); 112 113+ delete h->urb_in; 114+ delete h->urb_out; 115 delete h; 116 117 return 0; 118@@ -556,6 +558,8 @@ static void register_device(const char* dev_name, const char* dev_path, unsigned 119 usb->ep_out = ep_out; 120 usb->zero_mask = zero_mask; 121 usb->max_packet_size = max_packet_size; 122+ usb->urb_in = new usbdevfs_urb; 123+ usb->urb_out = new usbdevfs_urb; 124 125 // Initialize mark so we don't get garbage collected after the device scan. 126 usb->mark = true; 127