From: Lars-Peter Clausen Date: Tue, 3 Jul 2012 21:58:38 +0000 (+0200) Subject: sr: fx2lafw: Abort pending transfers when sampling is stopped X-Git-Tag: dsupstream~883 X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=0caa1ef0cb0b2231e232a7d1681e4e13fe838035;p=libsigrok.git sr: fx2lafw: Abort pending transfers when sampling is stopped The recent reworks of the fx2lafw made sure that the total buffer size is large enough hold 500ms of data. This was done to improve performance and stability. That the timeout value for a transfer was also increased to over 500ms, a side effect of this is that when sampling is stopped there will be a additional delay of 500ms. This is because the driver waits for all transfers to be freed before it sends a SR_DF_END packet. Once sampling has stopped this will only happen once a transfer times out. This patch cancels all pending transfers when sampling is stopped, this will cause them to be freed almost immediately and the additional delay will disappear. Also make sure, that if we know, that we just have received the last transfer to not resubmit this transfer again. Signed-off-by: Lars-Peter Clausen --- diff --git a/hardware/fx2lafw/fx2lafw.c b/hardware/fx2lafw/fx2lafw.c index 53a2e09f..28866133 100644 --- a/hardware/fx2lafw/fx2lafw.c +++ b/hardware/fx2lafw/fx2lafw.c @@ -662,7 +662,14 @@ static int receive_data(int fd, int revents, void *cb_data) static void abort_acquisition(struct context *ctx) { + unsigned int i; + ctx->num_samples = -1; + + for (i = 0; i < ctx->num_transfers; i++) { + if (ctx->transfers[i]) + libusb_cancel_transfer(ctx->transfers[i]); + } } static void finish_acquisition(struct context *ctx) @@ -680,16 +687,27 @@ static void finish_acquisition(struct context *ctx) for (i = 0; lupfd[i]; i++) sr_source_remove(lupfd[i]->fd); free(lupfd); /* NOT g_free()! */ + + ctx->num_transfers = 0; + g_free(ctx->transfers); } static void free_transfer(struct libusb_transfer *transfer) { struct context *ctx = transfer->user_data; + unsigned int i; g_free(transfer->buffer); transfer->buffer = NULL; libusb_free_transfer(transfer); + for (i = 0; i < ctx->num_transfers; i++) { + if (ctx->transfers[i] == transfer) { + ctx->transfers[i] = NULL; + break; + } + } + ctx->submitted_transfers--; if (ctx->submitted_transfers == 0) finish_acquisition(ctx); @@ -833,6 +851,8 @@ static void receive_transfer(struct libusb_transfer *transfer) if (ctx->limit_samples && (unsigned int)ctx->num_samples > ctx->limit_samples) { abort_acquisition(ctx); + free_transfer(transfer); + return; } } else { /* @@ -906,6 +926,12 @@ static int hw_dev_acquisition_start(int dev_index, void *cb_data) const unsigned int num_transfers = get_number_of_transfers(ctx); const size_t size = get_buffer_size(ctx); + ctx->transfers = g_try_malloc0(sizeof(*ctx->transfers) * num_transfers); + if (!ctx->transfers) + return SR_ERR; + + ctx->num_transfers = num_transfers; + for (i = 0; i < num_transfers; i++) { if (!(buf = g_try_malloc(size))) { sr_err("fx2lafw: %s: buf malloc failed.", __func__); @@ -921,7 +947,7 @@ static int hw_dev_acquisition_start(int dev_index, void *cb_data) g_free(buf); return SR_ERR; } - + ctx->transfers[i] = transfer; ctx->submitted_transfers++; } diff --git a/hardware/fx2lafw/fx2lafw.h b/hardware/fx2lafw/fx2lafw.h index 727c0fa6..ae3ed1bc 100644 --- a/hardware/fx2lafw/fx2lafw.h +++ b/hardware/fx2lafw/fx2lafw.h @@ -89,6 +89,9 @@ struct context { void *session_dev_id; struct sr_usb_dev_inst *usb; + + unsigned int num_transfers; + struct libusb_transfer **transfers; }; #endif