// SPDX-License-Identifier: GPL-2.0
/* $Id: os_bri.c,v 1.21 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_bri.h"
#include "diva_pci.h"
#include "mi_pc.h"
#include "pc_maint.h"
#include "dsrv_bri.h"

/*
**  IMPORTS
*/
extern void prepare_maestra_functions(PISDN_ADAPTER IoAdapter);
extern void diva_xdi_display_adapter_features(int card);
extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);

/*
**  LOCALS
*/
static int bri_bar_length[3] = {
	0x80,
	0x80,
	0x20
};
static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t *a);
static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t *a);
static int diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
				  diva_xdi_um_cfg_cmd_t *cmd, int length);
static int diva_bri_reregister_io(diva_os_xdi_adapter_t *a);
static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter);
static int diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
				      dword address,
				      const byte *data, dword length);
static int diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
				  dword start_address, dword features);
static int diva_bri_stop_adapter(diva_os_xdi_adapter_t *a);

static void diva_bri_set_addresses(diva_os_xdi_adapter_t *a)
{
	a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
	a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 1;
	a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2;
	a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 1;
	a->resources.pci.mem_type_id[MEM_TYPE_PORT] = 2;
	a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 2;

	a->xdi_adapter.ram = a->resources.pci.addr[0];
	a->xdi_adapter.cfg = a->resources.pci.addr[1];
	a->xdi_adapter.Address = a->resources.pci.addr[2];

	a->xdi_adapter.reset = a->xdi_adapter.cfg;
	a->xdi_adapter.port = a->xdi_adapter.Address;

	a->xdi_adapter.ctlReg = a->xdi_adapter.port + M_PCI_RESET;

	a->xdi_adapter.reset += 0x4C;	/* PLX 9050 !! */
}

/*
**  BAR0 - MEM Addr  - 0x80  - NOT USED
**  BAR1 - I/O Addr  - 0x80
**  BAR2 - I/O Addr  - 0x20
*/
int diva_bri_init_card(diva_os_xdi_adapter_t *a)
{
	int bar;
	dword bar2 = 0, bar2_length = 0xffffffff;
	word cmd = 0, cmd_org;
	byte Bus, Slot;
	void *hdev;
	byte __iomem *p;

	/*
	  Set properties
	*/
	a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
	DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name))

		/*
		  Get resources
		*/
		for (bar = 0; bar < 3; 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]) {
				DBG_ERR(("A: can't get BAR[%d]", 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);
	}

	/*
	  Get length of I/O bar 2 - it is different by older
	  EEPROM version
	*/
	Bus = a->resources.pci.bus;
	Slot = a->resources.pci.func;
	hdev = a->resources.pci.hdev;

	/*
	  Get plain original values of the BAR2 CDM registers
	*/
	PCIread(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev);
	PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
	/*
	  Disable device and get BAR2 length
	*/
	PCIwrite(Bus, Slot, 0x04, &cmd, sizeof(cmd), hdev);
	PCIwrite(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev);
	PCIread(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev);
	/*
	  Restore BAR2 and CMD registers
	*/
	PCIwrite(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev);
	PCIwrite(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);

	/*
	  Calculate BAR2 length
	*/
	bar2_length = (~(bar2_length & ~7)) + 1;
	DBG_LOG(("BAR[2] length=%lx", bar2_length))

		/*
		  Map and register resources
		*/
		if (!(a->resources.pci.addr[0] =
		      divasa_remap_pci_bar(a, 0, a->resources.pci.bar[0],
					   bri_bar_length[0]))) {
			DBG_ERR(("A: BRI, can't map BAR[0]"))
				diva_bri_cleanup_adapter(a);
			return (-1);
		}

	sprintf(&a->port_name[0], "BRI %02x:%02x",
		a->resources.pci.bus, a->resources.pci.func);

	if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
				     bri_bar_length[1], &a->port_name[0], 1)) {
		DBG_ERR(("A: BRI, can't register BAR[1]"))
			diva_bri_cleanup_adapter(a);
		return (-1);
	}
	a->resources.pci.addr[1] = (void *) (unsigned long) a->resources.pci.bar[1];
	a->resources.pci.length[1] = bri_bar_length[1];

	if (diva_os_register_io_port(a, 1, a->resources.pci.bar[2],
				     bar2_length, &a->port_name[0], 2)) {
		DBG_ERR(("A: BRI, can't register BAR[2]"))
			diva_bri_cleanup_adapter(a);
		return (-1);
	}
	a->resources.pci.addr[2] = (void *) (unsigned long) a->resources.pci.bar[2];
	a->resources.pci.length[2] = bar2_length;

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

	/*
	  Get Serial Number
	*/
	a->xdi_adapter.serialNo = diva_bri_get_serial_number(a);

	/*
	  Register I/O ports with correct name now
	*/
	if (diva_bri_reregister_io(a)) {
		diva_bri_cleanup_adapter(a);
		return (-1);
	}

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

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

	if (diva_os_initialize_soft_isr(&a->xdi_adapter.req_soft_isr,
					DIDpcRoutine, &a->xdi_adapter)) {
		diva_bri_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;

	/*
	  Create entity table
	*/
	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_bri_cleanup_adapter(a);
		return (-1);
	}
	memset(a->xdi_adapter.e_tbl, 0x00, a->xdi_adapter.e_max * sizeof(E_INFO));

	/*
	  Set up interface
	*/
	a->xdi_adapter.a.io = &a->xdi_adapter;
	a->xdi_adapter.DIRequest = request;
	a->interface.cleanup_adapter_proc = diva_bri_cleanup_adapter;
	a->interface.cmd_proc = diva_bri_cmd_card_proc;

	p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
	outpp(p, 0x41);
	DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);

	prepare_maestra_functions(&a->xdi_adapter);

	a->dsp_mask = 0x00000003;

	/*
	  Set IRQ handler
	*/
	a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
	sprintf(a->xdi_adapter.irq_info.irq_name, "DIVA BRI %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_bri_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_bri_cleanup_adapter(diva_os_xdi_adapter_t *a)
{
	int i;

	if (a->xdi_adapter.Initialized) {
		diva_bri_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;

	if (a->resources.pci.addr[0] && a->resources.pci.bar[0]) {
		divasa_unmap_pci_bar(a->resources.pci.addr[0]);
		a->resources.pci.addr[0] = NULL;
		a->resources.pci.bar[0] = 0;
	}

	for (i = 1; i < 3; i++) {
		if (a->resources.pci.addr[i] && a->resources.pci.bar[i]) {
			diva_os_register_io_port(a, 0,
						 a->resources.pci.bar[i],
						 a->resources.pci.
						 length[i],
						 &a->port_name[0], i);
			a->resources.pci.addr[i] = NULL;
			a->resources.pci.bar[i] = 0;
		}
	}

	/*
	  Free OS objects
	*/
	diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr);
	diva_os_cancel_soft_isr(&a->xdi_adapter.isr_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
	*/
	if (a->xdi_adapter.e_tbl) {
		diva_os_free(0, a->xdi_adapter.e_tbl);
		a->xdi_adapter.e_tbl = NULL;
	}

	return (0);
}

void diva_os_prepare_maestra_functions(PISDN_ADAPTER IoAdapter)
{
}

/*
**  Get serial number
*/
static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t *a)
{
	dword serNo = 0;
	byte __iomem *confIO;
	word serHi, serLo;
	word __iomem *confMem;

	confIO = DIVA_OS_MEM_ATTACH_CFG(&a->xdi_adapter);
	serHi = (word) (inppw(&confIO[0x22]) & 0x0FFF);
	serLo = (word) (inppw(&confIO[0x26]) & 0x0FFF);
	serNo = ((dword) serHi << 16) | (dword) serLo;
	DIVA_OS_MEM_DETACH_CFG(&a->xdi_adapter, confIO);

	if ((serNo == 0) || (serNo == 0xFFFFFFFF)) {
		DBG_FTL(("W: BRI use BAR[0] to get card serial number"))

			confMem = (word __iomem *)DIVA_OS_MEM_ATTACH_RAM(&a->xdi_adapter);
		serHi = (word) (READ_WORD(&confMem[0x11]) & 0x0FFF);
		serLo = (word) (READ_WORD(&confMem[0x13]) & 0x0FFF);
		serNo = (((dword) serHi) << 16) | ((dword) serLo);
		DIVA_OS_MEM_DETACH_RAM(&a->xdi_adapter, confMem);
	}

	DBG_LOG(("Serial Number=%ld", serNo))

		return (serNo);
}

/*
**  Unregister I/O and register it with new name,
**  based on Serial Number
*/
static int diva_bri_reregister_io(diva_os_xdi_adapter_t *a)
{
	int i;

	for (i = 1; i < 3; i++) {
		diva_os_register_io_port(a, 0, a->resources.pci.bar[i],
					 a->resources.pci.length[i],
					 &a->port_name[0], i);
		a->resources.pci.addr[i] = NULL;
	}

	sprintf(a->port_name, "DIVA BRI %ld",
		(long) a->xdi_adapter.serialNo);

	for (i = 1; i < 3; i++) {
		if (diva_os_register_io_port(a, 1, a->resources.pci.bar[i],
					     a->resources.pci.length[i],
					     &a->port_name[0], i)) {
			DBG_ERR(("A: failed to reregister BAR[%d]", i))
				return (-1);
		}
		a->resources.pci.addr[i] =
			(void *) (unsigned long) a->resources.pci.bar[i];
	}

	return (0);
}

/*
**  Process command from user mode
*/
static int
diva_bri_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_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.port) {
				*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_RESET_ADAPTER:
		ret = diva_bri_reset_adapter(&a->xdi_adapter);
		break;

	case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
		ret = diva_bri_write_sdram_block(&a->xdi_adapter,
						 cmd->command_data.
						 write_sdram.offset,
						 (byte *)&cmd[1],
						 cmd->command_data.
						 write_sdram.length);
		break;

	case DIVA_XDI_UM_CMD_START_ADAPTER:
		ret = diva_bri_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_STOP_ADAPTER:
		ret = diva_bri_stop_adapter(a);
		break;

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

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

	return (ret);
}

static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter)
{
	byte __iomem *addrHi, *addrLo, *ioaddr;
	dword i;
	byte __iomem *Port;

	if (!IoAdapter->port) {
		return (-1);
	}
	if (IoAdapter->Initialized) {
		DBG_ERR(("A: A(%d) can't reset BRI adapter - please stop first",
			 IoAdapter->ANum)) return (-1);
	}
	(*(IoAdapter->rstFnc)) (IoAdapter);
	diva_os_wait(100);
	Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
	addrHi = Port +
		((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
	addrLo = Port + ADDR;
	ioaddr = Port + DATA;
	/*
	  recover
	*/
	outpp(addrHi, (byte) 0);
	outppw(addrLo, (word) 0);
	outppw(ioaddr, (word) 0);
	/*
	  clear shared memory
	*/
	outpp(addrHi,
	      (byte) (
		      (IoAdapter->MemoryBase + IoAdapter->MemorySize -
		       BRI_SHARED_RAM_SIZE) >> 16));
	outppw(addrLo, 0);
	for (i = 0; i < 0x8000; outppw(ioaddr, 0), ++i);
	diva_os_wait(100);

	/*
	  clear signature
	*/
	outpp(addrHi,
	      (byte) (
		      (IoAdapter->MemoryBase + IoAdapter->MemorySize -
		       BRI_SHARED_RAM_SIZE) >> 16));
	outppw(addrLo, 0x1e);
	outpp(ioaddr, 0);
	outpp(ioaddr, 0);

	outpp(addrHi, (byte) 0);
	outppw(addrLo, (word) 0);
	outppw(ioaddr, (word) 0);

	DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);

	/*
	  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_bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
			   dword address, const byte *data, dword length)
{
	byte __iomem *addrHi, *addrLo, *ioaddr;
	byte __iomem *Port;

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

	Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
	addrHi = Port +
		((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
	addrLo = Port + ADDR;
	ioaddr = Port + DATA;

	while (length--) {
		outpp(addrHi, (word) (address >> 16));
		outppw(addrLo, (word) (address & 0x0000ffff));
		outpp(ioaddr, *data++);
		address++;
	}

	DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
	return (0);
}

static int
diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
		       dword start_address, dword features)
{
	byte __iomem *Port;
	dword i, test;
	byte __iomem *addrHi, *addrLo, *ioaddr;
	int started = 0;
	ADAPTER *a = &IoAdapter->a;

	if (IoAdapter->Initialized) {
		DBG_ERR(
			("A: A(%d) bri_start_adapter, adapter already running",
			 IoAdapter->ANum)) return (-1);
	}
	if (!IoAdapter->port) {
		DBG_ERR(("A: A(%d) bri_start_adapter, adapter not mapped",
			 IoAdapter->ANum)) return (-1);
	}

	sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
	DBG_LOG(("A(%d) start BRI", IoAdapter->ANum))

		Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
	addrHi = Port +
		((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
	addrLo = Port + ADDR;
	ioaddr = Port + DATA;

	outpp(addrHi,
	      (byte) (
		      (IoAdapter->MemoryBase + IoAdapter->MemorySize -
		       BRI_SHARED_RAM_SIZE) >> 16));
	outppw(addrLo, 0x1e);
	outppw(ioaddr, 0x00);
	DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);

	/*
	  start the protocol code
	*/
	Port = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
	outpp(Port, 0x08);
	DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, Port);

	Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
	addrHi = Port +
		((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
	addrLo = Port + ADDR;
	ioaddr = Port + DATA;
	/*
	  wait for signature (max. 3 seconds)
	*/
	for (i = 0; i < 300; ++i) {
		diva_os_wait(10);
		outpp(addrHi,
		      (byte) (
			      (IoAdapter->MemoryBase +
			       IoAdapter->MemorySize -
			       BRI_SHARED_RAM_SIZE) >> 16));
		outppw(addrLo, 0x1e);
		test = (dword) inppw(ioaddr);
		if (test == 0x4447) {
			DBG_LOG(
				("Protocol startup time %d.%02d seconds",
				 (i / 100), (i % 100)))
				started = 1;
			break;
		}
	}
	DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);

	if (!started) {
		DBG_FTL(("A: A(%d) %s: Adapter selftest failed 0x%04X",
			 IoAdapter->ANum, IoAdapter->Properties.Name,
			 test))
			(*(IoAdapter->trapFnc)) (IoAdapter);
		return (-1);
	}

	IoAdapter->Initialized = 1;

	/*
	  Check Interrupt
	*/
	IoAdapter->IrqCount = 0;
	a->ReadyInt = 1;

	if (IoAdapter->reset) {
		Port = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
		outpp(Port, 0x41);
		DIVA_OS_MEM_DETACH_RESET(IoAdapter, Port);
	}

	a->ram_out(a, &PR_RAM->ReadyInt, 1);
	for (i = 0; ((!IoAdapter->IrqCount) && (i < 100)); i++) {
		diva_os_wait(10);
	}
	if (!IoAdapter->IrqCount) {
		DBG_ERR(
			("A: A(%d) interrupt test failed",
			 IoAdapter->ANum))
			IoAdapter->Initialized = 0;
		IoAdapter->stop(IoAdapter);
		return (-1);
	}

	IoAdapter->Properties.Features = (word) features;
	diva_xdi_display_adapter_features(IoAdapter->ANum);
	DBG_LOG(("A(%d) BRI adapter successfully started", IoAdapter->ANum))
		/*
		  Register with DIDD
		*/
		diva_xdi_didd_register_adapter(IoAdapter->ANum);

	return (0);
}

static void diva_bri_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 card
*/
static int diva_bri_stop_adapter(diva_os_xdi_adapter_t *a)
{
	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
	int i = 100;

	if (!IoAdapter->port) {
		return (-1);
	}
	if (!IoAdapter->Initialized) {
		DBG_ERR(("A: A(%d) can't stop BRI 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_bri_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_bri_clear_interrupts(a);
		a->clear_interrupts_proc = NULL;
		DBG_ERR(("A: A(%d) no final interrupt from BRI adapter",
			 IoAdapter->ANum))
			}
	IoAdapter->a.ReadyInt = 0;

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

	return (0);
}
