X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Ffx2lafw%2Ffx2lafw.c;h=59ad5e73053fb111805b8e5af43535d842228254;hb=8489264f1e3ef07ba8f1143ed62fa88d90980f94;hp=53a2e09f025c03f0563fa1b9e75e75b20c5f6a57;hpb=2769eed9917aeb6e549b90be4925a4c192a92309;p=libsigrok.git diff --git a/hardware/fx2lafw/fx2lafw.c b/hardware/fx2lafw/fx2lafw.c index 53a2e09f..59ad5e73 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 { /* @@ -898,6 +918,10 @@ static int hw_dev_acquisition_start(int dev_index, void *cb_data) if (!(sdi = sr_dev_inst_get(dev_insts, dev_index))) return SR_ERR; ctx = sdi->priv; + + if (ctx->submitted_transfers != 0) + return SR_ERR; + ctx->session_dev_id = cb_data; ctx->num_samples = 0; ctx->empty_transfer_count = 0; @@ -906,6 +930,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__); @@ -916,12 +946,12 @@ static int hw_dev_acquisition_start(int dev_index, void *cb_data) 2 | LIBUSB_ENDPOINT_IN, buf, size, receive_transfer, ctx, timeout); if (libusb_submit_transfer(transfer) != 0) { - /* TODO: Free them all. */ libusb_free_transfer(transfer); g_free(buf); + abort_acquisition(ctx); return SR_ERR; } - + ctx->transfers[i] = transfer; ctx->submitted_transfers++; } @@ -946,6 +976,7 @@ static int hw_dev_acquisition_start(int dev_index, void *cb_data) if ((ret = command_start_acquisition (ctx->usb->devhdl, ctx->cur_samplerate, ctx->sample_wide)) != SR_OK) { + abort_acquisition(ctx); return ret; }