// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * altera-jtag.c
 *
 * altera FPGA driver
 *
 * Copyright (C) Altera Corporation 1998-2001
 * Copyright (C) 2010 NetUP Inc.
 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
 */

#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/slab.h>
#include <misc/altera.h>
#include "altera-exprt.h"
#include "altera-jtag.h"

#define	alt_jtag_io(a, b, c)\
		astate->config->jtag_io(astate->config->dev, a, b, c);

#define	alt_malloc(a)	kzalloc(a, GFP_KERNEL);

/*
 * This structure shows, for each JTAG state, which state is reached after
 * a single TCK clock cycle with TMS high or TMS low, respectively.  This
 * describes all possible state transitions in the JTAG state machine.
 */
struct altera_jtag_machine {
	enum altera_jtag_state tms_high;
	enum altera_jtag_state tms_low;
};

static const struct altera_jtag_machine altera_transitions[] = {
	/* RESET     */	{ RESET,	IDLE },
	/* IDLE      */	{ DRSELECT,	IDLE },
	/* DRSELECT  */	{ IRSELECT,	DRCAPTURE },
	/* DRCAPTURE */	{ DREXIT1,	DRSHIFT },
	/* DRSHIFT   */	{ DREXIT1,	DRSHIFT },
	/* DREXIT1   */	{ DRUPDATE,	DRPAUSE },
	/* DRPAUSE   */	{ DREXIT2,	DRPAUSE },
	/* DREXIT2   */	{ DRUPDATE,	DRSHIFT },
	/* DRUPDATE  */	{ DRSELECT,	IDLE },
	/* IRSELECT  */	{ RESET,	IRCAPTURE },
	/* IRCAPTURE */	{ IREXIT1,	IRSHIFT },
	/* IRSHIFT   */	{ IREXIT1,	IRSHIFT },
	/* IREXIT1   */	{ IRUPDATE,	IRPAUSE },
	/* IRPAUSE   */	{ IREXIT2,	IRPAUSE },
	/* IREXIT2   */	{ IRUPDATE,	IRSHIFT },
	/* IRUPDATE  */	{ DRSELECT,	IDLE }
};

/*
 * This table contains the TMS value to be used to take the NEXT STEP on
 * the path to the desired state.  The array index is the current state,
 * and the bit position is the desired endstate.  To find out which state
 * is used as the intermediate state, look up the TMS value in the
 * altera_transitions[] table.
 */
static const u16 altera_jtag_path_map[16] = {
	/* RST	RTI	SDRS	CDR	SDR	E1DR	PDR	E2DR */
	0x0001,	0xFFFD,	0xFE01,	0xFFE7,	0xFFEF,	0xFF0F,	0xFFBF,	0xFFFF,
	/* UDR	SIRS	CIR	SIR	E1IR	PIR	E2IR	UIR */
	0xFEFD,	0x0001,	0xF3FF,	0xF7FF,	0x87FF,	0xDFFF,	0xFFFF,	0x7FFD
};

/* Flag bits for alt_jtag_io() function */
#define TMS_HIGH   1
#define TMS_LOW    0
#define TDI_HIGH   1
#define TDI_LOW    0
#define READ_TDO   1
#define IGNORE_TDO 0

int altera_jinit(struct altera_state *astate)
{
	struct altera_jtag *js = &astate->js;

	/* initial JTAG state is unknown */
	js->jtag_state = ILLEGAL_JTAG_STATE;

	/* initialize to default state */
	js->drstop_state = IDLE;
	js->irstop_state = IDLE;
	js->dr_pre  = 0;
	js->dr_post = 0;
	js->ir_pre  = 0;
	js->ir_post = 0;
	js->dr_length    = 0;
	js->ir_length    = 0;

	js->dr_pre_data  = NULL;
	js->dr_post_data = NULL;
	js->ir_pre_data  = NULL;
	js->ir_post_data = NULL;
	js->dr_buffer	 = NULL;
	js->ir_buffer	 = NULL;

	return 0;
}

int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state)
{
	js->drstop_state = state;

	return 0;
}

int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state)
{
	js->irstop_state = state;

	return 0;
}

int altera_set_dr_pre(struct altera_jtag *js,
				u32 count, u32 start_index,
				u8 *preamble_data)
{
	int status = 0;
	u32 i;
	u32 j;

	if (count > js->dr_pre) {
		kfree(js->dr_pre_data);
		js->dr_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
		if (js->dr_pre_data == NULL)
			status = -ENOMEM;
		else
			js->dr_pre = count;
	} else
		js->dr_pre = count;

	if (status == 0) {
		for (i = 0; i < count; ++i) {
			j = i + start_index;

			if (preamble_data == NULL)
				js->dr_pre_data[i >> 3] |= (1 << (i & 7));
			else {
				if (preamble_data[j >> 3] & (1 << (j & 7)))
					js->dr_pre_data[i >> 3] |=
							(1 << (i & 7));
				else
					js->dr_pre_data[i >> 3] &=
							~(u32)(1 << (i & 7));

			}
		}
	}

	return status;
}

int altera_set_ir_pre(struct altera_jtag *js, u32 count, u32 start_index,
							u8 *preamble_data)
{
	int status = 0;
	u32 i;
	u32 j;

	if (count > js->ir_pre) {
		kfree(js->ir_pre_data);
		js->ir_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
		if (js->ir_pre_data == NULL)
			status = -ENOMEM;
		else
			js->ir_pre = count;

	} else
		js->ir_pre = count;

	if (status == 0) {
		for (i = 0; i < count; ++i) {
			j = i + start_index;
			if (preamble_data == NULL)
				js->ir_pre_data[i >> 3] |= (1 << (i & 7));
			else {
				if (preamble_data[j >> 3] & (1 << (j & 7)))
					js->ir_pre_data[i >> 3] |=
							(1 << (i & 7));
				else
					js->ir_pre_data[i >> 3] &=
							~(u32)(1 << (i & 7));

			}
		}
	}

	return status;
}

int altera_set_dr_post(struct altera_jtag *js, u32 count, u32 start_index,
						u8 *postamble_data)
{
	int status = 0;
	u32 i;
	u32 j;

	if (count > js->dr_post) {
		kfree(js->dr_post_data);
		js->dr_post_data = (u8 *)alt_malloc((count + 7) >> 3);

		if (js->dr_post_data == NULL)
			status = -ENOMEM;
		else
			js->dr_post = count;

	} else
		js->dr_post = count;

	if (status == 0) {
		for (i = 0; i < count; ++i) {
			j = i + start_index;

			if (postamble_data == NULL)
				js->dr_post_data[i >> 3] |= (1 << (i & 7));
			else {
				if (postamble_data[j >> 3] & (1 << (j & 7)))
					js->dr_post_data[i >> 3] |=
								(1 << (i & 7));
				else
					js->dr_post_data[i >> 3] &=
					    ~(u32)(1 << (i & 7));

			}
		}
	}

	return status;
}

int altera_set_ir_post(struct altera_jtag *js, u32 count, u32 start_index,
						u8 *postamble_data)
{
	int status = 0;
	u32 i;
	u32 j;

	if (count > js->ir_post) {
		kfree(js->ir_post_data);
		js->ir_post_data = (u8 *)alt_malloc((count + 7) >> 3);
		if (js->ir_post_data == NULL)
			status = -ENOMEM;
		else
			js->ir_post = count;

	} else
		js->ir_post = count;

	if (status != 0)
		return status;

	for (i = 0; i < count; ++i) {
		j = i + start_index;

		if (postamble_data == NULL)
			js->ir_post_data[i >> 3] |= (1 << (i & 7));
		else {
			if (postamble_data[j >> 3] & (1 << (j & 7)))
				js->ir_post_data[i >> 3] |= (1 << (i & 7));
			else
				js->ir_post_data[i >> 3] &=
				    ~(u32)(1 << (i & 7));

		}
	}

	return status;
}

static void altera_jreset_idle(struct altera_state *astate)
{
	struct altera_jtag *js = &astate->js;
	int i;
	/* Go to Test Logic Reset (no matter what the starting state may be) */
	for (i = 0; i < 5; ++i)
		alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);

	/* Now step to Run Test / Idle */
	alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
	js->jtag_state = IDLE;
}

int altera_goto_jstate(struct altera_state *astate,
					enum altera_jtag_state state)
{
	struct altera_jtag *js = &astate->js;
	int tms;
	int count = 0;
	int status = 0;

	if (js->jtag_state == ILLEGAL_JTAG_STATE)
		/* initialize JTAG chain to known state */
		altera_jreset_idle(astate);

	if (js->jtag_state == state) {
		/*
		 * We are already in the desired state.
		 * If it is a stable state, loop here.
		 * Otherwise do nothing (no clock cycles).
		 */
		if ((state == IDLE) || (state == DRSHIFT) ||
			(state == DRPAUSE) || (state == IRSHIFT) ||
				(state == IRPAUSE)) {
			alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
		} else if (state == RESET)
			alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);

	} else {
		while ((js->jtag_state != state) && (count < 9)) {
			/* Get TMS value to take a step toward desired state */
			tms = (altera_jtag_path_map[js->jtag_state] &
							(1 << state))
							? TMS_HIGH : TMS_LOW;

			/* Take a step */
			alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);

			if (tms)
				js->jtag_state =
					altera_transitions[js->jtag_state].tms_high;
			else
				js->jtag_state =
					altera_transitions[js->jtag_state].tms_low;

			++count;
		}
	}

	if (js->jtag_state != state)
		status = -EREMOTEIO;

	return status;
}

int altera_wait_cycles(struct altera_state *astate,
					s32 cycles,
					enum altera_jtag_state wait_state)
{
	struct altera_jtag *js = &astate->js;
	int tms;
	s32 count;
	int status = 0;

	if (js->jtag_state != wait_state)
		status = altera_goto_jstate(astate, wait_state);

	if (status == 0) {
		/*
		 * Set TMS high to loop in RESET state
		 * Set TMS low to loop in any other stable state
		 */
		tms = (wait_state == RESET) ? TMS_HIGH : TMS_LOW;

		for (count = 0L; count < cycles; count++)
			alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);

	}

	return status;
}

int altera_wait_msecs(struct altera_state *astate,
			s32 microseconds, enum altera_jtag_state wait_state)
/*
 * Causes JTAG hardware to sit in the specified stable
 * state for the specified duration of real time.  If
 * no JTAG operations have been performed yet, then only
 * a delay is performed.  This permits the WAIT USECS
 * statement to be used in VECTOR programs without causing
 * any JTAG operations.
 * Returns 0 for success, else appropriate error code.
 */
{
	struct altera_jtag *js = &astate->js;
	int status = 0;

	if ((js->jtag_state != ILLEGAL_JTAG_STATE) &&
	    (js->jtag_state != wait_state))
		status = altera_goto_jstate(astate, wait_state);

	if (status == 0)
		/* Wait for specified time interval */
		udelay(microseconds);

	return status;
}

static void altera_concatenate_data(u8 *buffer,
				u8 *preamble_data,
				u32 preamble_count,
				u8 *target_data,
				u32 start_index,
				u32 target_count,
				u8 *postamble_data,
				u32 postamble_count)
/*
 * Copies preamble data, target data, and postamble data
 * into one buffer for IR or DR scans.
 */
{
	u32 i, j, k;

	for (i = 0L; i < preamble_count; ++i) {
		if (preamble_data[i >> 3L] & (1L << (i & 7L)))
			buffer[i >> 3L] |= (1L << (i & 7L));
		else
			buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));

	}

	j = start_index;
	k = preamble_count + target_count;
	for (; i < k; ++i, ++j) {
		if (target_data[j >> 3L] & (1L << (j & 7L)))
			buffer[i >> 3L] |= (1L << (i & 7L));
		else
			buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));

	}

	j = 0L;
	k = preamble_count + target_count + postamble_count;
	for (; i < k; ++i, ++j) {
		if (postamble_data[j >> 3L] & (1L << (j & 7L)))
			buffer[i >> 3L] |= (1L << (i & 7L));
		else
			buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));

	}
}

static int alt_jtag_drscan(struct altera_state *astate,
			int start_state,
			int count,
			u8 *tdi,
			u8 *tdo)
{
	int i = 0;
	int tdo_bit = 0;
	int status = 1;

	/* First go to DRSHIFT state */
	switch (start_state) {
	case 0:						/* IDLE */
		alt_jtag_io(1, 0, 0);	/* DRSELECT */
		alt_jtag_io(0, 0, 0);	/* DRCAPTURE */
		alt_jtag_io(0, 0, 0);	/* DRSHIFT */
		break;

	case 1:						/* DRPAUSE */
		alt_jtag_io(1, 0, 0);	/* DREXIT2 */
		alt_jtag_io(1, 0, 0);	/* DRUPDATE */
		alt_jtag_io(1, 0, 0);	/* DRSELECT */
		alt_jtag_io(0, 0, 0);	/* DRCAPTURE */
		alt_jtag_io(0, 0, 0);	/* DRSHIFT */
		break;

	case 2:						/* IRPAUSE */
		alt_jtag_io(1, 0, 0);	/* IREXIT2 */
		alt_jtag_io(1, 0, 0);	/* IRUPDATE */
		alt_jtag_io(1, 0, 0);	/* DRSELECT */
		alt_jtag_io(0, 0, 0);	/* DRCAPTURE */
		alt_jtag_io(0, 0, 0);	/* DRSHIFT */
		break;

	default:
		status = 0;
	}

	if (status) {
		/* loop in the SHIFT-DR state */
		for (i = 0; i < count; i++) {
			tdo_bit = alt_jtag_io(
					(i == count - 1),
					tdi[i >> 3] & (1 << (i & 7)),
					(tdo != NULL));

			if (tdo != NULL) {
				if (tdo_bit)
					tdo[i >> 3] |= (1 << (i & 7));
				else
					tdo[i >> 3] &= ~(u32)(1 << (i & 7));

			}
		}

		alt_jtag_io(0, 0, 0);	/* DRPAUSE */
	}

	return status;
}

static int alt_jtag_irscan(struct altera_state *astate,
		    int start_state,
		    int count,
		    u8 *tdi,
		    u8 *tdo)
{
	int i = 0;
	int tdo_bit = 0;
	int status = 1;

	/* First go to IRSHIFT state */
	switch (start_state) {
	case 0:						/* IDLE */
		alt_jtag_io(1, 0, 0);	/* DRSELECT */
		alt_jtag_io(1, 0, 0);	/* IRSELECT */
		alt_jtag_io(0, 0, 0);	/* IRCAPTURE */
		alt_jtag_io(0, 0, 0);	/* IRSHIFT */
		break;

	case 1:						/* DRPAUSE */
		alt_jtag_io(1, 0, 0);	/* DREXIT2 */
		alt_jtag_io(1, 0, 0);	/* DRUPDATE */
		alt_jtag_io(1, 0, 0);	/* DRSELECT */
		alt_jtag_io(1, 0, 0);	/* IRSELECT */
		alt_jtag_io(0, 0, 0);	/* IRCAPTURE */
		alt_jtag_io(0, 0, 0);	/* IRSHIFT */
		break;

	case 2:						/* IRPAUSE */
		alt_jtag_io(1, 0, 0);	/* IREXIT2 */
		alt_jtag_io(1, 0, 0);	/* IRUPDATE */
		alt_jtag_io(1, 0, 0);	/* DRSELECT */
		alt_jtag_io(1, 0, 0);	/* IRSELECT */
		alt_jtag_io(0, 0, 0);	/* IRCAPTURE */
		alt_jtag_io(0, 0, 0);	/* IRSHIFT */
		break;

	default:
		status = 0;
	}

	if (status) {
		/* loop in the SHIFT-IR state */
		for (i = 0; i < count; i++) {
			tdo_bit = alt_jtag_io(
				      (i == count - 1),
				      tdi[i >> 3] & (1 << (i & 7)),
				      (tdo != NULL));
			if (tdo != NULL) {
				if (tdo_bit)
					tdo[i >> 3] |= (1 << (i & 7));
				else
					tdo[i >> 3] &= ~(u32)(1 << (i & 7));

			}
		}

		alt_jtag_io(0, 0, 0);	/* IRPAUSE */
	}

	return status;
}

static void altera_extract_target_data(u8 *buffer,
				u8 *target_data,
				u32 start_index,
				u32 preamble_count,
				u32 target_count)
/*
 * Copies target data from scan buffer, filtering out
 * preamble and postamble data.
 */
{
	u32 i;
	u32 j;
	u32 k;

	j = preamble_count;
	k = start_index + target_count;
	for (i = start_index; i < k; ++i, ++j) {
		if (buffer[j >> 3] & (1 << (j & 7)))
			target_data[i >> 3] |= (1 << (i & 7));
		else
			target_data[i >> 3] &= ~(u32)(1 << (i & 7));

	}
}

int altera_irscan(struct altera_state *astate,
				u32 count,
				u8 *tdi_data,
				u32 start_index)
/* Shifts data into instruction register */
{
	struct altera_jtag *js = &astate->js;
	int start_code = 0;
	u32 alloc_chars = 0;
	u32 shift_count = js->ir_pre + count + js->ir_post;
	int status = 0;
	enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;

	switch (js->jtag_state) {
	case ILLEGAL_JTAG_STATE:
	case RESET:
	case IDLE:
		start_code = 0;
		start_state = IDLE;
		break;

	case DRSELECT:
	case DRCAPTURE:
	case DRSHIFT:
	case DREXIT1:
	case DRPAUSE:
	case DREXIT2:
	case DRUPDATE:
		start_code = 1;
		start_state = DRPAUSE;
		break;

	case IRSELECT:
	case IRCAPTURE:
	case IRSHIFT:
	case IREXIT1:
	case IRPAUSE:
	case IREXIT2:
	case IRUPDATE:
		start_code = 2;
		start_state = IRPAUSE;
		break;

	default:
		status = -EREMOTEIO;
		break;
	}

	if (status == 0)
		if (js->jtag_state != start_state)
			status = altera_goto_jstate(astate, start_state);

	if (status == 0) {
		if (shift_count > js->ir_length) {
			alloc_chars = (shift_count + 7) >> 3;
			kfree(js->ir_buffer);
			js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
			if (js->ir_buffer == NULL)
				status = -ENOMEM;
			else
				js->ir_length = alloc_chars * 8;

		}
	}

	if (status == 0) {
		/*
		 * Copy preamble data, IR data,
		 * and postamble data into a buffer
		 */
		altera_concatenate_data(js->ir_buffer,
					js->ir_pre_data,
					js->ir_pre,
					tdi_data,
					start_index,
					count,
					js->ir_post_data,
					js->ir_post);
		/* Do the IRSCAN */
		alt_jtag_irscan(astate,
				start_code,
				shift_count,
				js->ir_buffer,
				NULL);

		/* alt_jtag_irscan() always ends in IRPAUSE state */
		js->jtag_state = IRPAUSE;
	}

	if (status == 0)
		if (js->irstop_state != IRPAUSE)
			status = altera_goto_jstate(astate, js->irstop_state);


	return status;
}

int altera_swap_ir(struct altera_state *astate,
			    u32 count,
			    u8 *in_data,
			    u32 in_index,
			    u8 *out_data,
			    u32 out_index)
/* Shifts data into instruction register, capturing output data */
{
	struct altera_jtag *js = &astate->js;
	int start_code = 0;
	u32 alloc_chars = 0;
	u32 shift_count = js->ir_pre + count + js->ir_post;
	int status = 0;
	enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;

	switch (js->jtag_state) {
	case ILLEGAL_JTAG_STATE:
	case RESET:
	case IDLE:
		start_code = 0;
		start_state = IDLE;
		break;

	case DRSELECT:
	case DRCAPTURE:
	case DRSHIFT:
	case DREXIT1:
	case DRPAUSE:
	case DREXIT2:
	case DRUPDATE:
		start_code = 1;
		start_state = DRPAUSE;
		break;

	case IRSELECT:
	case IRCAPTURE:
	case IRSHIFT:
	case IREXIT1:
	case IRPAUSE:
	case IREXIT2:
	case IRUPDATE:
		start_code = 2;
		start_state = IRPAUSE;
		break;

	default:
		status = -EREMOTEIO;
		break;
	}

	if (status == 0)
		if (js->jtag_state != start_state)
			status = altera_goto_jstate(astate, start_state);

	if (status == 0) {
		if (shift_count > js->ir_length) {
			alloc_chars = (shift_count + 7) >> 3;
			kfree(js->ir_buffer);
			js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
			if (js->ir_buffer == NULL)
				status = -ENOMEM;
			else
				js->ir_length = alloc_chars * 8;

		}
	}

	if (status == 0) {
		/*
		 * Copy preamble data, IR data,
		 * and postamble data into a buffer
		 */
		altera_concatenate_data(js->ir_buffer,
					js->ir_pre_data,
					js->ir_pre,
					in_data,
					in_index,
					count,
					js->ir_post_data,
					js->ir_post);

		/* Do the IRSCAN */
		alt_jtag_irscan(astate,
				start_code,
				shift_count,
				js->ir_buffer,
				js->ir_buffer);

		/* alt_jtag_irscan() always ends in IRPAUSE state */
		js->jtag_state = IRPAUSE;
	}

	if (status == 0)
		if (js->irstop_state != IRPAUSE)
			status = altera_goto_jstate(astate, js->irstop_state);


	if (status == 0)
		/* Now extract the returned data from the buffer */
		altera_extract_target_data(js->ir_buffer,
					out_data, out_index,
					js->ir_pre, count);

	return status;
}

int altera_drscan(struct altera_state *astate,
				u32 count,
				u8 *tdi_data,
				u32 start_index)
/* Shifts data into data register (ignoring output data) */
{
	struct altera_jtag *js = &astate->js;
	int start_code = 0;
	u32 alloc_chars = 0;
	u32 shift_count = js->dr_pre + count + js->dr_post;
	int status = 0;
	enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;

	switch (js->jtag_state) {
	case ILLEGAL_JTAG_STATE:
	case RESET:
	case IDLE:
		start_code = 0;
		start_state = IDLE;
		break;

	case DRSELECT:
	case DRCAPTURE:
	case DRSHIFT:
	case DREXIT1:
	case DRPAUSE:
	case DREXIT2:
	case DRUPDATE:
		start_code = 1;
		start_state = DRPAUSE;
		break;

	case IRSELECT:
	case IRCAPTURE:
	case IRSHIFT:
	case IREXIT1:
	case IRPAUSE:
	case IREXIT2:
	case IRUPDATE:
		start_code = 2;
		start_state = IRPAUSE;
		break;

	default:
		status = -EREMOTEIO;
		break;
	}

	if (status == 0)
		if (js->jtag_state != start_state)
			status = altera_goto_jstate(astate, start_state);

	if (status == 0) {
		if (shift_count > js->dr_length) {
			alloc_chars = (shift_count + 7) >> 3;
			kfree(js->dr_buffer);
			js->dr_buffer = (u8 *)alt_malloc(alloc_chars);
			if (js->dr_buffer == NULL)
				status = -ENOMEM;
			else
				js->dr_length = alloc_chars * 8;

		}
	}

	if (status == 0) {
		/*
		 * Copy preamble data, DR data,
		 * and postamble data into a buffer
		 */
		altera_concatenate_data(js->dr_buffer,
					js->dr_pre_data,
					js->dr_pre,
					tdi_data,
					start_index,
					count,
					js->dr_post_data,
					js->dr_post);
		/* Do the DRSCAN */
		alt_jtag_drscan(astate, start_code, shift_count,
				js->dr_buffer, NULL);
		/* alt_jtag_drscan() always ends in DRPAUSE state */
		js->jtag_state = DRPAUSE;
	}

	if (status == 0)
		if (js->drstop_state != DRPAUSE)
			status = altera_goto_jstate(astate, js->drstop_state);

	return status;
}

int altera_swap_dr(struct altera_state *astate, u32 count,
				u8 *in_data, u32 in_index,
				u8 *out_data, u32 out_index)
/* Shifts data into data register, capturing output data */
{
	struct altera_jtag *js = &astate->js;
	int start_code = 0;
	u32 alloc_chars = 0;
	u32 shift_count = js->dr_pre + count + js->dr_post;
	int status = 0;
	enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;

	switch (js->jtag_state) {
	case ILLEGAL_JTAG_STATE:
	case RESET:
	case IDLE:
		start_code = 0;
		start_state = IDLE;
		break;

	case DRSELECT:
	case DRCAPTURE:
	case DRSHIFT:
	case DREXIT1:
	case DRPAUSE:
	case DREXIT2:
	case DRUPDATE:
		start_code = 1;
		start_state = DRPAUSE;
		break;

	case IRSELECT:
	case IRCAPTURE:
	case IRSHIFT:
	case IREXIT1:
	case IRPAUSE:
	case IREXIT2:
	case IRUPDATE:
		start_code = 2;
		start_state = IRPAUSE;
		break;

	default:
		status = -EREMOTEIO;
		break;
	}

	if (status == 0)
		if (js->jtag_state != start_state)
			status = altera_goto_jstate(astate, start_state);

	if (status == 0) {
		if (shift_count > js->dr_length) {
			alloc_chars = (shift_count + 7) >> 3;
			kfree(js->dr_buffer);
			js->dr_buffer = (u8 *)alt_malloc(alloc_chars);

			if (js->dr_buffer == NULL)
				status = -ENOMEM;
			else
				js->dr_length = alloc_chars * 8;

		}
	}

	if (status == 0) {
		/*
		 * Copy preamble data, DR data,
		 * and postamble data into a buffer
		 */
		altera_concatenate_data(js->dr_buffer,
				js->dr_pre_data,
				js->dr_pre,
				in_data,
				in_index,
				count,
				js->dr_post_data,
				js->dr_post);

		/* Do the DRSCAN */
		alt_jtag_drscan(astate,
				start_code,
				shift_count,
				js->dr_buffer,
				js->dr_buffer);

		/* alt_jtag_drscan() always ends in DRPAUSE state */
		js->jtag_state = DRPAUSE;
	}

	if (status == 0)
		if (js->drstop_state != DRPAUSE)
			status = altera_goto_jstate(astate, js->drstop_state);

	if (status == 0)
		/* Now extract the returned data from the buffer */
		altera_extract_target_data(js->dr_buffer,
					out_data,
					out_index,
					js->dr_pre,
					count);

	return status;
}

void altera_free_buffers(struct altera_state *astate)
{
	struct altera_jtag *js = &astate->js;
	/* If the JTAG interface was used, reset it to TLR */
	if (js->jtag_state != ILLEGAL_JTAG_STATE)
		altera_jreset_idle(astate);

	kfree(js->dr_pre_data);
	js->dr_pre_data = NULL;

	kfree(js->dr_post_data);
	js->dr_post_data = NULL;

	kfree(js->dr_buffer);
	js->dr_buffer = NULL;

	kfree(js->ir_pre_data);
	js->ir_pre_data = NULL;

	kfree(js->ir_post_data);
	js->ir_post_data = NULL;

	kfree(js->ir_buffer);
	js->ir_buffer = NULL;
}
