// SPDX-License-Identifier: GPL-2.0
/* $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);
}
