This is an automated email from Gerrit.

"Erhan Kurubas <erhankuru...@gmail.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/6926

-- gerrit

commit e799887770f70a86b6bf485470947fb1d590a971
Author: erhankur <erhankuru...@gmail.com>
Date:   Mon Apr 11 18:03:10 2022 +0300

    libusb_helper: add find_device and get_serial functions
    
    If the target device unplugged and then plugged back in, the usb connection 
fails and cannot be rebuilt without libusb reset.
    In order to reset the correct device in the hub, the device's serial number 
can be compared with the initialized one.
    jtag_libusb_find_device() searches the serial number in the device list.
    And if device serial is not set from the tcl script during initialization, 
jtag_libusb_get_serial() can be used as a backup c library.
    
    Signed-off-by: erhankur <erhankuru...@gmail.com>
    Change-Id: Id5505672cc17749a9ed63f43df9811aba4dd11ae

diff --git a/src/jtag/drivers/libusb_helper.c b/src/jtag/drivers/libusb_helper.c
index fc961cb915..f602758a49 100644
--- a/src/jtag/drivers/libusb_helper.c
+++ b/src/jtag/drivers/libusb_helper.c
@@ -112,7 +112,7 @@ static bool string_descriptor_equal(struct 
libusb_device_handle *device, uint8_t
        retval = libusb_get_string_descriptor_ascii(device, str_index,
                        (unsigned char *)desc_string, sizeof(desc_string)-1);
        if (retval < 0) {
-               LOG_ERROR("libusb_get_string_descriptor_ascii() failed with 
%d", retval);
+               LOG_ERROR("libusb_get_string_descriptor_ascii() failed with 
'%s'", libusb_error_name(retval));
                return false;
        }
 
@@ -367,6 +367,74 @@ int jtag_libusb_get_pid(struct libusb_device *dev, 
uint16_t *pid)
        return ERROR_FAIL;
 }
 
+int jtag_libusb_get_serial(struct libusb_device_handle *devh, const char 
**serial)
+{
+       struct libusb_device *dev = libusb_get_device(devh);
+       struct libusb_device_descriptor dev_desc;
+
+       if (serial && libusb_get_device_descriptor(dev, &dev_desc) == 0) {
+
+               if (dev_desc.iSerialNumber == 0)
+                       return ERROR_FAIL;
+
+               char desc_string[256 + 1]; /* Max size of string descriptor */
+               int ret = libusb_get_string_descriptor_ascii(devh, 
dev_desc.iSerialNumber,
+                               (unsigned char *)desc_string, 
sizeof(desc_string) - 1);
+               if (ret < 0) {
+                       LOG_ERROR("libusb_get_string_descriptor_ascii() failed 
with %d", ret);
+                       return ERROR_FAIL;
+               }
+               desc_string[sizeof(desc_string) - 1] = '\0';
+               *serial = strdup(desc_string);
+               return *serial ? ERROR_OK : ERROR_FAIL;
+       }
+
+       return ERROR_FAIL;
+}
+
+libusb_device *jtag_libusb_find_device(const uint16_t vids[], const uint16_t 
pids[], const char *serial)
+{
+       libusb_device **devices, *found_dev = NULL;
+
+       int cnt = libusb_get_device_list(jtag_libusb_context, &devices);
+
+       for (int idx = 0; idx < cnt; idx++) {
+               struct libusb_device_descriptor dev_desc;
+               struct libusb_device_handle *libusb_handle = NULL;
+
+               if (libusb_get_device_descriptor(devices[idx], &dev_desc) != 0)
+                       continue;
+
+               if (!jtag_libusb_match_ids(&dev_desc, vids, pids))
+                       continue;
+
+               LOG_DEBUG("USB dev found %x:%x @ %d:%d-%d", dev_desc.idVendor, 
dev_desc.idProduct,
+                       libusb_get_bus_number(devices[idx]),
+                       libusb_get_port_number(devices[idx]),
+                       libusb_get_device_address(devices[idx]));
+
+               if (serial) {
+                       int ret = libusb_open(devices[idx], &libusb_handle);
+                       if (ret) {
+                               LOG_ERROR("libusb_open() failed with %s",
+                                       libusb_error_name(ret));
+                               continue;
+                       }
+                       bool found = string_descriptor_equal(libusb_handle, 
dev_desc.iSerialNumber, serial);
+                       libusb_close(libusb_handle);
+                       if (!found)
+                               continue;
+               }
+               found_dev = devices[idx];
+               libusb_ref_device(found_dev);
+               break;
+       }
+       if (cnt >= 0)
+               libusb_free_device_list(devices, 1);
+
+       return found_dev;
+}
+
 int jtag_libusb_handle_events_completed(int *completed)
 {
        return libusb_handle_events_completed(jtag_libusb_context, completed);
diff --git a/src/jtag/drivers/libusb_helper.h b/src/jtag/drivers/libusb_helper.h
index 9d51464a7f..1e7dfe35a9 100644
--- a/src/jtag/drivers/libusb_helper.h
+++ b/src/jtag/drivers/libusb_helper.h
@@ -73,6 +73,9 @@ int jtag_libusb_choose_interface(struct libusb_device_handle 
*devh,
                unsigned int *usb_write_ep,
                int bclass, int subclass, int protocol, int trans_type);
 int jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid);
+
+int jtag_libusb_get_serial(struct libusb_device_handle *devh, const char 
**serial);
+libusb_device *jtag_libusb_find_device(const uint16_t vids[], const uint16_t 
pids[], const char *serial);
 int jtag_libusb_handle_events_completed(int *completed);
 
 #endif /* OPENOCD_JTAG_DRIVERS_LIBUSB_HELPER_H */

-- 

Reply via email to