diff options
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | dediprog.c | 46 | ||||
| -rw-r--r-- | developerbox_spi.c | 64 | ||||
| -rw-r--r-- | programmer.h | 8 | ||||
| -rw-r--r-- | usbdev.c | 130 | 
5 files changed, 141 insertions, 108 deletions
@@ -1023,6 +1023,7 @@ endif  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 @@ -242,50 +242,6 @@ static int dediprog_write(enum dediprog_cmds cmd, unsigned int value, unsigned i  } -/* 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 @@ int dediprog_init(void)  	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 8482dea1..4ad966ec 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 @@ static const struct bitbang_spi_master bitbang_spi_master_cp210x = {  	.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 @@ int developerbox_spi_init(void)  	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 300cf5f1..311992a0 100644 --- a/programmer.h +++ b/programmer.h @@ -841,4 +841,12 @@ static inline bool spi_master_4ba(const struct flashctx *const flash)  		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 00000000..5c34ba12 --- /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; +}  | 
