Nico Huber merged this change.

View Change

Approvals: build bot (Jenkins): Verified Nico Huber: Looks good to me, approved
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(-)

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;
+}

To view, visit change 27443. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: Idfcc79371241c2c1dea97faf5e532aa971546a79
Gerrit-Change-Number: 27443
Gerrit-PatchSet: 4
Gerrit-Owner: Daniel Thompson <daniel.thompson@linaro.org>
Gerrit-Reviewer: Nico Huber <nico.h@gmx.de>
Gerrit-Reviewer: Paul Menzel <paulepanter@users.sourceforge.net>
Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org>