#ifndef DAGDRV_H
#define DAGDRV_H

#include "linux/version.h"
#include <linux/fs.h>

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
# include <linux/cdev.h>
#else
# include <linux/devfs_fs_kernel.h>
#endif

#include "dagnew.h"

#define DAG_REG_BASE    0x900
#define CAPS_BASE       0x98
#define CAPS_MAGIC      0xa6000000
#define CAPS_MAGIC_MASK 0xff000000

#define DAG_REG_ADDR_START 0xffa5
#define DAG_REG_ADDR_END   0xffff

typedef struct pciconfig {
	uint32_t	ba0;	/* base address 0 */
	uint32_t	ba1;	/* base address 1 */
	uint32_t	ba2;	/* base address 2 */
	uint32_t	com;	/* command */
	uint8_t	lin;	/* interrupt line */
	uint8_t	lat;	/* latency timer */
	uint8_t brd_rev;	/*Board revision ID */
	uint32_t dev_ctrl;
	uint32_t link_ctrl;
} pciconfig_t;

struct dag_duck;

typedef struct dag_lock {
	pid_t	pid;	/* pid of the process/thread */
	pid_t	tgid;	/* thread group Id */
    struct file* locked_file;   /* to remember through which fd  the streams are locked*/
} dag_lock_t;

typedef struct dag_softc {
	int		unit;
	int		flags;
	struct semaphore	lock_sem;
	struct pci_dev  *device;	/* PCI device */
	dag_lock_t	card_lock;
	dag_lock_t	mode_lock;
	dag_lock_t	stream_lock[DAG_STREAM_MAX];
	uint8_t         *mmio;
	uint32_t         mmio_size;
	dma_addr_t       bus_addr;
	dma_addr_t       phys_addr;
	uint32_t         pmem_size;
	uint32_t         pci_bar_memory;
	uint32_t         irq;
	uint32_t         monseq;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
	struct cdev     cdev_dag, cdev_mem, cdev_iom, cdev_arm;
# else
	devfs_handle_t	devfs_dag, devfs_mem, devfs_iom, devfs_arm;
# endif
	pciconfig_t	pciconfig;
	struct dag_duck	*duck;
	struct file *host_file;
} dag_softc_t;

int dag_pciconfig_restore(dag_softc_t *sc);


#endif /* DAGDRV_H */
