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;