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