]> sigrok.org Git - libsigrok.git/commitdiff
ftdi-la: Cleanup ftdi_context handling
authorLars-Peter Clausen <redacted>
Sat, 14 May 2016 15:24:27 +0000 (17:24 +0200)
committerUwe Hermann <redacted>
Wed, 18 May 2016 15:42:52 +0000 (17:42 +0200)
Signed-off-by: Lars-Peter Clausen <redacted>
src/hardware/ftdi-la/api.c
src/hardware/ftdi-la/protocol.h

index 34f79bf71b71d0066621a422f3cfa45b27a756b5..c3c3891fc500f16d662f30292ba5929c029316cc 100644 (file)
@@ -82,7 +82,8 @@ static const struct ftdi_chip_desc *chip_descs[] = {
        &ft232r_desc,
 };
 
-static void scan_device(struct sr_dev_driver *di, struct libusb_device *dev, GSList **devices)
+static void scan_device(struct sr_dev_driver *di, struct ftdi_context *ftdic,
+       struct libusb_device *dev, GSList **devices)
 {
        struct libusb_device_descriptor usb_desc;
        const struct ftdi_chip_desc *desc;
@@ -115,20 +116,15 @@ static void scan_device(struct sr_dev_driver *di, struct libusb_device *dev, GSL
        /* Allocate memory for the incoming data. */
        devc->data_buf = g_malloc0(DATA_BUF_SIZE);
 
-       /* Allocate memory for the FTDI context (ftdic) and initialize it. */
-       devc->ftdic = ftdi_new();
-       if (!devc->ftdic) {
-               sr_err("Failed to initialize libftdi.");
-               goto err_free_data_buf;
-       }
+       snprintf(devc->address, sizeof(devc->address), "d:%u/%u",
+               libusb_get_bus_number(dev), libusb_get_device_address(dev));
 
-       devc->usbdev = dev;
        devc->desc = desc;
 
        vendor = g_malloc(32);
        model = g_malloc(32);
        serial_num = g_malloc(32);
-       rv = ftdi_usb_get_strings(devc->ftdic, dev, vendor, 32,
+       rv = ftdi_usb_get_strings(ftdic, dev, vendor, 32,
                             model, 32, serial_num, 32);
        switch (rv) {
        case 0:
@@ -165,59 +161,45 @@ err_free_strings:
        g_free(vendor);
        g_free(model);
        g_free(serial_num);
-       ftdi_free(devc->ftdic);
-err_free_data_buf:
        g_free(devc->data_buf);
        g_free(devc);
 }
 
-static GSList *scan_all(struct sr_dev_driver *di, GSList *options)
+static GSList *scan_all(struct ftdi_context *ftdic, struct sr_dev_driver *di,
+       GSList *options)
 {
        GSList *devices;
        struct ftdi_device_list *devlist = 0;
        struct ftdi_device_list *curdev;
-       struct ftdi_context *ftdic;
        int ret;
 
        (void)options;
 
        devices = NULL;
 
-       /* Allocate memory for the FTDI context (ftdic) and initialize it. */
-       ftdic = ftdi_new();
-       if (!ftdic) {
-               sr_err("Failed to initialize libftdi.");
-               return NULL;
-       }
-
        ret = ftdi_usb_find_all(ftdic, &devlist, 0, 0);
        if (ret < 0) {
                sr_err("Failed to list devices (%d): %s", ret,
                       ftdi_get_error_string(ftdic));
-               goto err_free_ftdic;
+               return NULL;
        }
 
        sr_dbg("Number of FTDI devices found: %d", ret);
 
        curdev = devlist;
        while (curdev) {
-               scan_device(di, curdev->dev, &devices);
+               scan_device(di, ftdic, curdev->dev, &devices);
                curdev = curdev->next;
        }
 
        ftdi_list_free(&devlist);
-       ftdi_free(ftdic);
 
        return devices;
-
-err_free_ftdic:
-       ftdi_free(ftdic); /* NOT free() or g_free()! */
-
-       return NULL;
 }
 
 static GSList *scan(struct sr_dev_driver *di, GSList *options)
 {
+       struct ftdi_context *ftdic;
        struct sr_config *src;
        struct sr_usb_dev_inst *usb;
        const char *conn;
@@ -237,6 +219,14 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
                        break;
                }
        }
+
+       /* Allocate memory for the FTDI context (ftdic) and initialize it. */
+       ftdic = ftdi_new();
+       if (!ftdic) {
+               sr_err("Failed to initialize libftdi.");
+               return NULL;
+       }
+
        if (conn) {
                devices = NULL;
                libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
@@ -246,14 +236,17 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
                                usb = l->data;
                                if (usb->bus == libusb_get_bus_number(devlist[i])
                                        && usb->address == libusb_get_device_address(devlist[i])) {
-                                       scan_device(di, devlist[i], &devices);
+                                       scan_device(di, ftdic, devlist[i], &devices);
                                }
                        }
                }
                libusb_free_device_list(devlist, 1);
-               return devices;
        } else
-               return scan_all(di, options);
+               devices = scan_all(ftdic, di, options);
+
+       ftdi_free(ftdic);
+
+       return devices;
 }
 
 static void clear_helper(void *priv)
@@ -261,8 +254,6 @@ static void clear_helper(void *priv)
        struct dev_context *devc;
 
        devc = priv;
-
-       ftdi_free(devc->ftdic);
        g_free(devc->data_buf);
        g_free(devc);
 }
@@ -279,13 +270,17 @@ static int dev_open(struct sr_dev_inst *sdi)
 
        devc = sdi->priv;
 
-       ret = ftdi_usb_open_dev(devc->ftdic, devc->usbdev);
+       devc->ftdic = ftdi_new();
+       if (!devc->ftdic)
+               return SR_ERR;
+
+       ret = ftdi_usb_open_string(devc->ftdic, devc->address);
        if (ret < 0) {
                /* Log errors, except for -3 ("device not found"). */
                if (ret != -3)
                        sr_err("Failed to open device (%d): %s", ret,
                               ftdi_get_error_string(devc->ftdic));
-               return SR_ERR;
+               goto err_ftdi_free;
        }
 
        /* Purge RX/TX buffers in the FTDI chip. */
@@ -317,9 +312,10 @@ static int dev_open(struct sr_dev_inst *sdi)
        sdi->status = SR_ST_ACTIVE;
 
        return SR_OK;
-
 err_dev_open_close_ftdic:
        ftdi_usb_close(devc->ftdic);
+err_ftdi_free:
+       ftdi_free(devc->ftdic);
        return SR_ERR;
 }
 
@@ -329,7 +325,11 @@ static int dev_close(struct sr_dev_inst *sdi)
 
        devc = sdi->priv;
 
-       ftdi_usb_close(devc->ftdic);
+       if (devc->ftdic) {
+               ftdi_usb_close(devc->ftdic);
+               ftdi_free(devc->ftdic);
+               devc->ftdic = NULL;
+       }
 
        sdi->status = SR_ST_INACTIVE;
 
index aa72dffa723b83b2ac3e397816dca1df04048fa6..ab8ac5c3de8b69a9d8832343022c98a9f785ef6f 100644 (file)
@@ -40,7 +40,7 @@ struct ftdi_chip_desc {
 struct dev_context {
        struct ftdi_context *ftdic;
        const struct ftdi_chip_desc *desc;
-       struct libusb_device *usbdev;
+       char address[sizeof("d:000:000")];
 
        uint64_t limit_samples;
        uint32_t cur_samplerate;