Loading fastboot/usb_linux.cpp +38 −20 Original line number Diff line number Diff line Loading @@ -83,7 +83,18 @@ using namespace std::chrono_literals; // be reliable. // 256KiB seems to work, but 1MiB bulk transfers lock up my z620 with a 3.13 // kernel. #define MAX_USBFS_BULK_SIZE (16 * 1024) // 128KiB was experimentally found to be enough to saturate the bus at // SuperSpeed+, so we first try double that for writes. If the operation fails // due to a lack of contiguous regions (or an ancient kernel), try smaller sizes // until we find one that works (see LinuxUsbTransport::Write). Reads are less // performance critical so for now just use a known good size. #define MAX_USBFS_BULK_WRITE_SIZE (256 * 1024) #define MAX_USBFS_BULK_READ_SIZE (16 * 1024) // This size should pretty much always work (it's compatible with pre-3.3 // kernels and it's what we used to use historically), so if it doesn't work // something has gone badly wrong. #define MIN_USBFS_BULK_WRITE_SIZE (16 * 1024) struct usb_handle { Loading @@ -108,6 +119,7 @@ class LinuxUsbTransport : public UsbTransport { private: std::unique_ptr<usb_handle> handle_; const uint32_t ms_timeout_; size_t max_usbfs_bulk_write_size_ = MAX_USBFS_BULK_WRITE_SIZE; DISALLOW_COPY_AND_ASSIGN(LinuxUsbTransport); }; Loading Loading @@ -415,7 +427,8 @@ ssize_t LinuxUsbTransport::Write(const void* _data, size_t len) } auto submit_urb = [&](size_t i) { int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len; while (true) { int xfer = (len > max_usbfs_bulk_write_size_) ? max_usbfs_bulk_write_size_ : len; urb[i].type = USBDEVFS_URB_TYPE_BULK; urb[i].endpoint = handle_->ep_out; Loading @@ -425,6 +438,10 @@ ssize_t LinuxUsbTransport::Write(const void* _data, size_t len) int n = ioctl(handle_->desc, USBDEVFS_SUBMITURB, &urb[i]); if (n != 0) { if (errno == ENOMEM && max_usbfs_bulk_write_size_ > MIN_USBFS_BULK_WRITE_SIZE) { max_usbfs_bulk_write_size_ /= 2; continue; } DBG("ioctl(USBDEVFS_SUBMITURB) failed\n"); return false; } Loading @@ -435,6 +452,7 @@ ssize_t LinuxUsbTransport::Write(const void* _data, size_t len) data += xfer; return true; } }; auto reap_urb = [&](size_t i) { Loading Loading @@ -500,7 +518,7 @@ ssize_t LinuxUsbTransport::Read(void* _data, size_t len) } while (len > 0) { int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len; int xfer = (len > MAX_USBFS_BULK_READ_SIZE) ? MAX_USBFS_BULK_READ_SIZE : len; bulk.ep = handle_->ep_in; bulk.len = xfer; Loading Loading
fastboot/usb_linux.cpp +38 −20 Original line number Diff line number Diff line Loading @@ -83,7 +83,18 @@ using namespace std::chrono_literals; // be reliable. // 256KiB seems to work, but 1MiB bulk transfers lock up my z620 with a 3.13 // kernel. #define MAX_USBFS_BULK_SIZE (16 * 1024) // 128KiB was experimentally found to be enough to saturate the bus at // SuperSpeed+, so we first try double that for writes. If the operation fails // due to a lack of contiguous regions (or an ancient kernel), try smaller sizes // until we find one that works (see LinuxUsbTransport::Write). Reads are less // performance critical so for now just use a known good size. #define MAX_USBFS_BULK_WRITE_SIZE (256 * 1024) #define MAX_USBFS_BULK_READ_SIZE (16 * 1024) // This size should pretty much always work (it's compatible with pre-3.3 // kernels and it's what we used to use historically), so if it doesn't work // something has gone badly wrong. #define MIN_USBFS_BULK_WRITE_SIZE (16 * 1024) struct usb_handle { Loading @@ -108,6 +119,7 @@ class LinuxUsbTransport : public UsbTransport { private: std::unique_ptr<usb_handle> handle_; const uint32_t ms_timeout_; size_t max_usbfs_bulk_write_size_ = MAX_USBFS_BULK_WRITE_SIZE; DISALLOW_COPY_AND_ASSIGN(LinuxUsbTransport); }; Loading Loading @@ -415,7 +427,8 @@ ssize_t LinuxUsbTransport::Write(const void* _data, size_t len) } auto submit_urb = [&](size_t i) { int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len; while (true) { int xfer = (len > max_usbfs_bulk_write_size_) ? max_usbfs_bulk_write_size_ : len; urb[i].type = USBDEVFS_URB_TYPE_BULK; urb[i].endpoint = handle_->ep_out; Loading @@ -425,6 +438,10 @@ ssize_t LinuxUsbTransport::Write(const void* _data, size_t len) int n = ioctl(handle_->desc, USBDEVFS_SUBMITURB, &urb[i]); if (n != 0) { if (errno == ENOMEM && max_usbfs_bulk_write_size_ > MIN_USBFS_BULK_WRITE_SIZE) { max_usbfs_bulk_write_size_ /= 2; continue; } DBG("ioctl(USBDEVFS_SUBMITURB) failed\n"); return false; } Loading @@ -435,6 +452,7 @@ ssize_t LinuxUsbTransport::Write(const void* _data, size_t len) data += xfer; return true; } }; auto reap_urb = [&](size_t i) { Loading Loading @@ -500,7 +518,7 @@ ssize_t LinuxUsbTransport::Read(void* _data, size_t len) } while (len > 0) { int xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len; int xfer = (len > MAX_USBFS_BULK_READ_SIZE) ? MAX_USBFS_BULK_READ_SIZE : len; bulk.ep = handle_->ep_in; bulk.len = xfer; Loading