From 5e1901bf287e0ae917891386284f3903bf315926 Mon Sep 17 00:00:00 2001 From: Anatol Pomozov Date: Mon, 10 Oct 2022 10:47:57 -0700 Subject: [PATCH 2/3] 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 --- adb/client/usb_linux.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/adb/client/usb_linux.cpp b/adb/client/usb_linux.cpp index 81b8306..7d55ec5 100644 --- a/adb/client/usb_linux.cpp +++ b/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 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 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(); @@ -483,10 +483,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(); @@ -502,6 +502,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; @@ -537,6 +539,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; -- 2.20.1