#ifndef ClfFuncH
#define ClfFuncH ClfFuncH

#include "linux/mutex.h"
#include "hyperion_base.h"
#include "device_queue.h"
#include "hyperion_dma_nios.h"
#include "ksemaphore.h"

#define MAX_SGLIST_BUFFER_SIZE (512*1024)
#define MSG_BUFFER_SIZE (4*1024)
#define NIOS_MEMORY_APP_SIZE (32*1024)

//-------------------------------------------------------------------------------------------
struct dma_transfer_object
//-------------------------------------------------------------------------------------------
{
    unsigned int index;
    unsigned int init_done;
    struct device_queue* rw_queue;          ///< pointer to the read/write queue defined in the device extension
    struct mux_controller_sequence mux_seq;
};

//-------------------------------------------------------------------------------------------
struct dma_sg_list_entry
//-------------------------------------------------------------------------------------------
{
    struct list_head list_entry;
    int     index;
    int     buf_size;
    void*        buf;
    dma_addr_t      phy;
    int     size;
    struct io_object* ioobj;
    void*        nios_msg;
    dma_addr_t  nios_msg_phy;
    int     nios_msg_size;
    void*        host_msg;
    dma_addr_t  host_msg_phy;
    int     host_msg_size;
    void*        request_extension;
    dma_addr_t  req_ext_phy;
};

//-------------------------------------------------------------------------------------------
struct dma_sg_list
//-------------------------------------------------------------------------------------------
{
    struct list_head head;
    spinlock_t s_lock;
};

//-------------------------------------------------------------------------------------------
typedef struct ioctl_lock
//-------------------------------------------------------------------------------------------
{
    spinlock_t s_generic;
    spinlock_t s_request;
    spinlock_t s_digital_io;
    spinlock_t s_message;
    spinlock_t s_tasklet;
} t_ioctl_lock;

//-------------------------------------------------------------------------------------------
struct hyperion_device_object
//-------------------------------------------------------------------------------------------
{
    int                             index;
    struct pci_dev*                  pdev;
    struct memory_space             hyperion_base;
    HYPERION_BASE_REGISTER_DEF*      reg_def;
    struct device_queue*             pqueues[MAX_PARALLEL_TRANSFER]; ///< pointer to the queue objects
    struct device_queue             dq_read_write[MAX_PARALLEL_TRANSFER]; ///< queues for reads and writes for the DMA_Channels
    struct device_queue*             pqueue_result; ///< pointer to the result_queue
    struct device_queue             dq_result; ///< queue including result ioobj
    struct dma_transfer_object*      pdma_object[MAX_PARALLEL_TRANSFER]; ///< pointer to the dma objects
    struct dma_transfer_object      dma_transfer_object[MAX_PARALLEL_TRANSFER]; ///< the dmaobjects contains all structures and variables for transfering

    TPipe*                           interrupt_result_pipe; ///< resultqueue to save interruptstatus for handling in our DPC
    struct mux_controller_sequence  mux_seq;
    uart_object_t                   uart_port[UART_NUM];
    POCL_OBJECT                     pocl[MAX_PARALLEL_TRANSFER];
    void ( *set_mux_data )( struct hyperion_object* device, struct mux_controller_sequence* mux_seq, u_long inputchannel );
    void ( *set_hrtc_ram )( struct hyperion_object* device, struct transfer_parameter* tp );

    int                             pci_hyperion_page_size;
    volatile int                    aborting_in_process;
    int                             processor_status;
    unsigned int                    processor_app_size;
    struct processor_info_object
    {
        int cpu_clk_hz;
    } processor_info;
    TKSemaphore*                     sema_message_received;
    message_pipe                    request_message;
    message_pipe                    request_result_message;
    struct dma_sg_list_entry        dma_sg_list_pool[MAX_COUNT_REQUEST_OBJECT];
    struct dma_sg_list              dma_sg_list;
    int                             address_space_encoding;
    unsigned char                   user_flash_enabled;
    int                             eeprom_write_access;
    t_ioctl_lock                    ioctl_lock;
};

int hyperion_func_init( struct hyperion_object* device, unsigned long control );
int hyperion_func_close( struct hyperion_object* device );
int hyperion_func_async_read( struct hyperion_object* device, struct io_object* ioobj );
void hyperion_func_abort_transfer( struct hyperion_object* device );
int hyperion_func_enable_interrupt( struct hyperion_object* device );
int hyperion_boot_processor( struct hyperion_device_object* dev_obj, void* apps, unsigned int size );
void hyperion_func_complete( struct io_object* ioobj );
void hyperion_func_release_dma( struct hyperion_object* device, void* dma_list_entry );
int transmit_message( struct hyperion_device_object* dev_obj, unsigned int message, unsigned int timeout_msec, void* buffer, unsigned int size, unsigned long* processor_result );
void translate_property_to_property32( TPropertyElement* list, TPropertyElement32* list32, unsigned int prop_count );
void translate_property32_to_property( TPropertyElement* list, TPropertyElement32* list32, unsigned int prop_count );
void hyperion_halt_processor( struct hyperion_object* device );
void hyperion_func_release_hw( struct hyperion_object* device );
void hyperion_func_camera_power( struct hyperion_object* device, int state );
#endif //ClfFuncH
