/***************************************************************************************\

Module Name:    mtx_client.h

Description:    This module defines an abstraction layer of the kernel services used by 
                the kernel module.

Comments:       This is simply used to allow the binary to be compatible with kernels 
                compiled with switches that modifies the ABI.  It allows the binary to
                be kernel-independant.

    Copyright (C) 2004, Matrox Graphics Inc.
    All Rights Reserved.

\***************************************************************************************/

#ifndef INC_CLIENT_H
#define INC_CLIENT_H

/*-------------------------------------------------------------------------------------*\
                                 H E A D E R   F I L E S
\*-------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------*\
                          C O N S T A N T S   A N D   T Y P E S
\*-------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------*\
                   G L O B A L   V A R I A B L E   R E F E R E N C E S
\*-------------------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------------------*\
                 I N T E R F A C E   F U N C T I O N   P R O T O T Y P E S
\*-------------------------------------------------------------------------------------*/

/* Memory management functions called from binary modules */
#ifdef MEMORY_STATS
EXTERN_C STACK_LINKAGE void* ClientMemStatsAlloc(size_t size, const char* filename, int line);
EXTERN_C STACK_LINKAGE void  ClientMemStatsFree(void* ptr);
#else
EXTERN_C STACK_LINKAGE void* ClientMemAlloc(size_t size);
EXTERN_C STACK_LINKAGE void  ClientMemFree(void* ptr, size_t size);
#endif
EXTERN_C STACK_LINKAGE void* ClientIoRemap(unsigned long offset, unsigned long size);
EXTERN_C STACK_LINKAGE void  ClientIoUnmap(void* ptr);

// Function prototypes
EXTERN_C STACK_LINKAGE DWORD ClientRegisterReadDword(HDEVICE hDevice, DWORD ulOffset, DWORD *pdData);
EXTERN_C STACK_LINKAGE DWORD ClientRegisterReadWord(HDEVICE hDevice, DWORD ulOffset, WORD *pwData);
EXTERN_C STACK_LINKAGE DWORD ClientRegisterReadByte(HDEVICE hDevice, DWORD ulOffset, BYTE *pbData);
EXTERN_C STACK_LINKAGE DWORD ClientRegisterWriteDword(HDEVICE hDevice, DWORD ulOffset, DWORD dwData);
EXTERN_C STACK_LINKAGE DWORD ClientRegisterWriteWord(HDEVICE hDevice, DWORD ulOffset, WORD wData);
EXTERN_C STACK_LINKAGE DWORD ClientRegisterWriteByte(HDEVICE hDevice, DWORD ulOffset, BYTE bData);

EXTERN_C STACK_LINKAGE BYTE  ClientIoReadByte(WORD iPort);
EXTERN_C STACK_LINKAGE WORD  ClientIoReadWord(WORD iPort);
EXTERN_C STACK_LINKAGE DWORD ClientIoReadDword(WORD iPort);
EXTERN_C STACK_LINKAGE void  ClientIoWriteByte(WORD iPort, BYTE iValue);
EXTERN_C STACK_LINKAGE void  ClientIoWriteWord(WORD iPort, WORD iValue);
EXTERN_C STACK_LINKAGE void  ClientIoWriteDword(WORD iPort, DWORD iValue);

EXTERN_C STACK_LINKAGE DWORD ClientPciConfigReadByte(PCIHANDLE hDevice, DWORD iOffset, BYTE* piValue);
EXTERN_C STACK_LINKAGE DWORD ClientPciConfigReadWord(PCIHANDLE hDevice, DWORD iOffset, WORD* piValue);
EXTERN_C STACK_LINKAGE DWORD ClientPciConfigReadDword(PCIHANDLE hDevice, DWORD iOffset, DWORD* piValue);
EXTERN_C STACK_LINKAGE DWORD ClientPciConfigWriteByte(PCIHANDLE hDevice, DWORD iOffset, BYTE iValue);
EXTERN_C STACK_LINKAGE DWORD ClientPciConfigWriteWord(PCIHANDLE hDevice, DWORD iOffset, WORD iValue);
EXTERN_C STACK_LINKAGE DWORD ClientPciConfigWriteDword(PCIHANDLE hDevice, DWORD iOffset, DWORD iValue);

EXTERN_C STACK_LINKAGE void  ClientPrintLevel(UINT32 iVerboseLevel, const char* pszFormat, ...);
EXTERN_C STACK_LINKAGE int   ClientVSPrintf(char *buf, const char *fmt, va_list args);
EXTERN_C STACK_LINKAGE int   ClientVSNPrintf(char *buf, size_t size, const char *fmt, va_list args);

EXTERN_C STACK_LINKAGE void  ClientMicroDelay(UINT32 iMicroSecs);

EXTERN_C STACK_LINKAGE int   ClientGetNbCPUs(void);

EXTERN_C STACK_LINKAGE void  ClientSchedule(void);

EXTERN_C STACK_LINKAGE int   ClientCopyFromUserSpace(void* pvKnlData, void* pvUserData, UINT32 ulSize);
EXTERN_C STACK_LINKAGE int   ClientCopyToUserSpace(void* pvUserData, void* pvKnlData, UINT32 ulSize);

EXTERN_C STACK_LINKAGE void  ClientAtomicInc(void* pvValue);
EXTERN_C STACK_LINKAGE void  ClientAtomicDec(void* pvValue);
EXTERN_C STACK_LINKAGE int   ClientAtomicDecAndTest(void* pvValue);

/*-------------------------------------------------------------------------------------*\
                             I N L I N E S   A N D   M A C R O S
\*-------------------------------------------------------------------------------------*/

#define MTX_MODPARM(name)   { #name, &name }

#define MTX_GEN_MODPARM_LUT     0 
#define MTX_PARHL_MODPARM_LUT   1
#define MTX_MODPARM_LUT_COUNT   2

#define MTX_MSG_CRIT    0
#define MTX_MSG_ERROR   1
#define MTX_MSG_WARNING 2
#define MTX_MSG_INFO    3
#define MTX_MSG_DETAIL  4
#define MTX_MSG_NOISE   5

/*** Print statements to use in the generic layer and during initialization phase ***/
#define MTX_PRINT(fmt, arg...)   ClientPrintLevel(MTX_MSG_CRIT, "[mtx] "fmt, ##arg)
#define MTX_ERROR(fmt, arg...)   ClientPrintLevel(MTX_MSG_ERROR, "[mtx] *ERROR* "fmt, ##arg)
#define MTX_WARNING(fmt, arg...) ClientPrintLevel(MTX_MSG_WARNING, "[mtx] *WARNING* "fmt, ##arg)
#define MTX_INFO(fmt, arg...)    ClientPrintLevel(MTX_MSG_INFO, "[mtx] "fmt, ##arg)

#define MTX_STATUS_NOERROR	 0
#define MTX_STATUS_ERROR	 ~MTX_STATUS_NOERROR

#ifdef DEBUG
#define MTX_DEBUG(fmt, arg...)   ClientPrintLevel(MTX_MSG_INFO, "[%s(%s,%u)]: "fmt, __FUNCTION__, __FILE__, __LINE__, ##arg)
#else
#define MTX_DEBUG(fmt, arg...)
#endif


#endif  /* #ifndef INC_CLIENT_H */
