11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* $Id: os_pri.c,v 1.32 2004/03/21 17:26:01 armin Exp $ */
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "platform.h"
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "debuglib.h"
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "cardtype.h"
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "pc.h"
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "pr_pc.h"
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "di_defs.h"
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "dsp_defs.h"
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "di.h"
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "io.h"
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "xdi_msg.h"
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "xdi_adapter.h"
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "os_pri.h"
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "diva_pci.h"
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "mi_pc.h"
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "pc_maint.h"
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "dsp_tst.h"
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "diva_dma.h"
216e21bd9a30f1d7eab26ef8b9259376e5322d89e5Adrian Bunk#include "dsrv_pri.h"
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* --------------------------------------------------------------------------
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   OS Dependent part of XDI driver for DIVA PRI Adapter
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   DSP detection/validation by Anthony Booth (Eicon Networks, www.eicon.com)
27475be4d85a274d0961593db41cf85689db1d583cJoe Perches   -------------------------------------------------------------------------- */
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DIVA_PRI_NO_PCI_BIOS_WORKAROUND 1
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
31475be4d85a274d0961593db41cf85689db1d583cJoe Perchesextern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  IMPORTS
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void prepare_pri_functions(PISDN_ADAPTER IoAdapter);
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void prepare_pri2_functions(PISDN_ADAPTER IoAdapter);
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void diva_xdi_display_adapter_features(int card);
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
40475be4d85a274d0961593db41cf85689db1d583cJoe Perchesstatic int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a);
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
42475be4d85a274d0961593db41cf85689db1d583cJoe Perches				  diva_xdi_um_cfg_cmd_t *cmd, int length);
43475be4d85a274d0961593db41cf85689db1d583cJoe Perchesstatic int pri_get_serial_number(diva_os_xdi_adapter_t *a);
44475be4d85a274d0961593db41cf85689db1d583cJoe Perchesstatic int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a);
45475be4d85a274d0961593db41cf85689db1d583cJoe Perchesstatic dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a);
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  Check card revision
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int pri_is_rev_2_card(int card_ordinal)
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (card_ordinal) {
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case CARDTYPE_DIVASRV_P_30M_V2_PCI:
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI:
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (1);
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (0);
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
60475be4d85a274d0961593db41cf85689db1d583cJoe Perchesstatic void diva_pri_set_addresses(diva_os_xdi_adapter_t *a)
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 0;
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->resources.pci.mem_type_id[MEM_TYPE_CONFIG] = 4;
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 2;
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 4;
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 3;
69475be4d85a274d0961593db41cf85689db1d583cJoe Perches
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.Address = a->resources.pci.addr[0];
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.Control = a->resources.pci.addr[2];
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.Config = a->resources.pci.addr[4];
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.ram = a->resources.pci.addr[0];
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.ram += MP_SHARED_RAM_OFFSET;
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.reset = a->resources.pci.addr[2];
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.reset += MP_RESET;
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.cfg = a->resources.pci.addr[4];
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.cfg += MP_IRQ_RESET;
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.sdram_bar = a->resources.pci.bar[0];
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.prom = a->resources.pci.addr[3];
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  BAR0 - SDRAM, MP_MEMORY_SIZE, MP2_MEMORY_SIZE by Rev.2
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  BAR1 - DEVICES,				0x1000
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  BAR2 - CONTROL (REG), 0x2000
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  BAR3 - FLASH (REG),		0x8000
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  BAR4 - CONFIG (CFG),	0x1000
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
95475be4d85a274d0961593db41cf85689db1d583cJoe Perchesint diva_pri_init_card(diva_os_xdi_adapter_t *a)
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int bar = 0;
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int pri_rev_2;
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long bar_length[5] = {
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		MP_MEMORY_SIZE,
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		0x1000,
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		0x2000,
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		0x8000,
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		0x1000
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	};
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pri_rev_2 = pri_is_rev_2_card(a->CardOrdinal);
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (pri_rev_2) {
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		bar_length[0] = MP2_MEMORY_SIZE;
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
113475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Set properties
114475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name))
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
118475be4d85a274d0961593db41cf85689db1d583cJoe Perches		/*
119475be4d85a274d0961593db41cf85689db1d583cJoe Perches		  First initialization step: get and check hardware resoures.
120475be4d85a274d0961593db41cf85689db1d583cJoe Perches		  Do not map resources and do not acecess card at this step
121475be4d85a274d0961593db41cf85689db1d583cJoe Perches		*/
122475be4d85a274d0961593db41cf85689db1d583cJoe Perches		for (bar = 0; bar < 5; bar++) {
123475be4d85a274d0961593db41cf85689db1d583cJoe Perches			a->resources.pci.bar[bar] =
124475be4d85a274d0961593db41cf85689db1d583cJoe Perches				divasa_get_pci_bar(a->resources.pci.bus,
125475be4d85a274d0961593db41cf85689db1d583cJoe Perches						   a->resources.pci.func, bar,
126475be4d85a274d0961593db41cf85689db1d583cJoe Perches						   a->resources.pci.hdev);
127475be4d85a274d0961593db41cf85689db1d583cJoe Perches			if (!a->resources.pci.bar[bar]
128475be4d85a274d0961593db41cf85689db1d583cJoe Perches			    || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) {
129475be4d85a274d0961593db41cf85689db1d583cJoe Perches				DBG_ERR(("A: invalid bar[%d]=%08x", bar,
130475be4d85a274d0961593db41cf85689db1d583cJoe Perches					 a->resources.pci.bar[bar]))
131475be4d85a274d0961593db41cf85689db1d583cJoe Perches					return (-1);
132475be4d85a274d0961593db41cf85689db1d583cJoe Perches			}
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->resources.pci.irq =
135475be4d85a274d0961593db41cf85689db1d583cJoe Perches		(byte) divasa_get_pci_irq(a->resources.pci.bus,
136475be4d85a274d0961593db41cf85689db1d583cJoe Perches					  a->resources.pci.func,
137475be4d85a274d0961593db41cf85689db1d583cJoe Perches					  a->resources.pci.hdev);
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!a->resources.pci.irq) {
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: invalid irq"));
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (-1);
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
144475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Map all BAR's
145475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (bar = 0; bar < 5; bar++) {
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->resources.pci.addr[bar] =
148475be4d85a274d0961593db41cf85689db1d583cJoe Perches			divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
149475be4d85a274d0961593db41cf85689db1d583cJoe Perches					     bar_length[bar]);
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!a->resources.pci.addr[bar]) {
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DBG_ERR(("A: A(%d), can't map bar[%d]",
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 a->controller, bar))
153475be4d85a274d0961593db41cf85689db1d583cJoe Perches				diva_pri_cleanup_adapter(a);
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return (-1);
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
159475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Set all memory areas
160475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_pri_set_addresses(a);
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
164475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Get Serial Number of this adapter
165475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (pri_get_serial_number(a)) {
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dword serNo;
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		serNo = a->resources.pci.bar[1] & 0xffff0000;
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		serNo |= ((dword) a->resources.pci.bus) << 8;
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		serNo += (a->resources.pci.func + a->controller + 1);
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->xdi_adapter.serialNo = serNo & ~0xFF000000;
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: A(%d) can't get Serial Number, generated serNo=%ld",
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 a->controller, a->xdi_adapter.serialNo))
174475be4d85a274d0961593db41cf85689db1d583cJoe Perches			}
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
178475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Initialize os objects
179475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (diva_os_initialize_spin_lock(&a->xdi_adapter.isr_spin_lock, "isr")) {
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		diva_pri_cleanup_adapter(a);
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (-1);
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (diva_os_initialize_spin_lock
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    (&a->xdi_adapter.data_spin_lock, "data")) {
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		diva_pri_cleanup_adapter(a);
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (-1);
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	strcpy(a->xdi_adapter.req_soft_isr.dpc_thread_name, "kdivasprid");
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (diva_os_initialize_soft_isr(&a->xdi_adapter.req_soft_isr,
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					DIDpcRoutine, &a->xdi_adapter)) {
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		diva_pri_cleanup_adapter(a);
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (-1);
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
199475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Do not initialize second DPC - only one thread will be created
200475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.isr_soft_isr.object =
202475be4d85a274d0961593db41cf85689db1d583cJoe Perches		a->xdi_adapter.req_soft_isr.object;
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
205475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Next step of card initialization:
206475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  set up all interface pointers
207475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels;
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info;
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.e_tbl =
212475be4d85a274d0961593db41cf85689db1d583cJoe Perches		diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO));
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!a->xdi_adapter.e_tbl) {
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		diva_pri_cleanup_adapter(a);
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (-1);
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(a->xdi_adapter.e_tbl, 0x00, a->xdi_adapter.e_max * sizeof(E_INFO));
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.a.io = &a->xdi_adapter;
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.DIRequest = request;
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->interface.cleanup_adapter_proc = diva_pri_cleanup_adapter;
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->interface.cmd_proc = diva_pri_cmd_card_proc;
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (pri_rev_2) {
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		prepare_pri2_functions(&a->xdi_adapter);
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		prepare_pri_functions(&a->xdi_adapter);
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->dsp_mask = diva_pri_detect_dsps(a);
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
233475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Allocate DMA map
234475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (pri_rev_2) {
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		diva_init_dma_map(a->resources.pci.hdev,
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				  (struct _diva_dma_map_entry **) &a->xdi_adapter.dma_map, 32);
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
241475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Set IRQ handler
242475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sprintf(a->xdi_adapter.irq_info.irq_name,
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"DIVA PRI %ld", (long) a->xdi_adapter.serialNo);
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (diva_os_register_irq(a, a->xdi_adapter.irq_info.irq_nr,
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 a->xdi_adapter.irq_info.irq_name)) {
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		diva_pri_cleanup_adapter(a);
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (-1);
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.irq_info.registered = 1;
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name,
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		      a->resources.pci.irq, a->xdi_adapter.serialNo);
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (0);
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
260475be4d85a274d0961593db41cf85689db1d583cJoe Perchesstatic int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t *a)
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int bar = 0;
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
265475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Stop Adapter if adapter is running
266475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (a->xdi_adapter.Initialized) {
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		diva_pri_stop_adapter(a);
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
272475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Remove ISR Handler
273475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (a->xdi_adapter.irq_info.registered) {
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.irq_info.registered = 0;
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
280475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Step 1: unmap all BAR's, if any was mapped
281475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (bar = 0; bar < 5; bar++) {
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (a->resources.pci.bar[bar]
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    && a->resources.pci.addr[bar]) {
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			divasa_unmap_pci_bar(a->resources.pci.addr[bar]);
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			a->resources.pci.bar[bar] = 0;
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			a->resources.pci.addr[bar] = NULL;
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
292475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Free OS objects
293475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr);
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr);
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_os_remove_soft_isr(&a->xdi_adapter.req_soft_isr);
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.isr_soft_isr.object = NULL;
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_os_destroy_spin_lock(&a->xdi_adapter.isr_spin_lock, "rm");
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm");
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
304475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Free memory accupied by XDI adapter
305475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (a->xdi_adapter.e_tbl) {
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		diva_os_free(0, a->xdi_adapter.e_tbl);
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->xdi_adapter.e_tbl = NULL;
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.Channels = 0;
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.e_max = 0;
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
315475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Free adapter DMA map
316475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_free_dma_map(a->resources.pci.hdev,
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  (struct _diva_dma_map_entry *) a->xdi_adapter.
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  dma_map);
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.dma_map = NULL;
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
324475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Detach this adapter from debug driver
325475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (0);
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  Activate On Board Boot Loader
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dword i;
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mp_load __iomem *boot;
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IoAdapter->Address || !IoAdapter->reset) {
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (-1);
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (IoAdapter->Initialized) {
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: A(%d) can't reset PRI adapter - please stop first",
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 IoAdapter->ANum))
344475be4d85a274d0961593db41cf85689db1d583cJoe Perches			return (-1);
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	WRITE_DWORD(&boot->err, 0);
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->rstFnc(IoAdapter);
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_os_wait(10);
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	i = READ_DWORD(&boot->live);
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_os_wait(10);
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (i == READ_DWORD(&boot->live)) {
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: A(%d) CPU on PRI %ld is not alive!",
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 IoAdapter->ANum, IoAdapter->serialNo))
363475be4d85a274d0961593db41cf85689db1d583cJoe Perches			return (-1);
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (READ_DWORD(&boot->err)) {
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: A(%d) PRI %ld Board Selftest failed, error=%08lx",
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 IoAdapter->ANum, IoAdapter->serialNo,
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 READ_DWORD(&boot->err)))
369475be4d85a274d0961593db41cf85689db1d583cJoe Perches			DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (-1);
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
375475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Forget all outstanding entities
376475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->e_count = 0;
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (IoAdapter->e_tbl) {
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		memset(IoAdapter->e_tbl, 0x00,
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       IoAdapter->e_max * sizeof(E_INFO));
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->head = 0;
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->tail = 0;
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->assign = 0;
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->trapped = 0;
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(&IoAdapter->a.IdTable[0], 0x00,
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       sizeof(IoAdapter->a.IdTable));
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(&IoAdapter->a.IdTypeTable[0], 0x00,
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       sizeof(IoAdapter->a.IdTypeTable));
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(&IoAdapter->a.FlowControlIdTable[0], 0x00,
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       sizeof(IoAdapter->a.FlowControlIdTable));
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(&IoAdapter->a.FlowControlSkipTable[0], 0x00,
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       sizeof(IoAdapter->a.FlowControlSkipTable));
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(&IoAdapter->a.misc_flags_table[0], 0x00,
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       sizeof(IoAdapter->a.misc_flags_table));
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(&IoAdapter->a.rx_stream[0], 0x00,
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       sizeof(IoAdapter->a.rx_stream));
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(&IoAdapter->a.tx_stream[0], 0x00,
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       sizeof(IoAdapter->a.tx_stream));
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(&IoAdapter->a.tx_pos[0], 0x00, sizeof(IoAdapter->a.tx_pos));
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(&IoAdapter->a.rx_pos[0], 0x00, sizeof(IoAdapter->a.rx_pos));
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (0);
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdiva_pri_write_sdram_block(PISDN_ADAPTER IoAdapter,
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   dword address,
410475be4d85a274d0961593db41cf85689db1d583cJoe Perches			   const byte *data, dword length, dword limit)
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byte __iomem *mem = p;
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (((address + length) >= limit) || !mem) {
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: A(%d) write PRI address=0x%08lx",
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 IoAdapter->ANum, address + length))
419475be4d85a274d0961593db41cf85689db1d583cJoe Perches			return (-1);
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mem += address;
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* memcpy_toio(), maybe? */
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (length--) {
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		WRITE_BYTE(mem++, *data++);
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (0);
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdiva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		       dword start_address, dword features)
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dword i;
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int started = 0;
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byte __iomem *p;
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mp_load __iomem *boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADAPTER *a = &IoAdapter->a;
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (IoAdapter->Initialized) {
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: A(%d) pri_start_adapter, adapter already running",
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 IoAdapter->ANum))
446475be4d85a274d0961593db41cf85689db1d583cJoe Perches			return (-1);
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!boot) {
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: PRI %ld can't start, adapter not mapped",
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 IoAdapter->serialNo))
452475be4d85a274d0961593db41cf85689db1d583cJoe Perches			return (-1);
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DBG_LOG(("A(%d) start PRI at 0x%08lx", IoAdapter->ANum,
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 start_address))
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
459475be4d85a274d0961593db41cf85689db1d583cJoe Perches		WRITE_DWORD(&boot->addr, start_address);
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	WRITE_DWORD(&boot->cmd, 3);
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < 300; ++i) {
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		diva_os_wait(10);
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ((READ_DWORD(&boot->signature) >> 16) == 0x4447) {
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DBG_LOG(("A(%d) Protocol startup time %d.%02d seconds",
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 IoAdapter->ANum, (i / 100), (i % 100)))
467475be4d85a274d0961593db41cf85689db1d583cJoe Perches				started = 1;
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!started) {
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		byte __iomem *p = (byte __iomem *)boot;
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dword TrapId;
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dword debug;
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		TrapId = READ_DWORD(&p[0x80]);
4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		debug = READ_DWORD(&p[0x1c]);
4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A(%d) Adapter start failed 0x%08lx, TrapId=%08lx, debug=%08lx",
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 IoAdapter->ANum, READ_DWORD(&boot->signature),
4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 TrapId, debug))
481475be4d85a274d0961593db41cf85689db1d583cJoe Perches			DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (IoAdapter->trapFnc) {
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			(*(IoAdapter->trapFnc)) (IoAdapter);
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IoAdapter->stop(IoAdapter);
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (-1);
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
490986c4bb8c4a7bf248378954782553334a003d80aRichard Knutsson	IoAdapter->Initialized = true;
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
493475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Check Interrupt
494475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->IrqCount = 0;
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	p = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
497475be4d85a274d0961593db41cf85689db1d583cJoe Perches	WRITE_DWORD(p, (dword)~0x03E00000);
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DIVA_OS_MEM_DETACH_CFG(IoAdapter, p);
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->ReadyInt = 1;
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->ram_out(a, &PR_RAM->ReadyInt, 1);
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 100; !IoAdapter->IrqCount && (i-- > 0); diva_os_wait(10));
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IoAdapter->IrqCount) {
5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: A(%d) interrupt test failed",
5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 IoAdapter->ANum))
507475be4d85a274d0961593db41cf85689db1d583cJoe Perches			IoAdapter->Initialized = false;
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		IoAdapter->stop(IoAdapter);
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (-1);
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->Properties.Features = (word) features;
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_xdi_display_adapter_features(IoAdapter->ANum);
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
51673ac36ea14fd18ea3dc057e41b16ff31a3c0bd5aColy Li	DBG_LOG(("A(%d) PRI adapter successfully started", IoAdapter->ANum))
517475be4d85a274d0961593db41cf85689db1d583cJoe Perches		/*
518475be4d85a274d0961593db41cf85689db1d583cJoe Perches		  Register with DIDD
519475be4d85a274d0961593db41cf85689db1d583cJoe Perches		*/
520475be4d85a274d0961593db41cf85689db1d583cJoe Perches		diva_xdi_didd_register_adapter(IoAdapter->ANum);
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (0);
5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
525475be4d85a274d0961593db41cf85689db1d583cJoe Perchesstatic void diva_pri_clear_interrupts(diva_os_xdi_adapter_t *a)
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
530475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  clear any pending interrupt
531475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->disIrq(IoAdapter);
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->tst_irq(&IoAdapter->a);
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->clr_irq(&IoAdapter->a);
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->tst_irq(&IoAdapter->a);
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
539475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  kill pending dpcs
540475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  Stop Adapter, but do not unmap/unregister - adapter
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  will be restarted later
5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
549475be4d85a274d0961593db41cf85689db1d583cJoe Perchesstatic int diva_pri_stop_adapter(diva_os_xdi_adapter_t *a)
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i = 100;
5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IoAdapter->ram) {
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (-1);
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IoAdapter->Initialized) {
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: A(%d) can't stop PRI adapter - not running",
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 IoAdapter->ANum))
560475be4d85a274d0961593db41cf85689db1d583cJoe Perches			return (-1);	/* nothing to stop */
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->Initialized = 0;
5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
565475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Disconnect Adapter from DIDD
566475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_xdi_didd_remove_adapter(IoAdapter->ANum);
5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
570475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Stop interrupts
571475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->clear_interrupts_proc = diva_pri_clear_interrupts;
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->a.ReadyInt = 1;
5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	do {
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		diva_os_sleep(10);
5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} while (i-- && a->clear_interrupts_proc);
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (a->clear_interrupts_proc) {
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		diva_pri_clear_interrupts(a);
5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->clear_interrupts_proc = NULL;
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: A(%d) no final interrupt from PRI adapter",
5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 IoAdapter->ANum))
584475be4d85a274d0961593db41cf85689db1d583cJoe Perches			}
5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->a.ReadyInt = 0;
5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
588475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Stop and reset adapter
589475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	IoAdapter->stop(IoAdapter);
5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (0);
5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  Process commands form configuration/download framework and from
5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  user mode
5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  return 0 on success
6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdiva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
603475be4d85a274d0961593db41cf85689db1d583cJoe Perches		       diva_xdi_um_cfg_cmd_t *cmd, int length)
6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret = -1;
6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cmd->adapter != a->controller) {
6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: pri_cmd, invalid controller=%d != %d",
6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 cmd->adapter, a->controller))
610475be4d85a274d0961593db41cf85689db1d583cJoe Perches			return (-1);
6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (cmd->command) {
6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->xdi_mbox.data_length = sizeof(dword);
6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->xdi_mbox.data =
617475be4d85a274d0961593db41cf85689db1d583cJoe Perches			diva_os_malloc(0, a->xdi_mbox.data_length);
6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (a->xdi_mbox.data) {
6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			*(dword *) a->xdi_mbox.data =
620475be4d85a274d0961593db41cf85689db1d583cJoe Perches				(dword) a->CardOrdinal;
6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ret = 0;
6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->xdi_mbox.data_length = sizeof(dword);
6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->xdi_mbox.data =
629475be4d85a274d0961593db41cf85689db1d583cJoe Perches			diva_os_malloc(0, a->xdi_mbox.data_length);
6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (a->xdi_mbox.data) {
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			*(dword *) a->xdi_mbox.data =
632475be4d85a274d0961593db41cf85689db1d583cJoe Perches				(dword) a->xdi_adapter.serialNo;
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ret = 0;
6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->xdi_mbox.data_length = sizeof(dword) * 9;
6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->xdi_mbox.data =
641475be4d85a274d0961593db41cf85689db1d583cJoe Perches			diva_os_malloc(0, a->xdi_mbox.data_length);
6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (a->xdi_mbox.data) {
6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			int i;
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			dword *data = (dword *) a->xdi_mbox.data;
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for (i = 0; i < 8; i++) {
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				*data++ = a->resources.pci.bar[i];
6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			*data++ = (dword) a->resources.pci.irq;
6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ret = 0;
6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DIVA_XDI_UM_CMD_RESET_ADAPTER:
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ret = diva_pri_reset_adapter(&a->xdi_adapter);
6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ret = diva_pri_write_sdram_block(&a->xdi_adapter,
6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						 cmd->command_data.
6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						 write_sdram.offset,
663475be4d85a274d0961593db41cf85689db1d583cJoe Perches						 (byte *)&cmd[1],
6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						 cmd->command_data.
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						 write_sdram.length,
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						 pri_is_rev_2_card(a->
6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds								   CardOrdinal)
6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						 ? MP2_MEMORY_SIZE :
6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						 MP_MEMORY_SIZE);
6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DIVA_XDI_UM_CMD_STOP_ADAPTER:
6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ret = diva_pri_stop_adapter(a);
6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DIVA_XDI_UM_CMD_START_ADAPTER:
6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ret = diva_pri_start_adapter(&a->xdi_adapter,
6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					     cmd->command_data.start.
6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					     offset,
6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					     cmd->command_data.start.
6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					     features);
6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->xdi_adapter.features =
686475be4d85a274d0961593db41cf85689db1d583cJoe Perches			cmd->command_data.features.features;
6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->xdi_adapter.a.protocol_capabilities =
688475be4d85a274d0961593db41cf85689db1d583cJoe Perches			a->xdi_adapter.features;
6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_TRC(("Set raw protocol features (%08x)",
6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 a->xdi_adapter.features))
691475be4d85a274d0961593db41cf85689db1d583cJoe Perches			ret = 0;
6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DIVA_XDI_UM_CMD_GET_CARD_STATE:
6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->xdi_mbox.data_length = sizeof(dword);
6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->xdi_mbox.data =
697475be4d85a274d0961593db41cf85689db1d583cJoe Perches			diva_os_malloc(0, a->xdi_mbox.data_length);
6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (a->xdi_mbox.data) {
6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			dword *data = (dword *) a->xdi_mbox.data;
7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (!a->xdi_adapter.ram ||
701475be4d85a274d0961593db41cf85689db1d583cJoe Perches			    !a->xdi_adapter.reset ||
7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    !a->xdi_adapter.cfg) {
7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				*data = 3;
7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			} else if (a->xdi_adapter.trapped) {
7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				*data = 2;
7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			} else if (a->xdi_adapter.Initialized) {
7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				*data = 1;
7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			} else {
7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				*data = 0;
7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ret = 0;
7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY:
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ret = diva_card_read_xlog(a);
7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case DIVA_XDI_UM_CMD_READ_SDRAM:
7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (a->xdi_adapter.Address) {
7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (
723475be4d85a274d0961593db41cf85689db1d583cJoe Perches				(a->xdi_mbox.data_length =
724475be4d85a274d0961593db41cf85689db1d583cJoe Perches				 cmd->command_data.read_sdram.length)) {
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (
726475be4d85a274d0961593db41cf85689db1d583cJoe Perches					(a->xdi_mbox.data_length +
727475be4d85a274d0961593db41cf85689db1d583cJoe Perches					 cmd->command_data.read_sdram.offset) <
728475be4d85a274d0961593db41cf85689db1d583cJoe Perches					a->xdi_adapter.MemorySize) {
7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					a->xdi_mbox.data =
730475be4d85a274d0961593db41cf85689db1d583cJoe Perches						diva_os_malloc(0,
731475be4d85a274d0961593db41cf85689db1d583cJoe Perches							       a->xdi_mbox.
732475be4d85a274d0961593db41cf85689db1d583cJoe Perches							       data_length);
7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					if (a->xdi_mbox.data) {
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						byte __iomem *src = p;
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						byte *dst = a->xdi_mbox.data;
7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						dword len = a->xdi_mbox.data_length;
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						src += cmd->command_data.read_sdram.offset;
7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						while (len--) {
7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds							*dst++ = READ_BYTE(src++);
7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						}
7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						ret = 0;
7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					}
7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	default:
7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller,
7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 cmd->command))
756475be4d85a274d0961593db41cf85689db1d583cJoe Perches			}
7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (ret);
7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  Get Serial Number
7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
764475be4d85a274d0961593db41cf85689db1d583cJoe Perchesstatic int pri_get_serial_number(diva_os_xdi_adapter_t *a)
7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byte data[64];
7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dword len = sizeof(data);
7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	volatile byte __iomem *config;
7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	volatile byte __iomem *flash;
7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byte c;
7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  First set some GT6401x config registers before accessing the BOOT-ROM
7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
776475be4d85a274d0961593db41cf85689db1d583cJoe Perches	config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	c = READ_BYTE(&config[0xc3c]);
7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!(c & 0x08)) {
7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		WRITE_BYTE(&config[0xc3c], c);	/* Base Address enable register */
7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0x00);
7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
783475be4d85a274d0961593db41cf85689db1d583cJoe Perches	DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Read only the last 64 bytes of manufacturing data
7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(data, '\0', len);
788475be4d85a274d0961593db41cf85689db1d583cJoe Perches	flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < len; i++) {
7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		data[i] = READ_BYTE(&flash[0x8000 - len + i]);
7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
792475be4d85a274d0961593db41cf85689db1d583cJoe Perches	DIVA_OS_MEM_DETACH_PROM(&a->xdi_adapter, flash);
7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
794475be4d85a274d0961593db41cf85689db1d583cJoe Perches	config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0xFC);	/* Disable FLASH EPROM access */
7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
797475be4d85a274d0961593db41cf85689db1d583cJoe Perches	DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (memcmp(&data[48], "DIVAserverPR", 12)) {
8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if !defined(DIVA_PRI_NO_PCI_BIOS_WORKAROUND)	/* { */
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		word cmd = 0, cmd_org;
8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		void *addr;
8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dword addr1, addr3, addr4;
8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		byte Bus, Slot;
8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		void *hdev;
8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		addr4 = a->resources.pci.bar[4];
8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		addr3 = a->resources.pci.bar[3];	/* flash  */
8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		addr1 = a->resources.pci.bar[1];	/* unused */
8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: apply Compaq BIOS workaround"))
811475be4d85a274d0961593db41cf85689db1d583cJoe Perches			DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
812475be4d85a274d0961593db41cf85689db1d583cJoe Perches				 data[0], data[1], data[2], data[3],
813475be4d85a274d0961593db41cf85689db1d583cJoe Perches				 data[4], data[5], data[6], data[7]))
8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
815475be4d85a274d0961593db41cf85689db1d583cJoe Perches			Bus = a->resources.pci.bus;
8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		Slot = a->resources.pci.func;
8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		hdev = a->resources.pci.hdev;
8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		PCIwrite(Bus, Slot, 0x04, &cmd, sizeof(cmd), hdev);
8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		PCIwrite(Bus, Slot, 0x14, &addr4, sizeof(addr4), hdev);
8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		PCIwrite(Bus, Slot, 0x20, &addr1, sizeof(addr1), hdev);
8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		PCIwrite(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		addr = a->resources.pci.addr[1];
8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->resources.pci.addr[1] = a->resources.pci.addr[4];
8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->resources.pci.addr[4] = addr;
8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		addr1 = a->resources.pci.bar[1];
8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->resources.pci.bar[1] = a->resources.pci.bar[4];
8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->resources.pci.bar[4] = addr1;
8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/*
835475be4d85a274d0961593db41cf85689db1d583cJoe Perches		  Try to read Flash again
836475be4d85a274d0961593db41cf85689db1d583cJoe Perches		*/
8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		len = sizeof(data);
8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
839475be4d85a274d0961593db41cf85689db1d583cJoe Perches		config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!(config[0xc3c] & 0x08)) {
8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			config[0xc3c] |= 0x08;	/* Base Address enable register */
8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		config[LOW_BOOTCS_DREG] = 0x00;
8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		config[HI_BOOTCS_DREG] = 0xFF;
845475be4d85a274d0961593db41cf85689db1d583cJoe Perches		DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		memset(data, '\0', len);
848475be4d85a274d0961593db41cf85689db1d583cJoe Perches		flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (i = 0; i < len; i++) {
8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			data[i] = flash[0x8000 - len + i];
8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
852475be4d85a274d0961593db41cf85689db1d583cJoe Perches		DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter, flash);
853475be4d85a274d0961593db41cf85689db1d583cJoe Perches		config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		config[LOW_BOOTCS_DREG] = 0xFC;
8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		config[HI_BOOTCS_DREG] = 0xFF;
856475be4d85a274d0961593db41cf85689db1d583cJoe Perches		DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (memcmp(&data[48], "DIVAserverPR", 12)) {
8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DBG_ERR(("A: failed to read serial number"))
860475be4d85a274d0961593db41cf85689db1d583cJoe Perches				DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
861475be4d85a274d0961593db41cf85689db1d583cJoe Perches					 data[0], data[1], data[2], data[3],
862475be4d85a274d0961593db41cf85689db1d583cJoe Perches					 data[4], data[5], data[6], data[7]))
863475be4d85a274d0961593db41cf85689db1d583cJoe Perches				return (-1);
8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else				/* } { */
8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: failed to read DIVA signature word"))
867475be4d85a274d0961593db41cf85689db1d583cJoe Perches			DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
868475be4d85a274d0961593db41cf85689db1d583cJoe Perches				 data[0], data[1], data[2], data[3],
869475be4d85a274d0961593db41cf85689db1d583cJoe Perches				 data[4], data[5], data[6], data[7]))
870475be4d85a274d0961593db41cf85689db1d583cJoe Perches			DBG_LOG(("%02x:%02x:%02x:%02x", data[47], data[46],
871475be4d85a274d0961593db41cf85689db1d583cJoe Perches				 data[45], data[44]))
8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif				/* } */
873475be4d85a274d0961593db41cf85689db1d583cJoe Perches			}
8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	a->xdi_adapter.serialNo =
876475be4d85a274d0961593db41cf85689db1d583cJoe Perches		(data[47] << 24) | (data[46] << 16) | (data[45] << 8) |
877475be4d85a274d0961593db41cf85689db1d583cJoe Perches		data[44];
8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!a->xdi_adapter.serialNo
8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    || (a->xdi_adapter.serialNo == 0xffffffff)) {
8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		a->xdi_adapter.serialNo = 0;
8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: failed to read serial number"))
882475be4d85a274d0961593db41cf85689db1d583cJoe Perches			return (-1);
8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DBG_LOG(("Serial No.          : %ld", a->xdi_adapter.serialNo))
886475be4d85a274d0961593db41cf85689db1d583cJoe Perches		DBG_TRC(("Board Revision      : %d.%02d", (int) data[41],
887475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 (int) data[40]))
888475be4d85a274d0961593db41cf85689db1d583cJoe Perches		DBG_TRC(("PLD revision        : %d.%02d", (int) data[33],
889475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 (int) data[32]))
890475be4d85a274d0961593db41cf85689db1d583cJoe Perches		DBG_TRC(("Boot loader version : %d.%02d", (int) data[37],
891475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 (int) data[36]))
8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
893475be4d85a274d0961593db41cf85689db1d583cJoe Perches		DBG_TRC(("Manufacturing Date  : %d/%02d/%02d  (yyyy/mm/dd)",
894475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 (int) ((data[28] > 90) ? 1900 : 2000) +
895475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 (int) data[28], (int) data[29], (int) data[30]))
8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
897475be4d85a274d0961593db41cf85689db1d583cJoe Perches		return (0);
8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid diva_os_prepare_pri2_functions(PISDN_ADAPTER IoAdapter)
9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid diva_os_prepare_pri_functions(PISDN_ADAPTER IoAdapter)
9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  Checks presence of DSP on board
9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
912475be4d85a274d0961593db41cf85689db1d583cJoe Perchesdsp_check_presence(volatile byte __iomem *addr, volatile byte __iomem *data, int dsp)
9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	word pattern;
9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	WRITE_WORD(addr, 0x4000);
9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	WRITE_WORD(data, DSP_SIGNATURE_PROBE_WORD);
9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	WRITE_WORD(addr, 0x4000);
9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pattern = READ_WORD(data);
9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (pattern != DSP_SIGNATURE_PROBE_WORD) {
9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_TRC(("W: DSP[%d] %04x(is) != %04x(should)",
9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 dsp, pattern, DSP_SIGNATURE_PROBE_WORD))
925475be4d85a274d0961593db41cf85689db1d583cJoe Perches			return (-1);
9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	WRITE_WORD(addr, 0x4000);
9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	WRITE_WORD(data, ~DSP_SIGNATURE_PROBE_WORD);
9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	WRITE_WORD(addr, 0x4000);
9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pattern = READ_WORD(data);
9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
934475be4d85a274d0961593db41cf85689db1d583cJoe Perches	if (pattern != (word)~DSP_SIGNATURE_PROBE_WORD) {
9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: DSP[%d] %04x(is) != %04x(should)",
936475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 dsp, pattern, (word)~DSP_SIGNATURE_PROBE_WORD))
937475be4d85a274d0961593db41cf85689db1d583cJoe Perches			return (-2);
9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DBG_TRC(("DSP[%d] present", dsp))
9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
942475be4d85a274d0961593db41cf85689db1d583cJoe Perches		return (0);
9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  Check if DSP's are present and operating
9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  Information about detected DSP's is returned as bit mask
9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  Bit 0  - DSP1
9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  ...
9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  ...
9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  ...
9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds**  Bit 29 - DSP30
9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
955475be4d85a274d0961593db41cf85689db1d583cJoe Perchesstatic dword diva_pri_detect_dsps(diva_os_xdi_adapter_t *a)
9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byte __iomem *base;
9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byte __iomem *p;
9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dword ret = 0;
9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dword row_offset[7] = {
9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		0x00000000,
9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		0x00000800,	/* 1 - ROW 1 */
9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		0x00000840,	/* 2 - ROW 2 */
9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		0x00001000,	/* 3 - ROW 3 */
9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		0x00001040,	/* 4 - ROW 4 */
9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		0x00000000	/* 5 - ROW 0 */
9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	};
9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byte __iomem *dsp_addr_port;
9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byte __iomem *dsp_data_port;
9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byte row_state;
9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int dsp_row = 0, dsp_index, dsp_num;
9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!a->xdi_adapter.Control || !a->xdi_adapter.reset) {
9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (0);
9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	WRITE_BYTE(p, _MP_RISC_RESET | _MP_DSP_RESET);
9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_os_wait(5);
9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	base = DIVA_OS_MEM_ATTACH_CONTROL(&a->xdi_adapter);
9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (dsp_num = 0; dsp_num < 30; dsp_num++) {
9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dsp_row = dsp_num / 7 + 1;
9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dsp_index = dsp_num % 7;
9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dsp_data_port = base;
9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dsp_addr_port = base;
9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dsp_data_port += row_offset[dsp_row];
9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dsp_addr_port += row_offset[dsp_row];
9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dsp_data_port += (dsp_index * 8);
9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dsp_addr_port += (dsp_index * 8) + 0x80;
9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!dsp_check_presence
9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		    (dsp_addr_port, dsp_data_port, dsp_num + 1)) {
10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ret |= (1 << dsp_num);
10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DIVA_OS_MEM_DETACH_CONTROL(&a->xdi_adapter, base);
10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	diva_os_wait(5);
10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1011475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Verify modules
1012475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (dsp_row = 0; dsp_row < 4; dsp_row++) {
10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		row_state = ((ret >> (dsp_row * 7)) & 0x7F);
10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (row_state && (row_state != 0x7F)) {
10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			for (dsp_index = 0; dsp_index < 7; dsp_index++) {
10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (!(row_state & (1 << dsp_index))) {
10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					DBG_ERR(("A: MODULE[%d]-DSP[%d] failed",
10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						 dsp_row + 1,
10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds						 dsp_index + 1))
1021475be4d85a274d0961593db41cf85689db1d583cJoe Perches						}
10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!(ret & 0x10000000)) {
10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: ON BOARD-DSP[1] failed"))
1028475be4d85a274d0961593db41cf85689db1d583cJoe Perches			}
10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!(ret & 0x20000000)) {
10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DBG_ERR(("A: ON BOARD-DSP[2] failed"))
1031475be4d85a274d0961593db41cf85689db1d583cJoe Perches			}
10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1034475be4d85a274d0961593db41cf85689db1d583cJoe Perches	  Print module population now
1035475be4d85a274d0961593db41cf85689db1d583cJoe Perches	*/
10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DBG_LOG(("+-----------------------+"))
1037475be4d85a274d0961593db41cf85689db1d583cJoe Perches		DBG_LOG(("| DSP MODULE POPULATION |"))
1038475be4d85a274d0961593db41cf85689db1d583cJoe Perches		DBG_LOG(("+-----------------------+"))
1039475be4d85a274d0961593db41cf85689db1d583cJoe Perches		DBG_LOG(("|  1  |  2  |  3  |  4  |"))
1040475be4d85a274d0961593db41cf85689db1d583cJoe Perches		DBG_LOG(("+-----------------------+"))
1041475be4d85a274d0961593db41cf85689db1d583cJoe Perches		DBG_LOG(("|  %s  |  %s  |  %s  |  %s  |",
1042475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 ((ret >> (0 * 7)) & 0x7F) ? "Y" : "N",
1043475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 ((ret >> (1 * 7)) & 0x7F) ? "Y" : "N",
1044475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 ((ret >> (2 * 7)) & 0x7F) ? "Y" : "N",
1045475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 ((ret >> (3 * 7)) & 0x7F) ? "Y" : "N"))
1046475be4d85a274d0961593db41cf85689db1d583cJoe Perches		DBG_LOG(("+-----------------------+"))
1047475be4d85a274d0961593db41cf85689db1d583cJoe Perches
1048475be4d85a274d0961593db41cf85689db1d583cJoe Perches		DBG_LOG(("DSP's(present-absent):%08x-%08x", ret,
1049475be4d85a274d0961593db41cf85689db1d583cJoe Perches			 ~ret & 0x3fffffff))
1050475be4d85a274d0961593db41cf85689db1d583cJoe Perches
1051475be4d85a274d0961593db41cf85689db1d583cJoe Perches		return (ret);
10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1053