/*
 * 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,
};
