/******************************************************************************
 *
 * Name:	skvpd.c
 * Project:	Gigabit Ethernet Adapters, VPD-Module
 * Version:	$Revision: 2.6 $
 * Date:	$Date: 2004/11/02 10:47:39 $
 * Purpose:	Shared software to read and write VPD
 *
 ******************************************************************************/

/******************************************************************************
 *
 *	(C)Copyright 1998-2002 SysKonnect.
 *	(C)Copyright 2002-2004 Marvell.
 *
 *	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; either version 2 of the License, or
 *	(at your option) any later version.
 *	The information in this file is provided "AS IS" without warranty.
 *
 ******************************************************************************/
#include <config.h>

#ifdef CONFIG_SK98

/*
	Please refer skvpd.txt for infomation how to include this module
 */
static const char SysKonnectFileId[] =
	"@(#) $Id: skvpd.c,v 2.6 2004/11/02 10:47:39 rschmidt Exp $ (C) Marvell.";

#include "h/skdrv1st.h"
#include "h/sktypes.h"
#include "h/skdebug.h"
#include "h/skdrv2nd.h"

/*
 * Static functions
 */
#ifndef SK_KR_PROTO
static SK_VPD_PARA	*vpd_find_para(
	SK_AC	*pAC,
	const char	*key,
	SK_VPD_PARA *p);
#else	/* SK_KR_PROTO */
static SK_VPD_PARA	*vpd_find_para();
#endif	/* SK_KR_PROTO */

/*
 * waits for a completion of a VPD transfer
 * The VPD transfer must complete within SK_TICKS_PER_SEC/16
 *
 * returns	0:	success, transfer completes
 *		error	exit(9) with a error message
 */
static int VpdWait(
SK_AC	*pAC,	/* Adapters context */
SK_IOC	IoC,	/* IO Context */
int		event)	/* event to wait for (VPD_READ / VPD_write) completion*/
{
	SK_U64	start_time;
	SK_U16	state;

	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
		("VPD wait for %s\n", event?"Write":"Read"));
	start_time = SkOsGetTime(pAC);

	do {
		if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC) {

			/* Bug fix AF: Thu Mar 28 2002
			 * Do not call: VPD_STOP(pAC, IoC);
			 * A pending VPD read cycle can not be aborted by writing
			 * VPD_WRITE to the PCI_VPD_ADR_REG (VPD address register).
			 * Although the write threshold in the OUR-register protects
			 * VPD read only space from being overwritten this does not
			 * protect a VPD read from being `converted` into a VPD write
			 * operation (on the fly). As a consequence the VPD_STOP would
			 * delete VPD read only data. In case of any problems with the
			 * I2C bus we exit the loop here. The I2C read operation can
			 * not be aborted except by a reset (->LR).
			 */
			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_FATAL | SK_DBGCAT_ERR,
				("ERROR:VPD wait timeout\n"));
			return(1);
		}

		VPD_IN16(pAC, IoC, PCI_VPD_ADR_REG, &state);

		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
			("state = %x, event %x\n",state,event));
	} while ((int)(state & PCI_VPD_FLAG) == event);

	return(0);
}


#ifdef SK_DIAG

/*
 * Read the dword at address 'addr' from the VPD EEPROM.
 *
 * Needed Time:	MIN 1,3 ms	MAX 2,6 ms
 *
 * Note: The DWord is returned in the endianess of the machine the routine
 *       is running on.
 *
 * Returns the data read.
 */
SK_U32 VpdReadDWord(
SK_AC	*pAC,	/* Adapters context */
SK_IOC	IoC,	/* IO Context */
int		addr)	/* VPD address */
{
	SK_U32	Rtv;

	/* start VPD read */
	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
		("VPD read dword at 0x%x\n",addr));
	addr &= ~VPD_WRITE;		/* ensure the R/W bit is set to read */

	VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)addr);

	/* ignore return code here */
	(void)VpdWait(pAC, IoC, VPD_READ);

	/* Don't swap here, it's a data stream of bytes */
	Rtv = 0;

	VPD_IN32(pAC, IoC, PCI_VPD_DAT_REG, &Rtv);

	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
		("VPD read dword data = 0x%x\n",Rtv));
	return(Rtv);
}
#endif /* SK_DIAG */

#if 0

/*
	Write the dword 'data' at address 'addr' into the VPD EEPROM, and
	verify that the data is written.

 Needed Time:

.				MIN		MAX
. -------------------------------------------------------------------
. write				1.8 ms		3.6 ms
. internal write cyles		0.7 ms		7.0 ms
. -------------------------------------------------------------------
. over all program time	 	2.5 ms		10.6 ms
. read				1.3 ms		2.6 ms
. -------------------------------------------------------------------
. over all 			3.8 ms		13.2 ms
.

 Returns	0:	success
			1:	error,	I2C transfer does not terminate
			2:	error,	data verify error

 */
static int VpdWriteDWord(
SK_AC	*pAC,	/* pAC pointer */
SK_IOC	IoC,	/* IO Context */
int		addr,	/* VPD address */
SK_U32	data)	/* VPD data to write */
{
	/* start VPD write */
	/* Don't swap here, it's a data stream of bytes */
	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
		("VPD write dword at addr 0x%x, data = 0x%x\n",addr,data));
	VPD_OUT32(pAC, IoC, PCI_VPD_DAT_REG, (SK_U32)data);
	/* But do it here */
	addr |= VPD_WRITE;

	VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)(addr | VPD_WRITE));

	/* this may take up to 10,6 ms */
	if (VpdWait(pAC, IoC, VPD_WRITE)) {
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
			("Write Timed Out\n"));
		return(1);
	};

	/* verify data */
	if (VpdReadDWord(pAC, IoC, addr) != data) {
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
			("Data Verify Error\n"));
		return(2);
	}
	return(0);
}	/* VpdWriteDWord */

#endif	/* 0 */


/*
 *	Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
 *	or to the I2C EEPROM.
 *
 * Returns number of bytes read / written.
 */
static int VpdWriteStream(
SK_AC	*pAC,	/* Adapters context */
SK_IOC	IoC,	/* IO Context */
char	*buf,	/* data buffer */
int		Addr,	/* VPD start address */
int		Len)	/* number of bytes to read / to write */
{
	int		i;
	int		j;
	SK_U16	AdrReg;
	int		Rtv;
	SK_U8	* pComp;	/* Compare pointer */
	SK_U8	Data;		/* Input Data for Compare */

	/* Init Compare Pointer */
	pComp = (SK_U8 *) buf;

	for (i = 0; i < Len; i++, buf++) {
		if ((i % SZ_LONG) == 0) {
			/*
			 * At the begin of each cycle read the Data Reg
			 * So it is initialized even if only a few bytes
			 * are written.
			 */
			AdrReg = (SK_U16) Addr;
			AdrReg &= ~VPD_WRITE;	/* READ operation */

			VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);

			/* Wait for termination */
			Rtv = VpdWait(pAC, IoC, VPD_READ);
			if (Rtv != 0) {
				return(i);
			}
		}

		/* Write current byte */
		VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i % SZ_LONG), *(SK_U8*)buf);

		if (((i % SZ_LONG) == 3) || (i == (Len - 1))) {
			/* New Address needs to be written to VPD_ADDR reg */
			AdrReg = (SK_U16) Addr;
			Addr += SZ_LONG;
			AdrReg |= VPD_WRITE;	/* WRITE operation */

			VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);

			/* Wait for termination */
			Rtv = VpdWait(pAC, IoC, VPD_WRITE);
			if (Rtv != 0) {
				SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
					("Write Timed Out\n"));
				return(i - (i % SZ_LONG));
			}

			/*
			 * Now re-read to verify
			 */
			AdrReg &= ~VPD_WRITE;	/* READ operation */

			VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);

			/* Wait for termination */
			Rtv = VpdWait(pAC, IoC, VPD_READ);
			if (Rtv != 0) {
				SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
					("Verify Timed Out\n"));
				return(i - (i % SZ_LONG));
			}

			for (j = 0; j <= (int)(i % SZ_LONG); j++, pComp++) {

				VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data);

				if (Data != *pComp) {
					/* Verify Error */
					SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
						("WriteStream Verify Error\n"));
					return(i - (i % SZ_LONG) + j);
				}
			}
		}
	}

	return(Len);
}


/*
 *	Read one Stream of 'len' bytes of VPD data, starting at 'addr' from
 *	or to the I2C EEPROM.
 *
 * Returns number of bytes read / written.
 */
static int VpdReadStream(
SK_AC	*pAC,	/* Adapters context */
SK_IOC	IoC,	/* IO Context */
char	*buf,	/* data buffer */
int		Addr,	/* VPD start address */
int		Len)	/* number of bytes to read / to write */
{
	int		i;
	SK_U16	AdrReg;
	int		Rtv;

	for (i = 0; i < Len; i++, buf++) {
		if ((i % SZ_LONG) == 0) {
			/* New Address needs to be written to VPD_ADDR reg */
			AdrReg = (SK_U16) Addr;
			Addr += SZ_LONG;
			AdrReg &= ~VPD_WRITE;	/* READ operation */

			VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg);

			/* Wait for termination */
			Rtv = VpdWait(pAC, IoC, VPD_READ);
			if (Rtv != 0) {
				return(i);
			}
		}
		VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i % SZ_LONG), (SK_U8 *)buf);
	}

	return(Len);
}


/*
 *	Read ore writes 'len' bytes of VPD data, starting at 'addr' from
 *	or to the I2C EEPROM.
 *
 * Returns number of bytes read / written.
 */
static int VpdTransferBlock(
SK_AC	*pAC,	/* Adapters context */
SK_IOC	IoC,	/* IO Context */
char	*buf,	/* data buffer */
int		addr,	/* VPD start address */
int		len,	/* number of bytes to read / to write */
int		dir)	/* transfer direction may be VPD_READ or VPD_WRITE */
{
	int		Rtv;	/* Return value */
	int		vpd_rom_size;

	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
		("VPD %s block, addr = 0x%x, len = %d\n",
		dir ? "write" : "read", addr, len));

	if (len == 0)
		return(0);

	vpd_rom_size = pAC->vpd.rom_size;

	if (addr > vpd_rom_size - 4) {
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
			("Address error: 0x%x, exp. < 0x%x\n",
			addr, vpd_rom_size - 4));
		return(0);
	}

	if (addr + len > vpd_rom_size) {
		len = vpd_rom_size - addr;
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
			("Warning: len was cut to %d\n", len));
	}

	if (dir == VPD_READ) {
		Rtv = VpdReadStream(pAC, IoC, buf, addr, len);
	}
	else {
		Rtv = VpdWriteStream(pAC, IoC, buf, addr, len);
	}

	return(Rtv);
}


#if defined (SK_DIAG) || defined (SK_ASF)
/*
 *	Read 'len' bytes of VPD data, starting at 'addr'.
 *
 * Returns number of bytes read.
 */
int VpdReadBlock(
SK_AC	*pAC,	/* pAC pointer */
SK_IOC	IoC,	/* IO Context */
char	*buf,	/* buffer were the data should be stored */
int		addr,	/* start reading at the VPD address */
int		len)	/* number of bytes to read */
{
	return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ));
}


/*
 *	Write 'len' bytes of *but to the VPD EEPROM, starting at 'addr'.
 *
 * Returns number of bytes writes.
 */
int VpdWriteBlock(
SK_AC	*pAC,	/* pAC pointer */
SK_IOC	IoC,	/* IO Context */
char	*buf,	/* buffer, holds the data to write */
int		addr,	/* start writing at the VPD address */
int		len)	/* number of bytes to write */
{
	return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE));
}
#endif /* SK_DIAG */


/******************************************************************************
 *
 *	VpdInit() - (re)initialize the VPD buffer
 *
 * Description:
 *	Reads the VPD data from the EEPROM into the VPD buffer.
 *	Get the remaining read only and read / write space.
 *
 * Note:
 *	This is a local function and should be used locally only.
 *	However, the ASF module needs to use this function also.
 *	Therfore it has been published.
 *
 * Returns:
 *	0:	success
 *	1:	fatal VPD error
 */
int VpdInit(
SK_AC	*pAC,	/* Adapters context */
SK_IOC	IoC)	/* IO Context */
{
	SK_VPD_PARA *r, rp;	/* RW or RV */
	int		i;
	unsigned char	x;
	int		vpd_size;
	SK_U16	dev_id;
	SK_U32	our_reg2;

	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit ... "));

	VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &dev_id);

	VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2);

	pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14);

	/*
	 * this function might get used before the hardware is initialized
	 * therefore we cannot always trust in GIChipId
	 */
	if (((pAC->vpd.v.vpd_status & VPD_VALID) == 0 &&
		dev_id != VPD_DEV_ID_GENESIS) ||
		((pAC->vpd.v.vpd_status & VPD_VALID) != 0 &&
		!pAC->GIni.GIGenesis)) {

		/* for Yukon the VPD size is always 256 */
		vpd_size = VPD_SIZE_YUKON;
	}
	else {
		/* Genesis uses the maximum ROM size up to 512 for VPD */
		if (pAC->vpd.rom_size > VPD_SIZE_GENESIS) {
			vpd_size = VPD_SIZE_GENESIS;
		}
		else {
			vpd_size = pAC->vpd.rom_size;
		}
	}

	/* read the VPD data into the VPD buffer */
	if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf, 0, vpd_size, VPD_READ)
		!= vpd_size) {

		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
			("Block Read Error\n"));
		return(1);
	}

	pAC->vpd.vpd_size = vpd_size;

	/* Asus K8V Se Deluxe bugfix. Correct VPD content */
	i = 62;
	if (!SK_STRNCMP(pAC->vpd.vpd_buf + i, " 8<E", 4)) {

		pAC->vpd.vpd_buf[i + 2] = '8';
	}

	/* find the end tag of the RO area */
	if (!(r = vpd_find_para(pAC, VPD_RV, &rp))) {
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
			("Encoding Error: RV Tag not found\n"));
		return(1);
	}

	if (r->p_val + r->p_len > pAC->vpd.vpd_buf + vpd_size/2) {
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
			("Encoding Error: Invalid VPD struct size\n"));
		return(1);
	}
	pAC->vpd.v.vpd_free_ro = r->p_len - 1;

	/* test the checksum */
	for (i = 0, x = 0; (unsigned)i <= (unsigned)vpd_size/2 - r->p_len; i++) {
		x += pAC->vpd.vpd_buf[i];
	}

	if (x != 0) {
		/* checksum error */
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
			("VPD Checksum Error\n"));
		return(1);
	}

	/* find and check the end tag of the RW area */
	if (!(r = vpd_find_para(pAC, VPD_RW, &rp))) {
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
			("Encoding Error: RV Tag not found\n"));
		return(1);
	}

	if (r->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
			("Encoding Error: Invalid VPD struct size\n"));
		return(1);
	}
	pAC->vpd.v.vpd_free_rw = r->p_len;

	/* everything seems to be ok */
	if (pAC->GIni.GIChipId != 0) {
		pAC->vpd.v.vpd_status |= VPD_VALID;
	}

	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT,
		("done. Free RO = %d, Free RW = %d\n",
		pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));

	return(0);
}


/*
 *	find the Keyword 'key' in the VPD buffer and fills the
 *	parameter struct 'p' with it's values
 *
 * returns	*p	success
 *		0:	parameter was not found or VPD encoding error
 */
static SK_VPD_PARA *vpd_find_para(
SK_AC		*pAC,	/* common data base */
const char	*key,	/* keyword to find (e.g. "MN") */
SK_VPD_PARA	*p)		/* parameter description struct */
{
	char *v	;	/* points to VPD buffer */
	int max;	/* Maximum Number of Iterations */

	v = pAC->vpd.vpd_buf;
	max = 128;

	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
		("VPD find para %s .. ",key));

	/* check mandatory resource type ID string (Product Name) */
	if (*v != (char)RES_ID) {
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
			("Error: 0x%x missing\n", RES_ID));
		return(0);
	}

	if (SK_STRCMP(key, VPD_NAME) == 0) {
		p->p_len = VPD_GET_RES_LEN(v);
		p->p_val = VPD_GET_VAL(v);
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
			("found, len = %d\n", p->p_len));
		return(p);
	}

	v += 3 + VPD_GET_RES_LEN(v) + 3;
	for (;; ) {
		if (SK_MEMCMP(key, v, 2) == 0) {
			p->p_len = VPD_GET_VPD_LEN(v);
			p->p_val = VPD_GET_VAL(v);
			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
				("found, len = %d\n",p->p_len));
			return(p);
		}

		/* exit when reaching the "RW" Tag or the maximum of itera. */
		max--;
		if (SK_MEMCMP(VPD_RW, v, 2) == 0 || max == 0) {
			break;
		}

		if (SK_MEMCMP(VPD_RV, v, 2) == 0) {
			v += 3 + VPD_GET_VPD_LEN(v) + 3;	/* skip VPD-W */
		}
		else {
			v += 3 + VPD_GET_VPD_LEN(v);
		}
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
			("scanning '%c%c' len = %d\n",v[0],v[1],v[2]));
	}

#ifdef DEBUG
	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("not found\n"));
	if (max == 0) {
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
			("Key/Len Encoding error\n"));
	}
#endif /* DEBUG */
	return(0);
}


/*
 *	Move 'n' bytes. Begin with the last byte if 'n' is > 0,
 *	Start with the last byte if n is < 0.
 *
 * returns nothing
 */
static void vpd_move_para(
char	*start,		/* start of memory block */
char	*end,		/* end of memory block to move */
int		n)			/* number of bytes the memory block has to be moved */
{
	char *p;
	int i;		/* number of byte copied */

	if (n == 0)
		return;

	i = (int) (end - start + 1);
	if (n < 0) {
		p = start + n;
		while (i != 0) {
			*p++ = *start++;
			i--;
		}
	}
	else {
		p = end + n;
		while (i != 0) {
			*p-- = *end--;
			i--;
		}
	}
}


/*
 *	setup the VPD keyword 'key' at 'ip'.
 *
 * returns nothing
 */
static void vpd_insert_key(
const char	*key,	/* keyword to insert */
const char	*buf,	/* buffer with the keyword value */
int		len,		/* length of the value string */
char	*ip)		/* inseration point */
{
	SK_VPD_KEY *p;

	p = (SK_VPD_KEY *) ip;
	p->p_key[0] = key[0];
	p->p_key[1] = key[1];
	p->p_len = (unsigned char)len;
	SK_MEMCPY(&p->p_val, buf, len);
}


/*
 *	Setup the VPD end tag "RV" / "RW".
 *	Also correct the remaining space variables vpd_free_ro / vpd_free_rw.
 *
 * returns	0:	success
 *		1:	encoding error
 */
static int vpd_mod_endtag(
SK_AC	*pAC,		/* common data base */
char	*etp)		/* end pointer input position */
{
	SK_VPD_KEY *p;
	unsigned char	x;
	int	i;
	int	vpd_size;

	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
		("VPD modify endtag at 0x%x = '%c%c'\n",(unsigned int)etp, etp[0], etp[1]));

	vpd_size = pAC->vpd.vpd_size;

	p = (SK_VPD_KEY *) etp;

	if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) {
		/* something wrong here, encoding error */
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL,
			("Encoding Error: invalid end tag\n"));
		return(1);
	}
	if (etp > pAC->vpd.vpd_buf + vpd_size/2) {
		/* create "RW" tag */
		p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size-etp-3-1);
		pAC->vpd.v.vpd_free_rw = (int) p->p_len;
		i = pAC->vpd.v.vpd_free_rw;
		etp += 3;
	}
	else {
		/* create "RV" tag */
		p->p_len = (unsigned char)(pAC->vpd.vpd_buf+vpd_size/2-etp-3);
		pAC->vpd.v.vpd_free_ro = (int) p->p_len - 1;

		/* setup checksum */
		for (i = 0, x = 0; i < vpd_size/2 - p->p_len; i++) {
			x += pAC->vpd.vpd_buf[i];
		}
		p->p_val = (char) 0 - x;
		i = pAC->vpd.v.vpd_free_ro;
		etp += 4;
	}
	while (i) {
		*etp++ = 0x00;
		i--;
	}

	return(0);
}


/*
 *	Insert a VPD keyword into the VPD buffer.
 *
 *	The keyword 'key' is inserted at the position 'ip' in the
 *	VPD buffer.
 *	The keywords behind the input position will
 *	be moved. The VPD end tag "RV" or "RW" is generated again.
 *
 * returns	0:	success
 *		2:	value string was cut
 *		4:	VPD full, keyword was not written
 *		6:	fatal VPD error
 *
 */
int	VpdSetupPara(
SK_AC	*pAC,		/* common data base */
const char	*key,	/* keyword to insert */
const char	*buf,	/* buffer with the keyword value */
int		len,		/* length of the keyword value */
int		type,		/* VPD_RO_KEY or VPD_RW_KEY */
int		op)			/* operation to do: ADD_KEY or OWR_KEY */
{
	SK_VPD_PARA vp;
	char	*etp;		/* end tag position */
	int	free;		/* remaining space in selected area */
	char	*ip;		/* input position inside the VPD buffer */
	int	rtv;		/* return code */
	int	head;		/* additional haeder bytes to move */
	int	found;		/* additinoal bytes if the keyword was found */
	int vpd_size;

	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
		("VPD setup para key = %s, val = %s\n",key,buf));

	vpd_size = pAC->vpd.vpd_size;

	rtv = 0;
	ip = 0;
	if (type == VPD_RW_KEY) {
		/* end tag is "RW" */
		free = pAC->vpd.v.vpd_free_rw;
		etp = pAC->vpd.vpd_buf + (vpd_size - free - 1 - 3);
	}
	else {
		/* end tag is "RV" */
		free = pAC->vpd.v.vpd_free_ro;
		etp = pAC->vpd.vpd_buf + (vpd_size/2 - free - 4);
	}
	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
		("Free RO = %d, Free RW = %d\n",
		pAC->vpd.v.vpd_free_ro, pAC->vpd.v.vpd_free_rw));

	head = 0;
	found = 0;
	if (op == OWR_KEY) {
		if (vpd_find_para(pAC, key, &vp)) {
			found = 3;
			ip = vp.p_val - 3;
			free += vp.p_len + 3;
			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
				("Overwrite Key\n"));
		}
		else {
			op = ADD_KEY;
			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL,
				("Add Key\n"));
		}
	}
	if (op == ADD_KEY) {
		ip = etp;
		vp.p_len = 0;
		head = 3;
	}

	if (len + 3 > free) {
		if (free < 7) {
			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
				("VPD Buffer Overflow, keyword not written\n"));
			return(4);
		}
		/* cut it again */
		len = free - 3;
		rtv = 2;
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
			("VPD Buffer Full, Keyword was cut\n"));
	}

	vpd_move_para(ip + vp.p_len + found, etp+2, len-vp.p_len+head);
	vpd_insert_key(key, buf, len, ip);
	if (vpd_mod_endtag(pAC, etp + len - vp.p_len + head)) {
		pAC->vpd.v.vpd_status &= ~VPD_VALID;
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
			("VPD Encoding Error\n"));
		return(6);
	}

	return(rtv);
}


/*
 *	Read the contents of the VPD EEPROM and copy it to the
 *	VPD buffer if not already done.
 *
 * return:	A pointer to the vpd_status structure. The structure contains
 *		this fields.
 */
SK_VPD_STATUS *VpdStat(
SK_AC	*pAC,	/* Adapters context */
SK_IOC	IoC)	/* IO Context */
{
	if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
		(void)VpdInit(pAC, IoC);
	}
	return(&pAC->vpd.v);
}


/*
 *	Read the contents of the VPD EEPROM and copy it to the VPD
 *	buffer if not already done.
 *	Scan the VPD buffer for VPD keywords and create the VPD
 *	keyword list by copying the keywords to 'buf', all after
 *	each other and terminated with a '\0'.
 *
 * Exceptions:	o The Resource Type ID String (product name) is called "Name"
 *		o The VPD end tags 'RV' and 'RW' are not listed
 *
 *	The number of copied keywords is counted in 'elements'.
 *
 * returns	0:	success
 *		2:	buffer overfull, one or more keywords are missing
 *		6:	fatal VPD error
 *
 *	example values after returning:
 *
 *		buf =	"Name\0PN\0EC\0MN\0SN\0CP\0VF\0VL\0YA\0"
 *		*len =		30
 *		*elements =	 9
 */
int VpdKeys(
SK_AC	*pAC,		/* common data base */
SK_IOC	IoC,		/* IO Context */
char	*buf,		/* buffer where to copy the keywords */
int		*len,		/* buffer length */
int		*elements)	/* number of keywords returned */
{
	char *v;
	int n;

	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("list VPD keys .. "));
	*elements = 0;
	if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
		if (VpdInit(pAC, IoC) != 0) {
			*len = 0;
			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
				("VPD Init Error, terminated\n"));
			return(6);
		}
	}

	if ((signed)SK_STRLEN(VPD_NAME) + 1 <= *len) {
		v = pAC->vpd.vpd_buf;
		SK_STRCPY(buf, VPD_NAME);
		n = SK_STRLEN(VPD_NAME) + 1;
		buf += n;
		*elements = 1;
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
			("'%c%c' ", v[0], v[1]));
	}
	else {
		*len = 0;
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
			("buffer overflow\n"));
		return(2);
	}

	v += 3 + VPD_GET_RES_LEN(v) + 3;
	for (;; ) {
		/* exit when reaching the "RW" Tag */
		if (SK_MEMCMP(VPD_RW, v, 2) == 0) {
			break;
		}

		if (SK_MEMCMP(VPD_RV, v, 2) == 0) {
			v += 3 + VPD_GET_VPD_LEN(v) + 3;	/* skip VPD-W */
			continue;
		}

		if (n+3 <= *len) {
			SK_MEMCPY(buf, v, 2);
			buf += 2;
			*buf++ = '\0';
			n += 3;
			v += 3 + VPD_GET_VPD_LEN(v);
			*elements += 1;
			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
				("'%c%c' ",v[0],v[1]));
		}
		else {
			*len = n;
			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
				("buffer overflow\n"));
			return(2);
		}
	}

	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("\n"));
	*len = n;
	return(0);
}


/*
 *	Read the contents of the VPD EEPROM and copy it to the
 *	VPD buffer if not already done. Search for the VPD keyword
 *	'key' and copy its value to 'buf'. Add a terminating '\0'.
 *	If the value does not fit into the buffer cut it after
 *	'len' - 1 bytes.
 *
 * returns	0:	success
 *		1:	keyword not found
 *		2:	value string was cut
 *		3:	VPD transfer timeout
 *		6:	fatal VPD error
 */
int VpdRead(
SK_AC		*pAC,	/* common data base */
SK_IOC		IoC,	/* IO Context */
const char	*key,	/* keyword to read (e.g. "MN") */
char		*buf,	/* buffer where to copy the keyword value */
int			*len)	/* buffer length */
{
	SK_VPD_PARA *p, vp;

	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, ("VPD read %s .. ", key));
	if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
		if (VpdInit(pAC, IoC) != 0) {
			*len = 0;
			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
				("VPD init error\n"));
			return(6);
		}
	}

	if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
		if (p->p_len > (*(unsigned *)len)-1) {
			p->p_len = *len - 1;
		}
		SK_MEMCPY(buf, p->p_val, p->p_len);
		buf[p->p_len] = '\0';
		*len = p->p_len;
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX,
			("%c%c%c%c.., len = %d\n",
			buf[0],buf[1],buf[2],buf[3],*len));
	}
	else {
		*len = 0;
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("not found\n"));
		return(1);
	}
	return(0);
}


/*
 *	Check whether a given key may be written
 *
 * returns
 *	SK_TRUE		Yes it may be written
 *	SK_FALSE	No it may be written
 */
SK_BOOL VpdMayWrite(
char	*key)	/* keyword to write (allowed values "Yx", "Vx") */
{
	if ((*key != 'Y' && *key != 'V') ||
		key[1] < '0' || key[1] > 'Z' ||
		(key[1] > '9' && key[1] < 'A') || SK_STRLEN(key) != 2) {

		return(SK_FALSE);
	}
	return(SK_TRUE);
}


/*
 *	Read the contents of the VPD EEPROM and copy it to the VPD
 *	buffer if not already done. Insert/overwrite the keyword 'key'
 *	in the VPD buffer. Cut the keyword value if it does not fit
 *	into the VPD read / write area.
 *
 * returns	0:	success
 *		2:	value string was cut
 *		3:	VPD transfer timeout
 *		4:	VPD full, keyword was not written
 *		5:	keyword cannot be written
 *		6:	fatal VPD error
 */
int VpdWrite(
SK_AC		*pAC,	/* common data base */
SK_IOC		IoC,	/* IO Context */
const char	*key,	/* keyword to write (allowed values "Yx", "Vx") */
const char	*buf)	/* buffer where the keyword value can be read from */
{
	int len;		/* length of the keyword to write */
	int rtv;		/* return code */
	int rtv2;

	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX,
		("VPD write %s = %s\n",key,buf));

	if ((*key != 'Y' && *key != 'V') ||
		key[1] < '0' || key[1] > 'Z' ||
		(key[1] > '9' && key[1] < 'A') || SK_STRLEN(key) != 2) {

		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
			("illegal key tag, keyword not written\n"));
		return(5);
	}

	if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
		if (VpdInit(pAC, IoC) != 0) {
			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
				("VPD init error\n"));
			return(6);
		}
	}

	rtv = 0;
	len = SK_STRLEN(buf);
	if (len > VPD_MAX_LEN) {
		/* cut it */
		len = VPD_MAX_LEN;
		rtv = 2;
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
			("keyword too long, cut after %d bytes\n", VPD_MAX_LEN));
	}
	if ((rtv2 = VpdSetupPara(pAC, key, buf, len, VPD_RW_KEY, OWR_KEY)) != 0) {
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
			("VPD write error\n"));
		return(rtv2);
	}

	return(rtv);
}


/*
 *	Read the contents of the VPD EEPROM and copy it to the
 *	VPD buffer if not already done. Remove the VPD keyword
 *	'key' from the VPD buffer.
 *	Only the keywords in the read/write area can be deleted.
 *	Keywords in the read only area cannot be deleted.
 *
 * returns	0:	success, keyword was removed
 *		1:	keyword not found
 *		5:	keyword cannot be deleted
 *		6:	fatal VPD error
 */
int VpdDelete(
SK_AC	*pAC,	/* common data base */
SK_IOC	IoC,	/* IO Context */
char	*key)	/* keyword to read (e.g. "MN") */
{
	SK_VPD_PARA *p, vp;
	char *etp;
	int	vpd_size;

	vpd_size = pAC->vpd.vpd_size;

	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD delete key %s\n", key));
	if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
		if (VpdInit(pAC, IoC) != 0) {
			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
				("VPD init error\n"));
			return(6);
		}
	}

	if ((p = vpd_find_para(pAC, key, &vp)) != NULL) {
		if (p->p_val < pAC->vpd.vpd_buf + vpd_size/2) {
			/* try to delete read only keyword */
			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
				("cannot delete RO keyword\n"));
			return(5);
		}

		etp = pAC->vpd.vpd_buf + (vpd_size-pAC->vpd.v.vpd_free_rw-1-3);

		vpd_move_para(vp.p_val+vp.p_len, etp+2,
			- ((int)(vp.p_len + 3)));
		if (vpd_mod_endtag(pAC, etp - vp.p_len - 3)) {
			pAC->vpd.v.vpd_status &= ~VPD_VALID;
			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
				("VPD encoding error\n"));
			return(6);
		}
	}
	else {
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
			("keyword not found\n"));
		return(1);
	}

	return(0);
}


/*
 *	If the VPD buffer contains valid data write the VPD
 *	read/write area back to the VPD EEPROM.
 *
 * returns	0:	success
 *		3:	VPD transfer timeout
 */
int VpdUpdate(
SK_AC	*pAC,	/* Adapters context */
SK_IOC	IoC)	/* IO Context */
{
	int vpd_size;

	vpd_size = pAC->vpd.vpd_size;

	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD update .. "));
	if ((pAC->vpd.v.vpd_status & VPD_VALID) != 0) {
		if (VpdTransferBlock(pAC, IoC, pAC->vpd.vpd_buf + vpd_size/2,
			vpd_size/2, vpd_size/2, VPD_WRITE) != vpd_size/2) {

			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
				("transfer timed out\n"));
			return(3);
		}
	}
	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("done\n"));
	return(0);
}


/*
 *	Read the contents of the VPD EEPROM and copy it to the VPD buffer
 *	if not already done. If the keyword "VF" is not present it will be
 *	created and the error log message will be stored to this keyword.
 *	If "VF" is not present the error log message will be stored to the
 *	keyword "VL". "VL" will created or overwritten if "VF" is present.
 *	The VPD read/write area is saved to the VPD EEPROM.
 *
 * returns nothing, errors will be ignored.
 */
void VpdErrLog(
SK_AC	*pAC,	/* common data base */
SK_IOC	IoC,	/* IO Context */
char	*msg)	/* error log message */
{
	SK_VPD_PARA *v, vf;	/* VF */
	int len;

	SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX,
		("VPD error log msg %s\n", msg));
	if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) {
		if (VpdInit(pAC, IoC) != 0) {
			SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR,
				("VPD init error\n"));
			return;
		}
	}

	len = SK_STRLEN(msg);
	if (len > VPD_MAX_LEN) {
		/* cut it */
		len = VPD_MAX_LEN;
	}
	if ((v = vpd_find_para(pAC, VPD_VF, &vf)) != NULL) {
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("overwrite VL\n"));
		(void)VpdSetupPara(pAC, VPD_VL, msg, len, VPD_RW_KEY, OWR_KEY);
	}
	else {
		SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("write VF\n"));
		(void)VpdSetupPara(pAC, VPD_VF, msg, len, VPD_RW_KEY, ADD_KEY);
	}

	(void)VpdUpdate(pAC, IoC);
}

#endif
