diff options
-rw-r--r-- | utils/hwstub/include/hwstub_usb.hpp | 4 | ||||
-rw-r--r-- | utils/hwstub/lib/hwstub_usb.cpp | 21 |
2 files changed, 23 insertions, 2 deletions
diff --git a/utils/hwstub/include/hwstub_usb.hpp b/utils/hwstub/include/hwstub_usb.hpp index 15a0fcaaec..579594067c 100644 --- a/utils/hwstub/include/hwstub_usb.hpp +++ b/utils/hwstub/include/hwstub_usb.hpp | |||
@@ -101,6 +101,10 @@ public: | |||
101 | void set_timeout(std::chrono::milliseconds ms); | 101 | void set_timeout(std::chrono::milliseconds ms); |
102 | 102 | ||
103 | protected: | 103 | protected: |
104 | /* return the maximum size of a libusb control transfer, this is a "known" | ||
105 | * limitation that is completely undocumented (sigh) and applies at least | ||
106 | * to linux and windows hosts */ | ||
107 | size_t max_libusb_control_xfer_size() const; | ||
104 | /* interpret libusb error: >=0 means SUCCESS, others are treated as errors, | 108 | /* interpret libusb error: >=0 means SUCCESS, others are treated as errors, |
105 | * LIBUSB_ERROR_NO_DEVICE is treated as DISCONNECTED */ | 109 | * LIBUSB_ERROR_NO_DEVICE is treated as DISCONNECTED */ |
106 | error interpret_libusb_error(int err); | 110 | error interpret_libusb_error(int err); |
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; |