]> sigrok.org Git - libsigrok.git/blobdiff - src/usb.c
Various #include file cosmetic fixes.
[libsigrok.git] / src / usb.c
index c3279d0ae1ef58640013483f9b6711deca9be15a..9c34b38ad1bdb204d89c5a16f2631c11fb7617f0 100644 (file)
--- a/src/usb.c
+++ b/src/usb.c
@@ -20,6 +20,7 @@
  */
 
 #include <stdlib.h>
+#include <memory.h>
 #include <glib.h>
 #include <libusb.h>
 #include "libsigrok.h"
@@ -269,3 +270,41 @@ SR_PRIV int usb_source_remove(struct sr_session *session, struct sr_context *ctx
 
        return SR_OK;
 }
+
+SR_PRIV int usb_get_port_path(libusb_device *dev, char *path, int path_len)
+{
+       uint8_t port_numbers[8];
+       int i, n, len;
+
+/*
+ * FreeBSD requires that devices prior to calling libusb_get_port_numbers()
+ * have been opened with libusb_open().
+ */
+#ifdef __FreeBSD__
+       struct libusb_device_handle *devh;
+       if (libusb_open(dev, &devh) != 0)
+               return SR_ERR;
+#endif
+       n = libusb_get_port_numbers(dev, port_numbers, sizeof(port_numbers));
+#ifdef __FreeBSD__
+       libusb_close(devh);
+#endif
+
+/* Workaround FreeBSD libusb_get_port_numbers() returning 0. */
+#ifdef __FreeBSD__
+       if (n == 0) {
+               port_numbers[0] = libusb_get_device_address(dev);
+               n = 1;
+       }
+#endif
+       if (n < 1)
+               return SR_ERR;
+
+       len = snprintf(path, path_len, "usb/%d-%d",
+                      libusb_get_bus_number(dev), port_numbers[0]);
+
+       for (i = 1; i < n; i++)
+               len += snprintf(path+len, path_len-len, ".%d", port_numbers[i]);
+
+       return SR_OK;
+}