RTD ECAN Unix driver low-level API.


1. Preface

The drivers interface and behaviour designed to be the same as MS
Windows ones as close as possible in spite of its design flaws. In
order to meet this requirements there are three levels of interface:

High level is exact copy of Ecan* functions interface of MS Windows
driver wrapper, declared in <EcanFunc.h> header file.

Mid level is definitions of argument structures used in high-level
Ecan* functions and in low-level MS Windows DeviceIoControl() for the
driver, defined in <EcanIoctl.h> header file.

Low level is Unix/Linux driver interface functions rtd_ecan_*() defined in
<rtd-ecan-ioctl.h> header file.

For exact meaning of driver actions and function parameters see
the Ecan Windows driver API manual.



2. Some used integral types, defined in supplemental header files
   ( included by <rtd-ecan-ioctl.h> )


typedef u8_t;
	8-bit exact-width unsigned integral type, the same as uint8_t
	in ISO C99 and SUSv2 standard drafts.

typedef u16_t;
	16-bit exact-width unsigned integral type, the same as uint16_t
	in ISO C99 and SUSv2 standard drafts.

typedef u32_t;
	32-bit exact-width unsigned integral type, the same as uint32_t
	in ISO C99 and SUSv2 standard drafts.

Note:
	SUSv2 - The Single UNIX (R) Specification, Version 2
		Copyright  1997 The Open Group


typedef size_t;
	Unsigned integral type of the result of the sizeof operator.
	Used also to represent general purpose counters.

typedef ssize_t;
	Signed integral type for a counters or an error indication.

typedef ulonglong;
	The same as unsigned long long.
	Used to represent counters of operations.

typedef ulong;
	The same as unsigned long.

typedef uint;
	The same as unsigned int.



3. Structures

Almost all of parameter structures are analogous to ones in the Windows
driver, see Ecan Windows Driver API manual.
The structure definitions presented together with description of driver
functions below.



4. Driver functions



4.1. Device access

Programs gets access to CAN bus controller boards by opening
device file located in /dev directory.
See open(2) system call for details.



4.2. Device file names

Whole device file name can be presented as following template:
	"/dev/rtd-ecanMAGIC-N"

where MAGIC is "1000" for ECAN1000 and "527" for ECAN527,
N is board instance number, "0".."9".

Following C preprocessor symbols provided to construct device file name
from separate components:

	RTD_ECAN_DEVICE_NAME_BASE	"/dev/rtd-ecan"
	RTD_ECAN_DEVICE_MAX_NAME_LENGTH	(number)
	RTD_ECAN1000_MAGIC_NUMBER	(number)
	RTD_ECAN527_MAGIC_NUMBER	(number)

Example:

	[...]

	char devname[ RTD_ECAN_DEVICE_MAX_NAME_LENGTH ];
	uint board_type, board_number;

	[...]

	sprintf(devname, "%s%u-%u",
		RTD_ECAN_DEVICE_NAME_BASE, board_type, board_number);

	[...]

Note 1:
	In this example no checking for valid board type and number
	because it will be done at opening device time.

Note 2:
	It is not need to construct device name from components,
	supplying complete device file name from program arguments or
	configuration files is enough and much more simpler.
	Whole device name string contains no more magic then separate
	board type and number.



4.3. Open device

Use 'open' system call to open device.
See open(2) manual page for details.


Prototype:
	int open( const char* pathname, int flags )

Parameters:
	const char* pathname
		name of device file

	int flags
		open flags
		We need only O_RDWR,
		rest of them are invalid or ignored
		As exception to get account information only
		without intervention in current driver and board operations
		use (O_RDWR | O_SYNC).

Return value:
	new handle of opened device - small integer >= 0
	or -1 on errors.

Errors (errno):
	EACCES
		Permission denied.
		The device file permissions do not allow opening with
		supplied open flags.
		The open flags does not contain O_RDWR.
	ENXIO
		No such device or address.
		Invalid board number.
	ENODEV
		No such device.
		No board with specified number installed.
	EBUSY
		Device or resource busy.
		Board already opened by this or another process.
	ENOMEM
		No memory available.

	For other not driver-specific errno values see open(2) manual page.

Example (complete):

#include <fcntl.h>		/* open()                        */
#include <stdio.h>		/* sprintf()                     */
#include <stdlib.h>		/* EXIT_SUCCESS, EXIT_FAILURE    */
#include <dfcompat/error.h>	/* error()                       */
#include <dfcompat/errno.h>	/* errno and compatibility codes */
#include <rtd-ecan-ioctl.h>

static int usage( const char* progname )
{
	printf("Usage: %s devicename\n", progname);
	return EXIT_FAILURE;
}

int main( int argc, char* argv[] )
{
	int handle;

	if ( argc != 2 )
		return usage( argv[0] );

	handle = open( argv[1], O_RDWR );
	if ( handle < 0 )
		error( EXIT_FAILURE, errno, "open ( \"%s\" )", argv[1] );

	printf( "device '%s' opened successfully\n", argv[1] );
	return EXIT_SUCCESS;
}



4.4. Close device

Use close system call to close device.
See close(2) manual page for details.

Prototype:
	int close( int handle )

Parameters:
	int handle
		handle of opened device

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		Bad file descriptor.
		handle is not a valid file descriptor.
	EIO
		Input/output error.
		Error of switching board to reset mode.

	Other errno values of close(2) call are possible.

Note:
	In spite of any close error the device closed unconditionally.

Example:

[...]
	int handle;
	int rc;
[...]
	handle = open( argv[1], O_RDWR );
	if ( handle < 0 )
		error( EXIT_FAILURE, errno, "open ( \"%s\" )", argv[1] );
[...]
	rc = close( handle );
	if ( rc < 0 )
		error( 0, errno, "close ( \"%s\" )", argv[1] );



4.5. Get driver version.

Prototype:
	ssize_t rtd_ecan_get_driver_version( int handle )

Parameters:
	int handle
		handle of opened device

Return value:
	driver's version (040 or 100 or 200 etc)
	or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.

	Other errno values of ioctl(2) call are possible.



4.6. Get board's type name (a positive magic number)

Prototype:
	ssize_t rtd_ecan_get_board_name( int handle )

Parameters:
	int handle
		handle of opened device

Return value:
	board's type magic number, 1000 for ECAN1000, 527 for ECAN527
	or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.

	Other errno values of ioctl(2) call are possible.



4.7. Set CAN timing and bus configuration.

Prototype:
	int rtd_ecan_set_bus_config( int handle,
				     u8_t BusTiming0, u8_t BusTiming1,
				     u8_t ClockOut  , u8_t BusConfig )

Parameters:
	int handle
		handle of opened device

	u8_t BusTiming0
		device-specific value for bus timing register 0

	u8_t BusTiming1
		device-specific value for bus timing register 1

	u8_t ClockOut
		device-specific value for frequency divider
		at the external CLKOUT pin relatively to the frequency
		of the external oscillator, 0 - don't change.

	u8_t BusConfig
		device-specific value for Output Control or
		Bus Configuration Register

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	EINVAL
		Invalid parameter.

	Other errno values of ioctl(2) call are possible.



4.8. Send command (device specific)

Prototype:
	int rtd_ecan_send_command( int handle,
		const struct rtd_ecan_send_command* command )

Parameters:
	int handle
		handle of opened device

	const struct rtd_ecan_send_command* command
		pointer to command structure:

		struct rtd_ecan_send_command
		{   /* boolean */
		    int TR ; /* Transmission Request   */
		    int RRB; /* Release Receive Buffer */
		    int AT ; /* Abort Transmission     */
		    int CDO; /* Clear Data Overrun     */
		    int SRR; /* Self Reception Request */
		};

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	EPERM
		Operation not permitted.
		Board in operating mode, reset mode needed for this
		operation.
	ENOTSUP
		Not supported.
		This function is not supported by ECAN527 board.

	Other errno values of ioctl(2) call are possible.



4.9. Set LEDs (ECAN527 only)

Prototype:
	int rtd_ecan_set_leds( int handle, uint led_flags )

Parameters:
	int handle
		handle of opened device

	uint led_flags
		Bit masks to set LED states:
			RTD_ECAN_LED_RED
			RTD_ECAN_LED_GREEN

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	ENOTSUP
		Not supported.
		This function is not supported by ECAN1000 board.
	EINVAL
		Invalid parameter.
		led_flags contains unknown bits.

	Other errno values of ioctl(2) call are possible.



4.10. Get board's RAM area

Prototype:
	int rtd_ecan_get_ram( int handle, size_t ram_offset, size_t ram_len,
			      void* userbuf )

Parameters:
	int handle
		handle of opened device

	size_t ram_offset
		offset in board RAM area

	size_t ram_len
		length of board RAM area

	void* userbuf
		user supplied buffer to copy board RAM area to

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	EINVAL
		Invalid parameter.
		Invalid board RAM area specified.

	Other errno values of ioctl(2) call are possible.



4.11. Set board's RAM area

Prototype:
	int rtd_ecan_set_ram( int handle, size_t ram_offset, size_t ram_len,
			      const void* userbuf )

Parameters:
	int handle
		handle of opened device

	size_t ram_offset
		offset in board RAM area

	size_t ram_len
		length of board RAM area

	const void* userbuf
		user supplied buffer to copy board RAM area from

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	EINVAL
		Invalid parameter.
		Invalid board RAM area specified.

	Other errno values of ioctl(2) call are possible.



4.12. Set receive queue size

Prototype:
	int rtd_ecan_set_rx_max_queue_size( int handle,
					    size_t max_queue_size )

Parameters:
	int handle
		handle of opened device

	size_t max_queue_size
		new size of receive queue in message items

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	ENOMEM
		No memory available for specified amount
		of queue items. In this case the queue has
		zero size and driver needs the success call
		in order to function.

	Other errno values of ioctl(2) call are possible.

Note:
	Clears receive queue contents.



4.13. Set transmit queue size

Prototype:
	int rtd_ecan_set_tx_max_queue_size( int handle,
					    size_t max_queue_size )

Parameters:
	int handle
		handle of opened device

	size_t max_queue_size
		new size of transmit queue in message items

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	ENOMEM
		No memory available for specified amount
		of queue items. In this case the queue has
		zero size and driver needs the success call
		in order to function.

	Other errno values of ioctl(2) call are possible.

Note:
	Clears transmit queue contents.



4.14. Clear specified queue contents

Prototype:
	int rtd_ecan_clear_queues( int handle, uint queue_flags )

Parameters:
	int handle
		handle of opened device

	uint queue_flags
		Bit masks to address receive or transmit queue:
			RTD_ECAN_RX_QUEUE
			RTD_ECAN_TX_QUEUE

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	EINVAL
		Invalid parameter.
		queue_flags contains unknown bits.

	Other errno values of ioctl(2) call are possible.



4.15. Get queue counts

Prototype:
	int rtd_ecan_get_queues_counts( int handle,
					size_t* rx_count, size_t* tx_count )

Parameters:
	int handle
		handle of opened device

	size_t* rx_count
		pointer to store receive queue count
		(must not be NULL)

	size_t* tx_count
		pointer to store transmit queue count
		(must not be NULL)

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.

	Other errno values of ioctl(2) call are possible.



4.16. Stop board (set reset mode)

Prototype:
	int rtd_ecan_stop( int handle )

Parameters:
	int handle
		handle of opened device

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	EIO
		Input/output error.
		Error of switching board to reset mode.

	Other errno values of ioctl(2) call are possible.



4.17. Start board (set operating mode)

Prototype:
	int rtd_ecan_start( int handle )

Parameters:
	int handle
		handle of opened device

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	EIO
		Input/output error.
		Error of switching board to operating mode.

	Other errno values of ioctl(2) call are possible.



4.18. Test board

Prototype:
	int rtd_ecan_test( int handle )

Parameters:
	int handle
		handle of opened device

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	EIO
		Input/output error.
		Test failed.

	Other errno values of ioctl(2) call are possible.



4.19. Prepare received message for access by successive calls,
      get message interrupt bits and current receive queue size

Prototype:
	int rtd_ecan_prepare_received_message( int handle,
		  uint* events,
		size_t* rx_queue_count
		int dont_use_queue )
Parameters:
	int handle
		handle of opened device

	uint* events
		pointer to store event bits

	size_t* rx_queue_count
		pointer to store receive queue count

	int dont_use_queue
		boolean flag to get message from board directly

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	EPERM
		Operation not permitted.
		Board in reset mode and dont_use_queue!=0,
		operating mode needed for this operation.

	Other errno values of ioctl(2) call are possible.



4.20. Get status

Prototype:
	int rtd_ecan_get_status( int handle, struct rtd_ecan_status* status,
				 int dont_use_queue)

Parameters:
	int handle
		handle of opened device

	struct rtd_ecan_status* status
		pointer to store status structure:

			struct rtd_ecan_status
			{
			    u8_t Arbitration; /* Arbitration lost capture
						 register */
			    u8_t ErrorCode;   /* Last Error Code register */

			    /* boolean */
			    int BusOff ; /* bus off                  */
			    int Warning; /* Error Warning limit
					    reached                  */
			    int WakeUp ; /* not used in ECAN1000     */
			    int TXOK   ; /* Transmission Complete
					    (ECAN1000)               */
			    int RXOK   ; /* Receive Message
					    Successfully (ECAN527)   */
			    int TS     ; /* Transmit Status          */
			    int RS     ; /* Receive Status           */
			    int TBS    ; /* Transmit Buffer Status   */
			    int DOS    ; /* Data Overrun Status      */
			    int RBS    ; /* Receive Buffer Status    */
			};

	int dont_use_queue
		boolean flag to get status from board directly

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device
	EPERM
		Operation not permitted.
		Board in reset mode and dont_use_queue!=0,
		operating mode needed for this operation.

	Other errno values of ioctl(2) call are possible.



4.21. Get message

Prototype:
	int rtd_ecan_recv_message( int handle, struct rtd_ecan_message* msg,
				   int dont_use_queue )

Parameters:
	int handle
		handle of opened device

	struct rtd_ecan_message* msg
		pointer to store message structure:

			struct rtd_ecan_message
			{
			    u8_t Channel; /* ECAN527 only:
				0     - Default Transmitting or
					Defaullt Receiving of Message Object
				1..15 - Message Object by number */

			    u8_t ID[4];		/* Identifier octets       */
			    u8_t DataLength;	/* Data Length Code (0..8) */
			    u8_t Data[8];	/* Data Octets             */

			    /* boolean */
			    int Extended;	/* Extended Frame Format   */
			    int Remote;		/* Remote Frame request    */

			    int NextMsg;	/* out: the next message
						   available in a queue    */
			};

	int dont_use_queue
		boolean flag to get message from board directly

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	EPERM
		Operation not permitted.
		Board in reset mode and dont_use_queue!=0,
		operating mode needed for this operation.
	EBADSLT
		Invalid slot.
		dont_use_queue!=0 and msg->Channel==0 (ECAN527 only).

	Other errno values of ioctl(2) call are possible.



4.22. Send message

Prototype:
	int rtd_ecan_send_message( int handle, struct rtd_ecan_message* msg,
				   int dont_use_queue )

Parameters:
	int handle
		handle of opened device

	struct rtd_ecan_message* msg
		pointer to message structure (see above)

	int dont_use_queue
		boolean flag to send message to board directly

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	EPERM
		Operation not permitted.
		Board in reset mode and dont_use_queue!=0,
		operating mode needed for this operation.
	EBUSY
		Device or resource busy.
		dont_use_queue!=0 and board transmitter still busy.
	ENOBUFS
		No buffer space available.
		Transmit queue is full.

	Other errno values of ioctl(2) call are possible.



4.23. Setup message object (ECAN527 only)

Prototype:
	int rtd_ecan_setup_message_object( int handle,
		  const struct rtd_ecan_msg_obj_setup* msg,
		  int dont_use_queue )

Parameters:
	int handle
		handle of opened device

	const struct rtd_ecan_msg_obj_setup* msg
		pointer to message object setup structure:

			struct rtd_ecan_msg_obj_setup
			{
			    int State;	/* RTD_ECAN_MO_*, see below */

			    u8_t Channel; /* ECAN527 only:
				0     - Default Transmitting or
					Defaullt Receiving of Message Object
				1..15 - Message Object by number */

			    u8_t ID[4];		/* Identifier octets */

			    /* boolean */
			    int Valid   ; /* enable Message Object
					     after setup                 */
			    int Extended; /* Extended Frame Format       */
			    int RXIE    ; /* Enable  Receive Message
					     Interrupt for this object */
			    int TXIE    ; /* Enable Transmit Message
					     Interrupt for this object */
			    int MakeDefault; /* set msg obj 'Channel'
						to be default for rx/tx */
			};

		Constants to represent state of message object
		(ECAN527 only):

			RTD_ECAN_MO_DISABLED
			RTD_ECAN_MO_RECEIVE
			RTD_ECAN_MO_TRANSMIT
			RTD_ECAN_MO_REMOTE_TRANSMIT
				(transmit automatically after receiving
				 remote frame whith the same ID)

	int dont_use_queue
		boolean flag, if FALSE for MO_TRANSMIT,
		then changes Default Transmitting Object to this

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	ENOTSUP
		Not supported.
		This function is not supported by ECAN1000 board.
	EINVAL
		Invalid parameter.
		msg->State value must be one of RTD_ECAN_MO_*.
	EINVAL
		Message object 15 is for receiving only
		(msg->Channel==15 and msg->State is RTD_ECAN_MO_TRANSMIT
		 or RTD_ECAN_MO_REMOTE_TRANSMIT).
	EINVAL
		msg->Channel==0 (default message object) and
		msg->State is RTD_ECAN_MO_DISABLED.

	ECHRNG
		Channel number out of range.
		msg->Channel > 15

	Other errno values of ioctl(2) call are possible.



4.24. Set filter

Prototype:
	int rtd_ecan_set_filter( int handle,
				 const struct rtd_ecan_filter* filter,
				 int dont_use_queue )

Parameters:
	int handle
		handle of opened device

	const struct rtd_ecan_filter* filter
		pointer to filter structure:

			struct rtd_ecan_filter
			{
			    u8_t AC[4]; /* Acceptance Code Reg */
			    u8_t AM[4]; /* Acceptance Mask Reg */

			    /* Not used in the ECAN1000 */
			    u8_t ME[4]; /* Global Mask Extended */
			    u8_t MM[4]; /* Message 15 mask */

			    /* boolean */
			    int DualFilter  ; /* For ECAN1000 only */
			};

	int dont_use_queue
		boolean flag to set filter to board directly

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	EBUSY
		Device or resource busy.
		dont_use_queue!=0 and board transmitter still busy,
		don't want to stop.
	EIO
		Input/output error.
		dont_use_queue!=0 and error of switching board
		to reset mode.
	ENOBUFS
		No buffer space available.
		Transmit queue is full.

	Other errno values of ioctl(2) call are possible.



4.25. Set events mask

Prototype:
	int rtd_ecan_set_events_mask( int handle, uint events_mask )

Parameters:
	int handle
		handle of opened device

	uint events_mask
		bit mask (filter) of device events:

			RTD_ECAN_EVENT_RECEIVE
			RTD_ECAN_EVENT_TRANSMIT
			RTD_ECAN_EVENT_ERROR_WARN_LIMIT
			RTD_ECAN_EVENT_DATA_OVERRUN
			RTD_ECAN_EVENT_WAKE_UP
			RTD_ECAN_EVENT_ERROR_PASSIVE
			RTD_ECAN_EVENT_ARBITRATION_LOST
			RTD_ECAN_EVENT_BUS_ERROR
			RTD_ECAN_EVENT_ALL

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.
	EINVAL
		Invalid parameter.
		events_mask contains unknown bits.
	EIO
		Input/output error.
		Error of switching board to reset mode
		(Windows compatibility requirement).

	Other errno values of ioctl(2) call are possible.



4.26. Get account information

Prototype:
	int rtd_ecan_get_accounts( int handle,
				   rtd_ecan_accounts_t* accounts )

Parameters:
	int handle
		handle of opened device

	rtd_ecan_accounts_t* accounts
		pointer to accounting structure:

			typedef struct rtd_ecan_accounts
			{
			    ulonglong port_in;
			    ulonglong port_out;

			    ulonglong board_in;
			    ulonglong board_out;

			    ulonglong hard_reset;
			    ulonglong soft_reset;


			    ulonglong received_messages;
			    ulonglong received_rtr_messages;
			    ulonglong received_message_octets;
			    ulonglong lost_messages;

			    ulonglong transmitted_messages;
			    ulonglong transmitted_rtr_messages;
			    ulonglong transmitted_message_octets;


			    /* interrupt context locks */
			    ulonglong try_lock_fail;
			    ulonglong try_lock_success;
			    ulonglong try_lock_unlock;

			    /*   process context locks */
			    ulonglong     lock;
			    ulonglong   unlock;


			    ulonglong               all_interrupts;
			    ulonglong         immediate_interrupts;
			    ulonglong          deferred_interrupts;
			    ulonglong    taked_deferred_interrupts;
			    ulonglong deferred_serviced_interrupts;
			    ulonglong          serviced_interrupts;


			    /* current queue size and usage */
			    size_t rx_queue_size;
			    size_t rx_queue_used;

			    size_t tx_queue_size;
			    size_t tx_queue_used;


			    /* microseconds since last clear_accounts() */
			    ulonglong accounting_utime;

			} rtd_ecan_accounts_t;


Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.

	Other errno values of ioctl(2) call are possible.

Note:
	To prevent undesirable intervention in driver and board
	activity use additional open flag O_SYNC during opening device
	for get accounting information only.



4.27. Clear account information

Prototype:
	int rtd_ecan_clear_accounts( int handle )

Parameters:
	int handle
		handle of opened device

Return value:
	0 on success or -1 on errors.

Errors (errno):
	EBADF
		handle is not a valid file descriptor.
	ENOTTY
		Inappropriate ioctl for device.

	Other errno values of ioctl(2) call are possible.

Note:
	To prevent undesirable intervention in driver and board
	activity use additional open flag O_SYNC during opening device
	for clear accounting information only.

