// SPDX-License-Identifier: GPL-2.0
/* $Id: os_pri.c,v 1.32 2004/03/21 17:26:01 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_pri.h"
#include "diva_pci.h"
#include "mi_pc.h"
#include "pc_maint.h"
#include "dsp_tst.h"
#include "diva_dma.h"
#include "dsrv_pri.h"

/* --------------------------------------------------------------------------
   OS Dependent part of XDI driver for DIVA PRI Adapter

   DSP detection/validation by Anthony Booth (Eicon Networks, www.eicon.com)
   -------------------------------------------------------------------------- */

#define DIVA_PRI_NO_PCI_BIOS_WORKAROUND 1

extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);

/*
**  IMPORTS
*/
extern void prepare_pri_functions(PISDN_ADAPTER IoAdapter);
extern void prepare_pri2_functions(PISDN_ADAPTER IoAdapter);
extern void diva_xdi_display_adapter_features(int card);

static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a);
static int diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
				  diva_xdi_um_cfg_cmd_t *cmd, int length);
static int pri_get_serial_number(diva_os_xdi_adapter_t *a);
static int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a);
static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a);

/*
**  Check card revision
*/
static int pri_is_rev_2_card(int card_ordinal)
{
	switch (card_ordinal) {
	case CARDTYPE_DIVASRV_P_30M_V2_PCI:
	case CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI:
		return (1);
	}
	return (0);
}

static void diva_pri_set_addresses(diva_os_xdi_adapter_t *a)
{
	a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 0;
	a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
	a->resources.pci.mem_type_id[MEM_TYPE_CONFIG] = 4;
	a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
	a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 2;
	a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 4;
	a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 3;

	a->xdi_adapter.Address = a->resources.pci.addr[0];
	a->xdi_adapter.Control = a->resources.pci.addr[2];
	a->xdi_adapter.Config = a->resources.pci.addr[4];

	a->xdi_adapter.ram = a->resources.pci.addr[0];
	a->xdi_adapter.ram += MP_SHARED_RAM_OFFSET;

	a->xdi_adapter.reset = a->resources.pci.addr[2];
	a->xdi_adapter.reset += MP_RESET;

	a->xdi_adapter.cfg = a->resources.pci.addr[4];
	a->xdi_adapter.cfg += MP_IRQ_RESET;

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

	a->xdi_adapter.prom = a->resources.pci.addr[3];
}

/*
**  BAR0 - SDRAM, MP_MEMORY_SIZE, MP2_MEMORY_SIZE by Rev.2
**  BAR1 - DEVICES,				0x1000
**  BAR2 - CONTROL (REG), 0x2000
**  BAR3 - FLASH (REG),		0x8000
**  BAR4 - CONFIG (CFG),	0x1000
*/
int diva_pri_init_card(diva_os_xdi_adapter_t *a)
{
	int bar = 0;
	int pri_rev_2;
	unsigned long bar_length[5] = {
		MP_MEMORY_SIZE,
		0x1000,
		0x2000,
		0x8000,
		0x1000
	};

	pri_rev_2 = pri_is_rev_2_card(a->CardOrdinal);

	if (pri_rev_2) {
		bar_length[0] = MP2_MEMORY_SIZE;
	}
	/*
	  Set properties
	*/
	a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
	DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name))

		/*
		  First initialization step: get and check hardware resoures.
		  Do not map resources and do not acecess card at this step
		*/
		for (bar = 0; bar < 5; 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);
	}

	/*
	  Map all BAR's
	*/
	for (bar = 0; bar < 5; bar++) {
		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: A(%d), can't map bar[%d]",
				 a->controller, bar))
				diva_pri_cleanup_adapter(a);
			return (-1);
		}
	}

	/*
	  Set all memory areas
	*/
	diva_pri_set_addresses(a);

	/*
	  Get Serial Number of this adapter
	*/
	if (pri_get_serial_number(a)) {
		dword serNo;
		serNo = a->resources.pci.bar[1] & 0xffff0000;
		serNo |= ((dword) a->resources.pci.bus) << 8;
		serNo += (a->resources.pci.func + a->controller + 1);
		a->xdi_adapter.serialNo = serNo & ~0xFF000000;
		DBG_ERR(("A: A(%d) can't get Serial Number, generated serNo=%ld",
			 a->controller, a->xdi_adapter.serialNo))
			}


	/*
	  Initialize os objects
	*/
	if (diva_os_initialize_spin_lock(&a->xdi_adapter.isr_spin_lock, "isr")) {
		diva_pri_cleanup_adapter(a);
		return (-1);
	}
	if (diva_os_initialize_spin_lock
	    (&a->xdi_adapter.data_spin_lock, "data")) {
		diva_pri_cleanup_adapter(a);
		return (-1);
	}

	strcpy(a->xdi_adapter.req_soft_isr.dpc_thread_name, "kdivasprid");

	if (diva_os_initialize_soft_isr(&a->xdi_adapter.req_soft_isr,
					DIDpcRoutine, &a->xdi_adapter)) {
		diva_pri_cleanup_adapter(a);
		return (-1);
	}

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

	/*
	  Next step of card initialization:
	  set up all interface pointers
	*/
	a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels;
	a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info;

	a->xdi_adapter.e_tbl =
		diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO));
	if (!a->xdi_adapter.e_tbl) {
		diva_pri_cleanup_adapter(a);
		return (-1);
	}
	memset(a->xdi_adapter.e_tbl, 0x00, a->xdi_adapter.e_max * sizeof(E_INFO));

	a->xdi_adapter.a.io = &a->xdi_adapter;
	a->xdi_adapter.DIRequest = request;
	a->interface.cleanup_adapter_proc = diva_pri_cleanup_adapter;
	a->interface.cmd_proc = diva_pri_cmd_card_proc;

	if (pri_rev_2) {
		prepare_pri2_functions(&a->xdi_adapter);
	} else {
		prepare_pri_functions(&a->xdi_adapter);
	}

	a->dsp_mask = diva_pri_detect_dsps(a);

	/*
	  Allocate DMA map
	*/
	if (pri_rev_2) {
		diva_init_dma_map(a->resources.pci.hdev,
				  (struct _diva_dma_map_entry **) &a->xdi_adapter.dma_map, 32);
	}

	/*
	  Set IRQ handler
	*/
	a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
	sprintf(a->xdi_adapter.irq_info.irq_name,
		"DIVA PRI %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_pri_cleanup_adapter(a);
		return (-1);
	}
	a->xdi_adapter.irq_info.registered = 1;

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

	return (0);
}

static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a)
{
	int bar = 0;

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

	/*
	  Remove ISR 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;

	/*
	  Step 1: unmap all BAR's, if any was mapped
	*/
	for (bar = 0; bar < 5; bar++) {
		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;
		}
	}

	/*
	  Free OS objects
	*/
	diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr);
	diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr);

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

	diva_os_destroy_spin_lock(&a->xdi_adapter.isr_spin_lock, "rm");
	diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm");

	/*
	  Free memory accupied by XDI adapter
	*/
	if (a->xdi_adapter.e_tbl) {
		diva_os_free(0, a->xdi_adapter.e_tbl);
		a->xdi_adapter.e_tbl = NULL;
	}
	a->xdi_adapter.Channels = 0;
	a->xdi_adapter.e_max = 0;


	/*
	  Free adapter DMA map
	*/
	diva_free_dma_map(a->resources.pci.hdev,
			  (struct _diva_dma_map_entry *) a->xdi_adapter.
			  dma_map);
	a->xdi_adapter.dma_map = NULL;


	/*
	  Detach this adapter from debug driver
	*/

	return (0);
}

/*
**  Activate On Board Boot Loader
*/
static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)
{
	dword i;
	struct mp_load __iomem *boot;

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

	boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
	WRITE_DWORD(&boot->err, 0);
	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);

	IoAdapter->rstFnc(IoAdapter);

	diva_os_wait(10);

	boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
	i = READ_DWORD(&boot->live);

	diva_os_wait(10);
	if (i == READ_DWORD(&boot->live)) {
		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
		DBG_ERR(("A: A(%d) CPU on PRI %ld is not alive!",
			 IoAdapter->ANum, IoAdapter->serialNo))
			return (-1);
	}
	if (READ_DWORD(&boot->err)) {
		DBG_ERR(("A: A(%d) PRI %ld Board Selftest failed, error=%08lx",
			 IoAdapter->ANum, IoAdapter->serialNo,
			 READ_DWORD(&boot->err)))
			DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
		return (-1);
	}
	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);

	/*
	  Forget all outstanding entities
	*/
	IoAdapter->e_count = 0;
	if (IoAdapter->e_tbl) {
		memset(IoAdapter->e_tbl, 0x00,
		       IoAdapter->e_max * sizeof(E_INFO));
	}
	IoAdapter->head = 0;
	IoAdapter->tail = 0;
	IoAdapter->assign = 0;
	IoAdapter->trapped = 0;

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

	return (0);
}

static int
diva_pri_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 PRI address=0x%08lx",
			 IoAdapter->ANum, address + length))
			return (-1);
	}
	mem += address;

	/* memcpy_toio(), maybe? */
	while (length--) {
		WRITE_BYTE(mem++, *data++);
	}

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

static int
diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
		       dword start_address, dword features)
{
	dword i;
	int started = 0;
	byte __iomem *p;
	struct mp_load __iomem *boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
	ADAPTER *a = &IoAdapter->a;

	if (IoAdapter->Initialized) {
		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
		DBG_ERR(("A: A(%d) pri_start_adapter, adapter already running",
			 IoAdapter->ANum))
			return (-1);
	}
	if (!boot) {
		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
		DBG_ERR(("A: PRI %ld can't start, adapter not mapped",
			 IoAdapter->serialNo))
			return (-1);
	}

	sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
	DBG_LOG(("A(%d) start PRI at 0x%08lx", IoAdapter->ANum,
		 start_address))

		WRITE_DWORD(&boot->addr, start_address);
	WRITE_DWORD(&boot->cmd, 3);

	for (i = 0; i < 300; ++i) {
		diva_os_wait(10);
		if ((READ_DWORD(&boot->signature) >> 16) == 0x4447) {
			DBG_LOG(("A(%d) Protocol startup time %d.%02d seconds",
				 IoAdapter->ANum, (i / 100), (i % 100)))
				started = 1;
			break;
		}
	}

	if (!started) {
		byte __iomem *p = (byte __iomem *)boot;
		dword TrapId;
		dword debug;
		TrapId = READ_DWORD(&p[0x80]);
		debug = READ_DWORD(&p[0x1c]);
		DBG_ERR(("A(%d) Adapter start failed 0x%08lx, TrapId=%08lx, debug=%08lx",
			 IoAdapter->ANum, READ_DWORD(&boot->signature),
			 TrapId, debug))
			DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
		if (IoAdapter->trapFnc) {
			(*(IoAdapter->trapFnc)) (IoAdapter);
		}
		IoAdapter->stop(IoAdapter);
		return (-1);
	}
	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);

	IoAdapter->Initialized = true;

	/*
	  Check Interrupt
	*/
	IoAdapter->IrqCount = 0;
	p = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
	WRITE_DWORD(p, (dword)~0x03E00000);
	DIVA_OS_MEM_DETACH_CFG(IoAdapter, p);
	a->ReadyInt = 1;
	a->ram_out(a, &PR_RAM->ReadyInt, 1);

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

	if (!IoAdapter->IrqCount) {
		DBG_ERR(("A: A(%d) interrupt test failed",
			 IoAdapter->ANum))
			IoAdapter->Initialized = false;
		IoAdapter->stop(IoAdapter);
		return (-1);
	}

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

	diva_xdi_display_adapter_features(IoAdapter->ANum);

	DBG_LOG(("A(%d) PRI adapter successfully started", IoAdapter->ANum))
		/*
		  Register with DIDD
		*/
		diva_xdi_didd_register_adapter(IoAdapter->ANum);

	return (0);
}

static void diva_pri_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);
}

/*
**  Stop Adapter, but do not unmap/unregister - adapter
**  will be restarted later
*/
static int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a)
{
	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
	int i = 100;

	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 */
	}
	IoAdapter->Initialized = 0;

	/*
	  Disconnect Adapter from DIDD
	*/
	diva_xdi_didd_remove_adapter(IoAdapter->ANum);

	/*
	  Stop interrupts
	*/
	a->clear_interrupts_proc = diva_pri_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_pri_clear_interrupts(a);
		a->clear_interrupts_proc = NULL;
		DBG_ERR(("A: A(%d) no final interrupt from PRI adapter",
			 IoAdapter->ANum))
			}
	IoAdapter->a.ReadyInt = 0;

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

	return (0);
}

/*
**  Process commands form configuration/download framework and from
**  user mode
**
**  return 0 on success
*/
static int
diva_pri_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: pri_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:
		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_RESET_ADAPTER:
		ret = diva_pri_reset_adapter(&a->xdi_adapter);
		break;

	case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
		ret = diva_pri_write_sdram_block(&a->xdi_adapter,
						 cmd->command_data.
						 write_sdram.offset,
						 (byte *)&cmd[1],
						 cmd->command_data.
						 write_sdram.length,
						 pri_is_rev_2_card(a->
								   CardOrdinal)
						 ? MP2_MEMORY_SIZE :
						 MP_MEMORY_SIZE);
		break;

	case DIVA_XDI_UM_CMD_STOP_ADAPTER:
		ret = diva_pri_stop_adapter(a);
		break;

	case DIVA_XDI_UM_CMD_START_ADAPTER:
		ret = diva_pri_start_adapter(&a->xdi_adapter,
					     cmd->command_data.start.
					     offset,
					     cmd->command_data.start.
					     features);
		break;

	case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
		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_GET_CARD_STATE:
		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_READ_XLOG_ENTRY:
		ret = diva_card_read_xlog(a);
		break;

	case DIVA_XDI_UM_CMD_READ_SDRAM:
		if (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++);
						}
						a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
						DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
						ret = 0;
					}
				}
			}
		}
		break;

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

	return (ret);
}

/*
**  Get Serial Number
*/
static int pri_get_serial_number(diva_os_xdi_adapter_t *a)
{
	byte data[64];
	int i;
	dword len = sizeof(data);
	volatile byte __iomem *config;
	volatile byte __iomem *flash;
	byte c;

/*
 *  First set some GT6401x config registers before accessing the BOOT-ROM
 */
	config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
	c = READ_BYTE(&config[0xc3c]);
	if (!(c & 0x08)) {
		WRITE_BYTE(&config[0xc3c], c);	/* Base Address enable register */
	}
	WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0x00);
	WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
	DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
/*
 *  Read only the last 64 bytes of manufacturing data
 */
	memset(data, '\0', len);
	flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
	for (i = 0; i < len; i++) {
		data[i] = READ_BYTE(&flash[0x8000 - len + i]);
	}
	DIVA_OS_MEM_DETACH_PROM(&a->xdi_adapter, flash);

	config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
	WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0xFC);	/* Disable FLASH EPROM access */
	WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
	DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);

	if (memcmp(&data[48], "DIVAserverPR", 12)) {
#if !defined(DIVA_PRI_NO_PCI_BIOS_WORKAROUND)	/* { */
		word cmd = 0, cmd_org;
		void *addr;
		dword addr1, addr3, addr4;
		byte Bus, Slot;
		void *hdev;
		addr4 = a->resources.pci.bar[4];
		addr3 = a->resources.pci.bar[3];	/* flash  */
		addr1 = a->resources.pci.bar[1];	/* unused */

		DBG_ERR(("A: apply Compaq BIOS workaround"))
			DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
				 data[0], data[1], data[2], data[3],
				 data[4], data[5], data[6], data[7]))

			Bus = a->resources.pci.bus;
		Slot = a->resources.pci.func;
		hdev = a->resources.pci.hdev;
		PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
		PCIwrite(Bus, Slot, 0x04, &cmd, sizeof(cmd), hdev);

		PCIwrite(Bus, Slot, 0x14, &addr4, sizeof(addr4), hdev);
		PCIwrite(Bus, Slot, 0x20, &addr1, sizeof(addr1), hdev);

		PCIwrite(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);

		addr = a->resources.pci.addr[1];
		a->resources.pci.addr[1] = a->resources.pci.addr[4];
		a->resources.pci.addr[4] = addr;

		addr1 = a->resources.pci.bar[1];
		a->resources.pci.bar[1] = a->resources.pci.bar[4];
		a->resources.pci.bar[4] = addr1;

		/*
		  Try to read Flash again
		*/
		len = sizeof(data);

		config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
		if (!(config[0xc3c] & 0x08)) {
			config[0xc3c] |= 0x08;	/* Base Address enable register */
		}
		config[LOW_BOOTCS_DREG] = 0x00;
		config[HI_BOOTCS_DREG] = 0xFF;
		DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);

		memset(data, '\0', len);
		flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
		for (i = 0; i < len; i++) {
			data[i] = flash[0x8000 - len + i];
		}
		DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter, flash);
		config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
		config[LOW_BOOTCS_DREG] = 0xFC;
		config[HI_BOOTCS_DREG] = 0xFF;
		DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);

		if (memcmp(&data[48], "DIVAserverPR", 12)) {
			DBG_ERR(("A: failed to read serial number"))
				DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
					 data[0], data[1], data[2], data[3],
					 data[4], data[5], data[6], data[7]))
				return (-1);
		}
#else				/* } { */
		DBG_ERR(("A: failed to read DIVA signature word"))
			DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
				 data[0], data[1], data[2], data[3],
				 data[4], data[5], data[6], data[7]))
			DBG_LOG(("%02x:%02x:%02x:%02x", data[47], data[46],
				 data[45], data[44]))
#endif				/* } */
			}

	a->xdi_adapter.serialNo =
		(data[47] << 24) | (data[46] << 16) | (data[45] << 8) |
		data[44];
	if (!a->xdi_adapter.serialNo
	    || (a->xdi_adapter.serialNo == 0xffffffff)) {
		a->xdi_adapter.serialNo = 0;
		DBG_ERR(("A: failed to read serial number"))
			return (-1);
	}

	DBG_LOG(("Serial No.          : %ld", a->xdi_adapter.serialNo))
		DBG_TRC(("Board Revision      : %d.%02d", (int) data[41],
			 (int) data[40]))
		DBG_TRC(("PLD revision        : %d.%02d", (int) data[33],
			 (int) data[32]))
		DBG_TRC(("Boot loader version : %d.%02d", (int) data[37],
			 (int) data[36]))

		DBG_TRC(("Manufacturing Date  : %d/%02d/%02d  (yyyy/mm/dd)",
			 (int) ((data[28] > 90) ? 1900 : 2000) +
			 (int) data[28], (int) data[29], (int) data[30]))

		return (0);
}

void diva_os_prepare_pri2_functions(PISDN_ADAPTER IoAdapter)
{
}

void diva_os_prepare_pri_functions(PISDN_ADAPTER IoAdapter)
{
}

/*
**  Checks presence of DSP on board
*/
static int
dsp_check_presence(volatile byte __iomem *addr, volatile byte __iomem *data, int dsp)
{
	word pattern;

	WRITE_WORD(addr, 0x4000);
	WRITE_WORD(data, DSP_SIGNATURE_PROBE_WORD);

	WRITE_WORD(addr, 0x4000);
	pattern = READ_WORD(data);

	if (pattern != DSP_SIGNATURE_PROBE_WORD) {
		DBG_TRC(("W: DSP[%d] %04x(is) != %04x(should)",
			 dsp, pattern, DSP_SIGNATURE_PROBE_WORD))
			return (-1);
	}

	WRITE_WORD(addr, 0x4000);
	WRITE_WORD(data, ~DSP_SIGNATURE_PROBE_WORD);

	WRITE_WORD(addr, 0x4000);
	pattern = READ_WORD(data);

	if (pattern != (word)~DSP_SIGNATURE_PROBE_WORD) {
		DBG_ERR(("A: DSP[%d] %04x(is) != %04x(should)",
			 dsp, pattern, (word)~DSP_SIGNATURE_PROBE_WORD))
			return (-2);
	}

	DBG_TRC(("DSP[%d] present", dsp))

		return (0);
}


/*
**  Check if DSP's are present and operating
**  Information about detected DSP's is returned as bit mask
**  Bit 0  - DSP1
**  ...
**  ...
**  ...
**  Bit 29 - DSP30
*/
static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a)
{
	byte __iomem *base;
	byte __iomem *p;
	dword ret = 0;
	dword row_offset[7] = {
		0x00000000,
		0x00000800,	/* 1 - ROW 1 */
		0x00000840,	/* 2 - ROW 2 */
		0x00001000,	/* 3 - ROW 3 */
		0x00001040,	/* 4 - ROW 4 */
		0x00000000	/* 5 - ROW 0 */
	};

	byte __iomem *dsp_addr_port;
	byte __iomem *dsp_data_port;
	byte row_state;
	int dsp_row = 0, dsp_index, dsp_num;

	if (!a->xdi_adapter.Control || !a->xdi_adapter.reset) {
		return (0);
	}

	p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
	WRITE_BYTE(p, _MP_RISC_RESET | _MP_DSP_RESET);
	DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
	diva_os_wait(5);

	base = DIVA_OS_MEM_ATTACH_CONTROL(&a->xdi_adapter);

	for (dsp_num = 0; dsp_num < 30; dsp_num++) {
		dsp_row = dsp_num / 7 + 1;
		dsp_index = dsp_num % 7;

		dsp_data_port = base;
		dsp_addr_port = base;

		dsp_data_port += row_offset[dsp_row];
		dsp_addr_port += row_offset[dsp_row];

		dsp_data_port += (dsp_index * 8);
		dsp_addr_port += (dsp_index * 8) + 0x80;

		if (!dsp_check_presence
		    (dsp_addr_port, dsp_data_port, dsp_num + 1)) {
			ret |= (1 << dsp_num);
		}
	}
	DIVA_OS_MEM_DETACH_CONTROL(&a->xdi_adapter, base);

	p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
	WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
	DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
	diva_os_wait(5);

	/*
	  Verify modules
	*/
	for (dsp_row = 0; dsp_row < 4; dsp_row++) {
		row_state = ((ret >> (dsp_row * 7)) & 0x7F);
		if (row_state && (row_state != 0x7F)) {
			for (dsp_index = 0; dsp_index < 7; dsp_index++) {
				if (!(row_state & (1 << dsp_index))) {
					DBG_ERR(("A: MODULE[%d]-DSP[%d] failed",
						 dsp_row + 1,
						 dsp_index + 1))
						}
			}
		}
	}

	if (!(ret & 0x10000000)) {
		DBG_ERR(("A: ON BOARD-DSP[1] failed"))
			}
	if (!(ret & 0x20000000)) {
		DBG_ERR(("A: ON BOARD-DSP[2] failed"))
			}

	/*
	  Print module population now
	*/
	DBG_LOG(("+-----------------------+"))
		DBG_LOG(("| DSP MODULE POPULATION |"))
		DBG_LOG(("+-----------------------+"))
		DBG_LOG(("|  1  |  2  |  3  |  4  |"))
		DBG_LOG(("+-----------------------+"))
		DBG_LOG(("|  %s  |  %s  |  %s  |  %s  |",
			 ((ret >> (0 * 7)) & 0x7F) ? "Y" : "N",
			 ((ret >> (1 * 7)) & 0x7F) ? "Y" : "N",
			 ((ret >> (2 * 7)) & 0x7F) ? "Y" : "N",
			 ((ret >> (3 * 7)) & 0x7F) ? "Y" : "N"))
		DBG_LOG(("+-----------------------+"))

		DBG_LOG(("DSP's(present-absent):%08x-%08x", ret,
			 ~ret & 0x3fffffff))

		return (ret);
}
