1 /*
2  * Copyright (C) Eicon Technology Corporation, 2000.
3  *
4  * Eicon File Revision :    1.8
5  *
6  * This software may be used and distributed according to the terms
7  * of the GNU General Public License, incorporated herein by reference.
8  *
9  */
10 
11 #include "eicon.h"
12 #include "sys.h"
13 #include "idi.h"
14 #include "divas.h"
15 #include "pc.h"
16 #include "pr_pc.h"
17 #include "dsp_defs.h"
18 
19 #include "adapter.h"
20 #include "uxio.h"
21 
22 #define PCI_BADDR0	0x10
23 #define PCI_BADDR1	0x14
24 #define PCI_BADDR2	0x18
25 
26 #define DIVAS_SIGNATURE 0x4447
27 
28 /* offset to start of MAINT area (used by xlog) */
29 
30 #define	DIVAS_MAINT_OFFSET	0xff00		/* value for BRI card */
31 
32 #define PROTCAP_TELINDUS	0x1
33 #define PROTCAP_V90D		0x8
34 
35 word GetProtFeatureValue(char *sw_id);
36 byte io_in(ADAPTER *a, void *adr);
37 word io_inw(ADAPTER *a, void *adr);
38 void io_in_buffer(ADAPTER *a, void *adr, void *P, word length);
39 void io_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e);
40 void io_out(ADAPTER *a, void *adr, byte data);
41 void io_outw(ADAPTER *a, void *adr, word data);
42 void io_out_buffer(ADAPTER *a, void *adr, void *P, word length);
43 void io_inc(ADAPTER *a, void *adr);
44 
45 static int diva_server_bri_test_int(card_t *card);
46 static int bri_ISR (card_t* card);
47 
48 #define PLX_IOBASE		0
49 #define	DIVAS_IOBASE	1
50 
51 #define	REG_DATA		0x00
52 #define	REG_ADDRLO		0x04
53 #define REG_ADDRHI		0x0C
54 #define REG_IOCTRL		0x10
55 
56 #define M_PCI_RESET	0x10
57 
58 byte UxCardPortIoIn(ux_diva_card_t *card, byte *base, int offset);
59 word UxCardPortIoInW(ux_diva_card_t *card, byte *base, int offset);
60 void UxCardPortIoOut(ux_diva_card_t *card, byte *base, int offset, byte);
61 void UxCardPortIoOutW(ux_diva_card_t *card, byte *base, int offset, word);
62 
63 int DivasBRIInitPCI(card_t *card, dia_card_t *cfg);
64 
65 static
diva_server_bri_reset(card_t * card)66 int	diva_server_bri_reset(card_t *card)
67 {
68 	byte *DivasIOBase;
69 	word i;
70 	dword dwWait;
71 
72 	UxCardLog(0);
73 
74 	DPRINTF(("divas: resetting BRI adapter"));
75 
76 	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
77 
78 	UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0);
79 
80 	for (i=0; i < 50000; i++)
81 		;
82 
83 	UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0);
84 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0);
85 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_DATA  , 0);
86 
87 	UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
88 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x0000);
89 
90 	for (i=0; i<0x8000; i++)
91 	{
92 		UxCardPortIoOutW(card->hw, DivasIOBase, REG_DATA , 0);
93 	}
94 
95 	for (dwWait=0; dwWait < 0x00FFFFFF; dwWait++)
96 		;
97 
98 	UxCardMemDetach(card->hw, DivasIOBase);
99 
100 	return 0;
101 }
102 
103 static
diva_server_bri_reset_int(card_t * card)104 void diva_server_bri_reset_int(card_t *card)
105 {
106 	byte *DivasIOBase = NULL;
107 
108 	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
109 
110 	UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0x08);
111 
112 	UxCardMemDetach(card->hw, DivasIOBase);
113 
114 	return;
115 }
116 
117 static
diva_server_bri_start(card_t * card,byte * channels)118 int diva_server_bri_start(card_t *card, byte *channels)
119 {
120 	byte *DivasIOBase, *PLXIOBase;
121 	word wSig = 0;
122 	word i;
123 	dword dwSerialNum;
124 	byte bPLX9060 = FALSE;
125 
126 	DPRINTF(("divas: starting Diva Server BRI card"));
127 
128 	card->is_live = FALSE;
129 
130 	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
131 
132 	UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
133 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x1E);
134 
135 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA  , 0);
136 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA  , 0);
137 
138 	UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0x08);
139 
140 	/* wait for signature to indicate card has started */
141 	for (i = 0; i < 300; i++)
142 	{
143 		UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
144 		UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x1E);
145 		wSig = UxCardPortIoInW(card->hw, DivasIOBase, REG_DATA);
146 
147 		if (wSig == DIVAS_SIGNATURE)
148 		{
149 			DPRINTF(("divas: card started after %d ms", i * 10));
150 			break;
151 		}
152 		UxPause(10);
153 	}
154 
155 	if (wSig != DIVAS_SIGNATURE)
156 	{
157 		DPRINTF(("divas: card failed to start (Sig=0x%x)", wSig));
158 		UxCardMemDetach(card->hw, DivasIOBase);
159 		return -1;
160 	}
161 
162 	card->is_live = TRUE;
163 
164 	UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
165 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 0x3F6);
166 	*channels = UxCardPortIoInW(card->hw, DivasIOBase, REG_DATA);
167 
168 	UxCardMemDetach(card->hw, DivasIOBase);
169 
170 	PLXIOBase = UxCardMemAttach(card->hw, PLX_IOBASE);
171 
172 	bPLX9060 = UxCardPortIoInW(card->hw, PLXIOBase, 0x6C) | UxCardPortIoInW(card->hw, PLXIOBase, 0x6E);
173 
174 	if (bPLX9060)
175 	{
176 		dwSerialNum = (UxCardPortIoInW(card->hw, PLXIOBase, 0x1E) << 16) |
177 					(UxCardPortIoInW(card->hw, PLXIOBase, 0x22));
178 		DPRINTF(("divas: PLX9060 in use. Serial number 0x%04X", dwSerialNum));
179 	}
180 	else
181 	{
182 		dwSerialNum = (UxCardPortIoInW(card->hw, PLXIOBase, 0x22) << 16) |
183 					(UxCardPortIoInW(card->hw, PLXIOBase, 0x26));
184 		DPRINTF(("divas: PLX9050 in use. Serial number 0x%04X", dwSerialNum));
185 	}
186 
187 	UxCardMemDetach(card->hw, PLXIOBase);
188 
189 	card->serial_no = dwSerialNum;
190 
191 	diva_server_bri_test_int(card);
192 
193 	return 0;
194 }
195 
196 static
diva_server_bri_load(card_t * card,dia_load_t * load)197 int diva_server_bri_load(card_t *card, dia_load_t *load)
198 {
199 	byte *DivasIOBase;
200 	dword r3000_base;
201 	dword dwAddr, dwLength, i;
202 	word wTest, aWord;
203 
204 	DPRINTF(("divas: loading Diva Server BRI card"));
205 
206 	switch (load->code_type)
207 	{
208 		case DIA_CPU_CODE:
209 		DPRINTF(("divas: loading RISC %s", &load->code[0x80]));
210 
211 		card->hw->features = GetProtFeatureValue((char *)&load->code[0x80]);
212 		DPRINTF(("divas: features 0x%x", card->hw->features));
213 		if (card->hw->features == 0xFFFF)
214 		{
215 			DPRINTF(("divas: invalid feature string failed load\n"));
216 			return -1;
217 		}
218 
219 		r3000_base = 0;
220 		break;
221 
222 		case DIA_DSP_CODE:
223 		DPRINTF(("divas: DSP code \"%s\"", load->code));
224 
225 		if ((card->hw->features) && (!(card->hw->features & PROTCAP_TELINDUS)))
226 		{
227 			DPRINTF(("divas: only Telindus style binaries supported"));
228 			return -1;
229 		}
230 
231 		if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
232 		{
233 			DPRINTF(("divas: V.90 DSP binary"));
234 			r3000_base = (0xBF790000 + (((sizeof(dword) + (sizeof(t_dsp_download_desc)* DSP_MAX_DOWNLOAD_COUNT)) + 3) & 0xFFFFFFFC));
235 		}
236 		else
237 		{
238 			DPRINTF(("divas: non-V.90 DSP binary"));
239 			r3000_base = (0xBF7A0000 + (((sizeof(dword) + (sizeof(t_dsp_download_desc)* DSP_MAX_DOWNLOAD_COUNT)) + 3) & 0xFFFFFFFC));
240 		}
241 		DPRINTF(("divas: loading at 0x%x", r3000_base));
242 		break;
243 
244 		case DIA_TABLE_CODE:
245 		DPRINTF(("divas: TABLE code"));
246 		if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
247 		{
248 			r3000_base = 0xBF790000 + sizeof(dword);
249 		}
250 		else
251 		{
252 			r3000_base = 0xBF7A0000 + sizeof(dword);
253 		}
254 
255 		break;
256 
257 		case DIA_DLOAD_CNT:
258 		DPRINTF(("divas: COUNT code"));
259 		if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
260 		{
261 			r3000_base = 0xBF790000;
262 		}
263 		else
264 		{
265 			r3000_base = 0xBF7A0000;
266 		}
267 		break;
268 
269 		default:
270 		DPRINTF(("divas: unknown code type %d", load->code_type));
271 		return -1;
272 		break;
273 	}
274 
275 	DPRINTF(("divas: Writing %d bytes to adapter, address 0x%x", load->length, r3000_base));
276 
277 	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
278 
279 	DPRINTF(("divas: Attached to 0x%04X", DivasIOBase));
280 
281 	dwLength = load->length;
282 
283 	for (i=0; i < dwLength; i++)
284 	{
285 		dwAddr = r3000_base + i;
286 
287 		UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, dwAddr >> 16);
288 		UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, dwAddr);
289 
290 		UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, load->code[i]);
291 	}
292 
293 	DPRINTF(("divas: Verifying"));
294 
295 	for (i=0; i<dwLength; i++)
296 	{
297 		dwAddr = r3000_base + i;
298 
299 		UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, dwAddr >> 16);
300 		UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, dwAddr);
301 
302 		wTest = UxCardPortIoIn(card->hw, DivasIOBase, REG_DATA);
303 
304 		aWord = load->code[i];
305 
306 		if (wTest != aWord)
307 		{
308 			DPRINTF(("divas: load verify failed on byte %d", i));
309 			DPRINTF(("divas: RAM 0x%x   File 0x%x",wTest,aWord));
310 
311 			UxCardMemDetach(card->hw, DivasIOBase);
312 
313 			return -1;
314 		}
315 	}
316 
317 	DPRINTF(("divas: Loaded and verified. Detaching from adapter"));
318 
319 	UxCardMemDetach(card->hw, DivasIOBase);
320 
321 	UxCardLog(0);
322 
323 	return 0;
324 }
325 
326 static
diva_server_bri_config(card_t * card,dia_config_t * config)327 int diva_server_bri_config(card_t *card, dia_config_t *config)
328 {
329 	byte *DivasIOBase, i;
330 
331 	DPRINTF(("divas: configuring Diva Server BRI card"));
332 
333 	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
334 
335 	UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, 0xFF);
336 
337 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 8);
338 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->tei);
339 
340 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 9);
341 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->nt2);
342 
343 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 10);
344 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->sig_flags);
345 
346 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 11);
347 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->watchdog);
348 
349 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 12);
350 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->permanent);
351 
352 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 13);
353 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
354 
355 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 14);
356 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->stable_l2);
357 
358 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 15);
359 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->no_order_check);
360 
361 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 16);
362 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
363 
364 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 17);
365 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
366 
367 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 18);
368 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->low_channel);
369 
370 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 19);
371 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->prot_version);
372 
373 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 20);
374 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->crc4);
375 
376 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 21);
377 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
378 
379 	if ((card->hw->features) && (card->hw->features & PROTCAP_V90D))
380 	{
381 		DPRINTF(("divas: Signifying V.90"));
382 		UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 22);
383 		UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 4);
384 	}
385 	else
386 	{
387 		UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 22);
388 		UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 0);
389 	}
390 
391 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 23);
392 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, card->serial_no & 0xFF);
393 
394 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 24);
395 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, (card->serial_no >> 8) & 0xFF);
396 
397 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 25);
398 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, (card->serial_no >> 16) & 0xFF);
399 
400 	UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 26);
401 	UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, 21);
402 
403 	for (i=0; i<32; i++)
404 	{
405 		UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 32+i);
406 		UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[0].oad[i]);
407 
408 		UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 64+i);
409 		UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[0].osa[i]);
410 
411 		UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 96+i);
412 		UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[0].spid[i]);
413 
414 
415 		UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 128+i);
416 		UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[1].oad[i]);
417 
418 		UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 160+i);
419 		UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[1].osa[i]);
420 
421 		UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, 192+i);
422 		UxCardPortIoOut(card->hw, DivasIOBase, REG_DATA, config->terminal[1].spid[i]);
423 	}
424 
425 	UxCardMemDetach(card->hw, DivasIOBase);
426 
427 	return 0;
428 }
429 
DivasBriPatch(card_t * card)430 void DivasBriPatch(card_t *card)
431 {
432 	dword	PLXIOBase = 0;
433 	dword	DivasIOBase = 0;
434 
435 	PLXIOBase = card->cfg.reset_base;
436 	DivasIOBase = card->cfg.io_base;
437 
438 	if(card->hw == NULL)
439 	{
440 		DPRINTF(("Divas: BRI PATCH (PLX chip) card->hw is null"));
441 		return;
442 	}
443 
444 	if (PLXIOBase == 0)
445 	{
446 		DPRINTF(("Divas: BRI (PLX chip) cannot be patched. The BRI adapter may"));
447 		DPRINTF(("Divas:   not function properly. If you do encounter problems,"));
448 		DPRINTF(("Divas:   ensure that your machine is using the latest BIOS."));
449 		return;
450 	}
451 
452 	DPRINTF(("Divas: PLX I/O Base 0x%x", PLXIOBase));
453 	DPRINTF(("Divas: Divas I/O Base 0x%x", DivasIOBase));
454 
455 	if (PLXIOBase & 0x80)
456 	{
457 		dword dwSize, dwSerialNum, dwCmd;
458 		boolean_t bPLX9060;
459 		word wSerHi, wSerLo;
460 
461 		DPRINTF(("Divas: Patch required"));
462 		dwCmd = 0;
463 		UxPciConfigWrite(card->hw, 4, PCI_COMMAND, &dwCmd);
464 
465 		PLXIOBase &= ~0x80;
466 		UxPciConfigWrite(card->hw, 4, PCI_BADDR1, &PLXIOBase);
467 
468 		dwSize = 0xFFFFFFFF;
469 		UxPciConfigWrite(card->hw, 4, PCI_BADDR1, &dwSize);
470 		UxPciConfigRead(card->hw, 4, PCI_BADDR1, &dwSize);
471 
472 		dwSize = (~ (dwSize & ~7)) + 1;
473 
474 		DivasIOBase = PLXIOBase + dwSize;
475 
476 		card->cfg.reset_base = PLXIOBase;
477 		card->cfg.io_base = DivasIOBase;
478 		UxPciConfigWrite(card->hw, 4, PCI_BADDR1, &card->cfg.reset_base);
479 		UxPciConfigWrite(card->hw, 4, PCI_BADDR2, &card->cfg.io_base);
480 
481 		dwCmd = 5;
482 		UxPciConfigWrite(card->hw, 4, PCI_COMMAND, &dwCmd);
483 
484 		bPLX9060 = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6C) |
485 			   UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6E);
486 
487 		if (bPLX9060)
488 		{
489 			wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x1E);
490 			wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
491 			dwSerialNum = (wSerHi << 16) | wSerLo;
492 			UxCardLog(0);
493 		}
494 		else
495 		{
496 			wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
497 			wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x26);
498 			dwSerialNum = (wSerHi << 16) | wSerLo;
499 			UxCardLog(0);
500 		}
501 	}
502 	else
503 	{
504 		word wSerHi, wSerLo;
505 		boolean_t bPLX9060;
506 		dword dwSerialNum;
507 
508 		DPRINTF(("divas: No patch required"));
509 
510 		bPLX9060 = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6C) |
511 			   UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x6E);
512 
513 		if (bPLX9060)
514 		{
515 			wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x1E);
516 			wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
517 			dwSerialNum = (wSerHi << 16) | wSerLo;
518 		}
519 		else
520 		{
521 			wSerHi = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x22);
522 			wSerLo = UxCardPortIoInW(card->hw, (void *) card->cfg.reset_base, 0x26);
523 			dwSerialNum = (wSerHi << 16) | wSerLo;
524 		}
525 	}
526 	DPRINTF(("Divas: After patching:"));
527 	DPRINTF(("Divas: PLX I/O Base 0x%x", PLXIOBase));
528 	DPRINTF(("Divas: Divas I/O Base 0x%x", DivasIOBase));
529 
530 }
531 
532 #define TEST_INT_DIVAS_BRI	0x12
533 static
diva_server_bri_test_int(card_t * card)534 int	diva_server_bri_test_int(card_t *card)
535 {
536 	boolean_t bPLX9060 = FALSE;
537 	byte *PLXIOBase = NULL, *DivasIOBase = NULL;
538 
539 	DPRINTF(("divas: test interrupt for Diva Server BRI card"));
540 
541 	PLXIOBase = UxCardMemAttach(card->hw, PLX_IOBASE);
542 
543 	bPLX9060 = UxCardPortIoInW(card->hw, PLXIOBase, 0x6C) || UxCardPortIoInW(card->hw, PLXIOBase, 0x6E);
544 
545 	if (bPLX9060)
546 	{ /* PLX9060 */
547 		UxCardPortIoOut(card->hw, PLXIOBase, 0x69, 0x09);
548 	}
549 	else
550 	{ /* PLX9050 */
551 		UxCardPortIoOut(card->hw, PLXIOBase, 0x4C, 0x41);
552 	}
553 
554 	card->test_int_pend = TEST_INT_DIVAS_BRI;
555 
556 	UxCardMemDetach(card->hw, PLXIOBase);
557 
558 	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
559 
560 	UxCardPortIoOut(card->hw, DivasIOBase, REG_IOCTRL, 0x89);
561 
562 	UxCardMemDetach(card->hw, DivasIOBase);
563 
564 	return 0;
565 }
566 
567 static
diva_server_bri_mem_get(card_t * card,mem_block_t * mem_block)568 int diva_server_bri_mem_get(card_t *card, mem_block_t *mem_block)
569 {
570 	dword user_addr = mem_block->addr;
571 	word	length = 0;
572 	dword	addr;
573 	word	i;
574 	byte *DivasIOBase;
575 
576 	DPRINTF(("divas: Retrieving memory from 0x%x", user_addr));
577 
578 	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
579 
580 	addr = user_addr;
581 
582 	for (i=0; i < (16 * 8); i++)
583 	{
584 		addr = user_addr + i;
585 
586 		UxCardPortIoOut(card->hw, DivasIOBase, REG_ADDRHI, addr >> 16);
587 		UxCardPortIoOutW(card->hw, DivasIOBase, REG_ADDRLO, (word) addr);
588 
589 		mem_block->data[i] = UxCardPortIoIn(card->hw, DivasIOBase, REG_DATA);
590 		length++;
591 	}
592 
593 	UxCardMemDetach(card->hw, DivasIOBase);
594 
595 	return length;
596 }
597 
DivasBriInit(card_t * card,dia_card_t * cfg)598 int DivasBriInit(card_t *card, dia_card_t *cfg)
599 {
600 	DPRINTF(("divas: initialise Diva Server BRI card"));
601 
602 	if (DivasBRIInitPCI(card, cfg) == -1)
603 	{
604 		return -1;
605 	}
606 
607 	card->card_reset 		= diva_server_bri_reset;
608 	card->card_start 		= diva_server_bri_start;
609 	card->card_load  		= diva_server_bri_load;
610 	card->card_config		= diva_server_bri_config;
611 	card->reset_int 		= diva_server_bri_reset_int;
612 	card->card_mem_get 		= diva_server_bri_mem_get;
613 
614 	card->xlog_offset 		= DIVAS_MAINT_OFFSET;
615 
616 	card->out 			= DivasOut;
617 	card->test_int 			= DivasTestInt;
618 	card->dpc 			= DivasDpc;
619 	card->clear_int 		= DivasClearInt;
620 	card->card_isr 			= bri_ISR;
621 
622 	card->a.ram_out 		= io_out;
623 	card->a.ram_outw 		= io_outw;
624 	card->a.ram_out_buffer 	= io_out_buffer;
625 	card->a.ram_inc 		= io_inc;
626 
627 	card->a.ram_in 			= io_in;
628 	card->a.ram_inw 		= io_inw;
629 	card->a.ram_in_buffer 	= io_in_buffer;
630 	card->a.ram_look_ahead	= io_look_ahead;
631 
632 	return 0;
633 }
634 
GetProtFeatureValue(char * sw_id)635 word GetProtFeatureValue(char *sw_id)
636 {
637 	word features = 0;
638 
639 	while ((*sw_id) && (sw_id[0] != '['))
640 		sw_id++;
641 
642 	if (sw_id == NULL)
643 	{
644 		DPRINTF(("divas: no feature string present"));
645 		features = -1;
646 	}
647 	else
648 	{
649 		byte i, shifter;
650 
651 		sw_id += 3;
652 
653 		for (i=0, shifter=12; i<4; i++, shifter-=4)
654 		{
655 			if ((sw_id[i] >= '0') && (sw_id[i] <= '9'))
656 			{
657 				features |= (sw_id[i] - '0') << shifter;
658 			}
659 			else if ((sw_id[i] >= 'a') && (sw_id[i] <= 'f'))
660 			{
661 				features |= (sw_id[i] - 'a' + 10) << shifter;
662 			}
663 			else if ((sw_id[i] >= 'A') && (sw_id[i] <= 'F'))
664 			{
665 				features |= (sw_id[i] - 'A' + 10) << shifter;
666 			}
667 			else
668 			{
669 				DPRINTF(("divas: invalid feature string"));
670 				return -1;
671 			}
672 		}
673 	}
674 
675 	return features;
676 }
677 
678 
bri_ISR(card_t * card)679 int bri_ISR (card_t* card)
680 {
681 	int served = 0;
682 	byte *DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
683 
684 	if (UxCardPortIoIn (card->hw, DivasIOBase, M_PCI_RESET) & 0x01)
685 	{
686 		served = 1;
687 		card->int_pend  += 1;
688 		DivasDpcSchedule(); /* ISR DPC */
689 		UxCardPortIoOut (card->hw, DivasIOBase, M_PCI_RESET, 0x08);
690 	}
691 
692 	UxCardMemDetach(card->hw, DivasIOBase);
693 
694 	return (served != 0);
695 }
696 
697 
698