/* $Id: os_4bri.c,v 1.28.4.4 2005/02/11 19:40:25 armin Exp $ */

#include "platform.h"
#include "debuglib.h"
#include "cardtype.h"
#include "pc.h"
#include "pr_pc.h"
#include "di_defs.h"
#include "dsp_defs.h"
#include "di.h"
#include "io.h"

#include "xdi_msg.h"
#include "xdi_adapter.h"
#include "os_4bri.h"
#include "diva_pci.h"
#include "mi_pc.h"
#include "dsrv4bri.h"
#include "helpers.h"

static void *diva_xdiLoadFileFile = NULL;
static dword diva_xdiLoadFileLength = 0;

/*
**  IMPORTS
*/
extern void prepare_qBri_functions(PISDN_ADAPTER IoAdapter);
extern void prepare_qBri2_functions(PISDN_ADAPTER IoAdapter);
extern void diva_xdi_display_adapter_features(int card);
extern void diva_add_slave_adapter(diva_os_xdi_adapter_t * a);

extern int qBri_FPGA_download(PISDN_ADAPTER IoAdapter);
extern void start_qBri_hardware(PISDN_ADAPTER IoAdapter);

extern int diva_card_read_xlog(diva_os_xdi_adapter_t * a);

/*
**  LOCALS
*/
static unsigned long _4bri_bar_length[4] = {
	0x100,
	0x100,			/* I/O */
	MQ_MEMORY_SIZE,
	0x2000
};
static unsigned long _4bri_v2_bar_length[4] = {
	0x100,
	0x100,			/* I/O */
	MQ2_MEMORY_SIZE,
	0x10000
};
static unsigned long _4bri_v2_bri_bar_length[4] = {
	0x100,
	0x100,			/* I/O */
	BRI2_MEMORY_SIZE,
	0x10000
};


static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a);
static int _4bri_get_serial_number(diva_os_xdi_adapter_t * a);
static int diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
				   diva_xdi_um_cfg_cmd_t * cmd,
				   int length);
static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t * a);
static int diva_4bri_write_fpga_image(diva_os_xdi_adapter_t * a,
				      byte * data, dword length);
static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter);
static int diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
				       dword address,
				       const byte * data,
				       dword length, dword limit);
static int diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
				   dword start_address, dword features);
static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter);
static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a);

static int _4bri_is_rev_2_card(int card_ordinal)
{
	switch (card_ordinal) {
	case CARDTYPE_DIVASRV_Q_8M_V2_PCI:
	case CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI:
	case CARDTYPE_DIVASRV_B_2M_V2_PCI:
	case CARDTYPE_DIVASRV_B_2F_PCI:
	case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI:
		return (1);
	}
	return (0);
}

static int _4bri_is_rev_2_bri_card(int card_ordinal)
{
	switch (card_ordinal) {
	case CARDTYPE_DIVASRV_B_2M_V2_PCI:
	case CARDTYPE_DIVASRV_B_2F_PCI:
	case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI:
		return (1);
	}
	return (0);
}

static void diva_4bri_set_addresses(diva_os_xdi_adapter_t *a)
{
	dword offset = a->resources.pci.qoffset;
	dword c_offset = offset * a->xdi_adapter.ControllerNumber;

	a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 2;
	a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2;
	a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
	a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 0;
	a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 3;
	a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 0;

	/*
	   Set up hardware related pointers
	 */
	a->xdi_adapter.Address = a->resources.pci.addr[2];	/* BAR2 SDRAM  */
	a->xdi_adapter.Address += c_offset;

	a->xdi_adapter.Control = a->resources.pci.addr[2];	/* BAR2 SDRAM  */

	a->xdi_adapter.ram = a->resources.pci.addr[2];	/* BAR2 SDRAM  */
	a->xdi_adapter.ram += c_offset + (offset - MQ_SHARED_RAM_SIZE);
	
	a->xdi_adapter.reset = a->resources.pci.addr[0];	/* BAR0 CONFIG */
	/*
	   ctlReg contains the register address for the MIPS CPU reset control
	 */
	a->xdi_adapter.ctlReg = a->resources.pci.addr[3];	/* BAR3 CNTRL  */
	/*
	   prom contains the register address for FPGA and EEPROM programming
	 */
	a->xdi_adapter.prom = &a->xdi_adapter.reset[0x6E];
}

/*
**  BAR0 - MEM - 0x100    - CONFIG MEM
**  BAR1 - I/O - 0x100    - UNUSED
**  BAR2 - MEM - MQ_MEMORY_SIZE (MQ2_MEMORY_SIZE on Rev.2) - SDRAM
**  BAR3 - MEM - 0x2000 (0x10000 on Rev.2)   - CNTRL
**
**  Called by master adapter, that will initialize and add slave adapters
*/
int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
{
	int bar, i;
	byte __iomem *p;
	PADAPTER_LIST_ENTRY quadro_list;
	diva_os_xdi_adapter_t *diva_current;
	diva_os_xdi_adapter_t *adapter_list[4];
	PISDN_ADAPTER Slave;
	unsigned long bar_length[ARRAY_SIZE(_4bri_bar_length)];
	int v2 = _4bri_is_rev_2_card(a->CardOrdinal);
	int tasks = _4bri_is_rev_2_bri_card(a->CardOrdinal) ? 1 : MQ_INSTANCE_COUNT;
	int factor = (tasks == 1) ? 1 : 2;

	if (v2) {
		if (_4bri_is_rev_2_bri_card(a->CardOrdinal)) {
			memcpy(bar_length, _4bri_v2_bri_bar_length,
			       sizeof(bar_length));
		} else {
			memcpy(bar_length, _4bri_v2_bar_length,
			       sizeof(bar_length));
		}
	} else {
		memcpy(bar_length, _4bri_bar_length, sizeof(bar_length));
	}
	DBG_TRC(("SDRAM_LENGTH=%08x, tasks=%d, factor=%d",
		 bar_length[2], tasks, factor))

	/*
	   Get Serial Number
	   The serial number of 4BRI is accessible in accordance with PCI spec
	   via command register located in configuration space, also we do not
	   have to map any BAR before we can access it
	 */
	if (!_4bri_get_serial_number(a)) {
		DBG_ERR(("A: 4BRI can't get Serial Number"))
		diva_4bri_cleanup_adapter(a);
		return (-1);
	}

	/*
	   Set properties
	 */
	a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
	DBG_LOG(("Load %s, SN:%ld, bus:%02x, func:%02x",
		 a->xdi_adapter.Properties.Name,
		 a->xdi_adapter.serialNo,
		 a->resources.pci.bus, a->resources.pci.func))

	/*
	   First initialization step: get and check hardware resoures.
	   Do not map resources and do not access card at this step
	 */
	for (bar = 0; bar < 4; bar++) {
		a->resources.pci.bar[bar] =
		    divasa_get_pci_bar(a->resources.pci.bus,
				       a->resources.pci.func, bar,
				       a->resources.pci.hdev);
		if (!a->resources.pci.bar[bar]
		    || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) {
			DBG_ERR(
				("A: invalid bar[%d]=%08x", bar,
				 a->resources.pci.bar[bar]))
			return (-1);
		}
	}
	a->resources.pci.irq =
	    (byte) divasa_get_pci_irq(a->resources.pci.bus,
				      a->resources.pci.func,
				      a->resources.pci.hdev);
	if (!a->resources.pci.irq) {
		DBG_ERR(("A: invalid irq"));
		return (-1);
	}

	a->xdi_adapter.sdram_bar = a->resources.pci.bar[2];

	/*
	   Map all MEMORY BAR's
	 */
	for (bar = 0; bar < 4; bar++) {
		if (bar != 1) {	/* ignore I/O */
			a->resources.pci.addr[bar] =
			    divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
						 bar_length[bar]);
			if (!a->resources.pci.addr[bar]) {
				DBG_ERR(("A: 4BRI: can't map bar[%d]", bar))
				diva_4bri_cleanup_adapter(a);
				return (-1);
			}
		}
	}

	/*
	   Register I/O port
	 */
	sprintf(&a->port_name[0], "DIVA 4BRI %ld", (long) a->xdi_adapter.serialNo);

	if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
				     bar_length[1], &a->port_name[0], 1)) {
		DBG_ERR(("A: 4BRI: can't register bar[1]"))
		diva_4bri_cleanup_adapter(a);
		return (-1);
	}

	a->resources.pci.addr[1] =
		(void *) (unsigned long) a->resources.pci.bar[1];

	/*
	   Set cleanup pointer for base adapter only, so slave adapter
	   will be unable to get cleanup
	 */
	a->interface.cleanup_adapter_proc = diva_4bri_cleanup_adapter;

	/*
	   Create slave adapters
	 */
	if (tasks > 1) {
		if (!(a->slave_adapters[0] =
		     (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
		{
			diva_4bri_cleanup_adapter(a);
			return (-1);
		}
		if (!(a->slave_adapters[1] =
		     (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
		{
			diva_os_free(0, a->slave_adapters[0]);
			a->slave_adapters[0] = NULL;
			diva_4bri_cleanup_adapter(a);
			return (-1);
		}
		if (!(a->slave_adapters[2] =
		     (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
		{
			diva_os_free(0, a->slave_adapters[0]);
			diva_os_free(0, a->slave_adapters[1]);
			a->slave_adapters[0] = NULL;
			a->slave_adapters[1] = NULL;
			diva_4bri_cleanup_adapter(a);
			return (-1);
		}
		memset(a->slave_adapters[0], 0x00, sizeof(*a));
		memset(a->slave_adapters[1], 0x00, sizeof(*a));
		memset(a->slave_adapters[2], 0x00, sizeof(*a));
	}

	adapter_list[0] = a;
	adapter_list[1] = a->slave_adapters[0];
	adapter_list[2] = a->slave_adapters[1];
	adapter_list[3] = a->slave_adapters[2];

	/*
	   Allocate slave list
	 */
	quadro_list =
	    (PADAPTER_LIST_ENTRY) diva_os_malloc(0, sizeof(*quadro_list));
	if (!(a->slave_list = quadro_list)) {
		for (i = 0; i < (tasks - 1); i++) {
			diva_os_free(0, a->slave_adapters[i]);
			a->slave_adapters[i] = NULL;
		}
		diva_4bri_cleanup_adapter(a);
		return (-1);
	}
	memset(quadro_list, 0x00, sizeof(*quadro_list));

	/*
	   Set interfaces
	 */
	a->xdi_adapter.QuadroList = quadro_list;
	for (i = 0; i < tasks; i++) {
		adapter_list[i]->xdi_adapter.ControllerNumber = i;
		adapter_list[i]->xdi_adapter.tasks = tasks;
		quadro_list->QuadroAdapter[i] =
		    &adapter_list[i]->xdi_adapter;
	}

	for (i = 0; i < tasks; i++) {
		diva_current = adapter_list[i];

		diva_current->dsp_mask = 0x00000003;

		diva_current->xdi_adapter.a.io =
		    &diva_current->xdi_adapter;
		diva_current->xdi_adapter.DIRequest = request;
		diva_current->interface.cmd_proc = diva_4bri_cmd_card_proc;
		diva_current->xdi_adapter.Properties =
		    CardProperties[a->CardOrdinal];
		diva_current->CardOrdinal = a->CardOrdinal;

		diva_current->xdi_adapter.Channels =
		    CardProperties[a->CardOrdinal].Channels;
		diva_current->xdi_adapter.e_max =
		    CardProperties[a->CardOrdinal].E_info;
		diva_current->xdi_adapter.e_tbl =
		    diva_os_malloc(0,
				   diva_current->xdi_adapter.e_max *
				   sizeof(E_INFO));

		if (!diva_current->xdi_adapter.e_tbl) {
			diva_4bri_cleanup_slave_adapters(a);
			diva_4bri_cleanup_adapter(a);
			for (i = 1; i < (tasks - 1); i++) {
				diva_os_free(0, adapter_list[i]);
			}
			return (-1);
		}
		memset(diva_current->xdi_adapter.e_tbl, 0x00,
		       diva_current->xdi_adapter.e_max * sizeof(E_INFO));

		if (diva_os_initialize_spin_lock(&diva_current->xdi_adapter.isr_spin_lock, "isr")) {
			diva_4bri_cleanup_slave_adapters(a);
			diva_4bri_cleanup_adapter(a);
			for (i = 1; i < (tasks - 1); i++) {
				diva_os_free(0, adapter_list[i]);
			}
			return (-1);
		}
		if (diva_os_initialize_spin_lock(&diva_current->xdi_adapter.data_spin_lock, "data")) {
			diva_4bri_cleanup_slave_adapters(a);
			diva_4bri_cleanup_adapter(a);
			for (i = 1; i < (tasks - 1); i++) {
				diva_os_free(0, adapter_list[i]);
			}
			return (-1);
		}

		strcpy(diva_current->xdi_adapter.req_soft_isr. dpc_thread_name, "kdivas4brid");

		if (diva_os_initialize_soft_isr (&diva_current->xdi_adapter.req_soft_isr, DIDpcRoutine,
		     &diva_current->xdi_adapter)) {
			diva_4bri_cleanup_slave_adapters(a);
			diva_4bri_cleanup_adapter(a);
			for (i = 1; i < (tasks - 1); i++) {
				diva_os_free(0, adapter_list[i]);
			}
			return (-1);
		}

		/*
		   Do not initialize second DPC - only one thread will be created
		 */
		diva_current->xdi_adapter.isr_soft_isr.object =
		    diva_current->xdi_adapter.req_soft_isr.object;
	}

	if (v2) {
		prepare_qBri2_functions(&a->xdi_adapter);
	} else {
		prepare_qBri_functions(&a->xdi_adapter);
	}

	for (i = 0; i < tasks; i++) {
		diva_current = adapter_list[i];
		if (i)
			memcpy(&diva_current->resources, &a->resources, sizeof(divas_card_resources_t));
		diva_current->resources.pci.qoffset = (a->xdi_adapter.MemorySize >> factor); 
	}

	/*
	   Set up hardware related pointers
	 */
	a->xdi_adapter.cfg = (void *) (unsigned long) a->resources.pci.bar[0];	/* BAR0 CONFIG */
	a->xdi_adapter.port = (void *) (unsigned long) a->resources.pci.bar[1];	/* BAR1        */
	a->xdi_adapter.ctlReg = (void *) (unsigned long) a->resources.pci.bar[3];	/* BAR3 CNTRL  */

	for (i = 0; i < tasks; i++) {
		diva_current = adapter_list[i];
		diva_4bri_set_addresses(diva_current);
		Slave = a->xdi_adapter.QuadroList->QuadroAdapter[i];
		Slave->MultiMaster = &a->xdi_adapter;
		Slave->sdram_bar = a->xdi_adapter.sdram_bar;
		if (i) {
			Slave->serialNo = ((dword) (Slave->ControllerNumber << 24)) |
					a->xdi_adapter.serialNo;
			Slave->cardType = a->xdi_adapter.cardType;
		}
	}

	/*
	   reset contains the base address for the PLX 9054 register set
	 */
	p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
	WRITE_BYTE(&p[PLX9054_INTCSR], 0x00);	/* disable PCI interrupts */
	DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);

	/*
	   Set IRQ handler
	 */
	a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
	sprintf(a->xdi_adapter.irq_info.irq_name, "DIVA 4BRI %ld",
		(long) a->xdi_adapter.serialNo);

	if (diva_os_register_irq(a, a->xdi_adapter.irq_info.irq_nr,
				 a->xdi_adapter.irq_info.irq_name)) {
		diva_4bri_cleanup_slave_adapters(a);
		diva_4bri_cleanup_adapter(a);
		for (i = 1; i < (tasks - 1); i++) {
			diva_os_free(0, adapter_list[i]);
		}
		return (-1);
	}

	a->xdi_adapter.irq_info.registered = 1;

	/*
	   Add three slave adapters
	 */
	if (tasks > 1) {
		diva_add_slave_adapter(adapter_list[1]);
		diva_add_slave_adapter(adapter_list[2]);
		diva_add_slave_adapter(adapter_list[3]);
	}

	diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name,
		      a->resources.pci.irq, a->xdi_adapter.serialNo);

	return (0);
}

/*
**  Cleanup function will be called for master adapter only
**  this is guaranteed by design: cleanup callback is set
**  by master adapter only
*/
static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a)
{
	int bar;

	/*
	   Stop adapter if running
	 */
	if (a->xdi_adapter.Initialized) {
		diva_4bri_stop_adapter(a);
	}

	/*
	   Remove IRQ handler
	 */
	if (a->xdi_adapter.irq_info.registered) {
		diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
	}
	a->xdi_adapter.irq_info.registered = 0;

	/*
	   Free DPC's and spin locks on all adapters
	 */
	diva_4bri_cleanup_slave_adapters(a);

	/*
	   Unmap all BARS
	 */
	for (bar = 0; bar < 4; bar++) {
		if (bar != 1) {
			if (a->resources.pci.bar[bar]
			    && a->resources.pci.addr[bar]) {
				divasa_unmap_pci_bar(a->resources.pci.addr[bar]);
				a->resources.pci.bar[bar] = 0;
				a->resources.pci.addr[bar] = NULL;
			}
		}
	}

	/*
	   Unregister I/O
	 */
	if (a->resources.pci.bar[1] && a->resources.pci.addr[1]) {
		diva_os_register_io_port(a, 0, a->resources.pci.bar[1],
					 _4bri_is_rev_2_card(a->
							     CardOrdinal) ?
					 _4bri_v2_bar_length[1] :
					 _4bri_bar_length[1],
					 &a->port_name[0], 1);
		a->resources.pci.bar[1] = 0;
		a->resources.pci.addr[1] = NULL;
	}

	if (a->slave_list) {
		diva_os_free(0, a->slave_list);
		a->slave_list = NULL;
	}

	return (0);
}

static int _4bri_get_serial_number(diva_os_xdi_adapter_t * a)
{
	dword data[64];
	dword serNo;
	word addr, status, i, j;
	byte Bus, Slot;
	void *hdev;

	Bus = a->resources.pci.bus;
	Slot = a->resources.pci.func;
	hdev = a->resources.pci.hdev;

	for (i = 0; i < 64; ++i) {
		addr = i * 4;
		for (j = 0; j < 5; ++j) {
			PCIwrite(Bus, Slot, 0x4E, &addr, sizeof(addr),
				 hdev);
			diva_os_wait(1);
			PCIread(Bus, Slot, 0x4E, &status, sizeof(status),
				hdev);
			if (status & 0x8000)
				break;
		}
		if (j >= 5) {
			DBG_ERR(("EEPROM[%d] read failed (0x%x)", i * 4, addr))
			return (0);
		}
		PCIread(Bus, Slot, 0x50, &data[i], sizeof(data[i]), hdev);
	}
	DBG_BLK(((char *) &data[0], sizeof(data)))

	serNo = data[32];
	if (serNo == 0 || serNo == 0xffffffff)
		serNo = data[63];

	if (!serNo) {
		DBG_LOG(("W: Serial Number == 0, create one serial number"));
		serNo = a->resources.pci.bar[1] & 0xffff0000;
		serNo |= a->resources.pci.bus << 8;
		serNo |= a->resources.pci.func;
	}

	a->xdi_adapter.serialNo = serNo;

	DBG_REG(("Serial No.          : %ld", a->xdi_adapter.serialNo))

	return (serNo);
}

/*
**  Release resources of slave adapters
*/
static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t * a)
{
	diva_os_xdi_adapter_t *adapter_list[4];
	diva_os_xdi_adapter_t *diva_current;
	int i;

	adapter_list[0] = a;
	adapter_list[1] = a->slave_adapters[0];
	adapter_list[2] = a->slave_adapters[1];
	adapter_list[3] = a->slave_adapters[2];

	for (i = 0; i < a->xdi_adapter.tasks; i++) {
		diva_current = adapter_list[i];
		if (diva_current) {
			diva_os_destroy_spin_lock(&diva_current->
						  xdi_adapter.
						  isr_spin_lock, "unload");
			diva_os_destroy_spin_lock(&diva_current->
						  xdi_adapter.
						  data_spin_lock,
						  "unload");

			diva_os_cancel_soft_isr(&diva_current->xdi_adapter.
						req_soft_isr);
			diva_os_cancel_soft_isr(&diva_current->xdi_adapter.
						isr_soft_isr);

			diva_os_remove_soft_isr(&diva_current->xdi_adapter.
						req_soft_isr);
			diva_current->xdi_adapter.isr_soft_isr.object = NULL;

			if (diva_current->xdi_adapter.e_tbl) {
				diva_os_free(0,
					     diva_current->xdi_adapter.
					     e_tbl);
			}
			diva_current->xdi_adapter.e_tbl = NULL;
			diva_current->xdi_adapter.e_max = 0;
			diva_current->xdi_adapter.e_count = 0;
		}
	}

	return (0);
}

static int
diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
			diva_xdi_um_cfg_cmd_t * cmd, int length)
{
	int ret = -1;

	if (cmd->adapter != a->controller) {
		DBG_ERR(("A: 4bri_cmd, invalid controller=%d != %d",
			 cmd->adapter, a->controller))
		return (-1);
	}

	switch (cmd->command) {
	case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
		a->xdi_mbox.data_length = sizeof(dword);
		a->xdi_mbox.data =
		    diva_os_malloc(0, a->xdi_mbox.data_length);
		if (a->xdi_mbox.data) {
			*(dword *) a->xdi_mbox.data =
			    (dword) a->CardOrdinal;
			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
			ret = 0;
		}
		break;

	case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
		a->xdi_mbox.data_length = sizeof(dword);
		a->xdi_mbox.data =
		    diva_os_malloc(0, a->xdi_mbox.data_length);
		if (a->xdi_mbox.data) {
			*(dword *) a->xdi_mbox.data =
			    (dword) a->xdi_adapter.serialNo;
			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
			ret = 0;
		}
		break;

	case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
		if (!a->xdi_adapter.ControllerNumber) {
			/*
			   Only master adapter can access hardware config
			 */
			a->xdi_mbox.data_length = sizeof(dword) * 9;
			a->xdi_mbox.data =
			    diva_os_malloc(0, a->xdi_mbox.data_length);
			if (a->xdi_mbox.data) {
				int i;
				dword *data = (dword *) a->xdi_mbox.data;

				for (i = 0; i < 8; i++) {
					*data++ = a->resources.pci.bar[i];
				}
				*data++ = (dword) a->resources.pci.irq;
				a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
				ret = 0;
			}
		}
		break;

	case DIVA_XDI_UM_CMD_GET_CARD_STATE:
		if (!a->xdi_adapter.ControllerNumber) {
			a->xdi_mbox.data_length = sizeof(dword);
			a->xdi_mbox.data =
			    diva_os_malloc(0, a->xdi_mbox.data_length);
			if (a->xdi_mbox.data) {
				dword *data = (dword *) a->xdi_mbox.data;
				if (!a->xdi_adapter.ram
				    || !a->xdi_adapter.reset
				    || !a->xdi_adapter.cfg) {
					*data = 3;
				} else if (a->xdi_adapter.trapped) {
					*data = 2;
				} else if (a->xdi_adapter.Initialized) {
					*data = 1;
				} else {
					*data = 0;
				}
				a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
				ret = 0;
			}
		}
		break;

	case DIVA_XDI_UM_CMD_WRITE_FPGA:
		if (!a->xdi_adapter.ControllerNumber) {
			ret =
			    diva_4bri_write_fpga_image(a,
						       (byte *) & cmd[1],
						       cmd->command_data.
						       write_fpga.
						       image_length);
		}
		break;

	case DIVA_XDI_UM_CMD_RESET_ADAPTER:
		if (!a->xdi_adapter.ControllerNumber) {
			ret = diva_4bri_reset_adapter(&a->xdi_adapter);
		}
		break;

	case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
		if (!a->xdi_adapter.ControllerNumber) {
			ret = diva_4bri_write_sdram_block(&a->xdi_adapter,
							  cmd->
							  command_data.
							  write_sdram.
							  offset,
							  (byte *) &
							  cmd[1],
							  cmd->
							  command_data.
							  write_sdram.
							  length,
							  a->xdi_adapter.
							  MemorySize);
		}
		break;

	case DIVA_XDI_UM_CMD_START_ADAPTER:
		if (!a->xdi_adapter.ControllerNumber) {
			ret = diva_4bri_start_adapter(&a->xdi_adapter,
						      cmd->command_data.
						      start.offset,
						      cmd->command_data.
						      start.features);
		}
		break;

	case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
		if (!a->xdi_adapter.ControllerNumber) {
			a->xdi_adapter.features =
			    cmd->command_data.features.features;
			a->xdi_adapter.a.protocol_capabilities =
			    a->xdi_adapter.features;
			DBG_TRC(("Set raw protocol features (%08x)",
				 a->xdi_adapter.features))
			ret = 0;
		}
		break;

	case DIVA_XDI_UM_CMD_STOP_ADAPTER:
		if (!a->xdi_adapter.ControllerNumber) {
			ret = diva_4bri_stop_adapter(a);
		}
		break;

	case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY:
		ret = diva_card_read_xlog(a);
		break;

	case DIVA_XDI_UM_CMD_READ_SDRAM:
		if (!a->xdi_adapter.ControllerNumber
		    && a->xdi_adapter.Address) {
			if (
			    (a->xdi_mbox.data_length =
			     cmd->command_data.read_sdram.length)) {
				if (
				    (a->xdi_mbox.data_length +
				     cmd->command_data.read_sdram.offset) <
				    a->xdi_adapter.MemorySize) {
					a->xdi_mbox.data =
					    diva_os_malloc(0,
							   a->xdi_mbox.
							   data_length);
					if (a->xdi_mbox.data) {
						byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
						byte __iomem *src = p;
						byte *dst = a->xdi_mbox.data;
						dword len = a->xdi_mbox.data_length;

						src += cmd->command_data.read_sdram.offset;

						while (len--) {
							*dst++ = READ_BYTE(src++);
						}
						DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
						a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
						ret = 0;
					}
				}
			}
		}
		break;

	default:
		DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller,
			 cmd->command))
	}

	return (ret);
}

void *xdiLoadFile(char *FileName, dword *FileLength,
		  unsigned long lim)
{
	void *ret = diva_xdiLoadFileFile;

	if (FileLength) {
		*FileLength = diva_xdiLoadFileLength;
	}
	diva_xdiLoadFileFile = NULL;
	diva_xdiLoadFileLength = 0;

	return (ret);
}

void diva_os_set_qBri_functions(PISDN_ADAPTER IoAdapter)
{
}

void diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter)
{
}

static int
diva_4bri_write_fpga_image(diva_os_xdi_adapter_t * a, byte * data,
			   dword length)
{
	int ret;

	diva_xdiLoadFileFile = data;
	diva_xdiLoadFileLength = length;

	ret = qBri_FPGA_download(&a->xdi_adapter);

	diva_xdiLoadFileFile = NULL;
	diva_xdiLoadFileLength = 0;

	return (ret ? 0 : -1);
}

static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter)
{
	PISDN_ADAPTER Slave;
	int i;

	if (!IoAdapter->Address || !IoAdapter->reset) {
		return (-1);
	}
	if (IoAdapter->Initialized) {
		DBG_ERR(("A: A(%d) can't reset 4BRI adapter - please stop first",
			 IoAdapter->ANum))
		return (-1);
	}

	/*
	   Forget all entities on all adapters
	 */
	for (i = 0; ((i < IoAdapter->tasks) && IoAdapter->QuadroList); i++) {
		Slave = IoAdapter->QuadroList->QuadroAdapter[i];
		Slave->e_count = 0;
		if (Slave->e_tbl) {
			memset(Slave->e_tbl, 0x00,
			       Slave->e_max * sizeof(E_INFO));
		}
		Slave->head = 0;
		Slave->tail = 0;
		Slave->assign = 0;
		Slave->trapped = 0;

		memset(&Slave->a.IdTable[0], 0x00,
		       sizeof(Slave->a.IdTable));
		memset(&Slave->a.IdTypeTable[0], 0x00,
		       sizeof(Slave->a.IdTypeTable));
		memset(&Slave->a.FlowControlIdTable[0], 0x00,
		       sizeof(Slave->a.FlowControlIdTable));
		memset(&Slave->a.FlowControlSkipTable[0], 0x00,
		       sizeof(Slave->a.FlowControlSkipTable));
		memset(&Slave->a.misc_flags_table[0], 0x00,
		       sizeof(Slave->a.misc_flags_table));
		memset(&Slave->a.rx_stream[0], 0x00,
		       sizeof(Slave->a.rx_stream));
		memset(&Slave->a.tx_stream[0], 0x00,
		       sizeof(Slave->a.tx_stream));
		memset(&Slave->a.tx_pos[0], 0x00, sizeof(Slave->a.tx_pos));
		memset(&Slave->a.rx_pos[0], 0x00, sizeof(Slave->a.rx_pos));
	}

	return (0);
}


static int
diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
			    dword address,
			    const byte * data, dword length, dword limit)
{
	byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
	byte __iomem *mem = p;

	if (((address + length) >= limit) || !mem) {
		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
		DBG_ERR(("A: A(%d) write 4BRI address=0x%08lx",
			 IoAdapter->ANum, address + length))
		return (-1);
	}
	mem += address;

	while (length--) {
		WRITE_BYTE(mem++, *data++);
	}

	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
	return (0);
}

static int
diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
			dword start_address, dword features)
{
	volatile word __iomem *signature;
	int started = 0;
	int i;
	byte __iomem *p;

	/*
	   start adapter
	 */
	start_qBri_hardware(IoAdapter);

	p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
	/*
	   wait for signature in shared memory (max. 3 seconds)
	 */
	signature = (volatile word __iomem *) (&p[0x1E]);

	for (i = 0; i < 300; ++i) {
		diva_os_wait(10);
		if (READ_WORD(&signature[0]) == 0x4447) {
			DBG_TRC(("Protocol startup time %d.%02d seconds",
				 (i / 100), (i % 100)))
			started = 1;
			break;
		}
	}

	for (i = 1; i < IoAdapter->tasks; i++) {
		IoAdapter->QuadroList->QuadroAdapter[i]->features =
		    IoAdapter->features;
		IoAdapter->QuadroList->QuadroAdapter[i]->a.
		    protocol_capabilities = IoAdapter->features;
	}

	if (!started) {
		DBG_FTL(("%s: Adapter selftest failed, signature=%04x",
			 IoAdapter->Properties.Name,
			 READ_WORD(&signature[0])))
		DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
		(*(IoAdapter->trapFnc)) (IoAdapter);
		IoAdapter->stop(IoAdapter);
		return (-1);
	}
	DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);

	for (i = 0; i < IoAdapter->tasks; i++) {
		IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 1;
		IoAdapter->QuadroList->QuadroAdapter[i]->IrqCount = 0;
	}

	if (check_qBri_interrupt(IoAdapter)) {
		DBG_ERR(("A: A(%d) interrupt test failed",
			 IoAdapter->ANum))
		for (i = 0; i < IoAdapter->tasks; i++) {
			IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0;
		}
		IoAdapter->stop(IoAdapter);
		return (-1);
	}

	IoAdapter->Properties.Features = (word) features;
	diva_xdi_display_adapter_features(IoAdapter->ANum);

	for (i = 0; i < IoAdapter->tasks; i++) {
		DBG_LOG(("A(%d) %s adapter successfully started",
			 IoAdapter->QuadroList->QuadroAdapter[i]->ANum,
			 (IoAdapter->tasks == 1) ? "BRI 2.0" : "4BRI"))
		diva_xdi_didd_register_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum);
		IoAdapter->QuadroList->QuadroAdapter[i]->Properties.Features = (word) features;
	}

	return (0);
}

static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter)
{
#ifdef	SUPPORT_INTERRUPT_TEST_ON_4BRI
	int i;
	ADAPTER *a = &IoAdapter->a;
	byte __iomem *p;

	IoAdapter->IrqCount = 0;

	if (IoAdapter->ControllerNumber > 0)
		return (-1);

	p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
	WRITE_BYTE(&p[PLX9054_INTCSR], PLX9054_INT_ENABLE);
	DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
	/*
	   interrupt test
	 */
	a->ReadyInt = 1;
	a->ram_out(a, &PR_RAM->ReadyInt, 1);

	for (i = 100; !IoAdapter->IrqCount && (i-- > 0); diva_os_wait(10));

	return ((IoAdapter->IrqCount > 0) ? 0 : -1);
#else
	dword volatile __iomem *qBriIrq;
	byte __iomem *p;
	/*
	   Reset on-board interrupt register
	 */
	IoAdapter->IrqCount = 0;
	p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
	qBriIrq = (dword volatile __iomem *) (&p[_4bri_is_rev_2_card
				       (IoAdapter->
					cardType) ? (MQ2_BREG_IRQ_TEST)
				       : (MQ_BREG_IRQ_TEST)]);

	WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF);
	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);

	p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
	WRITE_BYTE(&p[PLX9054_INTCSR], PLX9054_INT_ENABLE);
	DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);

	diva_os_wait(100);

	return (0);
#endif				/* SUPPORT_INTERRUPT_TEST_ON_4BRI */
}

static void diva_4bri_clear_interrupts(diva_os_xdi_adapter_t * a)
{
	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;

	/*
	   clear any pending interrupt
	 */
	IoAdapter->disIrq(IoAdapter);

	IoAdapter->tst_irq(&IoAdapter->a);
	IoAdapter->clr_irq(&IoAdapter->a);
	IoAdapter->tst_irq(&IoAdapter->a);

	/*
	   kill pending dpcs
	 */
	diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
	diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
}

static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a)
{
	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
	int i;

	if (!IoAdapter->ram) {
		return (-1);
	}

	if (!IoAdapter->Initialized) {
		DBG_ERR(("A: A(%d) can't stop PRI adapter - not running",
			 IoAdapter->ANum))
		return (-1);	/* nothing to stop */
	}

	for (i = 0; i < IoAdapter->tasks; i++) {
		IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0;
	}

	/*
	   Disconnect Adapters from DIDD
	 */
	for (i = 0; i < IoAdapter->tasks; i++) {
		diva_xdi_didd_remove_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum);
	}

	i = 100;

	/*
	   Stop interrupts
	 */
	a->clear_interrupts_proc = diva_4bri_clear_interrupts;
	IoAdapter->a.ReadyInt = 1;
	IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
	do {
		diva_os_sleep(10);
	} while (i-- && a->clear_interrupts_proc);

	if (a->clear_interrupts_proc) {
		diva_4bri_clear_interrupts(a);
		a->clear_interrupts_proc = NULL;
		DBG_ERR(("A: A(%d) no final interrupt from 4BRI adapter",
			 IoAdapter->ANum))
	}
	IoAdapter->a.ReadyInt = 0;

	/*
	   Stop and reset adapter
	 */
	IoAdapter->stop(IoAdapter);

	return (0);
}
