/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2010 Carl-Daniel Hailfinger
 * Copyright (C) 2015 Simon Glass
 * Copyright (C) 2015 Stefan Tauner
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include <libusb.h>
#include "flash.h"
#include "chipdrivers/spi.h"
#include "programmer.h"
#include "spi.h"
#include "spi_command.h"

/* LIBUSB_CALL ensures the right calling conventions on libusb callbacks.
 * However, the macro is not defined everywhere. m(
 */
#ifndef LIBUSB_CALL
#define LIBUSB_CALL
#endif

#define FIRMWARE_VERSION(x,y,z) ((x << 16) | (y << 8) | z)
#define DEFAULT_TIMEOUT 3000
#define MAX_BLOCK_COUNT 65535
#define MAX_CMD_SIZE 15
#define DEDIPROG_ASYNC_TRANSFERS 8 /* at most 8 asynchronous transfers */
#define DEDIPROG_INTERFACE 0
#define REQTYPE_OTHER_OUT (LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_OTHER)	/* 0x43 */
#define REQTYPE_OTHER_IN (LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_OTHER)	/* 0xC3 */
#define REQTYPE_EP_OUT (LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_ENDPOINT)	/* 0x42 */
#define REQTYPE_EP_IN (LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_ENDPOINT)	/* 0xC2 */

enum dediprog_devtype {
	DEV_UNKNOWN		= 0,
	DEV_SF100		= 100,
	DEV_SF200		= 200,
	DEV_SF600		= 600,
	DEV_SF600PG2		= 600+2,
	DEV_SF700		= 700,
};

enum dediprog_leds {
	LED_INVALID		= -1,
	LED_NONE		= 0,
	LED_PASS		= 1 << 0,
	LED_BUSY		= 1 << 1,
	LED_ERROR		= 1 << 2,
	LED_ALL			= 7,
};

enum dediprog_cmds {
	CMD_TRANSCEIVE		= 0x01,
	CMD_POLL_STATUS_REG	= 0x02,
	CMD_SET_VPP		= 0x03,
	CMD_SET_TARGET		= 0x04,
	CMD_READ_EEPROM		= 0x05,
	CMD_WRITE_EEPROM	= 0x06,
	CMD_SET_IO_LED		= 0x07,
	CMD_READ_PROG_INFO	= 0x08,
	CMD_SET_VCC		= 0x09,
	CMD_SET_STANDALONE	= 0x0A,
	CMD_SET_VOLTAGE		= 0x0B,	/* Only in firmware older than 6.0.0 */
	CMD_GET_BUTTON		= 0x11,
	CMD_GET_UID		= 0x12,
	CMD_SET_CS		= 0x14,
	CMD_IO_MODE		= 0x15,
	CMD_FW_UPDATE		= 0x1A,
	CMD_FPGA_UPDATE		= 0x1B,
	CMD_READ_FPGA_VERSION	= 0x1C,
	CMD_SET_HOLD		= 0x1D,
	CMD_READ		= 0x20,
	CMD_WRITE		= 0x30,
	CMD_WRITE_AT45DB	= 0x31,
	CMD_NAND_WRITE		= 0x32,
	CMD_NAND_READ		= 0x33,
	CMD_SET_SPI_CLK		= 0x61,
	CMD_CHECK_SOCKET	= 0x62,
	CMD_DOWNLOAD_PRJ	= 0x63,
	CMD_READ_PRJ_NAME	= 0x64,
	// New protocol/firmware only
	CMD_CHECK_SDCARD	= 0x65,
	CMD_READ_PRJ		= 0x66,
};

enum dediprog_target {
	FLASH_TYPE_APPLICATION_FLASH_1	= 0,
	FLASH_TYPE_FLASH_CARD,
	FLASH_TYPE_APPLICATION_FLASH_2,
	FLASH_TYPE_SOCKET,
};

enum dediprog_readmode {
	READ_MODE_STD			= 1,
	READ_MODE_FAST			= 2,
	READ_MODE_ATMEL45		= 3,
	READ_MODE_4B_ADDR_FAST		= 4,
	READ_MODE_4B_ADDR_FAST_0x0C	= 5, /* New protocol only */
	READ_MODE_CONFIGURABLE		= 9, /* Not seen documented so far */
};

enum dediprog_writemode {
	WRITE_MODE_PAGE_PGM			= 1,
	WRITE_MODE_PAGE_WRITE			= 2,
	WRITE_MODE_1B_AAI			= 3,
	WRITE_MODE_2B_AAI			= 4,
	WRITE_MODE_128B_PAGE			= 5,
	WRITE_MODE_PAGE_AT26DF041		= 6,
	WRITE_MODE_SILICON_BLUE_FPGA		= 7,
	WRITE_MODE_64B_PAGE_NUMONYX_PCM		= 8,	/* unit of 512 bytes */
	WRITE_MODE_4B_ADDR_256B_PAGE_PGM	= 9,
	WRITE_MODE_32B_PAGE_PGM_MXIC_512K	= 10,	/* unit of 512 bytes */
	WRITE_MODE_4B_ADDR_256B_PAGE_PGM_0x12	= 11,
	WRITE_MODE_4B_ADDR_256B_PAGE_PGM_FLAGS	= 12,
};

enum dediprog_standalone_mode {
	ENTER_STANDALONE_MODE = 0,
	LEAVE_STANDALONE_MODE = 1,
};

/*
 * These are not official designations; they are for use in flashprog only.
 * Order must be preserved so that comparison operators work.
 */
enum protocol {
	PROTOCOL_UNKNOWN,
	PROTOCOL_V1,
	PROTOCOL_V2,
	PROTOCOL_V3,
};

static const struct dev_entry devs_dediprog[] = {
	{0x0483, 0xDADA, OK, "Dediprog", "SF100/SF200/SF600"},

	{0},
};

struct dediprog_data {
	struct libusb_context *usb_ctx;
	libusb_device_handle *handle;
	int in_endpoint;
	int out_endpoint;
	int firmwareversion;
	char devicestring[32+1];
	enum dediprog_devtype devicetype;
	int (*prepare_rw_cmd)(
		struct flashctx *, uint8_t cmd_buf[MAX_CMD_SIZE], uint16_t *value, uint16_t *idx,
		bool is_read, uint8_t dp_spi_cmd, unsigned int start, unsigned int block_count);
	enum io_mode io_mode;
};

#if defined(LIBUSB_MAJOR) && defined(LIBUSB_MINOR) && defined(LIBUSB_MICRO) && \
    LIBUSB_MAJOR <= 1 && LIBUSB_MINOR == 0 && LIBUSB_MICRO < 9
/* Quick and dirty replacement for missing libusb_error_name in libusb < 1.0.9 */
const char * LIBUSB_CALL libusb_error_name(int error_code)
{
	if (error_code >= INT16_MIN && error_code <= INT16_MAX) {
		/* 18 chars for text, rest for number (16 b should be enough), sign, nullbyte. */
		static char my_libusb_error[18 + 5 + 2];
		sprintf(my_libusb_error, "libusb error code %i", error_code);
		return my_libusb_error;
	} else {
		return "UNKNOWN";
	}
}
#endif

static enum protocol protocol(const struct dediprog_data *dp_data)
{
	/* Firmware version < 5.0.0 is handled explicitly in some cases. */
	switch (dp_data->devicetype) {
	case DEV_SF100:
	case DEV_SF200:
		if (dp_data->firmwareversion < FIRMWARE_VERSION(5, 5, 0))
			return PROTOCOL_V1;
		else
			return PROTOCOL_V2;
	case DEV_SF600:
		if (dp_data->firmwareversion < FIRMWARE_VERSION(6, 9, 0))
			return PROTOCOL_V1;
		else if (dp_data->firmwareversion <= FIRMWARE_VERSION(7, 2, 21))
			return PROTOCOL_V2;
		else
			return PROTOCOL_V3;
	case DEV_SF700:
	case DEV_SF600PG2:
		return PROTOCOL_V3;
	default:
		return PROTOCOL_UNKNOWN;
	}
}

struct dediprog_transfer_status {
	struct flashctx *flash;
	int error; /* OK if 0, ERROR else */
	unsigned int queued_idx;
	unsigned int finished_idx;
};

static void LIBUSB_CALL dediprog_bulk_read_cb(struct libusb_transfer *const transfer)
{
	struct dediprog_transfer_status *const status = (struct dediprog_transfer_status *)transfer->user_data;
	if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
		status->error = 1;
		msg_perr("SPI bulk read failed!\n");
	}
	flashprog_progress_add(status->flash, transfer->actual_length);
	++status->finished_idx;
}

static int dediprog_bulk_read_poll(struct libusb_context *usb_ctx,
				   const struct dediprog_transfer_status *const status,
				   const int finish)
{
	if (status->finished_idx >= status->queued_idx)
		return 0;

	do {
		struct timeval timeout = { 10, 0 };
		const int ret = libusb_handle_events_timeout(usb_ctx, &timeout);
		if (ret < 0) {
			msg_perr("Polling read events failed: %i %s!\n", ret, libusb_error_name(ret));
			return 1;
		}
	} while (finish && (status->finished_idx < status->queued_idx));
	return 0;
}

static int dediprog_read(libusb_device_handle *dediprog_handle,
			 enum dediprog_cmds cmd, unsigned int value, unsigned int idx,
			 uint8_t *bytes, size_t size)
{
	return libusb_control_transfer(dediprog_handle, REQTYPE_EP_IN, cmd, value, idx,
				      (unsigned char *)bytes, size, DEFAULT_TIMEOUT);
}

static int dediprog_write(libusb_device_handle *dediprog_handle,
			  enum dediprog_cmds cmd, unsigned int value, unsigned int idx,
			  const uint8_t *bytes, size_t size)
{
	return libusb_control_transfer(dediprog_handle, REQTYPE_EP_OUT, cmd, value, idx,
				      (unsigned char *)bytes, size, DEFAULT_TIMEOUT);
}


/* This function sets the GPIOs connected to the LEDs as well as IO1-IO4. */
static int dediprog_set_leds(int leds, const struct dediprog_data *dp_data)
{
	if (leds < LED_NONE || leds > LED_ALL)
		leds = LED_ALL;

	/* Older Dediprogs with 2.x.x and 3.x.x firmware only had two LEDs, assigned to different bits. So map
	 * them around if we have an old device. On those devices the LEDs map as follows:
	 *   bit 2 == 0: green light is on.
	 *   bit 0 == 0: red light is on.
	 *
	 * Additionally, the command structure has changed with the "new" protocol.
	 */
	int ret;
	if (protocol(dp_data) >= PROTOCOL_V2) {
		const unsigned int target_io_leds = (leds ^ 7) << 8 | 0x9;
		ret = dediprog_write(dp_data->handle, CMD_SET_IO_LED, target_io_leds, 0, NULL, 0);
	} else {
		unsigned int target_leds;
		if (dp_data->firmwareversion < FIRMWARE_VERSION(5, 0, 0)) {
			target_leds = ((leds & LED_ERROR) >> 2) | ((leds & LED_PASS) << 2);
		} else {
			target_leds = leds;
		}
		target_leds ^= 7;

		ret = dediprog_write(dp_data->handle, CMD_SET_IO_LED, 0x9, target_leds, NULL, 0);
	}

	if (ret != 0x0) {
		msg_perr("Command Set LED 0x%x failed (%s)!\n", leds, libusb_error_name(ret));
		return 1;
	}

	return 0;
}

static int dediprog_set_spi_voltage(libusb_device_handle *dediprog_handle, int millivolt)
{
	int ret;
	uint16_t voltage_selector;

	switch (millivolt) {
	case 0:
		/* Admittedly this one is an assumption. */
		voltage_selector = 0x0;
		break;
	case 1800:
		voltage_selector = 0x12;
		break;
	case 2500:
		voltage_selector = 0x11;
		break;
	case 3500:
		voltage_selector = 0x10;
		break;
	default:
		msg_perr("Unknown voltage %i mV! Aborting.\n", millivolt);
		return 1;
	}
	msg_pdbg("Setting SPI voltage to %u.%03u V\n", millivolt / 1000,
		 millivolt % 1000);

	if (voltage_selector == 0) {
		/* Wait some time as the original driver does. */
		programmer_delay(200 * 1000);
	}
	ret = dediprog_write(dediprog_handle, CMD_SET_VCC, voltage_selector, 0, NULL, 0);
	if (ret != 0x0) {
		msg_perr("Command Set SPI Voltage 0x%x failed!\n",
			 voltage_selector);
		return 1;
	}
	if (voltage_selector != 0) {
		/* Wait some time as the original driver does. */
		programmer_delay(200 * 1000);
	}
	return 0;
}

struct dediprog_spispeeds {
	const char *const name;
	const int speed;
};

static const struct dediprog_spispeeds spispeeds[] = {
	{ "24M",	0x0 },
	{ "12M",	0x2 },
	{ "8M",		0x1 },
	{ "3M",		0x3 },
	{ "2.18M",	0x4 },
	{ "1.5M",	0x5 },
	{ "750k",	0x6 },
	{ "375k",	0x7 },
	{ NULL,		0x0 },
};

static int dediprog_set_spi_speed(unsigned int spispeed_idx, const struct dediprog_data *dp_data)
{
	if (dp_data->devicetype < DEV_SF600PG2 && dp_data->firmwareversion < FIRMWARE_VERSION(5, 0, 0)) {
		msg_pwarn("Skipping to set SPI speed because firmware is too old.\n");
		return 0;
	}

	const struct dediprog_spispeeds *spispeed = &spispeeds[spispeed_idx];
	msg_pdbg("SPI speed is %sHz\n", spispeed->name);

	int ret = dediprog_write(dp_data->handle, CMD_SET_SPI_CLK, spispeed->speed, 0, NULL, 0);
	if (ret != 0x0) {
		msg_perr("Command Set SPI Speed 0x%x failed!\n", spispeed->speed);
		return 1;
	}
	return 0;
}

static int dediprog_set_io_mode(struct dediprog_data *const dp, const enum io_mode io_mode)
{
	const unsigned char dp_io_mode[] = {
		[SINGLE_IO_1_1_1] = 0,
		[DUAL_OUT_1_1_2]  = 1,
		[DUAL_IO_1_2_2]	  = 2,
		[QUAD_OUT_1_1_4]  = 3,
		[QUAD_IO_1_4_4]   = 4,
		[QPI_4_4_4]       = 5,
	};

	if (dp->devicetype < DEV_SF600)
		return 0;

	if (dp->io_mode == io_mode)
		return 0;

	if (io_mode >= ARRAY_SIZE(dp_io_mode)) {
		msg_perr("%s: Unsupported I/O mode %d! "
			 "Please report a bug at flashprog@flashprog.org\n",
			 __func__, io_mode);
		return 1;
	}

	const int ret = dediprog_write(dp->handle, CMD_IO_MODE, dp_io_mode[io_mode], 0, NULL, 0);
	if (ret) {
		msg_perr("Command I/O Mode 0x%x failed!\n", dp_io_mode[io_mode]);
		return 1;
	}

	dp->io_mode = io_mode;
	return 0;
}

static int prepare_rw_cmd_common(uint8_t cmd_buf[MAX_CMD_SIZE], uint8_t dp_spi_cmd, unsigned int count)
{
	if (count > MAX_BLOCK_COUNT) {
		msg_perr("%s: Unsupported transfer length of %u blocks!\n"
			 "Please report a bug at flashprog@flashprog.org\n",
			 __func__, count);
		return -1;
	}

	/* First 5 bytes are common in all generations. */
	cmd_buf[0] = count & 0xff;
	cmd_buf[1] = (count >> 8) & 0xff;
	cmd_buf[2] = 0;			/* RFU */
	cmd_buf[3] = dp_spi_cmd;	/* Read/Write Mode (see enums dediprog_readmode / dediprog_writemode) */
	cmd_buf[4] = 0;			/* "Opcode". Specs imply necessity only for READ_MODE_4B_ADDR_FAST and
					   WRITE_MODE_4B_ADDR_256B_PAGE_PGM. */
	return 5;
}

static int prepare_rw_cmd_v1(
		struct flashctx *flash, uint8_t cmd_buf[MAX_CMD_SIZE], uint16_t *value, uint16_t *idx,
		bool is_read, uint8_t dp_spi_cmd, unsigned int start, unsigned int block_count)
{
	const int cmd_len = prepare_rw_cmd_common(cmd_buf, dp_spi_cmd, block_count);
	if (cmd_len < 0)
		return -1;

	if (flash->chip->feature_bits & FEATURE_4BA_EAR_ANY) {
		if (spi_set_extended_address(flash, start >> 24))
			return -1;
	} else if (start >> 24) {
		msg_cerr("Can't handle 4-byte address with dediprog.\n");
		return -1;
	}
	/*
	 * We don't know how the dediprog firmware handles 4-byte
	 * addresses. So let's not tell it what we are doing and
	 * only send the lower 3 bytes.
	 */
	*value = start & 0xffff;
	*idx = (start >> 16) & 0xff;
	return cmd_len;
}

static int prepare_rw_cmd_v2(
		struct flashctx *flash, uint8_t cmd_buf[MAX_CMD_SIZE], uint16_t *value, uint16_t *idx,
		bool is_read, uint8_t dp_spi_cmd, unsigned int start, unsigned int block_count)
{
	struct dediprog_data *const dp = flash->mst.spi->data;

	if (prepare_rw_cmd_common(cmd_buf, dp_spi_cmd, block_count) < 0)
		return -1;

	if (is_read) {
		const struct spi_read_op *const read_op = get_spi_read_op(flash);
		if (dediprog_set_io_mode(dp, read_op->io_mode))
			return -1;

		if (read_op->native_4ba)
			cmd_buf[3] = READ_MODE_4B_ADDR_FAST_0x0C;
		else if (read_op->opcode != JEDEC_READ)
			cmd_buf[3] = READ_MODE_FAST;

		if (read_op->opcode == JEDEC_READ_4BA)
			cmd_buf[4] = JEDEC_FAST_READ_4BA;
		else
			cmd_buf[4] = read_op->opcode;
	} else {
		if (dediprog_set_io_mode(dp, SINGLE_IO_1_1_1))
			return -1;

		if (dp_spi_cmd == WRITE_MODE_PAGE_PGM
		    && (flash->chip->feature_bits & FEATURE_4BA_WRITE)) {
			cmd_buf[3] = WRITE_MODE_4B_ADDR_256B_PAGE_PGM_0x12;
			cmd_buf[4] = JEDEC_BYTE_PROGRAM_4BA;
		}
	}

	cmd_buf[5] = 0; /* RFU */
	cmd_buf[6] = (start >>  0) & 0xff;
	cmd_buf[7] = (start >>  8) & 0xff;
	cmd_buf[8] = (start >> 16) & 0xff;
	cmd_buf[9] = (start >> 24) & 0xff;

	return 10;
}

static int prepare_rw_cmd_v3(
		struct flashctx *flash, uint8_t cmd_buf[MAX_CMD_SIZE], uint16_t *value, uint16_t *idx,
		bool is_read, uint8_t dp_spi_cmd, unsigned int start, unsigned int block_count)
{
	struct dediprog_data *const dp = flash->mst.spi->data;

	if (prepare_rw_cmd_common(cmd_buf, dp_spi_cmd, block_count) < 0)
		return -1;

	cmd_buf[5] = 0; /* RFU */
	cmd_buf[6] = (start >>  0) & 0xff;
	cmd_buf[7] = (start >>  8) & 0xff;
	cmd_buf[8] = (start >> 16) & 0xff;
	cmd_buf[9] = (start >> 24) & 0xff;

	if (is_read) {
		const struct spi_read_op *const read_op = get_spi_read_op(flash);
		if (dediprog_set_io_mode(dp, read_op->io_mode))
			return -1;

		cmd_buf[3] = READ_MODE_CONFIGURABLE;
		cmd_buf[4] = read_op->opcode;
		cmd_buf[10] = read_op->native_4ba || flash->in_4ba_mode ? 4 : 3;
		cmd_buf[11] = spi_dummy_cycles(read_op) / 2;
		return 12;
	} else {
		if (dediprog_set_io_mode(dp, SINGLE_IO_1_1_1))
			return -1;

		if (dp_spi_cmd == WRITE_MODE_PAGE_PGM) {
			if (flash->chip->feature_bits & FEATURE_4BA_WRITE) {
				cmd_buf[3] = WRITE_MODE_4B_ADDR_256B_PAGE_PGM;
				cmd_buf[4] = JEDEC_BYTE_PROGRAM_4BA;
			} else if (flash->in_4ba_mode) {
				cmd_buf[3] = WRITE_MODE_4B_ADDR_256B_PAGE_PGM;
				cmd_buf[4] = JEDEC_BYTE_PROGRAM;
			} else if (flashprog_flash_getsize(flash) > 16*MiB) {
				msg_cerr("Can't handle 4-byte address with dediprog.\n");
				return -1;
			}
		}
		/* 16 LSBs and 16 HSBs of page size */
		/* FIXME: This assumes page size of 256. */
		cmd_buf[10] = 0x00;
		cmd_buf[11] = 0x01;
		cmd_buf[12] = 0x00;
		cmd_buf[13] = 0x00;
		return 14;
	}
}

/* Bulk read interface, will read multiple 512 byte chunks aligned to 512 bytes.
 * @start	start address
 * @len		length
 * @return	0 on success, 1 on failure
 */
static int dediprog_spi_bulk_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
{
	int err = 1;
	const struct dediprog_data *dp_data = flash->mst.spi->data;

	/* chunksize must be 512, other sizes will NOT work at all. */
	const unsigned int chunksize = 512;
	const unsigned int count = len / chunksize;

	struct dediprog_transfer_status status = { flash, 0, 0, 0 };
	struct libusb_transfer *transfers[DEDIPROG_ASYNC_TRANSFERS] = { NULL, };
	struct libusb_transfer *transfer;

	if (len == 0)
		return 0;

	if ((start % chunksize) || (len % chunksize)) {
		msg_perr("%s: Unaligned start=%i, len=%i!\n"
			 "Please report a bug at flashprog@flashprog.org\n",
			 __func__, start, len);
		return 1;
	}

	uint16_t value = 0, idx = 0;
	uint8_t data_packet[MAX_CMD_SIZE];
	const int command_packet_size = dp_data->prepare_rw_cmd(
			flash, data_packet, &value, &idx, /* is_read => */true, READ_MODE_STD, start, count);
	if (command_packet_size < 0)
		return 1;

	int ret = dediprog_write(dp_data->handle, CMD_READ, value, idx, data_packet, command_packet_size);
	if (ret != command_packet_size) {
		msg_perr("Command Read SPI Bulk failed, %i %s!\n", ret, libusb_error_name(ret));
		return 1;
	}

	/*
	 * Ring buffer of bulk transfers.
	 * Poll until at least one transfer is ready,
	 * schedule next transfers until buffer is full.
	 */

	/* Allocate bulk transfers. */
	unsigned int i;
	for (i = 0; i < MIN(DEDIPROG_ASYNC_TRANSFERS, count); ++i) {
		transfers[i] = libusb_alloc_transfer(0);
		if (!transfers[i]) {
			msg_perr("Allocating libusb transfer %i failed: %s!\n", i, libusb_error_name(ret));
			goto err_free;
		}
	}

	/* Now transfer requested chunks using libusb's asynchronous interface. */
	while (!status.error && (status.queued_idx < count)) {
		while ((status.queued_idx < count) &&
		       (status.queued_idx - status.finished_idx) < DEDIPROG_ASYNC_TRANSFERS)
		{
			transfer = transfers[status.queued_idx % DEDIPROG_ASYNC_TRANSFERS];
			libusb_fill_bulk_transfer(transfer, dp_data->handle, dp_data->in_endpoint,
					(unsigned char *)buf + status.queued_idx * chunksize, chunksize,
					dediprog_bulk_read_cb, &status, DEFAULT_TIMEOUT);
			transfer->flags |= LIBUSB_TRANSFER_SHORT_NOT_OK;
			ret = libusb_submit_transfer(transfer);
			if (ret < 0) {
				msg_perr("Submitting SPI bulk read %i failed: %s!\n",
					 status.queued_idx, libusb_error_name(ret));
				goto err_free;
			}
			++status.queued_idx;
		}
		if (dediprog_bulk_read_poll(dp_data->usb_ctx, &status, 0))
			goto err_free;
	}
	/* Wait for transfers to finish. */
	if (dediprog_bulk_read_poll(dp_data->usb_ctx, &status, 1))
		goto err_free;
	/* Check if everything has been transmitted. */
	if ((status.finished_idx < count) || status.error)
		goto err_free;

	err = 0;

err_free:
	dediprog_bulk_read_poll(dp_data->usb_ctx, &status, 1);
	for (i = 0; i < DEDIPROG_ASYNC_TRANSFERS; ++i)
		if (transfers[i]) libusb_free_transfer(transfers[i]);
	return err;
}

static int dediprog_slow_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
{
	msg_pdbg("Slow read for partial block from 0x%x, length 0x%x\n", start, len);

	/* Override fast-read function for a moment: */
	struct spi_read_op *const backup = flash->spi_fast_read;
	flash->spi_fast_read = NULL;

	const int ret = default_spi_read(flash, buf, start, len);

	flash->spi_fast_read = backup;
	return ret;
}

static int dediprog_spi_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
{
	int ret;
	/* chunksize must be 512, other sizes will NOT work at all. */
	const unsigned int chunksize = 0x200;
	unsigned int residue = start % chunksize ? min(len, chunksize - start % chunksize) : 0;
	unsigned int bulklen;
	const struct dediprog_data *dp_data = flash->mst.spi->data;

	dediprog_set_leds(LED_BUSY, dp_data);

	if (residue) {
		ret = dediprog_slow_read(flash, buf, start, residue);
		if (ret)
			goto err;
	}

	/* Round down. */
	bulklen = (len - residue) / chunksize * chunksize;
	ret = dediprog_spi_bulk_read(flash, buf + residue, start + residue, bulklen);
	if (ret)
		goto err;

	len -= residue + bulklen;
	if (len != 0) {
		ret = dediprog_slow_read(flash, buf + residue + bulklen,
					 start + residue + bulklen, len);
		if (ret)
			goto err;
	}

	dediprog_set_leds(LED_PASS, dp_data);
	return 0;
err:
	dediprog_set_leds(LED_ERROR, dp_data);
	return ret;
}

/* Bulk write interface, will write multiple chunksize byte chunks aligned to chunksize bytes.
 * @chunksize       length of data chunks, only 256 supported by now
 * @start           start address
 * @len             length
 * @dedi_spi_cmd    dediprog specific write command for spi bus
 * @return          0 on success, 1 on failure
 */
static int dediprog_spi_bulk_write(struct flashctx *flash, const uint8_t *buf, unsigned int chunksize,
				   unsigned int start, unsigned int len, uint8_t dedi_spi_cmd)
{
	/* 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
	 * space in a USB bulk transfer must be filled with 0xff padding.
	 */
	const unsigned int count = len / chunksize;
	const struct dediprog_data *dp_data = flash->mst.spi->data;

	/*
	 * We should change this check to
	 *   chunksize > 512
	 * once we know how to handle different chunk sizes.
	 */
	if (chunksize != 256) {
		msg_perr("%s: Chunk sizes other than 256 bytes are unsupported, chunksize=%u!\n"
			 "Please report a bug at flashprog@flashprog.org\n",
			 __func__, chunksize);
		return 1;
	}

	if ((start % chunksize) || (len % chunksize)) {
		msg_perr("%s: Unaligned start=%i, len=%i!\n"
			 "Please report a bug at flashprog@flashprog.org\n",
			 __func__, start, len);
		return 1;
	}

	/* No idea if the hardware can handle empty writes, so chicken out. */
	if (len == 0)
		return 0;

	uint16_t value = 0, idx = 0;
	uint8_t data_packet[MAX_CMD_SIZE];
	const int command_packet_size = dp_data->prepare_rw_cmd(
			flash, data_packet, &value, &idx, /* is_read => */false, dedi_spi_cmd, start, count);
	if (command_packet_size < 0)
		return 1;

	int ret = dediprog_write(dp_data->handle, CMD_WRITE, value, idx, data_packet, command_packet_size);
	if (ret != command_packet_size) {
		msg_perr("Command Write SPI Bulk failed, %s!\n", libusb_error_name(ret));
		return 1;
	}

	unsigned int i;
	for (i = 0; i < count; i++) {
		unsigned char usbbuf[512];
		memcpy(usbbuf, buf + i * chunksize, chunksize);
		memset(usbbuf + chunksize, 0xff, sizeof(usbbuf) - chunksize); // fill up with 0xFF
		int transferred;
		ret = libusb_bulk_transfer(dp_data->handle, dp_data->out_endpoint, usbbuf, 512, &transferred,
					   DEFAULT_TIMEOUT);
		if ((ret < 0) || (transferred != 512)) {
			msg_perr("SPI bulk write failed, expected %i, got %s!\n", 512, libusb_error_name(ret));
			return 1;
		}
		flashprog_progress_add(flash, chunksize);
	}

	return 0;
}

static int dediprog_spi_write(struct flashctx *flash, const uint8_t *buf,
			      unsigned int start, unsigned int len, uint8_t dedi_spi_cmd)
{
	int ret;
	const unsigned int chunksize = flash->chip->page_size;
	unsigned int residue = start % chunksize ? chunksize - start % chunksize : 0;
	unsigned int bulklen;
	const struct dediprog_data *dp_data = flash->mst.spi->data;

	dediprog_set_leds(LED_BUSY, dp_data);

	if (chunksize != 256) {
		msg_pdbg("Page sizes other than 256 bytes are unsupported as "
			 "we don't know how dediprog\nhandles them.\n");
		/* Write everything like it was residue. */
		residue = len;
	}

	if (residue) {
		msg_pdbg("Slow write for partial block from 0x%x, length 0x%x\n",
			 start, residue);
		/* No idea about the real limit. Maybe 16 including command and address, maybe more. */
		ret = default_spi_write_256(flash, buf, start, residue);
		if (ret) {
			dediprog_set_leds(LED_ERROR, dp_data);
			return ret;
		}
	}

	/* Round down. */
	bulklen = (len - residue) / chunksize * chunksize;
	ret = dediprog_spi_bulk_write(flash, buf + residue, chunksize, start + residue, bulklen, dedi_spi_cmd);
	if (ret) {
		dediprog_set_leds(LED_ERROR, dp_data);
		return ret;
	}

	len -= residue + bulklen;
	if (len) {
		msg_pdbg("Slow write for partial block from 0x%x, length 0x%x\n",
			 start, len);
		ret = default_spi_write_256(flash, buf + residue + bulklen, start + residue + bulklen, len);
		if (ret) {
			dediprog_set_leds(LED_ERROR, dp_data);
			return ret;
		}
	}

	dediprog_set_leds(LED_PASS, dp_data);
	return 0;
}

static int dediprog_spi_write_chunked(struct flashctx *flash, const uint8_t *buf,
				      unsigned int start, unsigned int len, uint8_t dedi_spi_cmd)
{
	/* We can write only up to 65535 pages at once: */
	while (len) {
		const size_t len_here = MIN(len, flash->chip->page_size * MAX_BLOCK_COUNT);
		const int ret = dediprog_spi_write(flash, buf, start, len_here, dedi_spi_cmd);
		if (ret)
			return ret;

		start += len_here;
		buf += len_here;
		len -= len_here;
	}
	return 0;
}

static int dediprog_spi_write_256(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
{
	return dediprog_spi_write_chunked(flash, buf, start, len, WRITE_MODE_PAGE_PGM);
}

static int dediprog_spi_write_aai(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
{
	return dediprog_spi_write_chunked(flash, buf, start, len, WRITE_MODE_2B_AAI);
}

static int dediprog_spi_send_command(const struct spi_master *mst,
				     unsigned int writecnt,
				     unsigned int readcnt,
				     const unsigned char *writearr,
				     unsigned char *readarr)
{
	struct dediprog_data *dp_data = mst->data;
	int ret;

	msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt);
	if (writecnt > mst->max_data_write + 5) {
		msg_perr("Invalid writecnt=%i, aborting.\n", writecnt);
		return 1;
	}
	if (readcnt > mst->max_data_read) {
		msg_perr("Invalid readcnt=%i, aborting.\n", readcnt);
		return 1;
	}

	if (dediprog_set_io_mode(dp_data, SINGLE_IO_1_1_1))
		return 1;

	unsigned int idx, value;
	/* New protocol has options and timeout combined as value while the old one used the value field for
	 * timeout and the index field for options. */
	if (protocol(dp_data) >= PROTOCOL_V2) {
		idx = 0;
		value = readcnt ? 0x1 : 0x0; // Indicate if we require a read
	} else {
		idx = readcnt ? 0x1 : 0x0; // Indicate if we require a read
		value = 0;
	}
	ret = dediprog_write(dp_data->handle, CMD_TRANSCEIVE, value, idx, writearr, writecnt);
	if (ret != (int)writecnt) {
		msg_perr("Send SPI failed, expected %i, got %i %s!\n",
			 writecnt, ret, libusb_error_name(ret));
		return 1;
	}
	if (readcnt == 0) // If we don't require a response, we are done here
		return 0;

	/* The specifications do state the possibility to set a timeout for transceive transactions.
	 * Apparently the "timeout" is a delay, and you can use long delays to accelerate writing - in case you
	 * can predict the time needed by the previous command or so (untested). In any case, using this
	 * "feature" to set sane-looking timouts for the read below will completely trash performance with
	 * SF600 and/or firmwares >= 6.0 while they seem to be benign on SF100 with firmwares <= 5.5.2. *shrug*
	 *
	 * The specification also uses only 0 in its examples, so the lesson to learn here:
	 * "Never trust the description of an interface in the documentation but use the example code and pray."
	const uint8_t read_timeout = 10 + readcnt/512;
	if (protocol() >= PROTOCOL_V2) {
		idx = 0;
		value = min(read_timeout, 0xFF) | (0 << 8) ; // Timeout in lower byte, option in upper byte
	} else {
		idx = (0 & 0xFF);  // Lower byte is option (0x01 = require SR, 0x02 keep CS low)
		value = min(read_timeout, 0xFF); // Possibly two bytes but we play safe here
	}
	ret = dediprog_read(dp_data->dediprog_handle, CMD_TRANSCEIVE, value, idx, readarr, readcnt);
	*/
	ret = dediprog_read(dp_data->handle, CMD_TRANSCEIVE, 0, 0, readarr, readcnt);
	if (ret != (int)readcnt) {
		msg_perr("Receive SPI failed, expected %i, got %i %s!\n", readcnt, ret, libusb_error_name(ret));
		return 1;
	}
	return 0;
}

static int dediprog_read_devicestring(struct dediprog_data *dp_data, bool warn)
{
	const int devstr_len = sizeof(dp_data->devicestring) - 1, old_devstr_len = 16;
	char *const buf = dp_data->devicestring;
	int ret;

	/* Command Receive Device String. */
	ret = dediprog_read(dp_data->handle, CMD_READ_PROG_INFO, 0, 0, (uint8_t *)buf, devstr_len);
	if (ret < old_devstr_len || ret > devstr_len) {
		if (warn)
			msg_perr("Incomplete/failed Command Receive Device String!\n");
		return 1;
	}
	buf[ret] = '\0';
	msg_pdbg("Found a %s\n", buf);
	if (memcmp(buf, "SF100", 5) == 0)
		dp_data->devicetype = DEV_SF100;
	else if (memcmp(buf, "SF200", 5) == 0)
		dp_data->devicetype = DEV_SF200;
	else if (memcmp(buf, "SF600PG2", 8) == 0) /* match first, before shorter, generic SF600 */
		dp_data->devicetype = DEV_SF600PG2;
	else if (memcmp(buf, "SF600", 5) == 0)
		dp_data->devicetype = DEV_SF600;
	else if (memcmp(buf, "SF700", 5) == 0)
		dp_data->devicetype = DEV_SF700;
	else
		return 1;

	return 0;
}

static int dediprog_check_devicestring(struct dediprog_data *dp_data)
{
	char *const buf = dp_data->devicestring;
	unsigned int sfnum;
	unsigned int fw[3];

	if (sscanf(buf, "SF%u", &sfnum) != 1 ||
	    sfnum != dp_data->devicetype / 100 * 100 ||
	    sscanf(buf, "SF%*s V:%u.%u.%u ", &fw[0], &fw[1], &fw[2]) != 3) {
		msg_perr("Unexpected firmware version string '%s'\n", buf);
		return 1;
	}

	/* Only allow major versions that were tested. */
	if ((dp_data->devicetype == DEV_SF600PG2 && fw[0] > 1) ||
	    (dp_data->devicetype == DEV_SF700    && fw[0] != 4) ||
	    (dp_data->devicetype <= DEV_SF600    && (fw[0] < 2 || fw[0] > 7))) {
		msg_perr("Unexpected firmware version %d.%d.%d!\n", fw[0], fw[1], fw[2]);
		return 1;
	}

	dp_data->firmwareversion = FIRMWARE_VERSION(fw[0], fw[1], fw[2]);
	if (protocol(dp_data) == PROTOCOL_UNKNOWN) {
		msg_perr("Internal error: Unable to determine protocol version.\n");
		return 1;
	}

	return 0;
}

/*
 * Read the id from the dediprog. This should return the numeric part of the
 * serial number found on a sticker on the back of the dediprog. Note this
 * number is stored in writable eeprom, so it could get out of sync.
 * @return  the id on success, -1 on failure
 */
static int dediprog_read_id(struct dediprog_data *const dp)
{
	const int min_len = 3;
	int ret;

	if (dp->devicetype >= DEV_SF600PG2) {
		const uint8_t out[6] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00 };
		const uint8_t cmd = 0x71;
		uint8_t buf[512];
		int transferred;
		int try;

		/* Always query the id twice as the endpoint
		   can lock up in mysterious ways otherwise. */
		for (try = 0; try < 2; ++try) {
			ret = dediprog_write(dp->handle, cmd, 0, 0, out, sizeof(out));
			if (ret != (int)sizeof(out))
				goto failed_ret;

			ret = libusb_bulk_transfer(dp->handle, dp->in_endpoint,
					buf, sizeof(buf), &transferred, DEFAULT_TIMEOUT);
		}

		if (ret == 0 && transferred >= min_len)
			return buf[2] << 16 | buf[1] << 8 | buf[0];
	} else {
		uint8_t buf[16];

		if (dp->devicetype >= DEV_SF600) {
			ret = dediprog_read(dp->handle, CMD_READ_EEPROM, 0, 0, buf, sizeof(buf));
		} else {
			ret = libusb_control_transfer(dp->handle, REQTYPE_OTHER_IN,
						      0x7,    /* request */
						      0,      /* value */
						      0xEF00, /* index */
						      buf, min_len, DEFAULT_TIMEOUT);
		}

		if (ret >= min_len)
			return buf[0] << 16 | buf[1] << 8 | buf[2];
	}

failed_ret:
	msg_perr("Failed to read dediprog id: ");
	if (ret < 0)
		msg_perr("%s (%d)\n", libusb_strerror(ret), ret);
	else
		msg_perr("short read!\n");
	return -1;
}

/*
 * This command presumably sets the voltage for the SF100 itself (not the
 * SPI flash). Only use this command with firmware older than V6.0.0. Newer
 * (including all SF600s) do not support it.
 */

/* This command presumably sets the voltage for the SF100 itself (not the SPI flash).
 * Only use dediprog_set_voltage on SF100 programmers with firmware older
 * than V6.0.0. Newer programmers (including all SF600s) do not support it. */
static int dediprog_set_voltage(libusb_device_handle *dediprog_handle)
{
	unsigned char buf[1] = {0};
	int ret = libusb_control_transfer(dediprog_handle, REQTYPE_OTHER_IN, CMD_SET_VOLTAGE, 0x0, 0x0,
			      buf, 0x1, DEFAULT_TIMEOUT);
	if (ret < 0) {
		msg_perr("Command Set Voltage failed (%s)!\n", libusb_error_name(ret));
		return 1;
	}
	if ((ret != 1) || (buf[0] != 0x6f)) {
		msg_perr("Unexpected response to init!\n");
		return 1;
	}

	return 0;
}

static int dediprog_standalone_mode(const struct dediprog_data *dp_data)
{
	int ret;

	if (dp_data->devicetype != DEV_SF600)
		return 0;

	msg_pdbg2("Disabling standalone mode.\n");
	ret = dediprog_write(dp_data->handle, CMD_SET_STANDALONE, LEAVE_STANDALONE_MODE, 0, NULL, 0);
	if (ret) {
		msg_perr("Failed to disable standalone mode: %s\n", libusb_error_name(ret));
		return 1;
	}

	return 0;
}

#if 0
/* Something.
 * Present in eng_detect_blink.log with firmware 3.1.8
 * Always preceded by Command Receive Device String
 */
static int dediprog_command_b(libusb_device_handle *dediprog_handle)
{
	int ret;
	char buf[0x3];

	ret = usb_control_msg(dediprog_handle, REQTYPE_OTHER_IN, 0x7, 0x0, 0xef00,
			      buf, 0x3, DEFAULT_TIMEOUT);
	if (ret < 0) {
		msg_perr("Command B failed (%s)!\n", libusb_error_name(ret));
		return 1;
	}
	if ((ret != 0x3) || (buf[0] != 0xff) || (buf[1] != 0xff) ||
	    (buf[2] != 0xff)) {
		msg_perr("Unexpected response to Command B!\n");
		return 1;
	}

	return 0;
}
#endif

static int set_target_flash(libusb_device_handle *dediprog_handle, enum dediprog_target target)
{
	int ret = dediprog_write(dediprog_handle, CMD_SET_TARGET, target, 0, NULL, 0);
	if (ret != 0) {
		msg_perr("set_target_flash failed (%s)!\n", libusb_error_name(ret));
		return 1;
	}
	return 0;
}

#if 0
/* Returns true if the button is currently pressed. */
static bool dediprog_get_button(libusb_device_handle *dediprog_handle)
{
	char buf[1];
	int ret = usb_control_msg(dediprog_handle, REQTYPE_EP_IN, CMD_GET_BUTTON, 0, 0,
			      buf, 0x1, DEFAULT_TIMEOUT);
	if (ret != 0) {
		msg_perr("Could not get button state (%s)!\n", libusb_error_name(ret));
		return 1;
	}
	return buf[0] != 1;
}
#endif

static int parse_voltage(char *voltage)
{
	char *tmp = NULL;
	int i;
	int millivolt = 0, fraction = 0;

	if (!voltage || !strlen(voltage)) {
		msg_perr("Empty voltage= specified.\n");
		return -1;
	}
	millivolt = (int)strtol(voltage, &tmp, 0);
	voltage = tmp;
	/* Handle "," and "." as decimal point. Everything after it is assumed
	 * to be in decimal notation.
	 */
	if ((*voltage == '.') || (*voltage == ',')) {
		voltage++;
		for (i = 0; i < 3; i++) {
			fraction *= 10;
			/* Don't advance if the current character is invalid,
			 * but continue multiplying.
			 */
			if ((*voltage < '0') || (*voltage > '9'))
				continue;
			fraction += *voltage - '0';
			voltage++;
		}
		/* Throw away remaining digits. */
		voltage += strspn(voltage, "0123456789");
	}
	/* The remaining string must be empty or "mV" or "V". */
	tolower_string(voltage);

	/* No unit or "V". */
	if ((*voltage == '\0') || !strncmp(voltage, "v", 1)) {
		millivolt *= 1000;
		millivolt += fraction;
	} else if (!strncmp(voltage, "mv", 2) ||
		   !strncmp(voltage, "milliv", 6)) {
		/* No adjustment. fraction is discarded. */
	} else {
		/* Garbage at the end of the string. */
		msg_perr("Garbage voltage= specified.\n");
		return -1;
	}
	return millivolt;
}

static int dediprog_shutdown(void *data);

static struct spi_master spi_master_dediprog = {
	.features	= SPI_MASTER_NO_4BA_MODES,
	.max_data_read	= 16, /* 18 seems to work fine as well, but 19 times out sometimes with FW 5.15. */
	.max_data_write	= 16 - 5, /* Account for 5 bytes cmd/addr. */
	.command	= dediprog_spi_send_command,
	.multicommand	= default_spi_send_multicommand,
	.read		= dediprog_spi_read,
	.write_256	= dediprog_spi_write_256,
	.write_aai	= dediprog_spi_write_aai,
	.shutdown	= dediprog_shutdown,
	.probe_opcode	= default_spi_probe_opcode,
};

static int dediprog_find_bulk_endpoints(struct dediprog_data *dp_data)
{
	struct libusb_config_descriptor *config;
	const struct libusb_interface_descriptor *interface = NULL;
	int in_endpoint = 0;
	int out_endpoint = 0;
	int ret;
	int i;

	ret = libusb_get_active_config_descriptor(libusb_get_device(dp_data->handle), &config);
	if (ret != 0) {
		msg_perr("Could not read USB configuration descriptor: %i %s\n",
			 ret, libusb_error_name(ret));
		return 1;
	}

	for (i = 0; i < config->bNumInterfaces; i++) {
		const struct libusb_interface *const iface = &config->interface[i];
		if (iface->num_altsetting > 0 && iface->altsetting[0].bInterfaceNumber == DEDIPROG_INTERFACE) {
			interface = &iface->altsetting[0];
			break;
		}
	}

	if (!interface) {
		msg_perr("Could not find USB interface %u in configuration descriptor.\n", DEDIPROG_INTERFACE);
		libusb_free_config_descriptor(config);
		return 1;
	}

	for (i = 0; i < interface->bNumEndpoints; i++) {
		const struct libusb_endpoint_descriptor *const endpoint = &interface->endpoint[i];
		const uint8_t type = endpoint->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK;
		const uint8_t address = endpoint->bEndpointAddress;

		if (type != LIBUSB_TRANSFER_TYPE_BULK)
			continue;

		if ((address & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) {
			if (!in_endpoint)
				in_endpoint = address;
		} else if (!out_endpoint) {
			out_endpoint = address;
		}
	}

	libusb_free_config_descriptor(config);

	if (!in_endpoint || !out_endpoint) {
		msg_perr("Could not find required bulk endpoints (in=0x%02x, out=0x%02x).\n",
			 in_endpoint, out_endpoint);
		return 1;
	}

	dp_data->in_endpoint = in_endpoint;
	dp_data->out_endpoint = out_endpoint;

	msg_pdbg("Using bulk endpoints in=0x%02x, out=0x%02x.\n",
		 dp_data->in_endpoint, dp_data->out_endpoint);
	return 0;
}

/*
 * Open a dediprog_handle with the USB device at the given index.
 * @index   index of the USB device
 * @return  0 for success, -1 for error, -2 for busy device, -3 for unknown device
 */
static int dediprog_open(int index, struct dediprog_data *dp_data)
{
	const uint16_t vid = devs_dediprog[0].vendor_id;
	const uint16_t pid = devs_dediprog[0].device_id;
	int ret;

	dp_data->handle = usb_dev_get_by_vid_pid_number(dp_data->usb_ctx, vid, pid, (unsigned int) index);
	if (!dp_data->handle) {
		msg_perr("Could not find a Dediprog programmer on USB.\n");
		libusb_exit(dp_data->usb_ctx);
		return -1;
	}
	ret = libusb_set_configuration(dp_data->handle, 1);
	if (ret != 0) {
		msg_perr("Could not set USB device configuration: %i %s\n",
			 ret, libusb_error_name(ret));
		libusb_close(dp_data->handle);
		return -2;
	}
	ret = libusb_claim_interface(dp_data->handle, 0);
	if (ret < 0) {
		msg_perr("Could not claim USB device interface %i: %i %s\n",
			 0, ret, libusb_error_name(ret));
		libusb_close(dp_data->handle);
		return -2;
	}

	/* Try reading the devicestring. If that fails and the device is old
	   (FW < 6.0.0, which we cannot know),  then we need to try the "set
	   voltage" command and then attempt to read the devicestring again. */
	if (dediprog_read_devicestring(dp_data, /* warn => */false)) {
		if (dediprog_set_voltage(dp_data->handle))
			goto unknown_dev;
		if (dediprog_read_devicestring(dp_data, /* warn => */true))
			goto unknown_dev;
	}

	if (dediprog_find_bulk_endpoints(dp_data))
		goto unknown_dev;

	return 0;

unknown_dev:
	msg_pwarn("Ignoring unknown Dediprog device. Not a SF100, SF200, SF600(Plus(G2)), or SF700!\n");
	libusb_release_interface(dp_data->handle, 0);
	libusb_close(dp_data->handle);
	return -3;
}

static int dediprog_shutdown(void *data)
{
	int ret = 0;
	struct dediprog_data *dp_data = data;

	dediprog_set_io_mode(dp_data, SINGLE_IO_1_1_1);

	/* URB 28. Command Set SPI Voltage to 0. */
	if (dediprog_set_spi_voltage(dp_data->handle, 0x0)) {
		ret = 1;
		goto out;
	}

	if (libusb_release_interface(dp_data->handle, 0)) {
		msg_perr("Could not release USB interface!\n");
		ret = 1;
		goto out;
	}
	libusb_close(dp_data->handle);
	libusb_exit(dp_data->usb_ctx);
out:
	free(data);
	return ret;
}

static int dediprog_init(struct flashprog_programmer *const prog)
{
	char *voltage, *id_str, *device, *spispeed, *target_str;
	enum {
		DEFAULT,
		SINGLE,
		DUAL,
		QUAD,
	} io_mode = DEFAULT;
	int spispeed_idx = 1;
	int millivolt = 3500;
	long id = -1; /* -1 defaults to enumeration order */
	int found_id;
	long usedevice = 0;
	long target = FLASH_TYPE_APPLICATION_FLASH_1;
	int i, ret;

	char *const io_mode_str = extract_programmer_param("iomode");
	if (io_mode_str) {
		if (strcmp(io_mode_str, "single") == 0) {
			io_mode = SINGLE;
		} else if (strcmp(io_mode_str, "dual") == 0) {
			io_mode = DUAL;
		} else if (strcmp(io_mode_str, "quad") == 0) {
			io_mode = QUAD;
		} else {
			msg_perr("Invalid iomode setting: %s\n", io_mode_str);
			return SPI_GENERIC_ERROR;
		}
	}
	free(io_mode_str);

	spispeed = extract_programmer_param("spispeed");
	if (spispeed) {
		for (i = 0; spispeeds[i].name; ++i) {
			if (!strcasecmp(spispeeds[i].name, spispeed)) {
				spispeed_idx = i;
				break;
			}
		}
		if (!spispeeds[i].name) {
			msg_perr("Error: Invalid spispeed value: '%s'.\n", spispeed);
			free(spispeed);
			return 1;
		}
		free(spispeed);
	}

	voltage = extract_programmer_param("voltage");
	if (voltage) {
		millivolt = parse_voltage(voltage);
		free(voltage);
		if (millivolt < 0)
			return 1;
		msg_pinfo("Setting voltage to %i mV\n", millivolt);
	}

	id_str = extract_programmer_param("id");
	if (id_str) {
		const char prefixes[][4] = { "SF", "DP", "S6B", };
		for (i = 0; i < (int)ARRAY_SIZE(prefixes); ++i) {
			if (!strncmp(id_str, prefixes[i], strlen(prefixes[i])))
				break;
		}
		if (i >= (int)ARRAY_SIZE(prefixes)) {
			msg_perr("Error: Could not parse dediprog `id'.\n");
			msg_perr("Expected a string prefixed with any of ");
			for (i = 0; i < (int)ARRAY_SIZE(prefixes); ++i)
				msg_perr("%s`%s'", i > 0 ? ", " : "", prefixes[i]);
			msg_perr(".\n");
			free(id_str);
			return 1;
		}
		char *endptr;
		id = strtol(id_str + strlen(prefixes[i]), &endptr, 10);
		if (strlen(id_str) <= strlen(prefixes[i]) || *endptr) {
			msg_perr("Error: Could not parse dediprog `id'.\n");
			msg_perr("Expected a number after string prefix.\n");
			free(id_str);
			return 1;
		}
		if (id < 0 || id >= 0x1000000) {
			msg_perr("Error: id `%s' is out of range!\n", id_str);
			free(id_str);
			return 1;
		}
		msg_pinfo("Will search for dediprog id %s.\n", id_str);
	}
	free(id_str);

	device = extract_programmer_param("device");
	if (device) {
		char *dev_suffix;
		if (id != -1) {
			msg_perr("Error: Cannot use 'id' and 'device'.\n");
		}
		errno = 0;
		usedevice = strtol(device, &dev_suffix, 10);
		if (errno != 0 || device == dev_suffix) {
			msg_perr("Error: Could not convert 'device'.\n");
			free(device);
			return 1;
		}
		if (usedevice < 0 || usedevice > INT_MAX) {
			msg_perr("Error: Value for 'device' is out of range.\n");
			free(device);
			return 1;
		}
		if (strlen(dev_suffix) > 0) {
			msg_perr("Error: Garbage following 'device' value.\n");
			free(device);
			return 1;
		}
		msg_pinfo("Using device %li.\n", usedevice);
	}
	free(device);

	target_str = extract_programmer_param("target");
	if (target_str) {
		char *target_suffix;
		errno = 0;
		target = strtol(target_str, &target_suffix, 10);
		if (errno != 0 || target_str == target_suffix) {
			msg_perr("Error: Could not convert 'target'.\n");
			free(target_str);
			return 1;
		}
		if (target < 1 || target > 2) {
			msg_perr("Error: Value for 'target' is out of range.\n");
			free(target_str);
			return 1;
		}
		if (strlen(target_suffix) > 0) {
			msg_perr("Error: Garbage following 'target' value.\n");
			free(target_str);
			return 1;
		}
		switch (target) {
		case 1:
			msg_pinfo("Using target %s.\n", "FLASH_TYPE_APPLICATION_FLASH_1");
			target = FLASH_TYPE_APPLICATION_FLASH_1;
			break;
		case 2:
			msg_pinfo("Using target %s.\n", "FLASH_TYPE_APPLICATION_FLASH_2");
			target = FLASH_TYPE_APPLICATION_FLASH_2;
			break;
		default:
			break;
		}
	}
	free(target_str);

	struct dediprog_data *dp_data = calloc(1, sizeof(*dp_data));
	if (!dp_data) {
		msg_perr("Unable to allocate space for SPI master data\n");
		return 1;
	}
	dp_data->firmwareversion = FIRMWARE_VERSION(0, 0, 0);
	dp_data->devicetype = DEV_UNKNOWN;
	dp_data->io_mode = -1;

	/* Here comes the USB stuff. */
	ret = libusb_init(&dp_data->usb_ctx);
	if (ret) {
		msg_perr("Could not initialize libusb!\n");
		goto init_err_exit;
	}

	if (id != -1) {
		for (i = 0; ; i++) {
			ret = dediprog_open(i, dp_data);
			if (ret == -1) {
				/* no dev */
				goto init_err_exit;
			} else if (ret < 0) {
				/* busy or unknown dev */
				continue;
			}

			/* Notice we can only call dediprog_read_id() after
			 * libusb_set_configuration() and
			 * libusb_claim_interface(). When searching by id and
			 * either configuration or claim fails (usually the
			 * device is in use by another instance of flashprog),
			 * the device is skipped and the next device is tried.
			 */
			found_id = dediprog_read_id(dp_data);
			if (found_id >= 0)
				msg_pinfo("Found dediprog id SF%06d.\n", found_id);
			if (found_id == id)
				break;

			libusb_release_interface(dp_data->handle, 0);
			libusb_close(dp_data->handle);
		}
	} else {
		if (dediprog_open(usedevice, dp_data)) {
			goto init_err_exit;
		}
		found_id = dediprog_read_id(dp_data);
	}

	if (found_id >= 0) {
		msg_pinfo("Using dediprog id SF%06d.\n", found_id);
	}

	if (dediprog_check_devicestring(dp_data))
		goto init_err_cleanup_exit;

	/* Set all possible LEDs as soon as possible to indicate activity.
	 * Because knowing the firmware version is required to set the LEDs correctly we need to this after
	 * dediprog_check_devicestring() has queried the device. */
	dediprog_set_leds(LED_ALL, dp_data);

	/* Select target/socket, frequency and VCC. */
	if (set_target_flash(dp_data->handle, target) ||
	    dediprog_set_spi_speed(spispeed_idx, dp_data) ||
	    dediprog_set_spi_voltage(dp_data->handle, millivolt)) {
		dediprog_set_leds(LED_ERROR, dp_data);
		goto init_err_cleanup_exit;
	}

	if (dediprog_standalone_mode(dp_data))
		goto init_err_cleanup_exit;

	switch (protocol(dp_data)) {
		case PROTOCOL_V3: dp_data->prepare_rw_cmd = prepare_rw_cmd_v3; break;
		case PROTOCOL_V2: dp_data->prepare_rw_cmd = prepare_rw_cmd_v2; break;
		default:          dp_data->prepare_rw_cmd = prepare_rw_cmd_v1; break;
	}

	if (io_mode == DEFAULT) {
		if (dp_data->devicetype != DEV_SF600PG2) {
			msg_pdbg("Multi i/o is only tested with SF600Plus-G2, not enabling by default.\n");
		} else {
			io_mode = DUAL;
		}
	} else if (io_mode > SINGLE &&
		   (dp_data->devicetype < DEV_SF600 || protocol(dp_data) < PROTOCOL_V2)) {
		msg_pinfo("Multi i/o is only supported for SF600 and SF700 models w/ protocol v2 or later.\n");
		io_mode = SINGLE;
	}

	switch (io_mode) {
		case DUAL: spi_master_dediprog.features |= SPI_MASTER_DUAL; break;
		case QUAD: spi_master_dediprog.features |= SPI_MASTER_DUAL | SPI_MASTER_QUAD; break;
		default: break;
	}

	/* The v2, fixed-op JEDEC_FAST_READ_DUAL_DIO command
	   seems to use the wrong number of dummy cycles. */
	if (protocol(dp_data) < PROTOCOL_V3)
		spi_master_dediprog.features &= ~SPI_MASTER_DUAL_IO;

	if ((dp_data->devicetype == DEV_SF100 && protocol(dp_data) == PROTOCOL_V1) ||
	    (dp_data->devicetype >= DEV_SF600 && protocol(dp_data) == PROTOCOL_V3))
		spi_master_dediprog.features &= ~SPI_MASTER_NO_4BA_MODES;

	if (protocol(dp_data) >= PROTOCOL_V2)
		spi_master_dediprog.features |= SPI_MASTER_4BA;

	if (dediprog_set_leds(LED_NONE, dp_data))
		goto init_err_cleanup_exit;

	return register_spi_master(&spi_master_dediprog, 0, dp_data);

init_err_cleanup_exit:
	dediprog_shutdown(dp_data);
	return 1;

init_err_exit:
	free(dp_data);
	return 1;
}

const struct programmer_entry programmer_dediprog = {
	.name			= "dediprog",
	.type			= USB,
	.devs.dev		= devs_dediprog,
	.init			= dediprog_init,
};
