/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2009, 2010, 2011, 2012 Carl-Daniel Hailfinger
 *
 * 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 <stdio.h>
#include <strings.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include "flash.h"
#include "programmer.h"
#include "spi.h"

/* Change this to #define if you want to test without a serial implementation */
#undef FAKE_COMMUNICATION

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

#define BP_DEFAULTBAUD 115200

#ifndef FAKE_COMMUNICATION
static int buspirate_serialport_setup(char *dev)
{
	/* 115200bps, 8 databits, no parity, 1 stopbit */
	sp_fd = sp_openserport(dev, BP_DEFAULTBAUD);
	if (sp_fd == SER_INV_FD)
		return 1;
	return 0;
}
#else
#define buspirate_serialport_setup(...) 0
#define serialport_shutdown(...) 0
#define serialport_write(...) 0
#define serialport_read(...) 0
#define sp_flush_incoming(...) 0
#endif

struct bp_spi_data {
	unsigned char *commbuf;
	int commbufsize;
};

static int buspirate_commbuf_grow(int bufsize, unsigned char **bp_commbuf, int *bp_commbufsize)
{
	unsigned char *tmpbuf;

	/* Never shrink. realloc() calls are expensive. */
	if (bufsize <= *bp_commbufsize)
		return 0;

	tmpbuf = realloc(*bp_commbuf, bufsize);
	if (!tmpbuf) {
		/* Keep the existing buffer because memory is already tight. */
		msg_perr("Out of memory!\n");
		return ERROR_OOM;
	}

	*bp_commbuf = tmpbuf;
	*bp_commbufsize = bufsize;
	return 0;
}

static int buspirate_sendrecv(unsigned char *buf, unsigned int writecnt,
			      unsigned int readcnt)
{
	unsigned int i;
	int ret = 0;

	msg_pspew("%s: write %i, read %i ", __func__, writecnt, readcnt);
	if (!writecnt && !readcnt) {
		msg_perr("Zero length command!\n");
		return 1;
	}
	if (writecnt)
		msg_pspew("Sending");
	for (i = 0; i < writecnt; i++)
		msg_pspew(" 0x%02x", buf[i]);
#ifdef FAKE_COMMUNICATION
	/* Placate the caller for now. */
	if (readcnt) {
		buf[0] = 0x01;
		memset(buf + 1, 0xff, readcnt - 1);
	}
	ret = 0;
#else
	if (writecnt)
		ret = serialport_write(buf, writecnt);
	if (ret)
		return ret;
	if (readcnt)
		ret = serialport_read(buf, readcnt);
	if (ret)
		return ret;
#endif
	if (readcnt)
		msg_pspew(", receiving");
	for (i = 0; i < readcnt; i++)
		msg_pspew(" 0x%02x", buf[i]);
	msg_pspew("\n");
	return 0;
}

static int buspirate_wait_for_string(unsigned char *buf, const char *key)
{
	unsigned int keylen = strlen(key);
	int ret;

	ret = buspirate_sendrecv(buf, 0, keylen);
	while (!ret) {
		if (!memcmp(buf, key, keylen))
			return 0;
		memmove(buf, buf + 1, keylen - 1);
		ret = buspirate_sendrecv(buf + keylen - 1, 0, 1);
	}
	return ret;
}

static int buspirate_spi_send_command_v1(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
					 const unsigned char *writearr, unsigned char *readarr);
static int buspirate_spi_send_command_v2(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
					 const unsigned char *writearr, unsigned char *readarr);
static int buspirate_spi_shutdown(void *data);

static struct spi_master spi_master_buspirate = {
	.features	= SPI_MASTER_4BA,
	.max_data_read	= MAX_DATA_UNSPECIFIED,
	.max_data_write	= MAX_DATA_UNSPECIFIED,
	.command	= NULL,
	.multicommand	= default_spi_send_multicommand,
	.read		= default_spi_read,
	.write_256	= default_spi_write_256,
	.shutdown	= buspirate_spi_shutdown,
	.probe_opcode	= default_spi_probe_opcode,
};

static const struct buspirate_speeds spispeeds[] = {
	{"30k",		0x0},
	{"125k",	0x1},
	{"250k",	0x2},
	{"1M",		0x3},
	{"2M",		0x4},
	{"2.6M",	0x5},
	{"4M",		0x6},
	{"8M",		0x7},
	{NULL,		0x0}
};

static const struct buspirate_speeds serialspeeds[] = {
	{"115200",  115200},
	{"230400",  230400},
	{"250000",  250000},
	{"2000000", 2000000},
	{"2M",      2000000},
	{NULL,      0}
};

static int buspirate_spi_shutdown(void *data)
{
	struct bp_spi_data *bp_data = data;
	unsigned char *const bp_commbuf = bp_data->commbuf;
	int ret = 0, ret2 = 0;
	/* No need to allocate a buffer here, we know that bp_commbuf is at least DEFAULT_BUFSIZE big. */

	/* Exit raw SPI mode (enter raw bitbang mode) */
	bp_commbuf[0] = 0x00;
	if ((ret = buspirate_sendrecv(bp_commbuf, 1, 0)))
		goto out_shutdown;
	if ((ret = buspirate_wait_for_string(bp_commbuf, "BBIO")))
		goto out_shutdown;
	if ((ret = buspirate_sendrecv(bp_commbuf, 0, 1)))
		goto out_shutdown;
	msg_pdbg("Raw bitbang mode version %c\n", bp_commbuf[0]);
	if (bp_commbuf[0] != '1') {
		msg_perr("Can't handle raw bitbang mode version %c!\n", bp_commbuf[0]);
		ret = 1;
		goto out_shutdown;
	}
	/* Reset Bus Pirate (return to user terminal) */
	bp_commbuf[0] = 0x0f;
	ret = buspirate_sendrecv(bp_commbuf, 1, 0);

out_shutdown:
	/* Shut down serial port communication */
	ret2 = serialport_shutdown(NULL);
	/* Keep the oldest error, it is probably the best indicator. */
	if (ret2 && !ret)
		ret = ret2;

	free(bp_commbuf);
	if (ret)
		msg_pdbg("Bus Pirate shutdown failed.\n");
	else
		msg_pdbg("Bus Pirate shutdown completed.\n");

	free(data);
	return ret;
}

#define BP_FWVERSION(a,b)	((a) << 8 | (b))
#define BP_HWVERSION(a,b)	BP_FWVERSION(a,b)

/**
 * The Bus Pirate's PIC microcontroller supports custom baud rates by manually specifying a
 * clock divisor that can be calculated with the formula (16000000 / (4 * baud)) - 1.
 */
#define BP_DIVISOR(baud) ((4000000/(baud)) - 1)

static int buspirate_spi_init(struct flashprog_programmer *const prog)
{
	char *tmp;
	char *dev;
	int i;
	int cnt;
	unsigned int fw_version_major = 0;
	unsigned int fw_version_minor = 0;
	unsigned int hw_version_major = 0;
	unsigned int hw_version_minor = 0;
	int spispeed = 0x7;
	int serialspeed_index = -1;
	int ret = 0;
	bool pullup = false;
	bool psu = false;
	unsigned char *bp_commbuf;
	int bp_commbufsize;

	dev = extract_programmer_param("dev");
	if (dev && !strlen(dev)) {
		free(dev);
		dev = NULL;
	}
	if (!dev) {
		msg_perr("No serial device given. Use flashprog -p buspirate_spi:dev=/dev/ttyUSB0\n");
		return 1;
	}

	tmp = extract_programmer_param("spispeed");
	if (tmp) {
		for (i = 0; spispeeds[i].name; i++) {
			if (!strncasecmp(spispeeds[i].name, tmp, strlen(spispeeds[i].name))) {
				spispeed = spispeeds[i].speed;
				break;
			}
		}
		if (!spispeeds[i].name)
			msg_perr("Invalid SPI speed, using default.\n");
	}
	free(tmp);

	/* Extract serialspeed parameter */
	tmp = extract_programmer_param("serialspeed");
	if (tmp) {
		for (i = 0; serialspeeds[i].name; i++) {
			if (!strncasecmp(serialspeeds[i].name, tmp, strlen(serialspeeds[i].name))) {
				serialspeed_index = i;
				break;
			}
		}
		if (!serialspeeds[i].name)
			msg_perr("Invalid serial speed %s, using default.\n", tmp);
	}
	free(tmp);

	tmp = extract_programmer_param("pullups");
	if (tmp) {
		if (strcasecmp("on", tmp) == 0)
			pullup = true;
		else if (strcasecmp("off", tmp) == 0)
			; // ignore
		else
			msg_perr("Invalid pullups state, not using them.\n");
	}
	free(tmp);

	tmp = extract_programmer_param("psus");
	if (tmp) {
		if (strcasecmp("on", tmp) == 0)
			psu = true;
		else if (strcasecmp("off", tmp) == 0)
			; // ignore
		else
			msg_perr("Invalid psus state, not enabling.\n");
	}
	free(tmp);

	/* Default buffer size is 19: 16 bytes data, 3 bytes control. */
#define DEFAULT_BUFSIZE (16 + 3)
	bp_commbuf = malloc(DEFAULT_BUFSIZE);
	if (!bp_commbuf) {
		msg_perr("Out of memory!\n");
		free(dev);
		return ERROR_OOM;
	}
	bp_commbufsize = DEFAULT_BUFSIZE;

	ret = buspirate_serialport_setup(dev);
	free(dev);
	if (ret) {
		free(bp_commbuf);
		return ret;
	}


	struct bp_spi_data *bp_data = calloc(1, sizeof(*bp_data));
	if (!bp_data) {
		msg_perr("Unable to allocate space for SPI master data\n");
		free(bp_commbuf);
		return 1;
	}
	bp_data->commbuf = bp_commbuf;
	bp_data->commbufsize = bp_commbufsize;

	/* This is the brute force version, but it should work.
	 * It is likely to fail if a previous flashprog run was aborted during a write with the new SPI commands
	 * in firmware v5.5 because that firmware may wait for up to 4096 bytes of input before responding to
	 * 0x00 again. The obvious workaround (sending 4096 bytes of \0) may cause significant startup delays.
	 */
	for (i = 0; i < 20; i++) {
		/* Enter raw bitbang mode */
		bp_commbuf[0] = 0x00;
		/* Send the command, don't read the response. */
		ret = buspirate_sendrecv(bp_commbuf, 1, 0);
		if (ret)
			goto init_err_cleanup_exit;
		/* The old way to handle responses from a Bus Pirate already in BBIO mode was to flush any
		 * response which came in over serial. Unfortunately that does not work reliably on Linux
		 * with FTDI USB-serial.
		 */
		//sp_flush_incoming();
		/* The Bus Pirate can't handle UART input buffer overflow in BBIO mode, and sending a sequence
		 * of 0x00 too fast apparently triggers such an UART input buffer overflow.
		 */
		internal_sleep(10000);
	}
	/* We know that 20 commands of \0 should elicit at least one BBIO1 response. */
	if ((ret = buspirate_wait_for_string(bp_commbuf, "BBIO")))
		goto init_err_cleanup_exit;

	/* Reset the Bus Pirate. */
	bp_commbuf[0] = 0x0f;
	/* Send the command, don't read the response. */
	if ((ret = buspirate_sendrecv(bp_commbuf, 1, 0)))
		goto init_err_cleanup_exit;
	if ((ret = buspirate_wait_for_string(bp_commbuf, "irate ")))
		goto init_err_cleanup_exit;
	/* Read the hardware version string. Last byte of the buffer is reserved for \0. */
	for (i = 0; i < DEFAULT_BUFSIZE - 1; i++) {
		if ((ret = buspirate_sendrecv(bp_commbuf + i, 0, 1)))
			goto init_err_cleanup_exit;
		if (strchr("\r\n\t ", bp_commbuf[i]))
			break;
	}
	bp_commbuf[i] = '\0';
	msg_pdbg("Detected Bus Pirate hardware ");
	if (bp_commbuf[0] != 'v')
		msg_pdbg("(unknown version number format)");
	else if (!strchr("0123456789", bp_commbuf[1]))
		msg_pdbg("(unknown version number format)");
	else {
		hw_version_major = strtoul((char *)bp_commbuf + 1, &tmp, 10);
		while ((*tmp != '\0') && !strchr("0123456789", *tmp))
			tmp++;
		hw_version_minor = strtoul(tmp, NULL, 10);
		msg_pdbg("%u.%u", hw_version_major, hw_version_minor);
	}
	msg_pdbg2(" (\"%s\")", bp_commbuf);
	msg_pdbg("\n");

	if ((ret = buspirate_wait_for_string(bp_commbuf, "irmware ")))
		goto init_err_cleanup_exit;
	/* Read the firmware version string. Last byte of the buffer is reserved for \0. */
	for (i = 0; i < DEFAULT_BUFSIZE - 1; i++) {
		if ((ret = buspirate_sendrecv(bp_commbuf + i, 0, 1)))
			goto init_err_cleanup_exit;
		if (strchr("\r\n\t ", bp_commbuf[i]))
			break;
	}
	bp_commbuf[i] = '\0';
	msg_pdbg("Detected Bus Pirate firmware ");
	if (bp_commbuf[0] != 'v')
		msg_pdbg("(unknown version number format)");
	else if (!strchr("0123456789", bp_commbuf[1]))
		msg_pdbg("(unknown version number format)");
	else {
		fw_version_major = strtoul((char *)bp_commbuf + 1, &tmp, 10);
		while ((*tmp != '\0') && !strchr("0123456789", *tmp))
			tmp++;
		fw_version_minor = strtoul(tmp, NULL, 10);
		msg_pdbg("%u.%u", fw_version_major, fw_version_minor);
	}
	msg_pdbg2(" (\"%s\")", bp_commbuf);
	msg_pdbg("\n");

	if ((ret = buspirate_wait_for_string(bp_commbuf, "HiZ>")))
		goto init_err_cleanup_exit;

	/* Tell the user about missing SPI binary mode in firmware 2.3 and older. */
	if (BP_FWVERSION(fw_version_major, fw_version_minor) < BP_FWVERSION(2, 4)) {
		msg_pinfo("Bus Pirate firmware 2.3 and older does not support binary SPI access.\n");
		msg_pinfo("Please upgrade to the latest firmware (at least 2.4).\n");
		ret = SPI_PROGRAMMER_ERROR;
		goto init_err_cleanup_exit;
	}

	/* Use fast SPI mode in firmware 5.5 and newer. */
	if (BP_FWVERSION(fw_version_major, fw_version_minor) >= BP_FWVERSION(5, 5)) {
		msg_pdbg("Using SPI command set v2.\n");
		/* Sensible default buffer size. */
		if (buspirate_commbuf_grow(260 + 5, &bp_commbuf, &bp_commbufsize)) {
			ret = ERROR_OOM;
			goto init_err_cleanup_exit;
		}
		bp_data->commbuf = bp_commbuf;
		bp_data->commbufsize = bp_commbufsize;
		spi_master_buspirate.max_data_read = 2048;
		spi_master_buspirate.max_data_write = 256;
		spi_master_buspirate.command = buspirate_spi_send_command_v2;
	} else {
		msg_pinfo("Bus Pirate firmware 5.4 and older does not support fast SPI access.\n");
		msg_pinfo("Reading/writing a flash chip may take hours.\n");
		msg_pinfo("It is recommended to upgrade to firmware 5.5 or newer.\n");
		/* Sensible default buffer size. */
		if (buspirate_commbuf_grow(16 + 3, &bp_commbuf, &bp_commbufsize)) {
			ret = ERROR_OOM;
			goto init_err_cleanup_exit;
		}
		bp_data->commbuf = bp_commbuf;
		bp_data->commbufsize = bp_commbufsize;
		spi_master_buspirate.max_data_read = 12;
		spi_master_buspirate.max_data_write = 12;
		spi_master_buspirate.command = buspirate_spi_send_command_v1;
	}

	/* Workaround for broken speed settings in firmware 6.1 and older. */
	if (BP_FWVERSION(fw_version_major, fw_version_minor) < BP_FWVERSION(6, 2))
		if (spispeed > 0x4) {
			msg_perr("Bus Pirate firmware 6.1 and older does not support SPI speeds above 2 MHz. "
				 "Limiting speed to 2 MHz.\n");
			msg_pinfo("It is recommended to upgrade to firmware 6.2 or newer.\n");
			spispeed = 0x4;
		}

	/* This works because speeds numbering starts at 0 and is contiguous. */
	msg_pdbg("SPI speed is %sHz\n", spispeeds[spispeed].name);

	/* Set 2M baud serial speed by default on hardware 3.0 and newer if a custom speed was not set */
	if (serialspeed_index == -1 && BP_HWVERSION(hw_version_major, hw_version_minor) >= BP_HWVERSION(3, 0)) {
		serialspeed_index = ARRAY_SIZE(serialspeeds) - 2;
		msg_pdbg("Bus Pirate v3 or newer detected. Set serial speed to 2M baud.\n");
	}

	/* Set custom serial speed if specified */
	if (serialspeed_index != -1) {
		if (BP_FWVERSION(fw_version_major, fw_version_minor) < BP_FWVERSION(5, 5)) {
			/* This feature requires firmware 5.5 or newer */
			msg_perr("Bus Pirate firmware 5.4 and older does not support custom serial speeds."
				 "Using default speed of 115200 baud.\n");
		} else if (serialspeeds[serialspeed_index].speed != BP_DEFAULTBAUD) {
			/* Set the serial speed to match the user's choice if it doesn't already */

			if (BP_HWVERSION(hw_version_major, hw_version_minor) < BP_HWVERSION(3, 0))
				msg_pwarn("Increased serial speeds may not work on older (<3.0) Bus Pirates."
					" Continue at your own risk.\n");

			/* Enter baud rate configuration mode */
			cnt = snprintf((char *)bp_commbuf, DEFAULT_BUFSIZE, "b\n");
			if ((ret = buspirate_sendrecv(bp_commbuf, cnt, 0)))
				goto init_err_cleanup_exit;
			if ((ret = buspirate_wait_for_string(bp_commbuf, ">")))
				goto init_err_cleanup_exit;

			/* Enter manual clock divisor entry mode */
			cnt = snprintf((char *)bp_commbuf, DEFAULT_BUFSIZE, "10\n");
			if ((ret = buspirate_sendrecv(bp_commbuf, cnt, 0)))
				goto init_err_cleanup_exit;
			if ((ret = buspirate_wait_for_string(bp_commbuf, ">")))
				goto init_err_cleanup_exit;

			/* Set the clock divisor to the value calculated from the user's input */
			cnt = snprintf((char *)bp_commbuf, DEFAULT_BUFSIZE, "%d\n",
				BP_DIVISOR(serialspeeds[serialspeed_index].speed));

			if ((ret = buspirate_sendrecv(bp_commbuf, cnt, 0)))
				goto init_err_cleanup_exit;
			sleep(1);

			/* Reconfigure the host's serial baud rate to the new value */
			if ((ret = serialport_config(sp_fd, serialspeeds[serialspeed_index].speed))) {
				msg_perr("Unable to configure system baud rate to specified value.");
				goto init_err_cleanup_exit;
			}

			/* Return to the main prompt */
			bp_commbuf[0] = ' ';
			if ((ret = buspirate_sendrecv(bp_commbuf, 1, 0)))
				goto init_err_cleanup_exit;
			if ((ret = buspirate_wait_for_string(bp_commbuf, "HiZ>")))
				goto init_err_cleanup_exit;

			msg_pdbg("Serial speed is %d baud\n", serialspeeds[serialspeed_index].speed);
		}

	}



	/* Enter raw bitbang mode */
	for (i = 0; i < 20; i++) {
		bp_commbuf[0] = 0x00;
		if ((ret = buspirate_sendrecv(bp_commbuf, 1, 0)))
			goto init_err_cleanup_exit;
	}
	if ((ret = buspirate_wait_for_string(bp_commbuf, "BBIO")))
		goto init_err_cleanup_exit;
	if ((ret = buspirate_sendrecv(bp_commbuf, 0, 1)))
		goto init_err_cleanup_exit;
	msg_pdbg("Raw bitbang mode version %c\n", bp_commbuf[0]);
	if (bp_commbuf[0] != '1') {
		msg_perr("Can't handle raw bitbang mode version %c!\n", bp_commbuf[0]);
		ret = 1;
		goto init_err_cleanup_exit;
	}
	/* Enter raw SPI mode */
	bp_commbuf[0] = 0x01;
	ret = buspirate_sendrecv(bp_commbuf, 1, 0);
	if (ret)
		goto init_err_cleanup_exit;
	if ((ret = buspirate_wait_for_string(bp_commbuf, "SPI")))
		goto init_err_cleanup_exit;
	if ((ret = buspirate_sendrecv(bp_commbuf, 0, 1)))
		goto init_err_cleanup_exit;
	msg_pdbg("Raw SPI mode version %c\n", bp_commbuf[0]);
	if (bp_commbuf[0] != '1') {
		msg_perr("Can't handle raw SPI mode version %c!\n", bp_commbuf[0]);
		ret = 1;
		goto init_err_cleanup_exit;
	}

	/* Initial setup (SPI peripherals config): Enable power, CS high, AUX */
	bp_commbuf[0] = 0x40 | 0x0b;
	if (pullup) {
		bp_commbuf[0] |= (1 << 2);
		msg_pdbg("Enabling pull-up resistors.\n");
	}
	if (psu) {
		bp_commbuf[0] |= (1 << 3);
		msg_pdbg("Enabling PSUs.\n");
	}
	ret = buspirate_sendrecv(bp_commbuf, 1, 1);
	if (ret)
		goto init_err_cleanup_exit;
	if (bp_commbuf[0] != 0x01) {
		msg_perr("Protocol error while setting power/CS/AUX(/Pull-up resistors)!\n");
		ret = 1;
		goto init_err_cleanup_exit;
	}

	/* Set SPI speed */
	bp_commbuf[0] = 0x60 | spispeed;
	ret = buspirate_sendrecv(bp_commbuf, 1, 1);
	if (ret)
		goto init_err_cleanup_exit;
	if (bp_commbuf[0] != 0x01) {
		msg_perr("Protocol error while setting SPI speed!\n");
		ret = 1;
		goto init_err_cleanup_exit;
	}

	/* Set SPI config: output type, idle, clock edge, sample */
	bp_commbuf[0] = 0x80 | 0xa;
	if (pullup) {
		bp_commbuf[0] &= ~(1 << 3);
		msg_pdbg("Pull-ups enabled, so using HiZ pin output! (Open-Drain mode)\n");
	}
	ret = buspirate_sendrecv(bp_commbuf, 1, 1);
	if (ret)
		goto init_err_cleanup_exit;
	if (bp_commbuf[0] != 0x01) {
		msg_perr("Protocol error while setting SPI config!\n");
		ret = 1;
		goto init_err_cleanup_exit;
	}

	/* De-assert CS# */
	bp_commbuf[0] = 0x03;
	ret = buspirate_sendrecv(bp_commbuf, 1, 1);
	if (ret)
		goto init_err_cleanup_exit;
	if (bp_commbuf[0] != 0x01) {
		msg_perr("Protocol error while raising CS#!\n");
		ret = 1;
		goto init_err_cleanup_exit;
	}

	return register_spi_master(&spi_master_buspirate, 0, bp_data);

init_err_cleanup_exit:
	buspirate_spi_shutdown(bp_data);
	return ret;
}

static int buspirate_spi_send_command_v1(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
					 const unsigned char *writearr, unsigned char *readarr)
{
	struct bp_spi_data *bp_data = flash->mst.spi->data;
	unsigned int i = 0;
	int ret = 0;

	if (writecnt > 16 || readcnt > 16 || (readcnt + writecnt) > 16)
		return SPI_INVALID_LENGTH;

	/* 3 bytes extra for CS#, len, CS#. */
	if (buspirate_commbuf_grow(writecnt + readcnt + 3, &bp_data->commbuf, &bp_data->commbufsize))
		return ERROR_OOM;

	unsigned char *const bp_commbuf = bp_data->commbuf;

	/* Assert CS# */
	bp_commbuf[i++] = 0x02;

	bp_commbuf[i++] = 0x10 | (writecnt + readcnt - 1);
	memcpy(bp_commbuf + i, writearr, writecnt);
	i += writecnt;
	memset(bp_commbuf + i, 0, readcnt);

	i += readcnt;
	/* De-assert CS# */
	bp_commbuf[i++] = 0x03;

	ret = buspirate_sendrecv(bp_commbuf, i, i);

	if (ret) {
		msg_perr("Bus Pirate communication error!\n");
		return SPI_GENERIC_ERROR;
	}

	if (bp_commbuf[0] != 0x01) {
		msg_perr("Protocol error while lowering CS#!\n");
		return SPI_GENERIC_ERROR;
	}

	if (bp_commbuf[1] != 0x01) {
		msg_perr("Protocol error while reading/writing SPI!\n");
		return SPI_GENERIC_ERROR;
	}

	if (bp_commbuf[i - 1] != 0x01) {
		msg_perr("Protocol error while raising CS#!\n");
		return SPI_GENERIC_ERROR;
	}

	/* Skip CS#, length, writearr. */
	memcpy(readarr, bp_commbuf + 2 + writecnt, readcnt);

	return ret;
}

static int buspirate_spi_send_command_v2(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
					 const unsigned char *writearr, unsigned char *readarr)
{
	struct bp_spi_data *bp_data = flash->mst.spi->data;
	int i = 0, ret = 0;

	if (writecnt > 4096 || readcnt > 4096 || (readcnt + writecnt) > 4096)
		return SPI_INVALID_LENGTH;

	/* 5 bytes extra for command, writelen, readlen.
	 * 1 byte extra for Ack/Nack.
	 */
	if (buspirate_commbuf_grow(max(writecnt + 5, readcnt + 1), &bp_data->commbuf, &bp_data->commbufsize))
		return ERROR_OOM;

	unsigned char *const bp_commbuf = bp_data->commbuf;

	/* Combined SPI write/read. */
	bp_commbuf[i++] = 0x04;
	bp_commbuf[i++] = (writecnt >> 8) & 0xff;
	bp_commbuf[i++] = writecnt & 0xff;
	bp_commbuf[i++] = (readcnt >> 8) & 0xff;
	bp_commbuf[i++] = readcnt & 0xff;
	memcpy(bp_commbuf + i, writearr, writecnt);

	ret = buspirate_sendrecv(bp_commbuf, i + writecnt, 1 + readcnt);

	if (ret) {
		msg_perr("Bus Pirate communication error!\n");
		return SPI_GENERIC_ERROR;
	}

	if (bp_commbuf[0] != 0x01) {
		msg_perr("Protocol error while sending SPI write/read!\n");
		return SPI_GENERIC_ERROR;
	}

	/* Skip Ack. */
	memcpy(readarr, bp_commbuf + 1, readcnt);

	return ret;
}

const struct programmer_entry programmer_buspirate_spi = {
	.name			= "buspirate_spi",
	.type			= OTHER,
				/* FIXME */
	.devs.note		= "Dangerous Prototypes Bus Pirate\n",
	.init			= buspirate_spi_init,
};
