/* $ZEL: sis1100_sc.h,v 1.6 2004/05/27 23:10:32 wuestner Exp $ */

/*
 * Copyright (c) 2001-2004
 * 	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 _sis1100_sc_h_
#define _sis1100_sc_h_

#ifdef __NetBSD__
#   include "dev/pci/compat_netbsd.h"
#elif __linux__
#   include "compat_linux.h"
#else
#   error INVALID or UNKNOWN SYSTEM
#endif


#include "plx9054reg.h"
#include "sis1100_map.h"
#include "sis3100_map.h"
#include "sis5100_map.h"
#include "f1_map.h"
#include "vertex_map.h"
#include "sis1100_var.h"

#ifndef PCI_VENDOR_FZJZEL
#   define PCI_VENDOR_FZJZEL 0x1796
#endif
#ifndef PCI_PRODUCT_FZJZEL_GIGALINK
#   define PCI_PRODUCT_FZJZEL_GIGALINK 0x0001
#endif

struct irq_vects {
    u_int32_t vector;
    int valid;
};

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};

enum handlercomm {
    handlercomm_doorbell=1,
    handlercomm_synch=2,
    handlercomm_lemo=4,
    handlercomm_mbx0=8,
    handlercomm_die=128,
};

#define SIS5100_CAMACaddr(N, A, F) \
        (((F)&0x1f)<<11 | ((N)&0x1f)<<6 | ((A)&0xf)<<2)

#ifdef __NetBSD__
#   include "dev/pci/sis1100_sc_netbsd.h"
#elif __linux__
#   include "sis1100_sc_linux.h"
#else
#   error INVALID or UNKNOWN SYSTEM
#endif

#define irq_pending(sc, fd, mask) \
    ((sc->pending_irqs & (fd->owned_irqs & mask)) || \
        (fd->old_remote_hw!=sc->remote_hw))

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

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

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

#define sis1100rawreadreg(sc, reg) \
 plxrawreadlocal0(sc, ofs(struct sis1100_reg, reg))
#define sis1100rawwritereg(sc, reg, val) \
 plxrawwritelocal0(sc, ofs(struct sis1100_reg, reg), val)

#define sis1100readremreg(sc, reg, val, locked) \
 sis1100_remote_reg_read(sc, ofs(struct sis1100_reg, reg), val, locked)
#define sis1100writeremreg(sc, reg, val, locked) \
 sis1100_remote_reg_write(sc, ofs(struct sis1100_reg, reg), val, locked)

#define sis3100readremreg(sc, reg, val, locked) \
 sis1100_remote_reg_read(sc, ofs(struct sis3100_reg, reg), val, locked)
#define sis3100writeremreg(sc, reg, val, locked) \
 sis1100_remote_reg_write(sc, ofs(struct sis3100_reg, reg), val, locked)

#define sis5100readremreg(sc, reg, val, locked) \
 sis1100_remote_reg_read(sc, ofs(struct sis5100_reg, reg), val, locked)
#define sis5100writeremreg(sc, reg, val, locked) \
 sis1100_remote_reg_write(sc, ofs(struct sis5100_reg, reg), val, locked)

#define f1_readremreg(sc, reg, val, locked) \
 sis1100_remote_reg_read(sc, ofs(struct f1_reg, reg), val, locked)
#define f1_writeremreg(sc, reg, val, locked) \
 sis1100_remote_reg_write(sc, ofs(struct f1_reg, reg), val, locked)

#define vertex_readremreg(sc, reg, val, locked) \
 sis1100_remote_reg_read(sc, ofs(struct vertex_reg, reg), val, locked)
#define vertex_writeremreg(sc, reg, val, locked) \
 sis1100_remote_reg_write(sc, ofs(struct vertex_reg, reg), val, locked)


int  sis1100_irq_handler(void* data);
void sis3100rem_irq_handler(struct sis1100_softc* sc);
void sis5100rem_irq_handler(struct sis1100_softc* sc);
void sis3100rem_enable_irqs(struct sis1100_softc*, struct sis1100_fdata*,
        u_int32_t mask);
void sis3100rem_disable_irqs(struct sis1100_softc*, struct sis1100_fdata*,
        u_int32_t mask);
void sis5100rem_enable_irqs(struct sis1100_softc*, struct sis1100_fdata*,
        u_int32_t mask);
void sis5100rem_disable_irqs(struct sis1100_softc*, struct sis1100_fdata*,
        u_int32_t mask);
void sis3100rem_irq_ack(struct sis1100_softc* sc, int irqs);
void sis5100rem_irq_ack(struct sis1100_softc* sc, int irqs);
void sis3100rem_get_vector(struct sis1100_softc* sc, int irqs,
        struct sis1100_irq_get* data);

int  sis1100_init(struct sis1100_softc* sc);

void sis1100_init_remote(struct sis1100_softc* sc);
int  sis1100rem_init(struct sis1100_softc* sc);
int  sis3100rem_init(struct sis1100_softc* sc);
int  sis5100rem_init(struct sis1100_softc* sc);
int  f1_rem_init(struct sis1100_softc* sc);
int  vertex_rem_init(struct sis1100_softc* sc);
int  sis1100_init_sdram(struct sis1100_softc* sc);

void sis1100_dump_glink_status(struct sis1100_softc* sc, char* text, int locked);
int sis1100_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_tmp_read(struct sis1100_softc *sc,
        u_int32_t addr, int32_t am, int size, int space, u_int32_t* data);
int sis1100_tmp_write(struct sis1100_softc *sc,
        u_int32_t addr, int32_t am, int size, int space, u_int32_t data);
int sis1100_tmp_camacread(struct sis1100_softc *sc,
        u_int32_t addr, u_int32_t* data);
int sis1100_tmp_camacwrite(struct sis1100_softc *sc,
        u_int32_t addr, u_int32_t data);
int sis1100_read_dma(struct sis1100_softc *sc, struct sis1100_fdata* fd,
        u_int32_t addr, int32_t am, int size, int space, int fifo,
        size_t count, size_t* count_read, u_int8_t* data, int* prot_err);
int _sis1100_read_dma(struct sis1100_softc *sc, struct sis1100_fdata* fd,
        u_int32_t addr, int32_t am, int size, int space, int fifo,
        size_t count, size_t* count_read, u_int8_t* data, int* prot_err, int* eot);
int sis1100_write_dma(struct sis1100_softc *sc, struct sis1100_fdata* fd,
        u_int32_t addr, int32_t am, int size, int space, int fifo,
        size_t count, size_t* count_written, const u_int8_t* data, int* prot_err);
int _sis1100_write_dma(struct sis1100_softc *sc, struct sis1100_fdata* fd,
        u_int32_t addr, int32_t am, int size, int space, int fifo,
        size_t count, size_t* count_written, const u_int8_t* data, int* prot_err);
int sis1100_read_loop(struct sis1100_softc *sc, struct sis1100_fdata* fd,
        u_int32_t addr, int32_t am, int size, int space, int fifo,
        size_t count, size_t* count_read, u_int8_t* data, int* prot_err);
int sis1100_write_loop(struct sis1100_softc *sc, struct sis1100_fdata* fd,
        u_int32_t addr, int32_t am, int size, int space, int fifo,
        size_t count, size_t* count_written, const u_int8_t* data, int* prot_err);
int  sis1100_read_pipe(struct sis1100_softc* sc, struct sis1100_pipe* control);
int  sis1100_write_pipe(struct sis1100_softc*, int32_t am, int space,
        int num, u_int32_t* data);
void sis1100_reset_plx(struct sis1100_softc* sc);
int  sis1100_reset(struct sis1100_softc* sc);

int  sis1100_read_block(struct sis1100_softc* sc, struct sis1100_fdata* fd,
        int size, int fifo, size_t num, size_t* num_read, int space,
        int32_t am, u_int32_t addr, u_int8_t* data, u_int32_t* error);
int  sis1100_write_block(struct sis1100_softc* sc, struct sis1100_fdata* fd,
        int size, int fifo, size_t num, size_t* num_written, int space,
        int32_t am, u_int32_t addr, const u_int8_t* data, u_int32_t* error);

int  sis1100_irq_ctl(struct sis1100_softc* sc, struct sis1100_fdata* fd,
        struct sis1100_irq_ctl* data);
int  sis1100_irq_get(struct sis1100_softc* sc, struct sis1100_fdata* fd,
        struct sis1100_irq_get* data);
int  sis1100_irq_ack(struct sis1100_softc* sc, struct sis1100_fdata* fd,
        struct sis1100_irq_ack* data);
int  sis1100_irq_wait(struct sis1100_softc* sc, struct sis1100_fdata* fd,
        struct sis1100_irq_get* data);
int  sis1100_remote_reg_read(struct sis1100_softc* sc, u_int32_t offs,
        u_int32_t* data, int locked);
int  sis1100_remote_reg_write(struct sis1100_softc* sc, u_int32_t offs,
        u_int32_t data, int locked);

int  sis1100_front_io(struct sis1100_softc* sc, u_int32_t* data, int locked);
int  sis1100_front_pulse(struct sis1100_softc* sc, u_int32_t* data, int locked);
int  sis1100_front_latch(struct sis1100_softc* sc, u_int32_t* data, int locked);
int  sis1100rem_front_io(struct sis1100_softc* sc, u_int32_t* data);
int  sis1100rem_front_pulse(struct sis1100_softc* sc, u_int32_t* data);
int  sis1100rem_front_latch(struct sis1100_softc* sc, u_int32_t* data);
int  sis3100rem_front_io(struct sis1100_softc* sc, u_int32_t* data);
int  sis3100rem_front_pulse(struct sis1100_softc* sc, u_int32_t* data);
int  sis3100rem_front_latch(struct sis1100_softc* sc, u_int32_t* data);
int  sis5100rem_front_io(struct sis1100_softc* sc, u_int32_t* data);
int  sis5100rem_front_pulse(struct sis1100_softc* sc, u_int32_t* data);
int  sis5100rem_front_latch(struct sis1100_softc* sc, u_int32_t* data);

void sis1100_synch_handler(struct sis1100_softc* sc);
void sis1100_lemo_handler(struct sis1100_softc* sc);
void sis1100_mbox0_handler(struct sis1100_softc* sc);

void sis1100_update_swapping(struct sis1100_softc* sc, const char* caller);
int sis3100_set_timeouts(struct sis1100_softc* sc, int berr, int arb);
int sis3100_get_timeouts(struct sis1100_softc* sc, int* berr, int* arb);

int sis1100_dma_alloc(struct sis1100_softc *sc, struct sis1100_fdata* fd,
    struct sis1100_dma_alloc* d);
int sis1100_dma_free(struct sis1100_softc *sc, struct sis1100_fdata* fd,
    struct sis1100_dma_alloc* d);

int sis1100_check_rw_access(struct sis1100_softc*,
    off_t, off_t, size_t, int, const char*, int);

int sis1100_dsp_reset(struct sis1100_softc* sc, struct sis1100_fdata* fd);
int sis1100_dsp_start(struct sis1100_softc* sc, struct sis1100_fdata* fd);
int sis1100_dsp_load(struct sis1100_softc* sc, struct sis1100_fdata* fd,
    struct sis1100_dsp_code* d);

int sis1100_read_eeprom(struct sis1100_softc* sc,
         u_int8_t num, u_int8_t addr, u_int16_t* data);
int sis1100_write_eeprom(struct sis1100_softc* sc,
         u_int8_t num, u_int8_t addr, u_int16_t* data);

#endif
