diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2017-01-17 11:32:50 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2017-01-24 15:31:05 +0100 |
commit | eadba57d53f6512a15ac86f18713c18491175ac4 (patch) | |
tree | a18b940066a468c068c1ecdc7b0e9e180b471d27 /utils/hwstub/lib/hwstub_usb.cpp | |
parent | 24c208336c795adc1e111b03e86526c2cfde7a61 (diff) | |
download | rockbox-eadba57d53f6512a15ac86f18713c18491175ac4.tar.gz rockbox-eadba57d53f6512a15ac86f18713c18491175ac4.zip |
hwstub: fix long transfers failing because of control xfer size of libusb
libusb limits control transfer sizes to 4k, see diff for details.
Change-Id: Id2e638010274009ea641d06e9040a8b9ab9d54a9
Diffstat (limited to 'utils/hwstub/lib/hwstub_usb.cpp')
-rw-r--r-- | utils/hwstub/lib/hwstub_usb.cpp | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/utils/hwstub/lib/hwstub_usb.cpp b/utils/hwstub/lib/hwstub_usb.cpp index 2020af0804..e8b8e7bc3d 100644 --- a/utils/hwstub/lib/hwstub_usb.cpp +++ b/utils/hwstub/lib/hwstub_usb.cpp | |||
@@ -245,6 +245,15 @@ handle::~handle() | |||
245 | libusb_close(m_handle); | 245 | libusb_close(m_handle); |
246 | } | 246 | } |
247 | 247 | ||
248 | size_t handle::max_libusb_control_xfer_size() const | ||
249 | { | ||
250 | /* on Linux and Windows, libusb limits control transfers to 4k, this is not | ||
251 | * documented anywhere except in the source code, see libusb/os/linux_usbfs.h | ||
252 | * for MAX_CTRL_BUFFER_LENGTH. Obviously they didn't put it in the system | ||
253 | * header files... */ | ||
254 | return 4096; | ||
255 | } | ||
256 | |||
248 | error handle::interpret_libusb_error(int err) | 257 | error handle::interpret_libusb_error(int err) |
249 | { | 258 | { |
250 | if(err >= 0) | 259 | if(err >= 0) |
@@ -252,7 +261,10 @@ error handle::interpret_libusb_error(int err) | |||
252 | if(err == LIBUSB_ERROR_NO_DEVICE) | 261 | if(err == LIBUSB_ERROR_NO_DEVICE) |
253 | return error::DISCONNECTED; | 262 | return error::DISCONNECTED; |
254 | else | 263 | else |
264 | { | ||
265 | get_device()->get_context()->debug() << "[usb::handle] libusb error: " << err << "\n"; | ||
255 | return error::USB_ERROR; | 266 | return error::USB_ERROR; |
267 | } | ||
256 | } | 268 | } |
257 | 269 | ||
258 | error handle::interpret_libusb_error(int err, size_t expected_val) | 270 | error handle::interpret_libusb_error(int err, size_t expected_val) |
@@ -332,7 +344,10 @@ rb_handle::~rb_handle() | |||
332 | 344 | ||
333 | size_t rb_handle::get_buffer_size() | 345 | size_t rb_handle::get_buffer_size() |
334 | { | 346 | { |
335 | return m_buf_size; | 347 | /* We return slightly less because the usb protocol involves sending a header |
348 | * followed by the data, so it reduces the actual buffer size by the size | ||
349 | * of the header. To be safe, allow for a 128 bytes header. */ | ||
350 | return std::min(m_buf_size, max_libusb_control_xfer_size()) - 128; | ||
336 | } | 351 | } |
337 | 352 | ||
338 | error rb_handle::status() const | 353 | error rb_handle::status() const |
@@ -543,7 +558,9 @@ error jz_handle::probe() | |||
543 | m_desc_layout.dStackStart = 0; /* As far as I can tell, the ROM uses no stack */ | 558 | m_desc_layout.dStackStart = 0; /* As far as I can tell, the ROM uses no stack */ |
544 | m_desc_layout.dStackSize = 0; | 559 | m_desc_layout.dStackSize = 0; |
545 | m_desc_layout.dBufferStart = 0x080000000; | 560 | m_desc_layout.dBufferStart = 0x080000000; |
546 | m_desc_layout.dBufferSize = 0x4000; | 561 | /* max buffer size: leave some space for header so that header + data doesn't |
562 | * hit the limit */ | ||
563 | m_desc_layout.dBufferSize = max_libusb_control_xfer_size() - 128; | ||
547 | 564 | ||
548 | m_desc_target.bLength = sizeof(m_desc_target); | 565 | m_desc_target.bLength = sizeof(m_desc_target); |
549 | m_desc_target.bDescriptorType = HWSTUB_DT_TARGET; | 566 | m_desc_target.bDescriptorType = HWSTUB_DT_TARGET; |