From e2e1a00b1595b4930b86e3ba3ea2e9b771a79653 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 11:27:07 +0200 Subject: Adding upstream version 1:014. Signed-off-by: Daniel Baumann --- usbhid-dump/src/dev_list.c | 125 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 usbhid-dump/src/dev_list.c (limited to 'usbhid-dump/src/dev_list.c') diff --git a/usbhid-dump/src/dev_list.c b/usbhid-dump/src/dev_list.c new file mode 100644 index 0000000..9848902 --- /dev/null +++ b/usbhid-dump/src/dev_list.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * usbhid-dump - device list + * + * Copyright (C) 2010 Nikolai Kondrashov + */ + +#include "config.h" + +#include "misc.h" +#include "dev_list.h" +#include +#include +#include + +bool +uhd_dev_list_valid(const uhd_dev *list) +{ + UHD_DEV_LIST_FOR_EACH(list, list) + if (!uhd_dev_valid(list)) + return false; + + return true; +} + + +void +uhd_dev_list_close(uhd_dev *list) +{ + uhd_dev *next; + + for (; list != NULL; list = next) + { + next = list->next; + uhd_dev_close(list); + } +} + + +enum libusb_error +uhd_dev_list_open(libusb_context *ctx, + uint8_t bus_num, uint8_t dev_addr, + uint16_t vid, uint16_t pid, + uhd_dev **plist) +{ + enum libusb_error err = LIBUSB_ERROR_OTHER; + libusb_device **lusb_list = NULL; + ssize_t num; + ssize_t idx; + libusb_device *lusb_dev; + struct libusb_device_descriptor desc; + uhd_dev *list = NULL; + uhd_dev *dev; + + assert(ctx != NULL); + + /* Retrieve libusb device list */ + num = libusb_get_device_list(ctx, &lusb_list); + if (num == LIBUSB_ERROR_NO_MEM) + { + err = num; + goto cleanup; + } + + /* Find and open the devices */ + for (idx = 0; idx < num; idx++) + { + lusb_dev = lusb_list[idx]; + + /* Skip devices not matching bus_num/dev_addr mask */ + if ((bus_num != UHD_BUS_NUM_ANY && + libusb_get_bus_number(lusb_dev) != bus_num) || + (dev_addr != UHD_DEV_ADDR_ANY && + libusb_get_device_address(lusb_dev) != dev_addr)) + continue; + + /* Skip devices not matching vendor/product mask */ + if (vid != UHD_VID_ANY || pid != UHD_PID_ANY) + { + err = libusb_get_device_descriptor(lusb_dev, &desc); + if (err != LIBUSB_SUCCESS) + goto cleanup; + + if ((vid != UHD_VID_ANY && vid != desc.idVendor) || + (pid != UHD_PID_ANY && pid != desc.idProduct)) + continue; + } + + /* Open and append the device to the list */ + err = uhd_dev_open(lusb_dev, &dev); + if (err != LIBUSB_SUCCESS) + goto cleanup; + + dev->next = list; + list = dev; + } + + /* Free the libusb device list freeing unused devices */ + libusb_free_device_list(lusb_list, true); + lusb_list = NULL; + + /* Output device list, if requested */ + assert(uhd_dev_list_valid(list)); + if (plist != NULL) + { + *plist = list; + list = NULL; + } + + /* Done! */ + err = LIBUSB_SUCCESS; + +cleanup: + + /* Close the device list if not output */ + uhd_dev_list_close(list); + + /* Free the libusb device list along with devices */ + if (lusb_list != NULL) + libusb_free_device_list(lusb_list, true); + + return err; +} + + -- cgit v1.2.3