// DxbKme.cpp : implementation file
//

#include "stdafx.h"
#include "NtKmed.h"
#include "DxbKme.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#pragma message("NOTE: NOTE: firmware packing is assumed to be 4")
#ifndef uint32
#define uint32 DWORD
#endif
#ifndef uint16
#define uint16 WORD
#endif
#ifndef uint8
#define uint8 BYTE
#endif
#pragma pack(push,4)
#include "64011.h"			// Galileo part
#pragma pack(pop)

IMPLEMENT_DYNAMIC( CDxbKme, CObject )

CDxbKme::CDxbKme()
{
	m_fInitialized = FALSE;
	m_hDriver = NULL;
}

CDxbKme::~CDxbKme()
{
	DxbShutdown();
	if (NULL != m_hDriver)
		DxbDeviceClose(m_hDriver);
}

BOOL CDxbKme::Init(CString const DriverName)
{
	if (m_fInitialized)
		return FALSE;	// no re-init

	SHIM_STATUS Status;
	ASSERT(!DriverName.IsEmpty());
	ASSERT(NULL == m_hDriver);
	Status = DxbDeviceOpen( DriverName, &m_hDriver);
	m_fInitialized = (SHIM_STATUS_SUCCESS == Status);
	return m_fInitialized;
}

// Magic macro
#define INSANE(q) ((Queue.cq_base<0x100)||(Queue.cq_base>=0x100000)||(Queue.cq_size<16)||(Queue.cq_size>1024)||(Queue.cq_in>=Queue.cq_size)||(Queue.cq_out>=Queue.cq_size))

int CDxbKme::WriteData(DWORD const dwAddr, void * const pData, DWORD const cbData)
{
	SHIM_STATUS Status;
	ASSERT(NULL != m_hDriver);
	if (!m_fInitialized)
		return FALSE;

	DWORD cbThisRequest;
	int BytesWritten = 0;

	// Read the queue structure header off the board
	Status = DxbKmeWrite(	m_hDriver,
								dwAddr,
								KME_MEMORY_FLAG_ADAPTER_MEMORY,
								pData, 
								cbData,
								&cbThisRequest,
								DEFAULT_TIMEOUT_MS, NULL, NULL);
	if ( (SHIM_STATUS_SUCCESS != Status) || (cbData != cbThisRequest))
		return(-1);

	BytesWritten = cbThisRequest;

	//NotifyBoard();

	return BytesWritten;
}

int CDxbKme::ReadData(DWORD const dwAddr, void * const pData, DWORD const cbData)
{
	if (!m_fInitialized)
		return FALSE;

	SHIM_STATUS Status;
	ASSERT(NULL != m_hDriver);
	if (!m_fInitialized)
		return FALSE;

	DWORD cbThisRequest;
	int BytesRead = 0;

	// Read the queue structure header off the board
	Status = DxbKmeRead(	m_hDriver,
								dwAddr,
								KME_MEMORY_FLAG_ADAPTER_MEMORY,
								pData,
								cbData,
								&cbThisRequest,
								DEFAULT_TIMEOUT_MS, NULL, NULL);
	if ( (SHIM_STATUS_SUCCESS != Status) || (cbData != cbThisRequest) /* || (INSANE(Queue))*/ )
		return(-1);

	BytesRead = cbThisRequest;

	return BytesRead;
}

void CDxbKme::NotifyBoard(void)
{
	ASSERT(NULL != m_hDriver);
	if (!m_fInitialized)
	{
		TRACE("Call to NotifyBoard prior to initialization");
		return;
	}

	size_t Offset = offsetof(REG64011, intr_cause);
	uint32 intr_cause = ~INT_PCIINT0;

	SHIM_STATUS Status;
	DWORD cbThisRequest;
	Status = DxbKmeWrite(	m_hDriver,
									Offset,
									KME_MEMORY_FLAG_PCI_INTERFACE_CHIP,
									(char *)(&intr_cause),
									sizeof intr_cause,
									&cbThisRequest,
									DEFAULT_TIMEOUT_MS, NULL, NULL);

	if ( (SHIM_STATUS_SUCCESS != Status) || ((sizeof intr_cause) != cbThisRequest) )
	{
		TRACE("KME Write in NotifyBoard failed");
	}

	return;
}
