Fix support for LIBUSB_HOTPLUG_ENUMERATE in libusb. Currently all

devices are enumerated regardless of of the LIBUSB_HOTPLUG_ENUMERATE
flag. Make sure when the flag is not specified no arrival events are
generated for currently enumerated devices.

MFC after:	3 days
Sponsored by:	Mellanox Technologies
This commit is contained in:
Hans Petter Selasky 2019-06-26 11:28:08 +00:00
parent 59c94acee9
commit a41b0ec143
2 changed files with 25 additions and 12 deletions

View File

@ -89,6 +89,8 @@ struct libusb_hotplug_callback_handle_struct {
void *user_data; void *user_data;
}; };
TAILQ_HEAD(libusb_device_head, libusb_device);
struct libusb_context { struct libusb_context {
int debug; int debug;
int debug_fixed; int debug_fixed;
@ -106,7 +108,7 @@ struct libusb_context {
TAILQ_HEAD(, libusb_super_pollfd) pollfds; TAILQ_HEAD(, libusb_super_pollfd) pollfds;
TAILQ_HEAD(, libusb_super_transfer) tr_done; TAILQ_HEAD(, libusb_super_transfer) tr_done;
TAILQ_HEAD(, libusb_hotplug_callback_handle_struct) hotplug_cbh; TAILQ_HEAD(, libusb_hotplug_callback_handle_struct) hotplug_cbh;
TAILQ_HEAD(, libusb_device) hotplug_devs; struct libusb_device_head hotplug_devs;
struct libusb_super_pollfd ctx_poll; struct libusb_super_pollfd ctx_poll;

View File

@ -85,20 +85,35 @@ libusb_hotplug_filter(libusb_context *ctx, libusb_hotplug_callback_handle pcbh,
return (pcbh->fn(ctx, dev, event, pcbh->user_data)); return (pcbh->fn(ctx, dev, event, pcbh->user_data));
} }
static int
libusb_hotplug_enumerate(libusb_context *ctx, struct libusb_device_head *phead)
{
libusb_device **ppdev;
ssize_t count;
ssize_t x;
count = libusb_get_device_list(ctx, &ppdev);
if (count < 0)
return (-1);
for (x = 0; x != count; x++)
TAILQ_INSERT_TAIL(phead, ppdev[x], hotplug_entry);
libusb_free_device_list(ppdev, 0);
return (0);
}
static void * static void *
libusb_hotplug_scan(void *arg) libusb_hotplug_scan(void *arg)
{ {
TAILQ_HEAD(, libusb_device) hotplug_devs; struct libusb_device_head hotplug_devs;
libusb_hotplug_callback_handle acbh; libusb_hotplug_callback_handle acbh;
libusb_hotplug_callback_handle bcbh; libusb_hotplug_callback_handle bcbh;
libusb_context *ctx = arg; libusb_context *ctx = arg;
libusb_device **ppdev;
libusb_device *temp; libusb_device *temp;
libusb_device *adev; libusb_device *adev;
libusb_device *bdev; libusb_device *bdev;
unsigned do_loop = 1; unsigned do_loop = 1;
ssize_t count;
ssize_t x;
while (do_loop) { while (do_loop) {
usleep(4000000); usleep(4000000);
@ -108,14 +123,8 @@ libusb_hotplug_scan(void *arg)
TAILQ_INIT(&hotplug_devs); TAILQ_INIT(&hotplug_devs);
if (ctx->hotplug_handler != NO_THREAD) { if (ctx->hotplug_handler != NO_THREAD) {
count = libusb_get_device_list(ctx, &ppdev); if (libusb_hotplug_enumerate(ctx, &hotplug_devs) < 0)
if (count < 0)
continue; continue;
for (x = 0; x != count; x++) {
TAILQ_INSERT_TAIL(&hotplug_devs, ppdev[x],
hotplug_entry);
}
libusb_free_device_list(ppdev, 0);
} else { } else {
do_loop = 0; do_loop = 0;
} }
@ -202,6 +211,8 @@ int libusb_hotplug_register_callback(libusb_context *ctx,
handle->fn = cb_fn; handle->fn = cb_fn;
handle->user_data = user_data; handle->user_data = user_data;
libusb_hotplug_enumerate(ctx, &ctx->hotplug_devs);
if (flags & LIBUSB_HOTPLUG_ENUMERATE) { if (flags & LIBUSB_HOTPLUG_ENUMERATE) {
TAILQ_FOREACH(adev, &ctx->hotplug_devs, hotplug_entry) { TAILQ_FOREACH(adev, &ctx->hotplug_devs, hotplug_entry) {
if (libusb_hotplug_filter(ctx, handle, adev, if (libusb_hotplug_filter(ctx, handle, adev,