/* $ZEL: sis1100pcivar.h,v 1.2 2002/02/27 09:59:03 wuestner Exp $ */

/*
 * Copyright (c) 2001
 * 	Matthias Drochner, Peter Wuestner.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _sis1100var_h_
#define _sis1100var_h_

#include <linux/timer.h>

#ifdef CONFIG_DEVFS_FS
#   define USE_DEVFS
/*#   undef USE_DEVFS*/
#else
#   undef USE_DEVFS
#endif

#ifdef USE_DEVFS
#include <linux/devfs_fs_kernel.h>
#endif


#include "plx9054reg.h"
#include "sis1100_map.h"
#include "sis1100pci_var.h"

#define MAX_SIS1100_DEVICES 8


struct SIS1100_dmabuf {
    size_t size;
    void* cpu_addr;
    dma_addr_t dma_handle;
};

enum irqs_got {got_dma0=1, got_dma1=2, got_end=4, got_eot=8,
        got_xoff=16, got_sync=32, got_l_err=64};

struct irq_info {
    pid_t pid;
    int sig;
    int vector;
};

struct SIS1100_softc {
    volatile u_int8_t *plxmembase, *plxlocalbase0, *plxlocalbase1;
    u_int32_t plxmemlen, plxlocallen0, plxlocallen1;
    int unit;
    u_int32_t local_ident;
    volatile u_int32_t doorbell;
    struct pci_dev *pcidev;
    wait_queue_head_t sis1100_wait;
    volatile int got_irqs;
    struct semaphore sem_irq_info; /* protects irq_info and      */
                                   /* SIS1100_fdata.owned_levels */
    volatile int irqcount;
    struct semaphore sem_hw; /* protects hardware */
    spinlock_t lock_intcsr;  /* protects INTCSR of PLX */
    spinlock_t lock_doorbell;
#ifdef USE_DEVFS
    devfs_handle_t devfs_dev, devfs_dev_sd, devfs_dev_sh;
#endif
    volatile int command_pending;
};

struct SIS1100_fdata {
    struct SIS1100_softc* sc;
    int dma_big_endian;        /* 0: little, 1: big */
    int last_prot_err;
    unsigned int kiolen_r, kiolen_w;
};

#define SIS1100FD(file) ((struct SIS1100_fdata*)(file)->private_data)
#define SIS1100SC(file) (((struct SIS1100_fdata*)(file)->private_data)->sc)

#define ofs(what, elem) ((int)&(((what *)0)->elem))

#define _plxreadreg(sc, offset) readl((sc)->plxmembase+(offset))
#define _plxwritereg(sc, offset, val) writel(val, (sc)->plxmembase+(offset))

#define plxreadreg(sc, reg) \
 _plxreadreg(sc, ofs(struct plx9045reg, reg))
#define plxwritereg(sc, reg, val) \
 _plxwritereg(sc, ofs(struct plx9045reg, reg), val)

#define plxreadlocal0(sc, offset) readl((sc)->plxlocalbase0+(offset))
#define plxwritelocal0(sc, offset, val) writel(val, (sc)->plxlocalbase0+(offset))

#define sis1100readreg(sc, reg) \
 plxreadlocal0(sc, ofs(struct sis1100_reg, reg))
#define sis1100writereg(sc, reg, val) \
 plxwritelocal0(sc, ofs(struct sis1100_reg, reg), val)

#define sis1100remreadreg(sc, reg, val) \
 sis1100_remote_reg_read(sc, ofs(struct sis1100_reg, reg), val)
#define sis1100remwritereg(sc, reg, val) \
 sis1100_remote_reg_write(sc, ofs(struct sis1100_reg, reg), val)

extern struct SIS1100_softc *SIS1100_devdata[MAX_SIS1100_DEVICES];

extern struct file_operations SIS1100_fops;

int sis1100_open(struct inode *inode, struct file *file);

int sis1100_release(struct inode *inode, struct file *file);
int sis1100_ioctl(struct inode *inode, struct file *file,
    	    	unsigned int cmd, unsigned long arg);
int sis1100_mmap(struct file * file, struct vm_area_struct * vma);
ssize_t sis1100_read(struct file* file, char* buf, size_t count,
    	    	loff_t* ppos);
ssize_t sis1100_write(struct file* file, const char* buf, size_t count,
    	    	loff_t* ppos);

int SIS1100_intr(struct SIS1100_softc* sc);
int SIS1100_init(struct SIS1100_softc* sc);
void SIS1100_done(struct SIS1100_softc* sc);

void dump_glink_status(struct SIS1100_softc* sc, char* text);
void flush_fifo(struct SIS1100_softc* sc, const char* text, int silent);

int sis1100_disable_irq(struct SIS1100_softc* sc,
    u_int32_t plx_mask, u_int32_t sis_mask);
int sis1100_enable_irq(struct SIS1100_softc* sc,
    u_int32_t plx_mask, u_int32_t sis_mask);
int sis1100_get_irq(struct SIS1100_softc* sc,
    u_int32_t* plx_mask, u_int32_t* sis_mask);
int sis1100_tmp_read(struct SIS1100_softc *sc,
    u_int32_t addr, int32_t am, u_int32_t size, int space, void* data);
int sis1100_tmp_write(struct SIS1100_softc *sc,
    u_int32_t addr, int32_t am, u_int32_t size, int space, u_int32_t data);
ssize_t sis1100_read_dma(struct SIS1100_fdata* fd,
    size_t count, u_int8_t* data, int* prot_err);
ssize_t sis1100_write_dma(struct SIS1100_fdata* fd,
    size_t count, const u_int8_t* data, int* prot_err);
void sis1100_reset_plx(struct SIS1100_softc* sc);
int sis1100_remote_reg_read(struct SIS1100_softc* sc, u_int32_t offs,
    u_int32_t* data);
int sis1100_remote_reg_write(struct SIS1100_softc* sc, u_int32_t offs,
    u_int32_t data);
int sis1100_write_command(struct SIS1100_softc* sc,
    struct sis1100_command* data);
int sis1100_read_command(struct SIS1100_softc* sc,
    struct sis1100_command* data);
int send_message(struct SIS1100_softc* sc, int idx, u_int32_t data, int locked);
int wait_message(struct SIS1100_softc* sc, int idx, u_int32_t* data, int locked);

#endif
