* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
err = libusb_open(device, &ctx->usb_dev);
if (err != LIBUSB_SUCCESS) {
- LOG_ERROR("libusb_open() failed with %d", err);
+ LOG_ERROR("libusb_open() failed with %s",
+ libusb_error_name(err));
continue;
}
case 0x800:
ctx->type = TYPE_FT4232H;
break;
+ case 0x900:
+ ctx->type = TYPE_FT232H;
+ break;
default:
LOG_ERROR("unsupported FTDI chip type: 0x%04x", desc.bcdDevice);
goto error;
while (length > 0) {
/* Guarantee buffer space enough for a minimum size transfer */
- if (buffer_write_space(ctx) + (length < 8) < (out ? 4 : 3)
- || (in && buffer_read_space(ctx) < 1))
+ if (buffer_write_space(ctx) + (length < 8) < (out || (!out && !in) ? 4 : 3)
+ || (in && buffer_read_space(ctx) < 1))
retval = mpsse_flush(ctx);
if (length < 8) {
if (this_bytes > 65536)
this_bytes = 65536;
/* Buffer space limit. We already made sure there's space for the minimum
- *transfer. */
- if (out && this_bytes + 3 > buffer_write_space(ctx))
+ * transfer. */
+ if ((out || (!out && !in)) && this_bytes + 3 > buffer_write_space(ctx))
this_bytes = buffer_write_space(ctx) - 3;
if (in && this_bytes > buffer_read_space(ctx))
this_bytes = buffer_read_space(ctx);
if (ctx->read_count) {
buffer_write_byte(ctx, 0x87); /* SEND_IMMEDIATE */
read_result.done = false;
- read_transfer = libusb_alloc_transfer(0);
- libusb_fill_bulk_transfer(read_transfer, ctx->usb_dev, ctx->in_ep, ctx->read_chunk,
- ctx->read_chunk_size, read_cb, &read_result,
- ctx->usb_read_timeout);
- retval = libusb_submit_transfer(read_transfer);
+ /* delay read transaction to ensure the FTDI chip can support us with data
+ immediately after processing the MPSSE commands in the write transaction */
}
struct transfer_result write_result = { .ctx = ctx, .done = false };
ctx->write_count, write_cb, &write_result, ctx->usb_write_timeout);
retval = libusb_submit_transfer(write_transfer);
+ if (ctx->read_count) {
+ read_transfer = libusb_alloc_transfer(0);
+ libusb_fill_bulk_transfer(read_transfer, ctx->usb_dev, ctx->in_ep, ctx->read_chunk,
+ ctx->read_chunk_size, read_cb, &read_result,
+ ctx->usb_read_timeout);
+ retval = libusb_submit_transfer(read_transfer);
+ }
+
/* Polling loop, more or less taken from libftdi */
while (!write_result.done || !read_result.done) {
retval = libusb_handle_events(ctx->usb_ctx);