]> sigrok.org Git - libsigrok.git/blobdiff - hardware/fx2lafw/fx2lafw.c
hardware: Call libusb_error_name() in all USB-related error messages
[libsigrok.git] / hardware / fx2lafw / fx2lafw.c
index a6817340cc221f71ef20aba8cf89c5db6954c964..648b13f48cb0361712a59b8bf032f778b1503280 100644 (file)
@@ -23,7 +23,6 @@
 #include <string.h>
 #include <inttypes.h>
 #include <libusb.h>
-#include "config.h"
 #include "libsigrok.h"
 #include "libsigrok-internal.h"
 #include "fx2lafw.h"
@@ -144,8 +143,7 @@ static struct sr_dev_driver *fdi = &fx2lafw_driver_info;
 static int hw_dev_close(struct sr_dev_inst *sdi);
 static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap,
                const void *value);
-static int hw_dev_acquisition_stop(const struct sr_dev_inst *sdi,
-               void *cb_data);
+static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data);
 
 /**
  * Check the USB configuration to determine if this is an fx2lafw device.
@@ -195,13 +193,12 @@ static int fx2lafw_dev_open(struct sr_dev_inst *sdi)
 {
        libusb_device **devlist;
        struct libusb_device_descriptor des;
-       struct drv_context *drvc;
        struct dev_context *devc;
+       struct drv_context *drvc = fdi->priv;
        struct version_info vi;
        int ret, skip, i;
        uint8_t revid;
 
-       drvc = fdi->priv;
        devc = sdi->priv;
 
        if (sdi->status == SR_ST_ACTIVE)
@@ -209,7 +206,8 @@ static int fx2lafw_dev_open(struct sr_dev_inst *sdi)
                return SR_ERR;
 
        skip = 0;
-       const int device_count = libusb_get_device_list(drvc->usb_context, &devlist);
+       const int device_count = libusb_get_device_list(
+               drvc->sr_ctx->libusb_ctx, &devlist);
        if (device_count < 0) {
                sr_err("fx2lafw: Failed to retrieve device list (%d)",
                        device_count);
@@ -218,8 +216,8 @@ static int fx2lafw_dev_open(struct sr_dev_inst *sdi)
 
        for (i = 0; i < device_count; i++) {
                if ((ret = libusb_get_device_descriptor(devlist[i], &des))) {
-                       sr_err("fx2lafw: Failed to get device descriptor: %d.",
-                              ret);
+                       sr_err("fx2lafw: Failed to get device descriptor: %s.",
+                              libusb_error_name(ret));
                        continue;
                }
 
@@ -252,7 +250,8 @@ static int fx2lafw_dev_open(struct sr_dev_inst *sdi)
                                 */
                                devc->usb->address = libusb_get_device_address(devlist[i]);
                } else {
-                       sr_err("fx2lafw: Failed to open device: %d.", ret);
+                       sr_err("fx2lafw: Failed to open device: %s.",
+                              libusb_error_name(ret));
                        break;
                }
 
@@ -297,20 +296,22 @@ static int fx2lafw_dev_open(struct sr_dev_inst *sdi)
        return SR_OK;
 }
 
-static int configure_probes(struct dev_context *devc, GSList *probes)
+static int configure_probes(const struct sr_dev_inst *sdi)
 {
+       struct dev_context *devc;
        struct sr_probe *probe;
        GSList *l;
        int probe_bit, stage, i;
        char *tc;
 
+       devc = sdi->priv;
        for (i = 0; i < NUM_TRIGGER_STAGES; i++) {
                devc->trigger_mask[i] = 0;
                devc->trigger_value[i] = 0;
        }
 
        stage = -1;
-       for (l = probes; l; l = l->next) {
+       for (l = sdi->probes; l; l = l->next) {
                probe = (struct sr_probe *)l->data;
                if (probe->enabled == FALSE)
                        continue;
@@ -385,6 +386,7 @@ static int clear_instances(void)
                        continue;
                }
                hw_dev_close(sdi);
+               sr_usb_dev_inst_free(devc->usb);
                sdi = l->data;
                sr_dev_inst_free(sdi);
        }
@@ -400,21 +402,16 @@ static int clear_instances(void)
  * API callbacks
  */
 
-static int hw_init(void)
+static int hw_init(struct sr_context *sr_ctx)
 {
        struct drv_context *drvc;
 
        if (!(drvc = g_try_malloc0(sizeof(struct drv_context)))) {
                sr_err("fx2lafw: driver context malloc failed.");
-               return SR_ERR;
-       }
-
-       if (libusb_init(&drvc->usb_context) != 0) {
-               g_free(drvc);
-               sr_warn("fx2lafw: Failed to initialize libusb.");
-               return SR_ERR;
+               return SR_ERR_MALLOC;
        }
 
+       drvc->sr_ctx = sr_ctx;
        fdi->priv = drvc;
 
        return SR_OK;
@@ -432,8 +429,8 @@ static GSList *hw_scan(GSList *options)
        libusb_device **devlist;
        int devcnt, num_logic_probes, ret, i, j;
 
-       /* Avoid compiler warnings. */
        (void)options;
+
        drvc = fdi->priv;
 
        /* This scan always invalidates any previous scans. */
@@ -441,12 +438,13 @@ static GSList *hw_scan(GSList *options)
 
        /* Find all fx2lafw compatible devices and upload firmware to them. */
        devices = NULL;
-       libusb_get_device_list(drvc->usb_context, &devlist);
+       libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
        for (i = 0; devlist[i]; i++) {
 
                if ((ret = libusb_get_device_descriptor(
                     devlist[i], &des)) != 0) {
-                       sr_warn("fx2lafw: Failed to get device descriptor: %d.", ret);
+                       sr_warn("fx2lafw: Failed to get device descriptor: %s.",
+                               libusb_error_name(ret));
                        continue;
                }
 
@@ -508,6 +506,15 @@ static GSList *hw_scan(GSList *options)
        return devices;
 }
 
+static GSList *hw_dev_list(void)
+{
+       struct drv_context *drvc;
+
+       drvc = fdi->priv;
+
+       return drvc->instances;
+}
+
 static int hw_dev_open(struct sr_dev_inst *sdi)
 {
        struct dev_context *devc;
@@ -559,7 +566,8 @@ static int hw_dev_open(struct sr_dev_inst *sdi)
                        break;
 
                default:
-                       sr_err("fx2lafw: Unable to claim interface: %d.", ret);
+                       sr_err("fx2lafw: Unable to claim interface: %s.",
+                              libusb_error_name(ret));
                        break;
                }
 
@@ -604,10 +612,6 @@ static int hw_cleanup(void)
 
        ret = clear_instances();
 
-       if (drvc->usb_context)
-               libusb_exit(drvc->usb_context);
-       drvc->usb_context = NULL;
-
        g_free(drvc);
        fdi->priv = NULL;
 
@@ -666,8 +670,6 @@ static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap,
        if (hwcap == SR_HWCAP_SAMPLERATE) {
                devc->cur_samplerate = *(const uint64_t *)value;
                ret = SR_OK;
-       } else if (hwcap == SR_HWCAP_PROBECONFIG) {
-               ret = configure_probes(devc, (GSList *) value);
        } else if (hwcap == SR_HWCAP_LIMIT_SAMPLES) {
                devc->limit_samples = *(const uint64_t *)value;
                ret = SR_OK;
@@ -680,17 +682,15 @@ static int hw_dev_config_set(const struct sr_dev_inst *sdi, int hwcap,
 
 static int receive_data(int fd, int revents, void *cb_data)
 {
-       struct drv_context *drvc;
        struct timeval tv;
+       struct drv_context *drvc = fdi->priv;
 
-       /* Avoid compiler warnings. */
        (void)fd;
        (void)revents;
        (void)cb_data;
 
-       drvc = fdi->priv;
        tv.tv_sec = tv.tv_usec = 0;
-       libusb_handle_events_timeout(drvc->usb_context, &tv);
+       libusb_handle_events_timeout(drvc->sr_ctx->libusb_ctx, &tv);
 
        return TRUE;
 }
@@ -709,11 +709,10 @@ static void abort_acquisition(struct dev_context *devc)
 
 static void finish_acquisition(struct dev_context *devc)
 {
-       struct drv_context *drvc;
        struct sr_datafeed_packet packet;
+       struct drv_context *drvc = fdi->priv;
        int i;
 
-       drvc = fdi->priv;
 
        /* Terminate session */
        packet.type = SR_DF_END;
@@ -721,7 +720,7 @@ static void finish_acquisition(struct dev_context *devc)
 
        /* Remove fds from polling */
        const struct libusb_pollfd **const lupfd =
-               libusb_get_pollfds(drvc->usb_context);
+               libusb_get_pollfds(drvc->sr_ctx->libusb_ctx);
        for (i = 0; lupfd[i]; i++)
                sr_source_remove(lupfd[i]->fd);
        free(lupfd); /* NOT g_free()! */
@@ -754,12 +753,15 @@ static void free_transfer(struct libusb_transfer *transfer)
 
 static void resubmit_transfer(struct libusb_transfer *transfer)
 {
-       if (libusb_submit_transfer(transfer) != 0) {
-               free_transfer(transfer);
-               /* TODO: Stop session? */
-               /* TODO: Better error message. */
-               sr_err("fx2lafw: %s: libusb_submit_transfer error.", __func__);
-       }
+       int ret = libusb_submit_transfer(transfer);
+
+       if (LIBUSB_SUCCESS == ret)
+               return;
+
+       free_transfer(transfer);
+       /* TODO: Stop session? */
+
+       sr_err("fx2lafw: %s: %s", __func__, libusb_error_name(ret));
 }
 
 static void receive_transfer(struct libusb_transfer *transfer)
@@ -946,19 +948,23 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
        struct sr_datafeed_packet packet;
        struct sr_datafeed_header header;
        struct sr_datafeed_meta_logic meta;
-       struct drv_context *drvc;
        struct dev_context *devc;
+       struct drv_context *drvc = fdi->priv;
        struct libusb_transfer *transfer;
        const struct libusb_pollfd **lupfd;
        unsigned int i;
        int ret;
        unsigned char *buf;
 
-       drvc = fdi->priv;
        devc = sdi->priv;
        if (devc->submitted_transfers != 0)
                return SR_ERR;
 
+       if (configure_probes(sdi) != SR_OK) {
+               sr_err("fx2lafw: failed to configured probes");
+               return SR_ERR;
+       }
+
        devc->session_dev_id = cb_data;
        devc->num_samples = 0;
        devc->empty_transfer_count = 0;
@@ -968,8 +974,10 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
        const size_t size = get_buffer_size(devc);
 
        devc->transfers = g_try_malloc0(sizeof(*devc->transfers) * num_transfers);
-       if (!devc->transfers)
-               return SR_ERR;
+       if (!devc->transfers) {
+               sr_err("fx2lafw: USB transfers malloc failed.");
+               return SR_ERR_MALLOC;
+       }
 
        devc->num_transfers = num_transfers;
 
@@ -982,7 +990,9 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
                libusb_fill_bulk_transfer(transfer, devc->usb->devhdl,
                                2 | LIBUSB_ENDPOINT_IN, buf, size,
                                receive_transfer, devc, timeout);
-               if (libusb_submit_transfer(transfer) != 0) {
+               if ((ret = libusb_submit_transfer(transfer)) != 0) {
+                       sr_err("fx2lafw: %s: libusb_submit_transfer: %s.",
+                              __func__, libusb_error_name(ret));
                        libusb_free_transfer(transfer);
                        g_free(buf);
                        abort_acquisition(devc);
@@ -992,7 +1002,7 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
                devc->submitted_transfers++;
        }
 
-       lupfd = libusb_get_pollfds(drvc->usb_context);
+       lupfd = libusb_get_pollfds(drvc->sr_ctx->libusb_ctx);
        for (i = 0; lupfd[i]; i++)
                sr_source_add(lupfd[i]->fd, lupfd[i]->events,
                              timeout, receive_data, NULL);
@@ -1021,11 +1031,8 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi,
 }
 
 /* TODO: This stops acquisition on ALL devices, ignoring dev_index. */
-static int hw_dev_acquisition_stop(const struct sr_dev_inst *sdi,
-               void *cb_data)
+static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
 {
-
-       /* Avoid compiler warnings. */
        (void)cb_data;
 
        abort_acquisition(sdi->priv);
@@ -1040,6 +1047,8 @@ SR_PRIV struct sr_dev_driver fx2lafw_driver_info = {
        .init = hw_init,
        .cleanup = hw_cleanup,
        .scan = hw_scan,
+       .dev_list = hw_dev_list,
+       .dev_clear = clear_instances,
        .dev_open = hw_dev_open,
        .dev_close = hw_dev_close,
        .info_get = hw_info_get,