Nico Huber has submitted this change and it was merged. ( https://review.coreboot.org/27443 )
Change subject: usbdev: Extract libusb1 device discovery into a separate file ......................................................................
usbdev: Extract libusb1 device discovery into a separate file
Currently there is a TODO-like comment in the dediprog driver: "Might be useful for other USB devices as well". Act on this comment by collecting all the device discovery code for libusb1 devices into a separate file.
Change-Id: Idfcc79371241c2c1dea97faf5e532aa971546a79 Signed-off-by: Daniel Thompson daniel.thompson@linaro.org Reviewed-on: https://review.coreboot.org/27443 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Nico Huber nico.h@gmx.de --- M Makefile M dediprog.c M developerbox_spi.c M programmer.h A usbdev.c 5 files changed, 141 insertions(+), 108 deletions(-)
Approvals: build bot (Jenkins): Verified Nico Huber: Looks good to me, approved
diff --git a/Makefile b/Makefile index ddfd711..b13cf7e 100644 --- a/Makefile +++ b/Makefile @@ -1023,6 +1023,7 @@ ifneq ($(NEED_LIBUSB1), ) CHECK_LIBUSB1 = yes FEATURE_CFLAGS += -D'NEED_LIBUSB1=1' +PROGRAMMER_OBJS += usbdev.o # FreeBSD and DragonflyBSD use a reimplementation of libusb-1.0 that is simply called libusb ifeq ($(TARGET_OS),$(filter $(TARGET_OS),FreeBSD DragonFlyBSD)) USB1LIBS += -lusb diff --git a/dediprog.c b/dediprog.c index 7fcadfb..1a469a7 100644 --- a/dediprog.c +++ b/dediprog.c @@ -242,50 +242,6 @@ }
-/* Might be useful for other USB devices as well. static for now. - * num parameter allows user to specify one device of multiple installed */ -static struct libusb_device_handle *get_device_by_vid_pid_number(uint16_t vid, uint16_t pid, unsigned int num) -{ - struct libusb_device **list; - ssize_t count = libusb_get_device_list(usb_ctx, &list); - if (count < 0) { - msg_perr("Getting the USB device list failed (%s)!\n", libusb_error_name(count)); - return NULL; - } - - struct libusb_device_handle *handle = NULL; - ssize_t i = 0; - for (i = 0; i < count; i++) { - struct libusb_device *dev = list[i]; - struct libusb_device_descriptor desc; - int err = libusb_get_device_descriptor(dev, &desc); - if (err != 0) { - msg_perr("Reading the USB device descriptor failed (%s)!\n", libusb_error_name(err)); - libusb_free_device_list(list, 1); - return NULL; - } - if ((desc.idVendor == vid) && (desc.idProduct == pid)) { - msg_pdbg("Found USB device %04"PRIx16":%04"PRIx16" at address %d-%d.\n", - desc.idVendor, desc.idProduct, - libusb_get_bus_number(dev), libusb_get_device_address(dev)); - if (num == 0) { - err = libusb_open(dev, &handle); - if (err != 0) { - msg_perr("Opening the USB device failed (%s)!\n", - libusb_error_name(err)); - libusb_free_device_list(list, 1); - return NULL; - } - break; - } - num--; - } - } - libusb_free_device_list(list, 1); - - return handle; -} - /* This function sets the GPIOs connected to the LEDs as well as IO1-IO4. */ static int dediprog_set_leds(int leds) { @@ -1102,7 +1058,7 @@
const uint16_t vid = devs_dediprog[0].vendor_id; const uint16_t pid = devs_dediprog[0].device_id; - dediprog_handle = get_device_by_vid_pid_number(vid, pid, (unsigned int) usedevice); + dediprog_handle = usb_dev_get_by_vid_pid_number(usb_ctx, vid, pid, (unsigned int) usedevice); if (!dediprog_handle) { msg_perr("Could not find a Dediprog programmer on USB.\n"); libusb_exit(usb_ctx); diff --git a/developerbox_spi.c b/developerbox_spi.c index 8482dea..4ad966e 100644 --- a/developerbox_spi.c +++ b/developerbox_spi.c @@ -34,7 +34,6 @@ #include "platform.h"
#include <stdlib.h> -#include <string.h> #include <libusb.h> #include "programmer.h" #include "spi.h" @@ -130,67 +129,6 @@ .set_sck_set_mosi = cp210x_bitbang_set_sck_set_mosi, };
-static struct libusb_device_handle *get_device_by_vid_pid_serial(uint16_t vid, uint16_t pid, - const char *serialno) -{ - struct libusb_device **list; - ssize_t count = libusb_get_device_list(usb_ctx, &list); - if (count < 0) { - msg_perr("Getting the USB device list failed (%s)!\n", libusb_error_name(count)); - return NULL; - } - - ssize_t i = 0; - for (i = 0; i < count; i++) { - struct libusb_device *dev = list[i]; - struct libusb_device_descriptor desc; - struct libusb_device_handle *handle; - - int res = libusb_get_device_descriptor(dev, &desc); - if (res != 0) { - msg_perr("Reading the USB device descriptor failed (%s)!\n", libusb_error_name(res)); - continue; - } - - if ((desc.idVendor != vid) && (desc.idProduct != pid)) - continue; - - msg_pdbg("Found USB device %04"PRIx16":%04"PRIx16" at address %d-%d.\n", - desc.idVendor, desc.idProduct, - libusb_get_bus_number(dev), libusb_get_device_address(dev)); - - res = libusb_open(dev, &handle); - if (res != 0) { - msg_perr("Opening the USB device failed (%s)!\n", libusb_error_name(res)); - continue; - } - - if (serialno) { - unsigned char myserial[64]; - res = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, myserial, - sizeof(myserial)); - if (res < 0) { - msg_perr("Reading the USB serialno failed (%s)!\n", libusb_error_name(res)); - libusb_close(handle); - continue; - } - msg_pdbg("Serial number is %s\n", myserial); - - /* Filter out any serial number that does not commence with serialno */ - if (0 != strncmp(serialno, (char *) myserial, strlen(serialno))) { - libusb_close(handle); - continue; - } - } - - libusb_free_device_list(list, 1); - return handle; - } - - libusb_free_device_list(list, 1); - return NULL; -} - static int developerbox_spi_shutdown(void *data) { libusb_close(cp210x_handle); @@ -210,7 +148,7 @@ char *serialno = extract_programmer_param("serial"); if (serialno) msg_pdbg("Looking for serial number commencing %s\n", serialno); - cp210x_handle = get_device_by_vid_pid_serial( + cp210x_handle = usb_dev_get_by_vid_pid_serial(usb_ctx, devs_developerbox_spi[0].vendor_id, devs_developerbox_spi[0].device_id, serialno); free(serialno); if (!cp210x_handle) { diff --git a/programmer.h b/programmer.h index 300cf5f..311992a 100644 --- a/programmer.h +++ b/programmer.h @@ -841,4 +841,12 @@ flash->mst->spi.features & SPI_MASTER_4BA; }
+/* usbdev.c */ +struct libusb_device_handle; +struct libusb_context; +struct libusb_device_handle *usb_dev_get_by_vid_pid_serial( + struct libusb_context *usb_ctx, uint16_t vid, uint16_t pid, const char *serialno); +struct libusb_device_handle *usb_dev_get_by_vid_pid_number( + struct libusb_context *usb_ctx, uint16_t vid, uint16_t pid, unsigned int num); + #endif /* !__PROGRAMMER_H__ */ diff --git a/usbdev.c b/usbdev.c new file mode 100644 index 0000000..5c34ba1 --- /dev/null +++ b/usbdev.c @@ -0,0 +1,130 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2016 secunet Security Networks AG + * Copyright (C) 2018 Linaro Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <string.h> +#include <libusb.h> +#include "programmer.h" + +struct libusb_device_handle *usb_dev_get_by_vid_pid_serial( + struct libusb_context *usb_ctx, uint16_t vid, uint16_t pid, const char *serialno) +{ + struct libusb_device **list; + ssize_t count = libusb_get_device_list(usb_ctx, &list); + if (count < 0) { + msg_perr("Getting the USB device list failed (%s)!\n", libusb_error_name(count)); + return NULL; + } + + ssize_t i = 0; + for (i = 0; i < count; i++) { + struct libusb_device *dev = list[i]; + struct libusb_device_descriptor desc; + struct libusb_device_handle *handle; + + int res = libusb_get_device_descriptor(dev, &desc); + if (res != 0) { + msg_perr("Reading the USB device descriptor failed (%s)!\n", libusb_error_name(res)); + continue; + } + + if ((desc.idVendor != vid) && (desc.idProduct != pid)) + continue; + + msg_pdbg("Found USB device %04"PRIx16":%04"PRIx16" at address %d-%d.\n", + desc.idVendor, desc.idProduct, + libusb_get_bus_number(dev), libusb_get_device_address(dev)); + + res = libusb_open(dev, &handle); + if (res != 0) { + msg_perr("Opening the USB device failed (%s)!\n", libusb_error_name(res)); + continue; + } + + if (serialno) { + unsigned char myserial[64]; + res = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, myserial, + sizeof(myserial)); + if (res < 0) { + msg_perr("Reading the USB serialno failed (%s)!\n", libusb_error_name(res)); + libusb_close(handle); + continue; + } + msg_pdbg("Serial number is %s\n", myserial); + + /* Reject any serial number that does not commence with serialno */ + if (0 != strncmp(serialno, (char *)myserial, strlen(serialno))) { + libusb_close(handle); + continue; + } + } + + libusb_free_device_list(list, 1); + return handle; + } + + libusb_free_device_list(list, 1); + return NULL; +} + +/* + * This function allows different devices to be targeted based on enumeration order. Different + * hotplug sequencing (or simply a reboot) may change the enumeration order. This function should + * only be used if a programmers does not provide an alternative way to identify itself uniquely + * (such as a unique serial number). + */ +struct libusb_device_handle *usb_dev_get_by_vid_pid_number( + struct libusb_context *usb_ctx, uint16_t vid, uint16_t pid, unsigned int num) +{ + struct libusb_device **list; + ssize_t count = libusb_get_device_list(usb_ctx, &list); + if (count < 0) { + msg_perr("Getting the USB device list failed (%s)!\n", libusb_error_name(count)); + return NULL; + } + + struct libusb_device_handle *handle = NULL; + ssize_t i = 0; + for (i = 0; i < count; i++) { + struct libusb_device *dev = list[i]; + struct libusb_device_descriptor desc; + int err = libusb_get_device_descriptor(dev, &desc); + if (err != 0) { + msg_perr("Reading the USB device descriptor failed (%s)!\n", libusb_error_name(err)); + libusb_free_device_list(list, 1); + return NULL; + } + if ((desc.idVendor == vid) && (desc.idProduct == pid)) { + msg_pdbg("Found USB device %04"PRIx16":%04"PRIx16" at address %d-%d.\n", + desc.idVendor, desc.idProduct, + libusb_get_bus_number(dev), libusb_get_device_address(dev)); + if (num == 0) { + err = libusb_open(dev, &handle); + if (err != 0) { + msg_perr("Opening the USB device failed (%s)!\n", + libusb_error_name(err)); + libusb_free_device_list(list, 1); + return NULL; + } + break; + } + num--; + } + } + libusb_free_device_list(list, 1); + + return handle; +}