#include <stdlib.h>
#include <sys/queue.h>
+#include "libhusb.h"
+#include "uref.h"
+#include "common.h"
+
struct libhusb_context {
libusb_context *lusb_ctx;
};
struct libhusb_device {
+ struct uref ref;
libusb_device *lusb_dev;
};
+static inline struct libhusb_device *to_libhusb_device(struct uref *_uref)
+{
+ return container_of(_uref, struct libhusb_device, ref);
+}
+
struct libhusb_device_handle {
struct libusb_device_handle *lusb_dev_handle;
};
return port_num;
}
+static void free_device(struct uref *uref)
+{
+ struct libhusb_device *dev = to_libhusb_device(uref);
+
+ libusb_unref_device(dev->lusb_dev);
+ free(dev);
+}
+
+static struct libhusb_device *alloc_device(libusb_device *lusb_dev)
+{
+ struct libhusb_device *dev;
+
+ dev = malloc(sizeof(*dev));
+ if (!dev)
+ goto out;
+
+ uref_init(&dev->ref, free_device);
+
+ libusb_ref_device(lusb_dev);
+ dev->lusb_dev = lusb_dev;
+out:
+ return dev;
+}
+
ssize_t libhusb_get_devices(libhusb_context *context, libhusb_device ***devs)
{
ssize_t len;
return -1;
list = calloc(len + 1, sizeof(*list));
- if (!list) {
- libusb_free_device_list(lusb_list, 1);
- return -99; /* TODO replace with propper error*/
- }
+ if (!list)
+ goto free_lusb_list;
list[len] = NULL;
for (i = 0; i < len; i++) {
- rdevice = malloc(sizeof(*rdevice));
- if (!rdevice) {
- libusb_free_device_list(lusb_list, 1);
- return -99; /* TODO replace with propper error*/
- }
+ rdevice = alloc_device(lusb_list[i]);
+ if (!rdevice)
+ goto free_dev_list;
+
list[i] = rdevice;
- list[i]->lusb_dev = lusb_list[i];
}
*devs = list;
- libusb_free_device_list(lusb_list, 0);
+ libusb_free_device_list(lusb_list, 1);
return len;
+
+free_dev_list:
+ while (--i <= 0)
+ libhusb_unref_device(list[i]);
+ free(list);
+free_lusb_list:
+ libusb_free_device_list(lusb_list, 1);
+
+ return -99; /* TODO replace with propper error*/
+}
+
+libhusb_device *libhusb_ref_device(libhusb_device *dev)
+{
+ uref_get(&dev->ref);
+ return dev;
+}
+
+void libhusb_unref_device(libhusb_device *dev)
+{
+ uref_put(&dev->ref);
}
void libhusb_free_devices(libhusb_device **list, int unref_devices)
if (!list)
return;
- for (i = 0; list[i] != NULL; i++) {
- if (unref_devices) {
- struct libusb_device *devp = list[i]->lusb_dev;
- assert(devp);
- libusb_unref_device(devp);
- }
- free(list[i]);
- }
+ for (i = 0; list[i] != NULL; i++)
+ if (unref_devices)
+ libhusb_unref_device(list[i]);
free(list);
}
ret = libusb_get_max_iso_packet_size(dev->lusb_dev, endpoint);
if (ret < 0)
- ret = usb_device_get_error_num(ret);
+ ret = -99;
return ret;
}