/*
 * ekd20.h
 *
 * Copyright (c) 1997-2008 ETEL SA. All Rights Reserved.
 *
 * This software is the confidential and proprietary informatione of ETEL SA
 * ("Confidential Information"). You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the
 * license agreement you entered into with ETEL.
 *
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. ETEL AND ITS LICENSORS SHALL NOT BE
 * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
 * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL ETEL OR ITS
 * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
 * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
 * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
 * OR INABILITY TO USE SOFTWARE, EVEN IF ETEL HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 *
 * This software is not designed or intended for use in on-line control of
 * aircraft, air traffic, aircraft navigation or aircraft communications; or in
 * the design, construction, operation or maintenance of any nuclear
 * facility. Licensee represents and warrants that it will not use or
 * redistribute the Software for such purposes.
 *
 */

/**
 * this header file contains public declaration for etel kernel driver interface
 * @library ekd20
 */

#ifndef _EKD20_H_
#define _EKD20_H_

/**********************************************************************************************************/
/*- LIBRARIES */
/**********************************************************************************************************/

/*------------------------*/
/* Windows		libraries */
#ifdef WIN32
	/*-----------------------*/
	/* Windows RTX libraries */
	#ifdef UNDER_RTSS
		#include <windows.h>
		#include <RtApi.h>
	/*-----------------------*/
	/* Windows W32 libraries */
	#else
		#ifndef _EKD_SYS
			#ifndef _EKD_VXD
				#include <windows.h>
			#endif /*_EKD_SYS*/
		#endif /*_EKD_VDX*/
	#endif /* UNDER_RTSS */
#endif /* WIN32 */

/*-----------------------*/
/* Common libraries*/
#include <lib20.h>
	#include <time.h>

/*----------------------------------------------------------------------------------*/
/* BYTE ORDER */
/*----------------------------------------------------------------------------------*/

#ifndef __BYTE_ORDER

	/*------------------------------*/
	/* Windows Byte order			*/
	#if defined WIN32
		#define __LITTLE_ENDIAN 1234
		#define __BIG_ENDIAN 4321
		#define __BYTE_ORDER __LITTLE_ENDIAN			/* define byte order for INTEL processor */
	#endif /*WIN32*/

	/*------------------------------*/
	/* QNX4 Byte order				*/
	#if defined WIN32 || defined QNX4
		#define __LITTLE_ENDIAN 1234
		#define __BIG_ENDIAN 4321
		#define __BYTE_ORDER __LITTLE_ENDIAN			/* define byte order for INTEL processor */
	#endif /*QNX4*/

	/*------------------------------*/
	/* POSIX SOLARIS Byte order		*/
	#if defined POSIX && defined SOLARIS
		#define __LITTLE_ENDIAN 1234
		#define __BIG_ENDIAN 4321
		#ifdef _BIG_ENDIAN
			#define __BYTE_ORDER __BIG_ENDIAN			/* define byte order for SPARC processor */
		#else
			#define __BYTE_ORDER __LITTLE_ENDIAN        /* define byte order for SPARC processor */
		#endif
	#endif /*SOLARIS*/

	/*------------------------------*/
	/* POSIX LINUX Byte order		*/
	#if defined POSIX && defined LINUX
		#include <endian.h>
	#endif /*LINUX*/

	/*------------------------------*/
	/* POSIX XENOMAI Byte order		*/
	#if defined POSIX && defined XENOMAI
		#include <endian.h>
	#endif /*XENOMAI*/

	/*------------------------------*/
	/* POSIX QNX6 Byte order		*/
	#if defined POSIX && defined QNX6
		#define __LITTLE_ENDIAN 1234
		#define __BIG_ENDIAN 4321
		#ifdef __BIGENDIAN__
			#define __BYTE_ORDER __BIG_ENDIAN			/* define byte order for SPARC processor */
		#else
			#define __BYTE_ORDER __LITTLE_ENDIAN        /* define byte order for SPARC processor */
		#endif
	#endif /*QNX6*/

	/*------------------------------*/
	/* VXWORKS Byte order			*/
	#ifdef VXWORKS
		#define __LITTLE_ENDIAN _LITTLE_ENDIAN
		#define __BIG_ENDIAN _BIG_ENDIAN
		#define __BYTE_ORDER _BYTE_ORDER
	#endif /*VXWORKS*/

#endif /*BYTE_ORDER*/

/*------------------------*/
/* POSIX		libraries */
#ifdef POSIX
	#include <stdlib.h>
#endif


/**********************************************************************************************************/
/*- TYPES */
/**********************************************************************************************************/
/*------------------------------------------------------------------------------
 * type modifiers
 *-----------------------------------------------------------------------------*/
/*--------------------------------------*/
/* WINDOWS type modifiers				*/
#ifdef WIN32
	#define _EKD_EXPORT __cdecl                          /* function exported by the library */
	#define EKD_CALLBACK __cdecl                         /* client callback function called by library */
#endif /* WIN32 */

/*--------------------------------------*/
/* QNX4 type modifiers					*/
#ifdef QNX4
	#define _EKD_EXPORT __cdecl                          /* function exported by the library */
	#define EKD_CALLBACK __cdecl                         /* client callback function called by library */
	#define HANDLE int
#endif /* QNX4 */

/*--------------------------------------*/
/* POSIX-LINUX type modifiers			*/
#if defined POSIX && defined LINUX
	#define HANDLE int
	#define _EKD_EXPORT                           /* function exported by library */
	#define EKD_CALLBACK                          /* client callback function called by library */
#endif /* LINUX */

/*--------------------------------------*/
/* POSIX-XENOMAI type modifiers			*/
#if defined POSIX && defined XENOMAI
	#define HANDLE int
	#define _EKD_EXPORT                           /* function exported by library */
	#define EKD_CALLBACK                          /* client callback function called by library */
#endif /* LINUX */

/*--------------------------------------*/
/* POSIX-LYNXOS type modifiers			*/
#if defined POSIX && defined LYNXOS
	#define HANDLE int
	#define _EKD_EXPORT                           /* function exported by library */
	#define EKD_CALLBACK                          /* client callback function called by library */
#endif /* LYNXOS */

/*--------------------------------------*/
/* POSIX-QNX6 type modifiers			*/
#if defined POSIX && defined QNX6
	#define HANDLE int
	#define _EKD_EXPORT                           /* function exported by library */
	#define EKD_CALLBACK                          /* client callback function called by library */
#endif /* QNX6 */

/*------------------------------------------------------------------------------
 * common types used in all libraries
 *-----------------------------------------------------------------------------*/
/*--------------------------*/
/* byte type				*/
#ifndef __BYTE
	#define __BYTE
	typedef unsigned char byte;
#endif

/*--------------------------*/
/* word type				*/
#ifndef __WORD
	#define __WORD
	typedef unsigned short word;
#endif

/*--------------------------*/
/* dword type				*/
#ifndef __DWORD
	#define __DWORD
	typedef unsigned int dword;
#endif

/*--------------------------*/
/* char_p type				*/
#ifndef __CHAR_P
	#define __CHAR_P
	typedef char *char_p;
#endif

/*--------------------------*/
/* char_cp type				*/
#ifndef __CHAR_CP
	#define __CHAR_CP
	typedef const char *char_cp;
	#ifndef __cplusplus
		#ifndef __BOOL
			#define __BOOL
			typedef byte bool;
		#endif /*BOOL */
	#endif /*__cplusplus */
#endif /*CHAR_CP */

/*--------------------------*/
/* 64 bits integer			*/
#ifndef __INT64
	#define __INT64
	#if __BYTE_ORDER == __LITTLE_ENDIAN
		typedef struct INT64_DWORD_MODE {
			dword low_dword;
			dword high_dword;
		} INT64_DWORD_MODE;
	#else /*__BYTE_ORDER*/
		typedef struct INT64_DWORD_MODE {
			dword high_dword;
			dword low_dword;
		} INT64_DWORD_MODE;
	#endif /*__BYTE_ORDER*/

	#if __BYTE_ORDER == __LITTLE_ENDIAN
		typedef struct INT64_BYTE_MODE {
			byte byte0;
			byte byte1;
			byte byte2;
			byte byte3;
			byte byte4;
			byte byte5;
			byte byte6;
			byte byte7;
		} INT64_BYTE_MODE;
	#else /*__BYTE_ORDER*/
		typedef struct INT64_BYTE_MODE {
			byte byte7;
			byte byte6;
			byte byte5;
			byte byte4;
			byte byte3;
			byte byte2;
			byte byte1;
			byte byte0;
		} INT64_BYTE_MODE;
	#endif /*__BYTE_ORDER*/

	/*------------------------------*/
	/* WINDOWS 64 bits integer		*/
	#if defined WIN32
		#ifdef _MSC_VER
			//Microsoft Compiler <= 6
			#if _MSC_VER <= 1200
				#define eint64 _int64
			#else
				#define eint64 long long
			#endif
		#else
				#define eint64 long long
		#endif
	/*------------------------------*/
	/* POSIX 64 bits integer		*/
	#elif defined POSIX
		#define eint64 long long
	/*--------------------------------------*/
	/* QNX4 and VXWORKS 64 bits integer		*/
	/* On these systems,64 bits integer are not standard */
	#elif (defined QNX4 || defined VXWORKS)
		typedef union eint64 {
			INT64_DWORD_MODE dwords;
			INT64_BYTE_MODE bytes;
			byte raw[8];
		} eint64;
	#endif
#endif


/*------------------------------------------------------------------------------
 * EKD BUS enum type
 *-----------------------------------------------------------------------------*/
typedef enum {
    EKD_BUS_UNDEFINED = -1,
    EKD_BUS_INTERNAL,
    EKD_BUS_ISA,
    EKD_BUS_EISA,
    EKD_BUS_MICROCHANNEL,
    EKD_BUS_TURBOCHANNEL,
    EKD_BUS_PCI,
    EKD_BUS_VME,
    EKD_BUS_NUBUS,
    EKD_BUS_PCMCIA,
    EKD_BUS_C,
    EKD_BUS_MPI,
    EKD_BUS_MPSA,
    EKD_BUS_PROCESSORINTERNAL,
    EKD_BUS_INTERNALPOWER,
    EKD_BUS_PNPISA,
	EKD_BUS_PPC_PER_BUS,
	EKD_BUS_PPC_DSGAT2_BUS,
	EKD_MAX_BUS_TYPE			/* Maximum value of bus type */
} EKD_BUS_TYPE;


/*------------------------------------------------------------------------------
 * EKD IRQ_MODE type
 *-----------------------------------------------------------------------------*/
typedef enum {
	EKD_IRQ_LEVEL_SENSITIVE,
	EKD_IRQ_LATCHED
} EKD_IRQ_MODE;


/*------------------------------------------------------------------------------
 * EKD PCI SLOT type
 *-----------------------------------------------------------------------------*/
typedef union {
	struct {
		dword device_number:5;
        dword function_number:3;
        dword reserved:24;
    } bits;
    dword as_dword;
} EKD_PCI_SLOT;


/*------------------------------------------------------------------------------
 * EKD PCI PlugAndPlay type
 *-----------------------------------------------------------------------------*/
typedef struct {
    word vendor_id;
    word device_id;
    word command;
    word status;
    byte revision_id;
    byte prog_if;
    byte SubClass;
    byte BaseClass;
    byte CacheLineSize;
    byte LatencyTimer;
    byte HeaderType;
    byte BIST;
    union {
         struct {
             dword BaseAddresses[6];
             dword Reserved1[2];
             dword ROMBaseAddress;
             dword Reserved2[2];
             byte InterruptLine;
             byte InterruptPin;
             byte MinimumGrant;
             byte MaximumLatency;
         } type0;
     } u;
     byte device_specific[192];
} EKD_PCI_PNP_INFO;


/*------------------------------------------------------------------------------
 * EKD ISA PlugAndPlay type
 *-----------------------------------------------------------------------------*/
typedef struct {
    byte return_code;
    byte return_flags;
    byte major_revision;
    byte minor_revision;
    word checksum;
    byte number_functions;
    byte function_information;
    dword compressed_id;
} EKD_ISA_PNP_INFO;



/*------------------------------------------------------------------------------
 * hidden structures for library clients
 *-----------------------------------------------------------------------------*/
#ifndef _EKD_LIB
	#define EKD_IRQ_SEMAPHORE void
	#define EKD_USB_DEVICE void
	#define PCI_DEVICE void
#endif

/*------------------------------------------------------------------------------
 * EKD PCI PLX9030 DEVICE type
 *-----------------------------------------------------------------------------*/
typedef struct {
    PCI_DEVICE *device;
    dword address[6];
} EKD_PCI_DEVICE;


/*------------------------------------------------------------------------------
 * EKD KERNEL CALLBACK type
 *-----------------------------------------------------------------------------*/
typedef void (EKD_CALLBACK *EKD_KERNEL_CALLBACK)(void *param);


/**********************************************************************************************************/
/*- LITERALS */
/**********************************************************************************************************/

/*------------------------------------------------------------------------------
 * Maximal number of USB devices
 *-----------------------------------------------------------------------------*/
#define EKD_USB_MAX_DEVICE 64

/*------------------------------------------------------------------------------
 * error codes
 *-----------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
 * error codes
 *-----------------------------------------------------------------------------*/
#define EKD_EBADLIBRARYVERSION           -619        /**< Bad WINDRVR6 library version installed */
#define EKD_EBADLIBRARY                  -618        /**< function of external library not found */
#define EKD_ENOLIBRARY                   -617        /**< external library not found */
#define EKD_EBADDRIVER                   -616        /**< wrong version of the installed device driver */
#define EKD_EINTERNAL                    -615        /**< some internal error in the etel software */
#define EKD_ESEMAPHORENOTACTIVE          -614        /**< semaphore is not active */
#define EKD_EEXCEPTION                   -613        /**< an exception has occurred */
#define EKD_EBADSTATE                    -612        /**< bad state */
#define EKD_ENOTIMPLEMENTED              -611        /**< this function is not implemented */
#define EKD_ETIMEOUT                     -610        /**< timeout error */
#define EKD_EOSDETECTION                 -609        /**< troubles in os detection */
#define EKD_ESEMAPHORELIMIT              -608        /**< the semaphore have the max value */
#define EKD_ESLOTNOTFOUND                -607        /**< isa or pci slot not found */
#define EKD_EBADPARAM                    -606        /**< bad parameters */
#define EKD_ESYSTEM                      -605        /**< some system resource return an error */
#define EKD_EVECTORBUSY                  -604        /**< the irq vector is already used */
#define EKD_EMAPPING                     -603        /**< troubles during the mapping or the unmapping */
#define EKD_EDEVIO                       -602        /**< troubles in data transfer with the driver */
#define EKD_EINIT                        -601        /**< initialization troubles */
#define EKD_EOPENDRV                     -600        /**< cannot open the driver */


/**********************************************************************************************************/
/* functions */
/**********************************************************************************************************/
#ifndef _EKD_SYS
	#ifndef _EKD_VXD
		char_cp _EKD_EXPORT ekd_translate_error(int code);
		int	_EKD_EXPORT ekd_get_driver_version(dword *drv_version);
		int	_EKD_EXPORT ekd_map_physical_memory(EKD_BUS_TYPE bus_type, dword bus_number, dword bus_addr, dword bus_addr_space, dword bus_addr_length, void **virtual_addr);
		int	_EKD_EXPORT ekd_unmap_physical_memory(void *virtual_addr);
		int _EKD_EXPORT ekd_get_device_pci_info(word vendor_id, word device_id, word device_idx,
												word sub_vendor_id, word sub_device_id,
												unsigned *bus, dword base_addr[], byte *irq);
		int	_EKD_EXPORT ekd_get_pci_pnp_info(dword bus_number, EKD_PCI_SLOT slot, EKD_PCI_PNP_INFO *pci_pnp_info);
		int	_EKD_EXPORT ekd_get_isa_pnp_info(dword bus_number, dword slot_number, EKD_ISA_PNP_INFO *isa_pnp_info);
		int _EKD_EXPORT ekd_create_irq_semaphore(EKD_BUS_TYPE bus_type, dword bus_number, dword irq_number, EKD_IRQ_MODE irq_mode, dword semaphore_limit, EKD_IRQ_SEMAPHORE **is_obj);
		int _EKD_EXPORT ekd_destroy_irq_semaphore(EKD_IRQ_SEMAPHORE *is_obj);
		int _EKD_EXPORT ekd_release_irq_semaphore(EKD_IRQ_SEMAPHORE *is_obj);
		int _EKD_EXPORT ekd_get_irq_semaphore_value(EKD_IRQ_SEMAPHORE *is_obj, dword *semaphore_value);
		int _EKD_EXPORT ekd_wait_for_irq_semaphore(EKD_IRQ_SEMAPHORE *is_obj, dword timeout);
		void _EKD_EXPORT ekd_outp(dword addr, dword data);
		void _EKD_EXPORT ekd_outpw(dword addr, dword data);
		void _EKD_EXPORT ekd_outpd(dword addr, dword data);
		dword _EKD_EXPORT ekd_inp(dword addr);
		dword _EKD_EXPORT ekd_inpw(dword addr);
		dword _EKD_EXPORT ekd_inpd(dword addr);
		int _EKD_EXPORT ekd_invoke_by_kernel(EKD_KERNEL_CALLBACK func, void *param);
		dword _EKD_EXPORT ekd_get_version(void);
		dword _EKD_EXPORT ekd_get_edi_version(void);
		time_t _EKD_EXPORT ekd_get_build_time(void);
		void _EKD_EXPORT ekd_close(void);
		int _EKD_EXPORT ekd_plx9030_read_gpio (EKD_PCI_DEVICE *dev, long *gpio);
		int _EKD_EXPORT ekd_plx9030_write_gpio (EKD_PCI_DEVICE *dev, long gpio);
		int _EKD_EXPORT ekd_plx9030_wait_for_irq(EKD_PCI_DEVICE *dev, int irq_timeout);
		int _EKD_EXPORT ekd_plx9030_device_open(EKD_PCI_DEVICE *dev, word subDeviceId, word deviceIdx);
		int _EKD_EXPORT ekd_plx9030_irq_enable(EKD_PCI_DEVICE *dev, dword offset0, dword offset1, dword offset2, dword offset3, dword offset4, dword offset5);
		int _EKD_EXPORT ekd_plx9030_irq_disable(EKD_PCI_DEVICE *dev);
		int _EKD_EXPORT ekd_plx9030_device_close(EKD_PCI_DEVICE *dev);
		int _EKD_EXPORT ekd_plx9030_get_events(EKD_PCI_DEVICE *dev, dword *evt0, dword *evt1, dword *evt2, dword *evt3, dword *evt4, dword *evt5);
		int _EKD_EXPORT ekd_plx9030_release_irq(EKD_PCI_DEVICE *dev);

		//USB functions
		#ifdef WIN32
			#ifndef UNDER_RTSS
				int _EKD_EXPORT ekd_usb_get_present_serial_number(char serial_number[][16], int *size);
				int	_EKD_EXPORT ekd_usb_create_device (EKD_USB_DEVICE **dev);
				int	_EKD_EXPORT ekd_usb_destroy_device (EKD_USB_DEVICE **dev);
				int	_EKD_EXPORT ekd_usb_open (EKD_USB_DEVICE *dev, char* serial_number);
				int	_EKD_EXPORT ekd_usb_write (EKD_USB_DEVICE *dev, void *buffer, dword size);
				int	_EKD_EXPORT ekd_usb_read (EKD_USB_DEVICE *dev, void *buffer, dword size);
				int	_EKD_EXPORT ekd_usb_reset (EKD_USB_DEVICE *dev);
				int	_EKD_EXPORT ekd_usb_purge (EKD_USB_DEVICE *dev);
				int	_EKD_EXPORT ekd_usb_close (EKD_USB_DEVICE *dev);
				int	_EKD_EXPORT ekd_usb_data_available (EKD_USB_DEVICE *dev, boolean *data_available);
				int	_EKD_EXPORT ekd_usb_set_timeout (EKD_USB_DEVICE *dev, dword timeout);
				char* _EKD_EXPORT ekd_usb_get_serial_number (EKD_USB_DEVICE *dev);
				int	_EKD_EXPORT ekd_usb_set_read_event (EKD_USB_DEVICE *dev, AUTOEVENT event);
				int _EKD_EXPORT ekd_usb_load_library();
				int _EKD_EXPORT ekd_usb_unload_library();
			#endif /* UNDER_RTSS */
		#endif /* WIN32 */

		//UltimET PCI functions
		#if defined WIN32 || defined LINUX || defined QNX6
			int	_EKD_EXPORT ekd_ultimet_load_library();
			int	_EKD_EXPORT ekd_ultimet_unload_library();
			int _EKD_EXPORT ekd_ultimet_irq_disable(EKD_PCI_DEVICE *dev);
			int _EKD_EXPORT ekd_ultimet_irq_enable(EKD_PCI_DEVICE *dev, dword offset0, dword offset1, dword offset2, dword offset3, dword offset4, dword offset5);
			int _EKD_EXPORT ekd_ultimet_device_close(EKD_PCI_DEVICE *dev);
			int _EKD_EXPORT ekd_ultimet_device_open(EKD_PCI_DEVICE *dev, word deviceIdx);
			int _EKD_EXPORT ekd_ultimet_wait_for_irq(EKD_PCI_DEVICE *dev, int timeout);
			int _EKD_EXPORT ekd_ultimet_release_irq(EKD_PCI_DEVICE *dev);
			int _EKD_EXPORT ekd_ultimet_get_events(EKD_PCI_DEVICE *dev, dword *evt0, dword *evt1, dword *evt2, dword *evt3, dword *evt4, dword *evt5);
		#endif /* WIN32 */
	#endif /* EKD_VXD */
#endif /*EKD_SYS */


#endif /* _EKD20_H_ */

