This patch tracks the changes in the libusb interface. Nothing changed in the behaviour of the driver, so far.
It will be used by a follow-up patch. It's based on "Enable spi clock setting in dediprog driver".
Signed-off-by: Nico Huber nico.huber@secunet.com
diff --git a/Makefile b/Makefile index b087b3d..6da7226 100644 --- a/Makefile +++ b/Makefile @@ -531,7 +531,7 @@ endif
ifeq ($(CONFIG_DEDIPROG), yes) FEATURE_CFLAGS += -D'CONFIG_DEDIPROG=1' -FEATURE_LIBS += -lusb +FEATURE_LIBS += -lusb-1.0 PROGRAMMER_OBJS += dediprog.o endif
diff --git a/dediprog.c b/dediprog.c index 60067a8..a558285 100644 --- a/dediprog.c +++ b/dediprog.c @@ -2,6 +2,7 @@ * This file is part of the flashrom project. * * Copyright (C) 2010 Carl-Daniel Hailfinger + * 2012 secunet Security Networks AG * * 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 @@ -19,7 +20,8 @@
#include <stdio.h> #include <string.h> -#include <usb.h> +#include <stdlib.h> +#include <libusb-1.0/libusb.h> #include "flash.h" #include "chipdrivers.h" #include "programmer.h" @@ -27,7 +29,8 @@
#define FIRMWARE_VERSION(x,y,z) ((x << 16) | (y << 8) | z) #define DEFAULT_TIMEOUT 3000 -static usb_dev_handle *dediprog_handle; +static libusb_context *usb_ctx; +static libusb_device_handle *dediprog_handle; static int dediprog_firmwareversion; static int dediprog_endpoint;
@@ -45,23 +48,6 @@ static void print_hex(void *buf, size_t len) } #endif
-/* Might be useful for other USB devices as well. static for now. */ -static struct usb_device *get_device_by_vid_pid(uint16_t vid, uint16_t pid) -{ - struct usb_bus *bus; - struct usb_device *dev; - - for (bus = usb_get_busses(); bus; bus = bus->next) - for (dev = bus->devices; dev; dev = dev->next) - if ((dev->descriptor.idVendor == vid) && - (dev->descriptor.idProduct == pid)) - return dev; - - return NULL; -} - -//int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout); - /* Set/clear LEDs on dediprog */ #define PASS_ON (0 << 0) #define PASS_OFF (1 << 0) @@ -95,11 +81,10 @@ static int dediprog_set_leds(int leds) target_leds = leds; }
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, target_leds, - NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x07, 0x09, target_leds, + NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command Set LED 0x%x failed (%s)!\n", - leds, usb_strerror()); + msg_perr("Command Set LED 0x%x failed (%s)!\n", leds, libusb_error_name(ret)); return 1; }
@@ -138,8 +123,8 @@ static int dediprog_set_spi_voltage(int millivolt) /* Wait some time as the original driver does. */ programmer_delay(200 * 1000); } - ret = usb_control_msg(dediprog_handle, 0x42, 0x9, voltage_selector, - 0xff, NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x9, voltage_selector, + 0xff, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { msg_perr("Command Set SPI Voltage 0x%x failed!\n", voltage_selector); @@ -182,8 +167,8 @@ static int dediprog_set_spi_speed(unsigned int spispeed_idx)
msg_pdbg("SPI speed is %sHz\n", spispeeds[spispeed_idx].name);
- ret = usb_control_msg(dediprog_handle, 0x42, 0x61, spispeeds[spispeed_idx].speed, 0xff, - NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x61, spispeeds[spispeed_idx].speed, 0xff, + NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { msg_perr("Command Set SPI Speed 0x%x failed!\n", spispeeds[spispeed_idx].speed); return 1; @@ -199,15 +184,15 @@ static int dediprog_set_spi_speed(unsigned int spispeed_idx) static int dediprog_spi_bulk_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len) { - int ret; + int ret, transferred; unsigned int i; /* chunksize must be 512, other sizes will NOT work at all. */ const unsigned int chunksize = 0x200; const unsigned int count = len / chunksize; - const char count_and_chunk[] = {count & 0xff, - (count >> 8) & 0xff, - chunksize & 0xff, - (chunksize >> 8) & 0xff}; + const unsigned char count_and_chunk[] = { + count & 0xff, (count >> 8) & 0xff, + chunksize & 0xff, (chunksize >> 8) & 0xff + };
if ((start % chunksize) || (len % chunksize)) { msg_perr("%s: Unaligned start=%i, len=%i! Please report a bug " @@ -221,22 +206,20 @@ static int dediprog_spi_bulk_read(struct flashctx *flash, uint8_t *buf, /* Command Read SPI Bulk. No idea which read command is used on the * SPI side. */ - ret = usb_control_msg(dediprog_handle, 0x42, 0x20, start % 0x10000, - start / 0x10000, (char *)count_and_chunk, - sizeof(count_and_chunk), DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x20, start % 0x10000, start / 0x10000, + (unsigned char *)count_and_chunk, sizeof(count_and_chunk), + DEFAULT_TIMEOUT); if (ret != sizeof(count_and_chunk)) { - msg_perr("Command Read SPI Bulk failed, %i %s!\n", ret, - usb_strerror()); + msg_perr("Command Read SPI Bulk failed, %i %s!\n", ret, libusb_error_name(ret)); return 1; }
for (i = 0; i < count; i++) { - ret = usb_bulk_read(dediprog_handle, 0x80 | dediprog_endpoint, - (char *)buf + i * chunksize, chunksize, - DEFAULT_TIMEOUT); - if (ret != chunksize) { - msg_perr("SPI bulk read %i failed, expected %i, got %i " - "%s!\n", i, chunksize, ret, usb_strerror()); + ret = libusb_bulk_transfer(dediprog_handle, 0x80 | dediprog_endpoint, + buf + i * chunksize, chunksize, &transferred, DEFAULT_TIMEOUT); + if ((ret < 0) || (transferred != chunksize)) { + msg_perr("SPI bulk read %i failed, expected %i, got %i %s!\n", + i, chunksize, ret, libusb_error_name(ret)); return 1; } } @@ -300,7 +283,7 @@ static int dediprog_spi_read(struct flashctx *flash, uint8_t *buf, static int dediprog_spi_bulk_write(struct flashctx *flash, uint8_t *buf, unsigned int chunksize, unsigned int start, unsigned int len, uint8_t dedi_spi_cmd) { - int ret; + int ret, transferred; unsigned int i; /* USB transfer size must be 512, other sizes will NOT work at all. * chunksize is the real data size per USB bulk transfer. The remaining @@ -308,7 +291,7 @@ static int dediprog_spi_bulk_write(struct flashctx *flash, uint8_t *buf, unsigne */ const unsigned int count = len / chunksize; const char count_and_cmd[] = {count & 0xff, (count >> 8) & 0xff, 0x00, dedi_spi_cmd}; - char usbbuf[512]; + unsigned char usbbuf[512];
/* * We should change this check to @@ -333,23 +316,21 @@ static int dediprog_spi_bulk_write(struct flashctx *flash, uint8_t *buf, unsigne /* Command Write SPI Bulk. No idea which write command is used on the * SPI side. */ - ret = usb_control_msg(dediprog_handle, 0x42, 0x30, start % 0x10000, start / 0x10000, - (char *)count_and_cmd, sizeof(count_and_cmd), DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x30, start % 0x10000, start / 0x10000, + (unsigned char *)count_and_cmd, sizeof(count_and_cmd), DEFAULT_TIMEOUT); if (ret != sizeof(count_and_cmd)) { - msg_perr("Command Write SPI Bulk failed, %i %s!\n", ret, - usb_strerror()); + msg_perr("Command Write SPI Bulk failed, %i %s!\n", ret, libusb_error_name(ret)); return 1; }
for (i = 0; i < count; i++) { memset(usbbuf, 0xff, sizeof(usbbuf)); memcpy(usbbuf, buf + i * chunksize, chunksize); - ret = usb_bulk_write(dediprog_handle, dediprog_endpoint, - usbbuf, 512, - DEFAULT_TIMEOUT); - if (ret != 512) { - msg_perr("SPI bulk write failed, expected %i, got %i " - "%s!\n", 512, ret, usb_strerror()); + ret = libusb_bulk_transfer(dediprog_handle, dediprog_endpoint, + usbbuf, 512, &transferred, DEFAULT_TIMEOUT); + if ((ret < 0) || (transferred != 512)) { + msg_perr("SPI bulk write failed, expected %i, got %i %s!\n", + 512, ret, libusb_error_name(ret)); return 1; } } @@ -438,23 +419,20 @@ static int dediprog_spi_send_command(struct flashctx *flash, msg_perr("Untested readcnt=%i, aborting.\n", readcnt); return 1; } - - ret = usb_control_msg(dediprog_handle, 0x42, 0x1, 0xff, - readcnt ? 0x1 : 0x0, (char *)writearr, writecnt, - DEFAULT_TIMEOUT); + + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x1, 0xff, readcnt ? 0x1 : 0x0, + (unsigned char *)writearr, writecnt, DEFAULT_TIMEOUT); if (ret != writecnt) { - msg_perr("Send SPI failed, expected %i, got %i %s!\n", - writecnt, ret, usb_strerror()); + msg_perr("Send SPI failed, expected %i, got %i %s!\n", writecnt, ret, libusb_error_name(ret)); return 1; } if (!readcnt) return 0; memset(readarr, 0, readcnt); - ret = usb_control_msg(dediprog_handle, 0xc2, 0x01, 0xbb8, 0x0000, - (char *)readarr, readcnt, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0xc2, 0x01, 0xbb8, 0x0000, + readarr, readcnt, DEFAULT_TIMEOUT); if (ret != readcnt) { - msg_perr("Receive SPI failed, expected %i, got %i %s!\n", - readcnt, ret, usb_strerror()); + msg_perr("Receive SPI failed, expected %i, got %i %s!\n", readcnt, ret, libusb_error_name(ret)); return 1; } return 0; @@ -464,22 +442,18 @@ static int dediprog_check_devicestring(void) { int ret; int fw[3]; - char buf[0x11]; + unsigned char buf[0x11];
/* Command Prepare Receive Device String. */ memset(buf, 0, sizeof(buf)); - ret = usb_control_msg(dediprog_handle, 0xc3, 0x7, 0x0, 0xef03, buf, - 0x1, DEFAULT_TIMEOUT); - /* The char casting is needed to stop gcc complaining about an always true comparison. */ - if ((ret != 0x1) || (buf[0] != (char)0xff)) { - msg_perr("Unexpected response to Command Prepare Receive Device" - " String!\n"); + ret = libusb_control_transfer(dediprog_handle, 0xc3, 0x7, 0x0, 0xef03, buf, 0x1, DEFAULT_TIMEOUT); + if ((ret != 0x1) || (buf[0] != 0xff)) { + msg_perr("Unexpected response to Command Prepare Receive Device String!\n"); return 1; } /* Command Receive Device String. */ memset(buf, 0, sizeof(buf)); - ret = usb_control_msg(dediprog_handle, 0xc2, 0x8, 0xff, 0xff, buf, - 0x10, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0xc2, 0x8, 0xff, 0xff, buf, 0x10, DEFAULT_TIMEOUT); if (ret != 0x10) { msg_perr("Incomplete/failed Command Receive Device String!\n"); return 1; @@ -490,7 +464,7 @@ static int dediprog_check_devicestring(void) msg_perr("Device not a SF100!\n"); return 1; } - if (sscanf(buf, "SF100 V:%d.%d.%d ", &fw[0], &fw[1], &fw[2]) != 3) { + if (sscanf((const char *)buf, "SF100 V:%d.%d.%d ", &fw[0], &fw[1], &fw[2]) != 3) { msg_perr("Unexpected firmware version string!\n"); return 1; } @@ -511,13 +485,12 @@ static int dediprog_check_devicestring(void) static int dediprog_command_a(void) { int ret; - char buf[0x1]; + unsigned char buf[0x1];
memset(buf, 0, sizeof(buf)); - ret = usb_control_msg(dediprog_handle, 0xc3, 0xb, 0x0, 0x0, buf, - 0x1, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0xc3, 0xb, 0x0, 0x0, buf, 0x1, DEFAULT_TIMEOUT); if (ret < 0) { - msg_perr("Command A failed (%s)!\n", usb_strerror()); + msg_perr("Command A failed (%s)!\n", libusb_error_name(ret)); return 1; } if ((ret != 0x1) || (buf[0] != 0x6f)) { @@ -535,13 +508,12 @@ static int dediprog_command_a(void) static int dediprog_command_b(void) { int ret; - char buf[0x3]; + unsigned char buf[0x3];
memset(buf, 0, sizeof(buf)); - ret = usb_control_msg(dediprog_handle, 0xc3, 0x7, 0x0, 0xef00, buf, - 0x3, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0xc3, 0x7, 0x0, 0xef00, buf, 0x3, DEFAULT_TIMEOUT); if (ret < 0) { - msg_perr("Command B failed (%s)!\n", usb_strerror()); + msg_perr("Command B failed (%s)!\n", libusb_error_name(ret)); return 1; } if ((ret != 0x3) || (buf[0] != 0xff) || (buf[1] != 0xff) || @@ -563,10 +535,9 @@ static int dediprog_command_c(void) { int ret;
- ret = usb_control_msg(dediprog_handle, 0x42, 0x4, 0x0, 0x0, NULL, - 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x4, 0x0, 0x0, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command C failed (%s)!\n", usb_strerror()); + msg_perr("Command C failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -581,17 +552,16 @@ static int dediprog_command_c(void) static int dediprog_command_f(int timeout) { int ret; - char buf[0x1]; + unsigned char buf[0x1];
memset(buf, 0, sizeof(buf)); - ret = usb_control_msg(dediprog_handle, 0xc2, 0x11, 0xff, 0xff, buf, - 0x1, timeout); + ret = libusb_control_transfer(dediprog_handle, 0xc2, 0x11, 0xff, 0xff, buf, 0x1, timeout); /* This check is most probably wrong. Command F always causes a timeout * in the logs, so we should check for timeout instead of checking for * success. */ if (ret != 0x1) { - msg_perr("Command F failed (%s)!\n", usb_strerror()); + msg_perr("Command F failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -605,9 +575,9 @@ static int dediprog_command_g(void) { int ret;
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x03, NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x07, 0x09, 0x03, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command G failed (%s)!\n", usb_strerror()); + msg_perr("Command G failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -622,9 +592,9 @@ static int dediprog_command_h(void) { int ret;
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x05, NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x07, 0x09, 0x05, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command H failed (%s)!\n", usb_strerror()); + msg_perr("Command H failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -639,9 +609,9 @@ static int dediprog_command_i(void) { int ret;
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x06, NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x07, 0x09, 0x06, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command I failed (%s)!\n", usb_strerror()); + msg_perr("Command I failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -659,9 +629,9 @@ static int dediprog_command_j(void) { int ret;
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x07, NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x07, 0x09, 0x07, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command J failed (%s)!\n", usb_strerror()); + msg_perr("Command J failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -764,24 +734,22 @@ static int dediprog_shutdown(void *data) if (dediprog_set_spi_voltage(0x0)) return 1;
- if (usb_release_interface(dediprog_handle, 0)) { + if (libusb_release_interface(dediprog_handle, 0)) { msg_perr("Could not release USB interface!\n"); return 1; } - if (usb_close(dediprog_handle)) { - msg_perr("Could not close USB device!\n"); - return 1; - } + libusb_close(dediprog_handle); + libusb_exit(usb_ctx); return 0; }
/* URB numbers refer to the first log ever captured. */ int dediprog_init(void) { - struct usb_device *dev; char *voltage, *spispeed; int spispeed_idx = 2, millivolt = 3500; int i, ret; + struct libusb_device_descriptor usb_desc;
msg_pspew("%s\n", __func__);
@@ -804,31 +772,31 @@ int dediprog_init(void) }
/* Here comes the USB stuff. */ - usb_init(); - usb_find_busses(); - usb_find_devices(); - dev = get_device_by_vid_pid(0x0483, 0xdada); - if (!dev) { + libusb_init(&usb_ctx); + if (!usb_ctx) { + msg_perr("Could not open libusb interface!\n"); + return 1; + } + dediprog_handle = libusb_open_device_with_vid_pid(usb_ctx, 0x0483, 0xdada); + if (!dediprog_handle) { msg_perr("Could not find a Dediprog SF100 on USB!\n"); return 1; } - msg_pdbg("Found USB device (%04x:%04x).\n", - dev->descriptor.idVendor, dev->descriptor.idProduct); - dediprog_handle = usb_open(dev); - ret = usb_set_configuration(dediprog_handle, 1); - if (ret < 0) { - msg_perr("Could not set USB device configuration: %i %s\n", - ret, usb_strerror()); - if (usb_close(dediprog_handle)) - msg_perr("Could not close USB device!\n"); + ret = libusb_get_device_descriptor(libusb_get_device(dediprog_handle), &usb_desc); + if (ret != 0) + msg_pinfo("Warning: Could not get usb device descriptor: %i %s\n", ret, libusb_error_name(ret)); + else + msg_pdbg("Found USB device (%04hx:%04hx).\n", usb_desc.idVendor, usb_desc.idProduct); + ret = libusb_set_configuration(dediprog_handle, 1); + if (ret != 0) { + msg_perr("Could not set USB device configuration: %i %s\n", ret, libusb_error_name(ret)); + libusb_close(dediprog_handle); return 1; } - ret = usb_claim_interface(dediprog_handle, 0); + ret = libusb_claim_interface(dediprog_handle, 0); if (ret < 0) { - msg_perr("Could not claim USB device interface %i: %i %s\n", - 0, ret, usb_strerror()); - if (usb_close(dediprog_handle)) - msg_perr("Could not close USB device!\n"); + msg_perr("Could not claim USB device interface %i: %i %s\n", 0, ret, libusb_error_name(ret)); + libusb_close(dediprog_handle); return 1; } dediprog_endpoint = 2;
Hi Nico,
thanks for your patch.
Am 16.11.2012 11:28 schrieb Nico Huber:
This patch tracks the changes in the libusb interface. Nothing changed in the behaviour of the driver, so far.
It will be used by a follow-up patch. It's based on "Enable spi clock setting in dediprog driver".
Signed-off-by: Nico Huber nico.huber@secunet.com
Review follows. The Makefile part checked for libusb 0.1, but it set the linker parameter for libusb 1.0. The code assumed that libusb_error_name() is always available, but that function was only introduced in libusb 1.0.9. There was a conflict between the added device parameter for multiple Dedipro SF100 devices on one PC (r1628) and the removal of get_device_by_vid_pid().
I have fixed and forward ported the code, please check that it works and looks sane.
This patch is completely untested, I only checked whether it compiles. If it works for you and looks sane, please tell me so I can commit.
Signed-off-by: Nico Huber nico.huber@secunet.com Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-dediprog_libusb1_nicohuber/Makefile =================================================================== --- flashrom-dediprog_libusb1_nicohuber/Makefile (Revision 1649) +++ flashrom-dediprog_libusb1_nicohuber/Makefile (Arbeitskopie) @@ -117,7 +117,7 @@ else override CONFIG_PONY_SPI = no endif -# Dediprog and FT2232 are not supported under DOS (missing USB support). +# Dediprog and FT2232 are not supported under DOS (missing libusb support). ifeq ($(CONFIG_DEDIPROG), yes) UNSUPPORTED_FEATURES += CONFIG_DEDIPROG=yes else @@ -480,8 +480,9 @@ FEATURE_CFLAGS += $(shell LC_ALL=C grep -q "FT232H := yes" .features && printf "%s" "-D'HAVE_FT232H=1'") FEATURE_LIBS += $(shell LC_ALL=C grep -q "FTDISUPPORT := yes" .features && printf "%s" "$(FTDILIBS)") PROGRAMMER_OBJS += ft2232_spi.o -# We can't set NEED_USB here because that would transform libftdi auto-enabling +# We can't set NEED_LIBUSB1 here because that would transform libftdi auto-enabling # into a hard requirement for libusb, defeating the purpose of auto-enabling. +# Besides that, the old libftdi requires libusb 0.1, not libusb 1.0. endif
ifeq ($(CONFIG_DUMMY), yes) @@ -534,7 +535,7 @@ ifeq ($(CONFIG_DEDIPROG), yes) FEATURE_CFLAGS += -D'CONFIG_DEDIPROG=1' PROGRAMMER_OBJS += dediprog.o -NEED_USB := yes +NEED_LIBUSB1 := yes endif
ifeq ($(CONFIG_SATAMV), yes) @@ -589,10 +590,11 @@ endif endif
-ifeq ($(NEED_USB), yes) -CHECK_LIBUSB0 = yes -FEATURE_CFLAGS += -D'NEED_USB=1' -USBLIBS := $(shell pkg-config --libs libusb 2>/dev/null || printf "%s" "-lusb") +ifeq ($(NEED_LIBUSB1), yes) +CHECK_LIBUSB1 = yes +FEATURE_CFLAGS += -D'NEED_LIBUSB1=1' +USBLIBS := $(shell pkg-config --libs libusb-1.0 2>/dev/null || printf "%s" "-lusb-1.0") +FEATURE_CFLAGS += $(shell LC_ALL=C grep -q "LIBUSB1_ERROR_NAME := yes" .features && printf "%s" "-D'LIBUSB_HAVE_ERROR_NAME=1'") endif
ifeq ($(CONFIG_PRINT_WIKI), yes) @@ -687,17 +689,17 @@ endef export LIBPCI_TEST
-define LIBUSB0_TEST -#include <usb.h> +define LIBUSB1_TEST +#include <libusb-1.0/libusb.h> int main(int argc, char **argv) { (void) argc; (void) argv; - usb_init(); + libusb_init(NULL); return 0; } endef -export LIBUSB0_TEST +export LIBUSB1_TEST
hwlibs: compiler @printf "" > .libdeps @@ -720,18 +722,18 @@ rm -f .test.c .test.o .test$(EXEC_SUFFIX); exit 1) ) @rm -f .test.c .test.o .test$(EXEC_SUFFIX) endif -ifeq ($(CHECK_LIBUSB0), yes) - @printf "Checking for libusb-0.1/libusb-compat headers... " - @echo "$$LIBUSB0_TEST" > .test.c +ifeq ($(CHECK_LIBUSB1), yes) + @printf "Checking for libusb-1.0 headers... " + @echo "$$LIBUSB1_TEST" > .test.c @$(CC) -c $(CPPFLAGS) $(CFLAGS) .test.c -o .test.o >/dev/null && \ echo "found." || ( echo "not found."; echo; \ - echo "Please install libusb-0.1 headers or libusb-compat headers."; \ + echo "Please install libusb-1.0 headers."; \ echo "See README for more information."; echo; \ rm -f .test.c .test.o; exit 1) - @printf "Checking if libusb-0.1 is usable... " + @printf "Checking if libusb-1.0 is usable... " @$(CC) $(LDFLAGS) .test.o -o .test$(EXEC_SUFFIX) $(LIBS) $(USBLIBS) >/dev/null && \ echo "yes." || ( echo "no."; \ - echo "Please install libusb-0.1 or libusb-compat."; \ + echo "Please install libusb-1.0."; \ echo "See README for more information."; echo; \ rm -f .test.c .test.o .test$(EXEC_SUFFIX); exit 1) @rm -f .test.c .test.o .test$(EXEC_SUFFIX) @@ -753,6 +755,18 @@ @false endif
+define LIBUSB1_ERROR_NAME_TEST +#include <libusb-1.0/libusb.h> +int main(int argc, char **argv) +{ + (void) argc; + (void) argv; + libusb_error_name(0); + return 0; +} +endef +export LIBUSB1_ERROR_NAME_TEST + define FTDI_TEST #include <ftdi.h> struct ftdi_context *ftdic = NULL; @@ -799,6 +813,13 @@
features: compiler @echo "FEATURES := yes" > .features.tmp +ifeq ($(CHECK_LIBUSB1), yes) + @printf "Checking for libusb_error_name support in libusb-1.0... " + @echo "$$LIBUSB1_ERROR_NAME_TEST" >> .featuretest.c + @$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) .featuretest.c -o .featuretest$(EXEC_SUFFIX) $(USBLIBS) $(LIBS) >/dev/null 2>&1 && \ + ( echo "found."; echo "LIBUSB1_ERROR_NAME := yes" >> .features.tmp ) || \ + ( echo "not found." ) +endif ifeq ($(CONFIG_FT2232_SPI), yes) @printf "Checking for FTDI support... " @echo "$$FTDI_TEST" > .featuretest.c Index: flashrom-dediprog_libusb1_nicohuber/dediprog.c =================================================================== --- flashrom-dediprog_libusb1_nicohuber/dediprog.c (Revision 1649) +++ flashrom-dediprog_libusb1_nicohuber/dediprog.c (Arbeitskopie) @@ -2,6 +2,7 @@ * This file is part of the flashrom project. * * Copyright (C) 2010 Carl-Daniel Hailfinger + * 2012 secunet Security Networks AG * * 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 @@ -21,7 +22,8 @@ #include <string.h> #include <limits.h> #include <errno.h> -#include <usb.h> +#include <stdlib.h> +#include <libusb-1.0/libusb.h> #include "flash.h" #include "chipdrivers.h" #include "programmer.h" @@ -29,7 +31,8 @@
#define FIRMWARE_VERSION(x,y,z) ((x << 16) | (y << 8) | z) #define DEFAULT_TIMEOUT 3000 -static usb_dev_handle *dediprog_handle; +static libusb_context *usb_ctx; +static libusb_device_handle *dediprog_handle; static int dediprog_firmwareversion; static int dediprog_endpoint;
@@ -47,27 +50,61 @@ } #endif
+#ifndef LIBUSB_HAVE_ERROR_NAME +/* Quick and dirty replacement for missing libusb_error_name in older libusb 1.0. */ +const char *libusb_error_name(int error_code) +{ + /* 18 chars for text, rest for number, sign, nullbyte. */ + static char my_libusb_error[18 + 3 * sizeof(int) + 2]; + + sprintf(my_libusb_error, "libusb error code %i", error_code); + return my_libusb_error; +} +#endif + /* Might be useful for other USB devices as well. static for now. */ /* device parameter allows user to specify one device of multiple installed */ -static struct usb_device *get_device_by_vid_pid(uint16_t vid, uint16_t pid, unsigned int device) +static struct libusb_device_handle *get_device_by_vid_pid_number(uint16_t vid, uint16_t pid, unsigned int num) { - struct usb_bus *bus; - struct usb_device *dev; + struct libusb_device **list; + ssize_t i = 0; + int err = 0; + struct libusb_device_handle *handle = NULL; + struct libusb_device_descriptor desc = {}; + ssize_t count = libusb_get_device_list(usb_ctx, &list);
- for (bus = usb_get_busses(); bus; bus = bus->next) - for (dev = bus->devices; dev; dev = dev->next) - if ((dev->descriptor.idVendor == vid) && - (dev->descriptor.idProduct == pid)) { - if (device == 0) - return dev; - device--; + if (count < 0) { + msg_perr("Getting the USB device list failed (%s)!\n", libusb_error_name(count)); + return NULL; + } + + for (i = 0; i < count; i++) { + struct libusb_device *dev = list[i]; + err = libusb_get_device_descriptor(dev, &desc); + if (err != 0) { + msg_perr("Getting the USB device list failed (%s)!\n", libusb_error_name(err)); + libusb_free_device_list(list, 1); + return NULL; + } + if ((desc.idVendor == vid) && (desc.idProduct == pid)) { + if (num == 0) { + err = libusb_open(dev, &handle); + if (err != 0) { + msg_perr("Getting the USB device list failed (%s)!\n", + libusb_error_name(err)); + libusb_free_device_list(list, 1); + return NULL; + } + break; } + num--; + } + } + libusb_free_device_list(list, 1);
- return NULL; + return handle; }
-//int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout); - /* Set/clear LEDs on dediprog */ #define PASS_ON (0 << 0) #define PASS_OFF (1 << 0) @@ -101,11 +138,10 @@ target_leds = leds; }
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, target_leds, - NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x07, 0x09, target_leds, + NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command Set LED 0x%x failed (%s)!\n", - leds, usb_strerror()); + msg_perr("Command Set LED 0x%x failed (%s)!\n", leds, libusb_error_name(ret)); return 1; }
@@ -144,8 +180,8 @@ /* Wait some time as the original driver does. */ programmer_delay(200 * 1000); } - ret = usb_control_msg(dediprog_handle, 0x42, 0x9, voltage_selector, - 0xff, NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x9, voltage_selector, + 0xff, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { msg_perr("Command Set SPI Voltage 0x%x failed!\n", voltage_selector); @@ -188,8 +224,8 @@
msg_pdbg("SPI speed is %sHz\n", spispeeds[spispeed_idx].name);
- ret = usb_control_msg(dediprog_handle, 0x42, 0x61, spispeeds[spispeed_idx].speed, 0xff, - NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x61, spispeeds[spispeed_idx].speed, 0xff, + NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { msg_perr("Command Set SPI Speed 0x%x failed!\n", spispeeds[spispeed_idx].speed); return 1; @@ -205,15 +241,15 @@ static int dediprog_spi_bulk_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len) { - int ret; + int ret, transferred; unsigned int i; /* chunksize must be 512, other sizes will NOT work at all. */ const unsigned int chunksize = 0x200; const unsigned int count = len / chunksize; - const char count_and_chunk[] = {count & 0xff, - (count >> 8) & 0xff, - chunksize & 0xff, - (chunksize >> 8) & 0xff}; + const unsigned char count_and_chunk[] = { + count & 0xff, (count >> 8) & 0xff, + chunksize & 0xff, (chunksize >> 8) & 0xff + };
if ((start % chunksize) || (len % chunksize)) { msg_perr("%s: Unaligned start=%i, len=%i! Please report a bug " @@ -227,22 +263,20 @@ /* Command Read SPI Bulk. No idea which read command is used on the * SPI side. */ - ret = usb_control_msg(dediprog_handle, 0x42, 0x20, start % 0x10000, - start / 0x10000, (char *)count_and_chunk, - sizeof(count_and_chunk), DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x20, start % 0x10000, start / 0x10000, + (unsigned char *)count_and_chunk, sizeof(count_and_chunk), + DEFAULT_TIMEOUT); if (ret != sizeof(count_and_chunk)) { - msg_perr("Command Read SPI Bulk failed, %i %s!\n", ret, - usb_strerror()); + msg_perr("Command Read SPI Bulk failed, %i %s!\n", ret, libusb_error_name(ret)); return 1; }
for (i = 0; i < count; i++) { - ret = usb_bulk_read(dediprog_handle, 0x80 | dediprog_endpoint, - (char *)buf + i * chunksize, chunksize, - DEFAULT_TIMEOUT); - if (ret != chunksize) { - msg_perr("SPI bulk read %i failed, expected %i, got %i " - "%s!\n", i, chunksize, ret, usb_strerror()); + ret = libusb_bulk_transfer(dediprog_handle, 0x80 | dediprog_endpoint, + buf + i * chunksize, chunksize, &transferred, DEFAULT_TIMEOUT); + if ((ret < 0) || (transferred != chunksize)) { + msg_perr("SPI bulk read %i failed, expected %i, got %i %s!\n", + i, chunksize, ret, libusb_error_name(ret)); return 1; } } @@ -306,7 +340,7 @@ static int dediprog_spi_bulk_write(struct flashctx *flash, uint8_t *buf, unsigned int chunksize, unsigned int start, unsigned int len, uint8_t dedi_spi_cmd) { - int ret; + int ret, transferred; unsigned int i; /* USB transfer size must be 512, other sizes will NOT work at all. * chunksize is the real data size per USB bulk transfer. The remaining @@ -314,7 +348,7 @@ */ const unsigned int count = len / chunksize; const char count_and_cmd[] = {count & 0xff, (count >> 8) & 0xff, 0x00, dedi_spi_cmd}; - char usbbuf[512]; + unsigned char usbbuf[512];
/* * We should change this check to @@ -339,23 +373,21 @@ /* Command Write SPI Bulk. No idea which write command is used on the * SPI side. */ - ret = usb_control_msg(dediprog_handle, 0x42, 0x30, start % 0x10000, start / 0x10000, - (char *)count_and_cmd, sizeof(count_and_cmd), DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x30, start % 0x10000, start / 0x10000, + (unsigned char *)count_and_cmd, sizeof(count_and_cmd), DEFAULT_TIMEOUT); if (ret != sizeof(count_and_cmd)) { - msg_perr("Command Write SPI Bulk failed, %i %s!\n", ret, - usb_strerror()); + msg_perr("Command Write SPI Bulk failed, %i %s!\n", ret, libusb_error_name(ret)); return 1; }
for (i = 0; i < count; i++) { memset(usbbuf, 0xff, sizeof(usbbuf)); memcpy(usbbuf, buf + i * chunksize, chunksize); - ret = usb_bulk_write(dediprog_handle, dediprog_endpoint, - usbbuf, 512, - DEFAULT_TIMEOUT); - if (ret != 512) { - msg_perr("SPI bulk write failed, expected %i, got %i " - "%s!\n", 512, ret, usb_strerror()); + ret = libusb_bulk_transfer(dediprog_handle, dediprog_endpoint, + usbbuf, 512, &transferred, DEFAULT_TIMEOUT); + if ((ret < 0) || (transferred != 512)) { + msg_perr("SPI bulk write failed, expected %i, got %i %s!\n", + 512, ret, libusb_error_name(ret)); return 1; } } @@ -444,23 +476,20 @@ msg_perr("Untested readcnt=%i, aborting.\n", readcnt); return 1; } - - ret = usb_control_msg(dediprog_handle, 0x42, 0x1, 0xff, - readcnt ? 0x1 : 0x0, (char *)writearr, writecnt, - DEFAULT_TIMEOUT); + + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x1, 0xff, readcnt ? 0x1 : 0x0, + (unsigned char *)writearr, writecnt, DEFAULT_TIMEOUT); if (ret != writecnt) { - msg_perr("Send SPI failed, expected %i, got %i %s!\n", - writecnt, ret, usb_strerror()); + msg_perr("Send SPI failed, expected %i, got %i %s!\n", writecnt, ret, libusb_error_name(ret)); return 1; } if (!readcnt) return 0; memset(readarr, 0, readcnt); - ret = usb_control_msg(dediprog_handle, 0xc2, 0x01, 0xbb8, 0x0000, - (char *)readarr, readcnt, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0xc2, 0x01, 0xbb8, 0x0000, + readarr, readcnt, DEFAULT_TIMEOUT); if (ret != readcnt) { - msg_perr("Receive SPI failed, expected %i, got %i %s!\n", - readcnt, ret, usb_strerror()); + msg_perr("Receive SPI failed, expected %i, got %i %s!\n", readcnt, ret, libusb_error_name(ret)); return 1; } return 0; @@ -470,22 +499,18 @@ { int ret; int fw[3]; - char buf[0x11]; + unsigned char buf[0x11];
/* Command Prepare Receive Device String. */ memset(buf, 0, sizeof(buf)); - ret = usb_control_msg(dediprog_handle, 0xc3, 0x7, 0x0, 0xef03, buf, - 0x1, DEFAULT_TIMEOUT); - /* The char casting is needed to stop gcc complaining about an always true comparison. */ - if ((ret != 0x1) || (buf[0] != (char)0xff)) { - msg_perr("Unexpected response to Command Prepare Receive Device" - " String!\n"); + ret = libusb_control_transfer(dediprog_handle, 0xc3, 0x7, 0x0, 0xef03, buf, 0x1, DEFAULT_TIMEOUT); + if ((ret != 0x1) || (buf[0] != 0xff)) { + msg_perr("Unexpected response to Command Prepare Receive Device String!\n"); return 1; } /* Command Receive Device String. */ memset(buf, 0, sizeof(buf)); - ret = usb_control_msg(dediprog_handle, 0xc2, 0x8, 0xff, 0xff, buf, - 0x10, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0xc2, 0x8, 0xff, 0xff, buf, 0x10, DEFAULT_TIMEOUT); if (ret != 0x10) { msg_perr("Incomplete/failed Command Receive Device String!\n"); return 1; @@ -496,7 +521,7 @@ msg_perr("Device not a SF100!\n"); return 1; } - if (sscanf(buf, "SF100 V:%d.%d.%d ", &fw[0], &fw[1], &fw[2]) != 3) { + if (sscanf((const char *)buf, "SF100 V:%d.%d.%d ", &fw[0], &fw[1], &fw[2]) != 3) { msg_perr("Unexpected firmware version string!\n"); return 1; } @@ -517,13 +542,12 @@ static int dediprog_command_a(void) { int ret; - char buf[0x1]; + unsigned char buf[0x1];
memset(buf, 0, sizeof(buf)); - ret = usb_control_msg(dediprog_handle, 0xc3, 0xb, 0x0, 0x0, buf, - 0x1, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0xc3, 0xb, 0x0, 0x0, buf, 0x1, DEFAULT_TIMEOUT); if (ret < 0) { - msg_perr("Command A failed (%s)!\n", usb_strerror()); + msg_perr("Command A failed (%s)!\n", libusb_error_name(ret)); return 1; } if ((ret != 0x1) || (buf[0] != 0x6f)) { @@ -541,13 +565,12 @@ static int dediprog_command_b(void) { int ret; - char buf[0x3]; + unsigned char buf[0x3];
memset(buf, 0, sizeof(buf)); - ret = usb_control_msg(dediprog_handle, 0xc3, 0x7, 0x0, 0xef00, buf, - 0x3, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0xc3, 0x7, 0x0, 0xef00, buf, 0x3, DEFAULT_TIMEOUT); if (ret < 0) { - msg_perr("Command B failed (%s)!\n", usb_strerror()); + msg_perr("Command B failed (%s)!\n", libusb_error_name(ret)); return 1; } if ((ret != 0x3) || (buf[0] != 0xff) || (buf[1] != 0xff) || @@ -569,10 +592,9 @@ { int ret;
- ret = usb_control_msg(dediprog_handle, 0x42, 0x4, 0x0, 0x0, NULL, - 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x4, 0x0, 0x0, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command C failed (%s)!\n", usb_strerror()); + msg_perr("Command C failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -587,17 +609,16 @@ static int dediprog_command_f(int timeout) { int ret; - char buf[0x1]; + unsigned char buf[0x1];
memset(buf, 0, sizeof(buf)); - ret = usb_control_msg(dediprog_handle, 0xc2, 0x11, 0xff, 0xff, buf, - 0x1, timeout); + ret = libusb_control_transfer(dediprog_handle, 0xc2, 0x11, 0xff, 0xff, buf, 0x1, timeout); /* This check is most probably wrong. Command F always causes a timeout * in the logs, so we should check for timeout instead of checking for * success. */ if (ret != 0x1) { - msg_perr("Command F failed (%s)!\n", usb_strerror()); + msg_perr("Command F failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -611,9 +632,9 @@ { int ret;
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x03, NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x07, 0x09, 0x03, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command G failed (%s)!\n", usb_strerror()); + msg_perr("Command G failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -628,9 +649,9 @@ { int ret;
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x05, NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x07, 0x09, 0x05, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command H failed (%s)!\n", usb_strerror()); + msg_perr("Command H failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -645,9 +666,9 @@ { int ret;
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x06, NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x07, 0x09, 0x06, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command I failed (%s)!\n", usb_strerror()); + msg_perr("Command I failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -665,9 +686,9 @@ { int ret;
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x07, NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x07, 0x09, 0x07, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command J failed (%s)!\n", usb_strerror()); + msg_perr("Command J failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -770,26 +791,24 @@ if (dediprog_set_spi_voltage(0x0)) return 1;
- if (usb_release_interface(dediprog_handle, 0)) { + if (libusb_release_interface(dediprog_handle, 0)) { msg_perr("Could not release USB interface!\n"); return 1; } - if (usb_close(dediprog_handle)) { - msg_perr("Could not close USB device!\n"); - return 1; - } + libusb_close(dediprog_handle); + libusb_exit(usb_ctx); return 0; }
/* URB numbers refer to the first log ever captured. */ int dediprog_init(void) { - struct usb_device *dev; char *voltage, *device, *spispeed; int spispeed_idx = 2; int millivolt = 3500; long usedevice = 0; int i, ret; + struct libusb_device_descriptor usb_desc;
msg_pspew("%s\n", __func__);
@@ -842,31 +861,31 @@ free(device);
/* Here comes the USB stuff. */ - usb_init(); - usb_find_busses(); - usb_find_devices(); - dev = get_device_by_vid_pid(0x0483, 0xdada, (unsigned int) usedevice); - if (!dev) { + libusb_init(&usb_ctx); + if (!usb_ctx) { + msg_perr("Could not open libusb interface!\n"); + return 1; + } + dediprog_handle = get_device_by_vid_pid_number(0x0483, 0xdada, (unsigned int) usedevice); + if (!dediprog_handle) { msg_perr("Could not find a Dediprog SF100 on USB!\n"); return 1; } - msg_pdbg("Found USB device (%04x:%04x).\n", - dev->descriptor.idVendor, dev->descriptor.idProduct); - dediprog_handle = usb_open(dev); - ret = usb_set_configuration(dediprog_handle, 1); - if (ret < 0) { - msg_perr("Could not set USB device configuration: %i %s\n", - ret, usb_strerror()); - if (usb_close(dediprog_handle)) - msg_perr("Could not close USB device!\n"); + ret = libusb_get_device_descriptor(libusb_get_device(dediprog_handle), &usb_desc); + if (ret != 0) + msg_pinfo("Warning: Could not get usb device descriptor: %i %s\n", ret, libusb_error_name(ret)); + else + msg_pdbg("Found USB device (%04hx:%04hx).\n", usb_desc.idVendor, usb_desc.idProduct); + ret = libusb_set_configuration(dediprog_handle, 1); + if (ret != 0) { + msg_perr("Could not set USB device configuration: %i %s\n", ret, libusb_error_name(ret)); + libusb_close(dediprog_handle); return 1; } - ret = usb_claim_interface(dediprog_handle, 0); + ret = libusb_claim_interface(dediprog_handle, 0); if (ret < 0) { - msg_perr("Could not claim USB device interface %i: %i %s\n", - 0, ret, usb_strerror()); - if (usb_close(dediprog_handle)) - msg_perr("Could not close USB device!\n"); + msg_perr("Could not claim USB device interface %i: %i %s\n", 0, ret, libusb_error_name(ret)); + libusb_close(dediprog_handle); return 1; } dediprog_endpoint = 2;
Am 21.02.2013 01:46 schrieb Carl-Daniel Hailfinger:
Hi Nico,
thanks for your patch.
Am 16.11.2012 11:28 schrieb Nico Huber:
This patch tracks the changes in the libusb interface. Nothing changed in the behaviour of the driver, so far.
It will be used by a follow-up patch. It's based on "Enable spi clock setting in dediprog driver".
Signed-off-by: Nico Huber nico.huber@secunet.com
Review follows. The Makefile part checked for libusb 0.1, but it set the linker parameter for libusb 1.0. The code assumed that libusb_error_name() is always available, but that function was only introduced in libusb 1.0.9. There was a conflict between the added device parameter for multiple Dedipro SF100 devices on one PC (r1628) and the removal of get_device_by_vid_pid().
I have fixed and forward ported the code, please check that it works and looks sane.
This patch is completely untested, I only checked whether it compiles. If it works for you and looks sane, please tell me so I can commit.
Signed-off-by: Nico Huber nico.huber@secunet.com
New version. Fixed error messages and incomplete cleanup in the error case.
libusb header file location is still something I have to fix in another iteration.
Signed-off-by: Nico Huber nico.huber@secunet.com Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-dediprog_libusb1_nicohuber/Makefile =================================================================== --- flashrom-dediprog_libusb1_nicohuber/Makefile (Revision 1649) +++ flashrom-dediprog_libusb1_nicohuber/Makefile (Arbeitskopie) @@ -117,7 +117,7 @@ else override CONFIG_PONY_SPI = no endif -# Dediprog and FT2232 are not supported under DOS (missing USB support). +# Dediprog and FT2232 are not supported under DOS (missing libusb support). ifeq ($(CONFIG_DEDIPROG), yes) UNSUPPORTED_FEATURES += CONFIG_DEDIPROG=yes else @@ -480,8 +480,9 @@ FEATURE_CFLAGS += $(shell LC_ALL=C grep -q "FT232H := yes" .features && printf "%s" "-D'HAVE_FT232H=1'") FEATURE_LIBS += $(shell LC_ALL=C grep -q "FTDISUPPORT := yes" .features && printf "%s" "$(FTDILIBS)") PROGRAMMER_OBJS += ft2232_spi.o -# We can't set NEED_USB here because that would transform libftdi auto-enabling +# We can't set NEED_LIBUSB1 here because that would transform libftdi auto-enabling # into a hard requirement for libusb, defeating the purpose of auto-enabling. +# Besides that, the old libftdi requires libusb 0.1, not libusb 1.0. endif
ifeq ($(CONFIG_DUMMY), yes) @@ -534,7 +535,7 @@ ifeq ($(CONFIG_DEDIPROG), yes) FEATURE_CFLAGS += -D'CONFIG_DEDIPROG=1' PROGRAMMER_OBJS += dediprog.o -NEED_USB := yes +NEED_LIBUSB1 := yes endif
ifeq ($(CONFIG_SATAMV), yes) @@ -589,10 +590,11 @@ endif endif
-ifeq ($(NEED_USB), yes) -CHECK_LIBUSB0 = yes -FEATURE_CFLAGS += -D'NEED_USB=1' -USBLIBS := $(shell pkg-config --libs libusb 2>/dev/null || printf "%s" "-lusb") +ifeq ($(NEED_LIBUSB1), yes) +CHECK_LIBUSB1 = yes +FEATURE_CFLAGS += -D'NEED_LIBUSB1=1' +USBLIBS := $(shell pkg-config --libs libusb-1.0 2>/dev/null || printf "%s" "-lusb-1.0") +FEATURE_CFLAGS += $(shell LC_ALL=C grep -q "LIBUSB1_ERROR_NAME := yes" .features && printf "%s" "-D'LIBUSB_HAVE_ERROR_NAME=1'") endif
ifeq ($(CONFIG_PRINT_WIKI), yes) @@ -687,17 +689,17 @@ endef export LIBPCI_TEST
-define LIBUSB0_TEST -#include <usb.h> +define LIBUSB1_TEST +#include <libusb-1.0/libusb.h> int main(int argc, char **argv) { (void) argc; (void) argv; - usb_init(); + libusb_init(NULL); return 0; } endef -export LIBUSB0_TEST +export LIBUSB1_TEST
hwlibs: compiler @printf "" > .libdeps @@ -720,18 +722,18 @@ rm -f .test.c .test.o .test$(EXEC_SUFFIX); exit 1) ) @rm -f .test.c .test.o .test$(EXEC_SUFFIX) endif -ifeq ($(CHECK_LIBUSB0), yes) - @printf "Checking for libusb-0.1/libusb-compat headers... " - @echo "$$LIBUSB0_TEST" > .test.c +ifeq ($(CHECK_LIBUSB1), yes) + @printf "Checking for libusb-1.0 headers... " + @echo "$$LIBUSB1_TEST" > .test.c @$(CC) -c $(CPPFLAGS) $(CFLAGS) .test.c -o .test.o >/dev/null && \ echo "found." || ( echo "not found."; echo; \ - echo "Please install libusb-0.1 headers or libusb-compat headers."; \ + echo "Please install libusb-1.0 headers."; \ echo "See README for more information."; echo; \ rm -f .test.c .test.o; exit 1) - @printf "Checking if libusb-0.1 is usable... " + @printf "Checking if libusb-1.0 is usable... " @$(CC) $(LDFLAGS) .test.o -o .test$(EXEC_SUFFIX) $(LIBS) $(USBLIBS) >/dev/null && \ echo "yes." || ( echo "no."; \ - echo "Please install libusb-0.1 or libusb-compat."; \ + echo "Please install libusb-1.0."; \ echo "See README for more information."; echo; \ rm -f .test.c .test.o .test$(EXEC_SUFFIX); exit 1) @rm -f .test.c .test.o .test$(EXEC_SUFFIX) @@ -753,6 +755,18 @@ @false endif
+define LIBUSB1_ERROR_NAME_TEST +#include <libusb-1.0/libusb.h> +int main(int argc, char **argv) +{ + (void) argc; + (void) argv; + libusb_error_name(0); + return 0; +} +endef +export LIBUSB1_ERROR_NAME_TEST + define FTDI_TEST #include <ftdi.h> struct ftdi_context *ftdic = NULL; @@ -799,6 +813,13 @@
features: compiler @echo "FEATURES := yes" > .features.tmp +ifeq ($(CHECK_LIBUSB1), yes) + @printf "Checking for libusb_error_name support in libusb-1.0... " + @echo "$$LIBUSB1_ERROR_NAME_TEST" >> .featuretest.c + @$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) .featuretest.c -o .featuretest$(EXEC_SUFFIX) $(USBLIBS) $(LIBS) >/dev/null 2>&1 && \ + ( echo "found."; echo "LIBUSB1_ERROR_NAME := yes" >> .features.tmp ) || \ + ( echo "not found." ) +endif ifeq ($(CONFIG_FT2232_SPI), yes) @printf "Checking for FTDI support... " @echo "$$FTDI_TEST" > .featuretest.c Index: flashrom-dediprog_libusb1_nicohuber/dediprog.c =================================================================== --- flashrom-dediprog_libusb1_nicohuber/dediprog.c (Revision 1649) +++ flashrom-dediprog_libusb1_nicohuber/dediprog.c (Arbeitskopie) @@ -2,6 +2,7 @@ * This file is part of the flashrom project. * * Copyright (C) 2010 Carl-Daniel Hailfinger + * 2012 secunet Security Networks AG * * 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 @@ -21,7 +22,8 @@ #include <string.h> #include <limits.h> #include <errno.h> -#include <usb.h> +#include <stdlib.h> +#include <libusb-1.0/libusb.h> #include "flash.h" #include "chipdrivers.h" #include "programmer.h" @@ -29,7 +31,8 @@
#define FIRMWARE_VERSION(x,y,z) ((x << 16) | (y << 8) | z) #define DEFAULT_TIMEOUT 3000 -static usb_dev_handle *dediprog_handle; +static libusb_context *usb_ctx; +static libusb_device_handle *dediprog_handle; static int dediprog_firmwareversion; static int dediprog_endpoint;
@@ -47,27 +50,63 @@ } #endif
+#ifndef LIBUSB_HAVE_ERROR_NAME +/* Quick and dirty replacement for missing libusb_error_name in older libusb 1.0. */ +const char *libusb_error_name(int error_code) +{ + /* 18 chars for text, rest for number, sign, nullbyte. */ + static char my_libusb_error[18 + 3 * sizeof(int) + 2]; + + sprintf(my_libusb_error, "libusb error code %i", error_code); + return my_libusb_error; +} +#endif + /* Might be useful for other USB devices as well. static for now. */ /* device parameter allows user to specify one device of multiple installed */ -static struct usb_device *get_device_by_vid_pid(uint16_t vid, uint16_t pid, unsigned int device) +static struct libusb_device_handle *get_device_by_vid_pid_number(uint16_t vid, uint16_t pid, unsigned int num) { - struct usb_bus *bus; - struct usb_device *dev; + struct libusb_device **list; + ssize_t i = 0; + int err = 0; + struct libusb_device_handle *handle = NULL; + struct libusb_device_descriptor desc = {}; + ssize_t count = libusb_get_device_list(usb_ctx, &list);
- for (bus = usb_get_busses(); bus; bus = bus->next) - for (dev = bus->devices; dev; dev = dev->next) - if ((dev->descriptor.idVendor == vid) && - (dev->descriptor.idProduct == pid)) { - if (device == 0) - return dev; - device--; + if (count < 0) { + msg_perr("Getting the USB device list failed (%s)!\n", libusb_error_name(count)); + return NULL; + } + + for (i = 0; i < count; i++) { + struct libusb_device *dev = list[i]; + 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 %04hx:%04hx at address %hhx-%hhx.\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 NULL; + return handle; }
-//int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout); - /* Set/clear LEDs on dediprog */ #define PASS_ON (0 << 0) #define PASS_OFF (1 << 0) @@ -101,11 +140,10 @@ target_leds = leds; }
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, target_leds, - NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x07, 0x09, target_leds, + NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command Set LED 0x%x failed (%s)!\n", - leds, usb_strerror()); + msg_perr("Command Set LED 0x%x failed (%s)!\n", leds, libusb_error_name(ret)); return 1; }
@@ -144,8 +182,8 @@ /* Wait some time as the original driver does. */ programmer_delay(200 * 1000); } - ret = usb_control_msg(dediprog_handle, 0x42, 0x9, voltage_selector, - 0xff, NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x9, voltage_selector, + 0xff, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { msg_perr("Command Set SPI Voltage 0x%x failed!\n", voltage_selector); @@ -188,8 +226,8 @@
msg_pdbg("SPI speed is %sHz\n", spispeeds[spispeed_idx].name);
- ret = usb_control_msg(dediprog_handle, 0x42, 0x61, spispeeds[spispeed_idx].speed, 0xff, - NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x61, spispeeds[spispeed_idx].speed, 0xff, + NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { msg_perr("Command Set SPI Speed 0x%x failed!\n", spispeeds[spispeed_idx].speed); return 1; @@ -205,15 +243,15 @@ static int dediprog_spi_bulk_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len) { - int ret; + int ret, transferred; unsigned int i; /* chunksize must be 512, other sizes will NOT work at all. */ const unsigned int chunksize = 0x200; const unsigned int count = len / chunksize; - const char count_and_chunk[] = {count & 0xff, - (count >> 8) & 0xff, - chunksize & 0xff, - (chunksize >> 8) & 0xff}; + const unsigned char count_and_chunk[] = { + count & 0xff, (count >> 8) & 0xff, + chunksize & 0xff, (chunksize >> 8) & 0xff + };
if ((start % chunksize) || (len % chunksize)) { msg_perr("%s: Unaligned start=%i, len=%i! Please report a bug " @@ -227,22 +265,20 @@ /* Command Read SPI Bulk. No idea which read command is used on the * SPI side. */ - ret = usb_control_msg(dediprog_handle, 0x42, 0x20, start % 0x10000, - start / 0x10000, (char *)count_and_chunk, - sizeof(count_and_chunk), DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x20, start % 0x10000, start / 0x10000, + (unsigned char *)count_and_chunk, sizeof(count_and_chunk), + DEFAULT_TIMEOUT); if (ret != sizeof(count_and_chunk)) { - msg_perr("Command Read SPI Bulk failed, %i %s!\n", ret, - usb_strerror()); + msg_perr("Command Read SPI Bulk failed, %i %s!\n", ret, libusb_error_name(ret)); return 1; }
for (i = 0; i < count; i++) { - ret = usb_bulk_read(dediprog_handle, 0x80 | dediprog_endpoint, - (char *)buf + i * chunksize, chunksize, - DEFAULT_TIMEOUT); - if (ret != chunksize) { - msg_perr("SPI bulk read %i failed, expected %i, got %i " - "%s!\n", i, chunksize, ret, usb_strerror()); + ret = libusb_bulk_transfer(dediprog_handle, 0x80 | dediprog_endpoint, + buf + i * chunksize, chunksize, &transferred, DEFAULT_TIMEOUT); + if ((ret < 0) || (transferred != chunksize)) { + msg_perr("SPI bulk read %i failed, expected %i, got %i %s!\n", + i, chunksize, ret, libusb_error_name(ret)); return 1; } } @@ -306,7 +342,7 @@ static int dediprog_spi_bulk_write(struct flashctx *flash, uint8_t *buf, unsigned int chunksize, unsigned int start, unsigned int len, uint8_t dedi_spi_cmd) { - int ret; + int ret, transferred; unsigned int i; /* USB transfer size must be 512, other sizes will NOT work at all. * chunksize is the real data size per USB bulk transfer. The remaining @@ -314,7 +350,7 @@ */ const unsigned int count = len / chunksize; const char count_and_cmd[] = {count & 0xff, (count >> 8) & 0xff, 0x00, dedi_spi_cmd}; - char usbbuf[512]; + unsigned char usbbuf[512];
/* * We should change this check to @@ -339,23 +375,21 @@ /* Command Write SPI Bulk. No idea which write command is used on the * SPI side. */ - ret = usb_control_msg(dediprog_handle, 0x42, 0x30, start % 0x10000, start / 0x10000, - (char *)count_and_cmd, sizeof(count_and_cmd), DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x30, start % 0x10000, start / 0x10000, + (unsigned char *)count_and_cmd, sizeof(count_and_cmd), DEFAULT_TIMEOUT); if (ret != sizeof(count_and_cmd)) { - msg_perr("Command Write SPI Bulk failed, %i %s!\n", ret, - usb_strerror()); + msg_perr("Command Write SPI Bulk failed, %i %s!\n", ret, libusb_error_name(ret)); return 1; }
for (i = 0; i < count; i++) { memset(usbbuf, 0xff, sizeof(usbbuf)); memcpy(usbbuf, buf + i * chunksize, chunksize); - ret = usb_bulk_write(dediprog_handle, dediprog_endpoint, - usbbuf, 512, - DEFAULT_TIMEOUT); - if (ret != 512) { - msg_perr("SPI bulk write failed, expected %i, got %i " - "%s!\n", 512, ret, usb_strerror()); + ret = libusb_bulk_transfer(dediprog_handle, dediprog_endpoint, + usbbuf, 512, &transferred, DEFAULT_TIMEOUT); + if ((ret < 0) || (transferred != 512)) { + msg_perr("SPI bulk write failed, expected %i, got %i %s!\n", + 512, ret, libusb_error_name(ret)); return 1; } } @@ -444,23 +478,20 @@ msg_perr("Untested readcnt=%i, aborting.\n", readcnt); return 1; } - - ret = usb_control_msg(dediprog_handle, 0x42, 0x1, 0xff, - readcnt ? 0x1 : 0x0, (char *)writearr, writecnt, - DEFAULT_TIMEOUT); + + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x1, 0xff, readcnt ? 0x1 : 0x0, + (unsigned char *)writearr, writecnt, DEFAULT_TIMEOUT); if (ret != writecnt) { - msg_perr("Send SPI failed, expected %i, got %i %s!\n", - writecnt, ret, usb_strerror()); + msg_perr("Send SPI failed, expected %i, got %i %s!\n", writecnt, ret, libusb_error_name(ret)); return 1; } if (!readcnt) return 0; memset(readarr, 0, readcnt); - ret = usb_control_msg(dediprog_handle, 0xc2, 0x01, 0xbb8, 0x0000, - (char *)readarr, readcnt, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0xc2, 0x01, 0xbb8, 0x0000, + readarr, readcnt, DEFAULT_TIMEOUT); if (ret != readcnt) { - msg_perr("Receive SPI failed, expected %i, got %i %s!\n", - readcnt, ret, usb_strerror()); + msg_perr("Receive SPI failed, expected %i, got %i %s!\n", readcnt, ret, libusb_error_name(ret)); return 1; } return 0; @@ -470,22 +501,18 @@ { int ret; int fw[3]; - char buf[0x11]; + unsigned char buf[0x11];
/* Command Prepare Receive Device String. */ memset(buf, 0, sizeof(buf)); - ret = usb_control_msg(dediprog_handle, 0xc3, 0x7, 0x0, 0xef03, buf, - 0x1, DEFAULT_TIMEOUT); - /* The char casting is needed to stop gcc complaining about an always true comparison. */ - if ((ret != 0x1) || (buf[0] != (char)0xff)) { - msg_perr("Unexpected response to Command Prepare Receive Device" - " String!\n"); + ret = libusb_control_transfer(dediprog_handle, 0xc3, 0x7, 0x0, 0xef03, buf, 0x1, DEFAULT_TIMEOUT); + if ((ret != 0x1) || (buf[0] != 0xff)) { + msg_perr("Unexpected response to Command Prepare Receive Device String!\n"); return 1; } /* Command Receive Device String. */ memset(buf, 0, sizeof(buf)); - ret = usb_control_msg(dediprog_handle, 0xc2, 0x8, 0xff, 0xff, buf, - 0x10, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0xc2, 0x8, 0xff, 0xff, buf, 0x10, DEFAULT_TIMEOUT); if (ret != 0x10) { msg_perr("Incomplete/failed Command Receive Device String!\n"); return 1; @@ -496,7 +523,7 @@ msg_perr("Device not a SF100!\n"); return 1; } - if (sscanf(buf, "SF100 V:%d.%d.%d ", &fw[0], &fw[1], &fw[2]) != 3) { + if (sscanf((const char *)buf, "SF100 V:%d.%d.%d ", &fw[0], &fw[1], &fw[2]) != 3) { msg_perr("Unexpected firmware version string!\n"); return 1; } @@ -517,13 +544,12 @@ static int dediprog_command_a(void) { int ret; - char buf[0x1]; + unsigned char buf[0x1];
memset(buf, 0, sizeof(buf)); - ret = usb_control_msg(dediprog_handle, 0xc3, 0xb, 0x0, 0x0, buf, - 0x1, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0xc3, 0xb, 0x0, 0x0, buf, 0x1, DEFAULT_TIMEOUT); if (ret < 0) { - msg_perr("Command A failed (%s)!\n", usb_strerror()); + msg_perr("Command A failed (%s)!\n", libusb_error_name(ret)); return 1; } if ((ret != 0x1) || (buf[0] != 0x6f)) { @@ -541,13 +567,12 @@ static int dediprog_command_b(void) { int ret; - char buf[0x3]; + unsigned char buf[0x3];
memset(buf, 0, sizeof(buf)); - ret = usb_control_msg(dediprog_handle, 0xc3, 0x7, 0x0, 0xef00, buf, - 0x3, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0xc3, 0x7, 0x0, 0xef00, buf, 0x3, DEFAULT_TIMEOUT); if (ret < 0) { - msg_perr("Command B failed (%s)!\n", usb_strerror()); + msg_perr("Command B failed (%s)!\n", libusb_error_name(ret)); return 1; } if ((ret != 0x3) || (buf[0] != 0xff) || (buf[1] != 0xff) || @@ -569,10 +594,9 @@ { int ret;
- ret = usb_control_msg(dediprog_handle, 0x42, 0x4, 0x0, 0x0, NULL, - 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x4, 0x0, 0x0, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command C failed (%s)!\n", usb_strerror()); + msg_perr("Command C failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -587,17 +611,16 @@ static int dediprog_command_f(int timeout) { int ret; - char buf[0x1]; + unsigned char buf[0x1];
memset(buf, 0, sizeof(buf)); - ret = usb_control_msg(dediprog_handle, 0xc2, 0x11, 0xff, 0xff, buf, - 0x1, timeout); + ret = libusb_control_transfer(dediprog_handle, 0xc2, 0x11, 0xff, 0xff, buf, 0x1, timeout); /* This check is most probably wrong. Command F always causes a timeout * in the logs, so we should check for timeout instead of checking for * success. */ if (ret != 0x1) { - msg_perr("Command F failed (%s)!\n", usb_strerror()); + msg_perr("Command F failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -611,9 +634,9 @@ { int ret;
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x03, NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x07, 0x09, 0x03, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command G failed (%s)!\n", usb_strerror()); + msg_perr("Command G failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -628,9 +651,9 @@ { int ret;
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x05, NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x07, 0x09, 0x05, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command H failed (%s)!\n", usb_strerror()); + msg_perr("Command H failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -645,9 +668,9 @@ { int ret;
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x06, NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x07, 0x09, 0x06, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command I failed (%s)!\n", usb_strerror()); + msg_perr("Command I failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -665,9 +688,9 @@ { int ret;
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, 0x07, NULL, 0x0, DEFAULT_TIMEOUT); + ret = libusb_control_transfer(dediprog_handle, 0x42, 0x07, 0x09, 0x07, NULL, 0x0, DEFAULT_TIMEOUT); if (ret != 0x0) { - msg_perr("Command J failed (%s)!\n", usb_strerror()); + msg_perr("Command J failed (%s)!\n", libusb_error_name(ret)); return 1; } return 0; @@ -770,21 +793,18 @@ if (dediprog_set_spi_voltage(0x0)) return 1;
- if (usb_release_interface(dediprog_handle, 0)) { + if (libusb_release_interface(dediprog_handle, 0)) { msg_perr("Could not release USB interface!\n"); return 1; } - if (usb_close(dediprog_handle)) { - msg_perr("Could not close USB device!\n"); - return 1; - } + libusb_close(dediprog_handle); + libusb_exit(usb_ctx); return 0; }
/* URB numbers refer to the first log ever captured. */ int dediprog_init(void) { - struct usb_device *dev; char *voltage, *device, *spispeed; int spispeed_idx = 2; int millivolt = 3500; @@ -842,31 +862,29 @@ free(device);
/* Here comes the USB stuff. */ - usb_init(); - usb_find_busses(); - usb_find_devices(); - dev = get_device_by_vid_pid(0x0483, 0xdada, (unsigned int) usedevice); - if (!dev) { + libusb_init(&usb_ctx); + if (!usb_ctx) { + msg_perr("Could not initialize libusb!\n"); + return 1; + } + dediprog_handle = get_device_by_vid_pid_number(0x0483, 0xdada, (unsigned int) usedevice); + if (!dediprog_handle) { msg_perr("Could not find a Dediprog SF100 on USB!\n"); + libusb_exit(usb_ctx); return 1; } - msg_pdbg("Found USB device (%04x:%04x).\n", - dev->descriptor.idVendor, dev->descriptor.idProduct); - dediprog_handle = usb_open(dev); - ret = usb_set_configuration(dediprog_handle, 1); - if (ret < 0) { - msg_perr("Could not set USB device configuration: %i %s\n", - ret, usb_strerror()); - if (usb_close(dediprog_handle)) - msg_perr("Could not close USB device!\n"); + ret = libusb_set_configuration(dediprog_handle, 1); + if (ret != 0) { + msg_perr("Could not set USB device configuration: %i %s\n", ret, libusb_error_name(ret)); + libusb_close(dediprog_handle); + libusb_exit(usb_ctx); return 1; } - ret = usb_claim_interface(dediprog_handle, 0); + ret = libusb_claim_interface(dediprog_handle, 0); if (ret < 0) { - msg_perr("Could not claim USB device interface %i: %i %s\n", - 0, ret, usb_strerror()); - if (usb_close(dediprog_handle)) - msg_perr("Could not close USB device!\n"); + msg_perr("Could not claim USB device interface %i: %i %s\n", 0, ret, libusb_error_name(ret)); + libusb_close(dediprog_handle); + libusb_exit(usb_ctx); return 1; } dediprog_endpoint = 2;
Hello Carl-Daniel,
I have fixed and forward ported the code, please check that it works and looks sane.
Thanks for your time. Current (your second) iteration works flawlessly here.
libusb header file location is still something I have to fix in another iteration.
I guess `#include <libusb.h>` would be right. But we'd have to ask pkg-config for the includedir, then.
I'm not quite sure if I changed anything since my post, so I'll rebase, test, and repost my pending changes.
Regards, Nico
On Fri, 22 Feb 2013 11:56:03 +0100 Nico Huber nico.huber@secunet.com wrote:
I'm not quite sure if I changed anything since my post, so I'll rebase, test, and repost my pending changes.
Were there any pending changes or can we continue with what carldani posted?
Am 27.03.2013 11:51, schrieb Stefan Tauner:
On Fri, 22 Feb 2013 11:56:03 +0100 Nico Huber nico.huber@secunet.com wrote:
I'm not quite sure if I changed anything since my post, so I'll rebase, test, and repost my pending changes.
Were there any pending changes or can we continue with what carldani posted?
I'm happy with Carl-Daniel's version. What I meant to say was that I was going to rebase other patches on his work. Which I did with [PATCH] dediprog: Use asynchronous bulk transfers for reading
So my patches on the mailing list are up to date.
Regards, Nico
On Wed, 2013-03-27 at 12:11 +0100, Nico Huber wrote:
Am 27.03.2013 11:51, schrieb Stefan Tauner:
On Fri, 22 Feb 2013 11:56:03 +0100 Nico Huber nico.huber@secunet.com wrote:
I'm not quite sure if I changed anything since my post, so I'll rebase, test, and repost my pending changes.
Were there any pending changes or can we continue with what carldani posted?
I'm happy with Carl-Daniel's version. What I meant to say was that I was going to rebase other patches on his work. Which I did with [PATCH] dediprog: Use asynchronous bulk transfers for reading
So my patches on the mailing list are up to date.
Regards, Nico
Well adding usbblaster_spi made it ouf-of-date. I have rebased it and also changed the libusb-1.0 includes to use paths from pkg-config.
https://bitbucket.org/kmalkki/flashrom/commits/branch/usb-update
That branch also has version of libftdi-1.0 Makefile update and usbblaster_spi update for asynchronous bulk transfers.
I noticed libusb-1.0-0_1.0.9~rc3-2ubuntu1_i386.deb on Ubuntu 12.04 LTS segfaults on my asynchronous bulk transfers for usbblaster_spi, while libusb-1.0-1.0.9rc3 compiled from git works fine.
Kyösti