/******************************************************************************
 *
 * Name:	skvpd.c
 * Project:	GEnesis, PCI Gigabit Ethernet Adapter
 * Version:	$Revision: 1.37 $
 * Date:	$Date: 2003/01/13 10:42:45 $
 * Purpose:	Shared software to read and write VPD data
 *
 ******************************************************************************/

/******************************************************************************
 *
 *	(C)Copyright 1998-2003 SysKonnect GmbH.
 *
 *	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.
 *
 ******************************************************************************/

/*
	Please refer skvpd.txt for infomation how to include this module
 */
static const char SysKonnectFileId[] =
	"@(#)$Id: skvpd.c,v 1.37 2003/01/13 10:42:45 rschmidt Exp $ (C) SK";

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

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

/*
 *	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%sizeof(SK_U32)) == 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%sizeof(SK_U32)),
				*(SK_U8*)buf);

		if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) {
			/* New Address needs to be written to VPD_ADDR reg */
			AdrReg = (SK_U16) Addr;
			Addr += sizeof(SK_U32);
			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%sizeof(SK_U32)));
			}

			/*
			 * 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%sizeof(SK_U32)));
			}

			for (j = 0; j <= (int)(i%sizeof(SK_U32)); 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%sizeof(SK_U32)) + 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%sizeof(SK_U32)) == 0) {
			/* New Address needs to be written to VPD_ADDR reg */
			AdrReg = (SK_U16) Addr;
			Addr += sizeof(SK_U32);
			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%sizeof(SK_U32)),
			(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);
}

#ifdef SKDIAG

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

/*
 * (re)initialize the VPD buffer
 *
 * Reads the VPD data from the EEPROM into the VPD buffer.
 * Get the remaining read only and read / write space.
 *
 * return	0:	success
 *		1:	fatal VPD error
 */
static 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 */
	/* MBo April 2004 */
	if (((unsigned char)pAC->vpd.vpd_buf[0x3f] == 0x38) &&
	    ((unsigned char)pAC->vpd.vpd_buf[0x40] == 0x3c) &&
	    ((unsigned char)pAC->vpd.vpd_buf[0x41] == 0x45)) {
		printk("sk98lin: Asus mainboard with buggy VPD? "
				"Correcting data.\n");
		pAC->vpd.vpd_buf[0x40] = 0x38;
	}


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

	if (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 NULL;
}

/*
 *	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",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
 *
 */
static 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 = NULL;
	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)strlen(VPD_NAME) + 1 <= *len) {
		v = pAC->vpd.vpd_buf;
		strcpy(buf,VPD_NAME);
		n = 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') || 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') || 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 = 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);
}

