/*
 * 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 "platform.h"

#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"

/* 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 DEDIPROG_ASYNC_TRANSFERS 8 /* at most 8 asynchronous transfers */
#define REQTYPE_OTHER_OUT (LIBUSB_ENDPOINT_IN | 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 */
static struct libusb_context *usb_ctx;
static libusb_device_handle *dediprog_handle;
static int dediprog_in_endpoint;
static int dediprog_out_endpoint;

enum dediprog_devtype {
	DEV_UNKNOWN		= 0,
	DEV_SF100		= 100,
	DEV_SF200		= 200,
	DEV_SF600		= 600,
};

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

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 flashrom only.
 * Order must be preserved so that comparison operators work.
 */
enum protocol {
	PROTOCOL_UNKNOWN,
	PROTOCOL_V1,
	PROTOCOL_V2,
	PROTOCOL_V3,
};

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

	{0},
};

static int dediprog_firmwareversion = FIRMWARE_VERSION(0, 0, 0);
static enum dediprog_devtype dediprog_devicetype = DEV_UNKNOWN;

#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(void)
{
	/* Firmware version < 5.0.0 is handled explicitly in some cases. */
	switch (dediprog_devicetype) {
	case DEV_SF100:
	case DEV_SF200:
		if (dediprog_firmwareversion < FIRMWARE_VERSION(5, 5, 0))
			return PROTOCOL_V1;
		else
			return PROTOCOL_V2;
	case DEV_SF600:
		if (dediprog_firmwareversion < FIRMWARE_VERSION(6, 9, 0))
			return PROTOCOL_V1;
		else if (dediprog_firmwareversion <= FIRMWARE_VERSION(7, 2, 21))
			return PROTOCOL_V2;
		else
			return PROTOCOL_V3;
	default:
		return PROTOCOL_UNKNOWN;
	}
}

struct dediprog_transfer_status {
	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");
	}
	++status->finished_idx;
}

static int dediprog_bulk_read_poll(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(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(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)
{
	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() >= PROTOCOL_V2) {
		target_leds = (leds ^ 7) << 8;
		ret = dediprog_write(CMD_SET_IO_LED, target_leds, 0, NULL, 0);
	} else {
		if (dediprog_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(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(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(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)
{
	if (dediprog_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(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 prepare_rw_cmd(
		struct flashctx *const flash, uint8_t *data_packet, unsigned int count,
		uint8_t dedi_spi_cmd, unsigned int *value, unsigned int *idx, unsigned int start, int is_read)
{
	if (count >= 1 << 16) {
		msg_perr("%s: Unsupported transfer length of %u blocks! "
			 "Please report a bug at flashrom@flashrom.org\n",
			 __func__, count);
		return 1;
	}

	/* First 5 bytes are common in both generations. */
	data_packet[0] = count & 0xff;
	data_packet[1] = (count >> 8) & 0xff;
	data_packet[2] = 0; /* RFU */
	data_packet[3] = dedi_spi_cmd; /* Read/Write Mode (currently READ_MODE_STD, WRITE_MODE_PAGE_PGM or WRITE_MODE_2B_AAI) */
	data_packet[4] = 0; /* "Opcode". Specs imply necessity only for READ_MODE_4B_ADDR_FAST and WRITE_MODE_4B_ADDR_256B_PAGE_PGM */

	if (protocol() >= PROTOCOL_V2) {
		if (is_read && flash->chip->feature_bits & FEATURE_4BA_FAST_READ) {
			data_packet[3] = READ_MODE_4B_ADDR_FAST_0x0C;
			data_packet[4] = JEDEC_READ_4BA_FAST;
		} else if (dedi_spi_cmd == WRITE_MODE_PAGE_PGM
			   && (flash->chip->feature_bits & FEATURE_4BA_WRITE)) {
			data_packet[3] = WRITE_MODE_4B_ADDR_256B_PAGE_PGM_0x12;
			data_packet[4] = JEDEC_BYTE_PROGRAM_4BA;
		}

		*value = *idx = 0;
		data_packet[5] = 0; /* RFU */
		data_packet[6] = (start >>  0) & 0xff;
		data_packet[7] = (start >>  8) & 0xff;
		data_packet[8] = (start >> 16) & 0xff;
		data_packet[9] = (start >> 24) & 0xff;
		if (protocol() >= PROTOCOL_V3) {
			if (is_read) {
				data_packet[10] = 0x00;	/* address length (3 or 4) */
				data_packet[11] = 0x00;	/* dummy cycle / 2 */
			} else {
				/* 16 LSBs and 16 HSBs of page size */
				/* FIXME: This assumes page size of 256. */
				data_packet[10] = 0x00;
				data_packet[11] = 0x01;
				data_packet[12] = 0x00;
				data_packet[13] = 0x00;
			}
		}
	} else {
		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 0;
}

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

	/* 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 = { 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! Please report a bug at flashrom@flashrom.org\n",
			 __func__, start, len);
		return 1;
	}

	int command_packet_size;
	switch (protocol()) {
	case PROTOCOL_V1:
		command_packet_size = 5;
		break;
	case PROTOCOL_V2:
		command_packet_size = 10;
		break;
	case PROTOCOL_V3:
		command_packet_size = 12;
		break;
	default:
		return 1;
	}

	uint8_t data_packet[command_packet_size];
	unsigned int value, idx;
	if (prepare_rw_cmd(flash, data_packet, count, READ_MODE_STD, &value, &idx, start, 1))
		return 1;

	int ret = dediprog_write(CMD_READ, value, idx, data_packet, sizeof(data_packet));
	if (ret != (int)sizeof(data_packet)) {
		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, dediprog_handle, 0x80 | dediprog_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(&status, 0))
			goto err_free;
	}
	/* Wait for transfers to finish. */
	if (dediprog_bulk_read_poll(&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(&status, 1);
	for (i = 0; i < DEDIPROG_ASYNC_TRANSFERS; ++i)
		if (transfers[i]) libusb_free_transfer(transfers[i]);
	return err;
}

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;

	dediprog_set_leds(LED_BUSY);

	if (residue) {
		msg_pdbg("Slow read for partial block from 0x%x, length 0x%x\n",
			 start, residue);
		ret = spi_read_chunked(flash, buf, start, residue, 16);
		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) {
		msg_pdbg("Slow read for partial block from 0x%x, length 0x%x\n",
			 start, len);
		ret = spi_read_chunked(flash, buf + residue + bulklen,
				       start + residue + bulklen, len, 16);
		if (ret)
			goto err;
	}

	dediprog_set_leds(LED_PASS);
	return 0;
err:
	dediprog_set_leds(LED_ERROR);
	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;

	/*
	 * 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 flashrom@flashrom.org\n", __func__, chunksize);
		return 1;
	}

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

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

	int command_packet_size;
	switch (protocol()) {
	case PROTOCOL_V1:
		command_packet_size = 5;
		break;
	case PROTOCOL_V2:
		command_packet_size = 10;
		break;
	case PROTOCOL_V3:
		command_packet_size = 14;
		break;
	default:
		return 1;
	}

	uint8_t data_packet[command_packet_size];
	unsigned int value, idx;
	if (prepare_rw_cmd(flash, data_packet, count, dedi_spi_cmd, &value, &idx, start, 0))
		return 1;
	int ret = dediprog_write(CMD_WRITE, value, idx, data_packet, sizeof(data_packet));
	if (ret != (int)sizeof(data_packet)) {
		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(dediprog_handle, dediprog_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;
		}
	}

	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;

	dediprog_set_leds(LED_BUSY);

	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 = spi_write_chunked(flash, buf, start, residue, 11);
		if (ret) {
			dediprog_set_leds(LED_ERROR);
			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);
		return ret;
	}

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

	dediprog_set_leds(LED_PASS);
	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(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(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)
{
	int ret;

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

	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() >= 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(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(CMD_TRANSCEIVE, value, idx, readarr, readcnt);
	*/
	ret = dediprog_read(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_check_devicestring(void)
{
	int ret;
	char buf[0x11];

	/* Command Receive Device String. */
	ret = dediprog_read(CMD_READ_PROG_INFO, 0, 0, (uint8_t *)buf, 0x10);
	if (ret != 0x10) {
		msg_perr("Incomplete/failed Command Receive Device String!\n");
		return 1;
	}
	buf[0x10] = '\0';
	msg_pdbg("Found a %s\n", buf);
	if (memcmp(buf, "SF100", 0x5) == 0)
		dediprog_devicetype = DEV_SF100;
	else if (memcmp(buf, "SF200", 0x5) == 0)
		dediprog_devicetype = DEV_SF200;
	else if (memcmp(buf, "SF600", 0x5) == 0)
		dediprog_devicetype = DEV_SF600;
	else {
		msg_perr("Device not a SF100, SF200, or SF600!\n");
		return 1;
	}

	int sfnum;
	int fw[3];
	if (sscanf(buf, "SF%d V:%d.%d.%d ", &sfnum, &fw[0], &fw[1], &fw[2]) != 4 ||
	    sfnum != (int)dediprog_devicetype) {
		msg_perr("Unexpected firmware version string '%s'\n", buf);
		return 1;
	}
	/* Only these major versions were tested. */
	if (fw[0] < 2 || fw[0] > 7) {
		msg_perr("Unexpected firmware version %d.%d.%d!\n", fw[0], fw[1], fw[2]);
		return 1;
	}

	dediprog_firmwareversion = FIRMWARE_VERSION(fw[0], fw[1], fw[2]);
	if (protocol() == 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. Also note,
 * this function only supports SF100 at this time, but SF600 support is not too
 * much different.
 * @return  the id on success, -1 on failure
 */
static int dediprog_read_id(void)
{
	int ret;
	uint8_t buf[3];

	ret = libusb_control_transfer(dediprog_handle, REQTYPE_OTHER_IN,
				      0x7,    /* request */
				      0,      /* value */
				      0xEF00, /* index */
				      buf, sizeof(buf),
				      DEFAULT_TIMEOUT);
	if (ret != sizeof(buf)) {
		msg_perr("Failed to read dediprog id, error %d!\n", ret);
		return -1;
	}

	return buf[0] << 16 | buf[1] << 8 | buf[2];
}

/*
 * 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(void)
{
	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(void)
{
	int ret;

	if (dediprog_devicetype != DEV_SF600)
		return 0;

	msg_pdbg2("Disabling standalone mode.\n");
	ret = dediprog_write(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(void)
{
	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(enum dediprog_target target)
{
	int ret = dediprog_write(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(void)
{
	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 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,
	.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,
};

/*
 * 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
 */
static int dediprog_open(int index)
{
	const uint16_t vid = devs_dediprog[0].vendor_id;
	const uint16_t pid = devs_dediprog[0].device_id;
	int ret;

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

static int dediprog_shutdown(void *data)
{
	dediprog_devicetype = DEV_UNKNOWN;

	/* URB 28. Command Set SPI Voltage to 0. */
	if (dediprog_set_spi_voltage(0x0))
		return 1;

	if (libusb_release_interface(dediprog_handle, 0)) {
		msg_perr("Could not release USB interface!\n");
		return 1;
	}
	libusb_close(dediprog_handle);
	libusb_exit(usb_ctx);

	return 0;
}

int dediprog_init(void)
{
	char *voltage, *id_str, *device, *spispeed, *target_str;
	int spispeed_idx = 1;
	int millivolt = 3500;
	int id = -1; /* -1 defaults to enumeration order */
	int found_id;
	long usedevice = 0;
	long target = FLASH_TYPE_APPLICATION_FLASH_1;
	int i, ret;

	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) {
		char prefix0, prefix1;
		if (sscanf(id_str, "%c%c%d", &prefix0, &prefix1, &id) != 3) {
			msg_perr("Error: Could not parse dediprog 'id'.\n");
			msg_perr("Expected a string like SF012345 or DP012345.\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;
		}
		if (!(prefix0 == 'S' && prefix1 == 'F') && !(prefix0 == 'D' && prefix1 == 'P')) {
			msg_perr("Error: %s is an invalid id!\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);

	/* Here comes the USB stuff. */
	libusb_init(&usb_ctx);
	if (!usb_ctx) {
		msg_perr("Could not initialize libusb!\n");
		return 1;
	}

	if (id != -1) {
		for (i = 0; ; i++) {
			ret = dediprog_open(i);
			if (ret == -1) {
				/* no dev */
				return 1;
			} else if (ret == -2) {
				/* busy 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 flashrom),
			 * the device is skipped and the next device is tried.
			 */
			found_id = dediprog_read_id();
			if (found_id < 0) {
				msg_perr("Could not read id.\n");
				libusb_release_interface(dediprog_handle, 0);
				libusb_close(dediprog_handle);
				continue;
			}
			msg_pinfo("Found dediprog id SF%06d.\n", found_id);
			if (found_id != id) {
				libusb_release_interface(dediprog_handle, 0);
				libusb_close(dediprog_handle);
				continue;
			}
			break;
		}
	} else {
		if (dediprog_open(usedevice)) {
			return 1;
		}
		found_id = dediprog_read_id();
	}

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

	if (register_shutdown(dediprog_shutdown, NULL))
		return 1;

	/* Try reading the devicestring. If that fails and the device is old (FW < 6.0.0, which we can not know)
	 * then we need to try the "set voltage" command and then attempt to read the devicestring again. */
	if (dediprog_check_devicestring()) {
		if (dediprog_set_voltage())
			return 1;
		if (dediprog_check_devicestring())
			return 1;
	}

	/* SF100/SF200 uses one in/out endpoint, SF600 uses separate in/out endpoints */
	dediprog_in_endpoint = 2;
	switch (dediprog_devicetype) {
	case DEV_SF100:
	case DEV_SF200:
		dediprog_out_endpoint = 2;
		break;
	default:
		dediprog_out_endpoint = 1;
		break;
	}

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

	/* Select target/socket, frequency and VCC. */
	if (set_target_flash(target) ||
	    dediprog_set_spi_speed(spispeed_idx) ||
	    dediprog_set_spi_voltage(millivolt)) {
		dediprog_set_leds(LED_ERROR);
		return 1;
	}

	if (dediprog_standalone_mode())
		return 1;

	if (dediprog_devicetype == DEV_SF100 && protocol() == PROTOCOL_V1)
		spi_master_dediprog.features &= ~SPI_MASTER_NO_4BA_MODES;

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

	if (register_spi_master(&spi_master_dediprog) || dediprog_set_leds(LED_NONE))
		return 1;

	return 0;
}
