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(a)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;