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

/* IO bits for CMD_SET_IO_LED message */
enum dediprog_ios {
	IO1			= 1 << 0,
	IO2			= 1 << 1,
	IO3			= 1 << 2,
	IO4			= 1 << 3,
};

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.
	 *
	 * FIXME: take IO pins into account
	 */
	int target_leds, ret;
	if (protocol(dp_data) >= PROTOCOL_V2) {
		target_leds = (leds ^ 7) << 8;
		ret = dediprog_write(dp_data->handle, CMD_SET_IO_LED, target_leds, 0, NULL, 0);
	} else {
		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 flashctx *flash,
				     unsigned int writecnt,
				     unsigned int readcnt,
				     const unsigned char *writearr,
				     unsigned char *readarr)
{
	struct dediprog_data *const dp_data = flash->mst.spi->data;
	int ret;

	msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt);
	if (writecnt > flash->mst.spi->max_data_write + 5) {
		msg_perr("Invalid writecnt=%i, aborting.\n", writecnt);
		return 1;
	}
	if (readcnt > flash->mst.spi->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,
};

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

	dp_data->in_endpoint = LIBUSB_ENDPOINT_IN | 2;
	if (dp_data->devicetype <= DEV_SF200)
		dp_data->out_endpoint = 2;
	else
		dp_data->out_endpoint = 1;

	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 (protocol(dp_data) < PROTOCOL_V3) {
			msg_pdbg("Multi i/o is only tested with protocol v3, 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,
};
