X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Ffx2lafw%2Ffx2lafw.c;h=4344cf24199e4913b3313d09fafb89abe58f26e1;hb=dd34b8d3c4da18f8cf339c5bb8f0d6268f3d13f6;hp=53a2e09f025c03f0563fa1b9e75e75b20c5f6a57;hpb=2769eed9917aeb6e549b90be4925a4c192a92309;p=libsigrok.git diff --git a/hardware/fx2lafw/fx2lafw.c b/hardware/fx2lafw/fx2lafw.c index 53a2e09f..4344cf24 100644 --- a/hardware/fx2lafw/fx2lafw.c +++ b/hardware/fx2lafw/fx2lafw.c @@ -24,8 +24,8 @@ #include #include #include "config.h" -#include "sigrok.h" -#include "sigrok-internal.h" +#include "libsigrok.h" +#include "libsigrok-internal.h" #include "fx2lafw.h" #include "command.h" @@ -38,6 +38,13 @@ static const struct fx2lafw_profile supported_fx2[] = { { 0x08a9, 0x0014, "CWAV", "USBee AX", NULL, FIRMWARE_DIR "/fx2lafw-cwav-usbeeax.fw", 0 }, + /* + * CWAV USBee DX + * XZL-Studio DX + */ + { 0x08a9, 0x0015, "CWAV", "USBee DX", NULL, + FIRMWARE_DIR "/fx2lafw-cwav-usbeedx.fw", + DEV_CAPS_16BIT }, /* * CWAV USBee SX @@ -375,26 +382,28 @@ static struct context *fx2lafw_dev_new(void) * API callbacks */ -static int hw_init(const char *devinfo) +static int hw_init(void) +{ + + if (libusb_init(&usb_context) != 0) { + sr_warn("fx2lafw: Failed to initialize libusb."); + return SR_ERR; + } + + return SR_OK; +} + +static int hw_scan(void) { struct sr_dev_inst *sdi; struct libusb_device_descriptor des; const struct fx2lafw_profile *prof; struct context *ctx; libusb_device **devlist; - int ret; - int devcnt = 0; - int i, j; - - /* Avoid compiler warnings. */ - (void)devinfo; - - if (libusb_init(&usb_context) != 0) { - sr_warn("fx2lafw: Failed to initialize libusb."); - return 0; - } + int devcnt, ret, i, j; /* Find all fx2lafw compatible devices and upload firmware to them. */ + devcnt = 0; libusb_get_device_list(usb_context, &devlist); for (i = 0; devlist[i]; i++) { @@ -662,7 +671,14 @@ static int receive_data(int fd, int revents, void *cb_data) static void abort_acquisition(struct context *ctx) { + int i; + ctx->num_samples = -1; + + for (i = ctx->num_transfers - 1; i >= 0; i--) { + if (ctx->transfers[i]) + libusb_cancel_transfer(ctx->transfers[i]); + } } static void finish_acquisition(struct context *ctx) @@ -680,16 +696,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 +860,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 +927,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 +939,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 +955,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 +985,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; } @@ -974,6 +1014,7 @@ SR_PRIV struct sr_dev_driver fx2lafw_driver_info = { .api_version = 1, .init = hw_init, .cleanup = hw_cleanup, + .scan = hw_scan, .dev_open = hw_dev_open, .dev_close = hw_dev_close, .dev_info_get = hw_dev_info_get,