1 /*
2  * Copyright (C) Eicon Technology Corporation, 2000.
3  *
4  * Eicon File Revision :    1.15
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 "constant.h"
15 #include "divas.h"
16 #include "pc.h"
17 #include "pr_pc.h"
18 
19 #include "uxio.h"
20 
21 #define DIVAS_LOAD_CMD		0x02
22 #define DIVAS_START_CMD		0x03
23 #define DIVAS_IRQ_RESET		0xC18
24 #define DIVAS_IRQ_RESET_VAL	0xFE
25 
26 #define TEST_INT_DIVAS		0x11
27 #define TEST_INT_DIVAS_BRI	0x12
28 #define TEST_INT_DIVAS_Q	0x13
29 
30 #define DIVAS_RESET	0x81
31 #define DIVAS_LED1	0x04
32 #define DIVAS_LED2	0x08
33 #define DIVAS_LED3	0x20
34 #define DIVAS_LED4	0x40
35 
36 #define DIVAS_SIGNATURE 0x4447
37 
38 #define MP_PROTOCOL_ADDR 0xA0011000
39 
40 #define PLX_IOBASE	0
41 #define	DIVAS_IOBASE	1
42 
43 typedef struct {
44 		dword cmd;
45 		dword addr;
46 		dword len;
47 		dword err;
48 		dword live;
49 		dword reserved[(0x1020>>2)-6];
50 		dword signature;
51 		byte  data[1];
52 } diva_server_boot_t;
53 
54 int		DivasCardNext;
55 card_t	DivasCards[MAX_CARDS];
56 
57 dia_config_t *DivasConfig(card_t *, dia_config_t *);
58 
59 static
60 DESCRIPTOR DIDD_Table[32];
61 
DIVA_DIDD_Read(DESCRIPTOR * table,int tablelength)62 void    DIVA_DIDD_Read( DESCRIPTOR *table, int tablelength )
63 {
64         memset(table, 0, tablelength);
65 
66         if (tablelength > sizeof(DIDD_Table))
67           tablelength = sizeof(DIDD_Table);
68 
69         if(tablelength % sizeof(DESCRIPTOR)) {
70           tablelength /= sizeof(DESCRIPTOR);
71           tablelength *= sizeof(DESCRIPTOR);
72         }
73 
74         if (tablelength > 0)
75           memcpy((void *)table, (void *)DIDD_Table, tablelength);
76 
77 	return;
78 }
79 
DIVA_DIDD_Write(DESCRIPTOR * table,int tablelength)80 void 	DIVA_DIDD_Write(DESCRIPTOR *table, int tablelength)
81 {
82         if (tablelength > sizeof(DIDD_Table))
83           tablelength = sizeof(DIDD_Table);
84 
85 	memcpy((void *)DIDD_Table, (void *)table, tablelength);
86 
87 	return;
88 }
89 
90 static
init_idi_tab(void)91 void    init_idi_tab(void)
92 {
93     DESCRIPTOR d[32];
94 
95     memset(d, 0, sizeof(d));
96 
97     d[0].type = IDI_DIMAINT;  /* identify the DIMAINT entry */
98     d[0].channels = 0; /* zero channels associated with dimaint*/
99     d[0].features = 0; /* no features associated with dimaint */
100     d[0].request = (IDI_CALL) DivasPrintf;
101 
102     DIVA_DIDD_Write(d, sizeof(d));
103 
104     return;
105 }
106 
107 /*
108  * I/O routines for memory mapped cards
109  */
110 
mem_in(ADAPTER * a,void * adr)111 byte mem_in(ADAPTER *a, void *adr)
112 {
113 	card_t			*card = a->io;
114 	unsigned char	*b, *m;
115 	byte			value;
116 
117 	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
118 
119 	m += (unsigned int) adr;
120 
121 	value = UxCardMemIn(card->hw, m);
122 
123 	UxCardMemDetach(card->hw, b);
124 
125 	return value;
126 }
127 
mem_inw(ADAPTER * a,void * adr)128 word mem_inw(ADAPTER *a, void *adr)
129 {
130 	card_t			*card = a->io;
131 	unsigned char	*b, *m;
132 	word			value;
133 
134 	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
135 
136 	m += (unsigned int) adr;
137 
138 	value = UxCardMemInW(card->hw, m);
139 
140 	UxCardMemDetach(card->hw, b);
141 
142 	return value;
143 }
144 
mem_in_buffer(ADAPTER * a,void * adr,void * P,word length)145 void mem_in_buffer(ADAPTER *a, void *adr, void *P, word length)
146 {
147 	card_t			*card = a->io;
148 	unsigned char	*b, *m;
149 
150 	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
151 
152 	m += (unsigned int) adr;
153 
154 	UxCardMemInBuffer(card->hw, m, P, length);
155 
156 	UxCardMemDetach(card->hw, b);
157 
158 	return;
159 }
160 
mem_look_ahead(ADAPTER * a,PBUFFER * RBuffer,ENTITY * e)161 void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
162 {
163 	card_t			*card = a->io;
164 	unsigned char	*b, *m;
165 
166 	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
167 
168 	m += (dword) &RBuffer->length;
169 	card->RBuffer.length = UxCardMemInW(card->hw, m);
170 
171 	m = b;
172 	m += (dword) &RBuffer->P;
173 	UxCardMemInBuffer(card->hw, m, card->RBuffer.P, card->RBuffer.length);
174 
175 	e->RBuffer = (DBUFFER *) &card->RBuffer;
176 
177 	UxCardMemDetach(card->hw, b);
178 
179 	return;
180 }
181 
mem_out(ADAPTER * a,void * adr,byte data)182 void mem_out(ADAPTER *a, void *adr, byte data)
183 {
184 	card_t			*card = a->io;
185 	unsigned char	*b, *m;
186 
187 	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
188 
189 	m += (unsigned int) adr;
190 
191 	UxCardMemOut(card->hw, m, data);
192 
193 	UxCardMemDetach(card->hw, b);
194 
195 	return;
196 }
197 
mem_outw(ADAPTER * a,void * adr,word data)198 void mem_outw(ADAPTER *a, void *adr, word data)
199 {
200 	card_t			*card = a->io;
201 	unsigned char	*b, *m;
202 
203 	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
204 
205 	m += (unsigned int) adr;
206 
207 	UxCardMemOutW(card->hw, m, data);
208 
209 	UxCardMemDetach(card->hw, b);
210 
211 	return;
212 }
213 
mem_out_buffer(ADAPTER * a,void * adr,void * P,word length)214 void mem_out_buffer(ADAPTER *a, void *adr, void *P, word length)
215 {
216 	card_t			*card = a->io;
217 	unsigned char	*b, *m;
218 
219 	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
220 
221 	m += (unsigned int) adr;
222 
223 	UxCardMemOutBuffer(card->hw, m, P, length);
224 
225 	UxCardMemDetach(card->hw, b);
226 
227 	return;
228 }
229 
mem_inc(ADAPTER * a,void * adr)230 void mem_inc(ADAPTER *a, void *adr)
231 {
232 	word			value;
233 	card_t			*card = a->io;
234 	unsigned char	*b, *m;
235 
236 	m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
237 
238 	m += (unsigned int) adr;
239 
240 	value = UxCardMemInW(card->hw, m);
241 	value++;
242 	UxCardMemOutW(card->hw, m, value);
243 
244 	UxCardMemDetach(card->hw, b);
245 
246 	return;
247 }
248 
249 /*
250  * I/O routines for I/O mapped cards
251  */
252 
io_in(ADAPTER * a,void * adr)253 byte io_in(ADAPTER *a, void *adr)
254 {
255 	card_t		    *card = a->io;
256 	byte		    value;
257 	byte	*DivasIOBase = NULL;
258 
259 	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
260 
261 	value = UxCardIoIn(card->hw, DivasIOBase, adr);
262 
263 	UxCardMemDetach(card->hw, DivasIOBase);
264 
265     return value;
266 }
267 
io_inw(ADAPTER * a,void * adr)268 word io_inw(ADAPTER *a, void *adr)
269 {
270 	card_t		*card = a->io;
271 	word		value;
272 	byte	*DivasIOBase = NULL;
273 
274 	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
275 
276 	value = UxCardIoInW(card->hw, DivasIOBase, adr);
277 
278 	UxCardMemDetach(card->hw, DivasIOBase);
279 
280 	return value;
281 }
282 
io_in_buffer(ADAPTER * a,void * adr,void * P,word length)283 void io_in_buffer(ADAPTER *a, void *adr, void *P, word length)
284 {
285 	card_t *card = a->io;
286 	byte *DivasIOBase = NULL;
287 
288 	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
289 
290 	UxCardIoInBuffer(card->hw, DivasIOBase, adr, P,length);
291 
292 	UxCardMemDetach(card->hw, DivasIOBase);
293 
294     return;
295 }
296 
io_look_ahead(ADAPTER * a,PBUFFER * RBuffer,ENTITY * e)297 void io_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
298 {
299 	card_t *card = a->io;
300 	byte *DivasIOBase = NULL;
301 
302 	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
303 
304 	card->RBuffer.length = UxCardIoInW(card->hw, DivasIOBase, (byte *) RBuffer);
305 
306 	UxCardIoInBuffer(card->hw, DivasIOBase, &RBuffer->P, card->RBuffer.P, card->RBuffer.length);
307 
308 	UxCardMemDetach(card->hw, DivasIOBase);
309 
310 	e->RBuffer = (DBUFFER *) &card->RBuffer;
311 
312     return;
313 }
314 
io_out(ADAPTER * a,void * adr,byte data)315 void io_out(ADAPTER *a, void *adr, byte data)
316 {
317 	card_t		*card = a->io;
318 	byte	*DivasIOBase = NULL;
319 
320 	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
321 
322 	UxCardIoOut(card->hw, DivasIOBase, adr, data);
323 
324 	UxCardMemDetach(card->hw, DivasIOBase);
325 
326     return;
327 }
328 
io_outw(ADAPTER * a,void * adr,word data)329 void io_outw(ADAPTER *a, void *adr, word data)
330 {
331 	card_t		*card = a->io;
332 	byte	*DivasIOBase = NULL;
333 
334 	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
335 
336 	UxCardIoOutW(card->hw, DivasIOBase, adr, data);
337 
338 	UxCardMemDetach(card->hw, DivasIOBase);
339 
340     return;
341 }
342 
io_out_buffer(ADAPTER * a,void * adr,void * P,word length)343 void io_out_buffer(ADAPTER *a, void *adr, void *P, word length)
344 {
345 	card_t		*card = a->io;
346 	byte *DivasIOBase = NULL;
347 
348 	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
349 
350 	UxCardIoOutBuffer(card->hw, DivasIOBase, adr, P, length);
351 
352 	UxCardMemDetach(card->hw, DivasIOBase);
353 
354     return;
355 }
356 
io_inc(ADAPTER * a,void * adr)357 void io_inc(ADAPTER *a, void *adr)
358 {
359 	word		value;
360 	card_t		*card = a->io;
361 	byte *DivasIOBase;
362 
363 	DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
364 
365 	value = UxCardIoInW(card->hw, DivasIOBase, adr);
366 
367 	value++;
368 
369 	UxCardIoOutW(card->hw, DivasIOBase, adr, value);
370 
371 	UxCardMemDetach(card->hw, DivasIOBase);
372 
373     return;
374 }
375 
376 static
test_int(card_t * card)377 void test_int(card_t *card)
378 
379 {
380 	byte *shared, *DivasIOBase;
381 
382 	switch (card->test_int_pend)
383 	{
384 		case TEST_INT_DIVAS:
385 			DPRINTF(("divas: test interrupt pending"));
386 			shared = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
387 
388 			if (UxCardMemIn(card->hw, &shared[0x3FE]))
389 			{
390 				UxCardMemOut(card->hw,
391 								&(((struct pr_ram *)shared)->RcOutput), 0);
392 				UxCardMemDetach(card->hw, shared);
393             	(*card->reset_int)(card);
394 				shared = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
395 				UxCardMemOut(card->hw, &shared[0x3FE], 0);
396 				DPRINTF(("divas: test interrupt cleared"));
397 			}
398 
399 			UxCardMemDetach(card->hw, shared);
400 
401 			card->test_int_pend = 0;
402 			break;
403 
404 		case TEST_INT_DIVAS_BRI:
405 			DPRINTF(("divas: BRI test interrupt pending"));
406 			(*card->reset_int)(card);
407 			DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
408 			UxCardIoOutW(card->hw, DivasIOBase, (void *) 0x3FE, 0);
409 			UxCardMemDetach(card->hw, DivasIOBase);
410 			DPRINTF(("divas: test interrupt cleared"));
411 			card->test_int_pend = 0;
412 			break;
413 
414 		case TEST_INT_DIVAS_Q:
415 			DPRINTF(("divas: 4BRI test interrupt pending"));
416 			(*card->reset_int)(card);
417 			card->test_int_pend = 0;
418 			break;
419 
420 		default:
421 			DPRINTF(("divas: unknown test interrupt pending"));
422 			return;
423 	}
424 	return;
425 }
426 
card_isr(void * dev_id)427 void card_isr (void *dev_id)
428 {
429 	card_t *card = (card_t *) dev_id;
430 	ADAPTER *a = &card->a;
431 	int ipl;
432 
433 	if (card->test_int_pend)
434 	{
435 		ipl = UxCardLock(card->hw);
436 		card->int_pend=0;
437 		test_int(card);
438 		UxCardUnlock(card->hw,ipl);
439 		return;
440 	}
441 
442 	if(card->card_isr)
443 	{
444 		(*(card->card_isr))(card);
445 	}
446 	else
447 	{
448 		ipl = UxCardLock(card->hw);
449 
450 		if ((card->test_int)(a))
451 		{
452 			(card->reset_int)(card);
453 		}
454 
455 		UxCardUnlock(card->hw,ipl);
456 
457 	}
458 
459 }
460 
DivasCardNew(dia_card_t * card_info)461 int DivasCardNew(dia_card_t *card_info)
462 {
463 	card_t *card;
464 	static boolean_t first_call = TRUE;
465 	boolean_t NeedISRandReset = FALSE;
466 
467 	DPRINTF(("divas: new card "));
468 
469 	if (first_call)
470 	{
471 		first_call = FALSE;
472 		init_idi_tab();
473 	}
474 
475 	DivasConfigGet(card_info);
476 
477 	if (DivasCardNext == DIM(DivasCards))
478 	{
479 		KDPRINTF((KERN_WARNING "Divas: no space available for new card"));
480 		return -1;
481 	}
482 
483 	card = &DivasCards[DivasCardNext];
484 
485 	card->state = DIA_UNKNOWN;
486 
487 	card->cfg = *card_info;
488 
489 	card->a.io = card;
490 
491 	if (UxCardHandleGet(&card->hw, card_info))
492 	{
493 		KDPRINTF((KERN_WARNING "Divas: cannot get OS specific handle for card"));
494 		return -1;
495 	}
496 
497 	if (card_info->card_type == DIA_CARD_TYPE_DIVA_SERVER_B)
498 	{
499 		DivasBriPatch(card);
500 		card_info->io_base = card->cfg.io_base;
501 	}
502 
503 	switch (card_info->card_type)
504 	{
505 		case DIA_CARD_TYPE_DIVA_SERVER:
506 			if (DivasPriInit(card, card_info))
507 			{
508 				return -1;
509 			}
510 			NeedISRandReset = TRUE;
511 			break;
512 
513 		case DIA_CARD_TYPE_DIVA_SERVER_B:
514 			if (DivasBriInit(card, card_info))
515 			{
516 				return -1;
517 			}
518 			NeedISRandReset = TRUE;
519 			break;
520 
521  		case DIA_CARD_TYPE_DIVA_SERVER_Q:
522 			if (Divas4BriInit(card, card_info))
523 			{
524 				return -1;
525 			}
526 
527 			if (card_info->name[6] == '0')
528 			{
529 				NeedISRandReset = TRUE;
530 			}
531 			else // Need to set paramater for ISR anyway
532 			{
533 				card->hw->user_isr_arg = card;
534 				card->hw->user_isr = card_isr;
535 			}
536 			break;
537 
538 		default:
539 			KDPRINTF((KERN_WARNING "Divas: unsupported card type (%d)", card_info->card_type));
540 			return -1;
541 	}
542 
543 	if (NeedISRandReset)
544 	{
545 		if (UxIsrInstall(card->hw, card_isr, card))
546 		{
547 			KDPRINTF((KERN_WARNING "Divas: Install ISR failed (IRQ %d)", card->cfg.irq));
548 			UxCardHandleFree(card->hw);
549 			return -1;
550 		}
551 
552 		if (card_info->card_type != DIA_CARD_TYPE_DIVA_SERVER_Q)
553 		{
554 			if ((*card->card_reset)(card))
555 			{
556 				KDPRINTF((KERN_WARNING "Divas: Adapter reset failed"));
557 				return -1;
558 			}
559 			card->state = DIA_RESET;
560 		}
561 
562 		NeedISRandReset = FALSE;
563 	}
564 
565 	DivasCardNext++;
566 
567 	return 0;
568 }
569 
get_card(int card_id)570 void	*get_card(int card_id)
571 {
572 	int i;
573 
574 	for (i=0; i < DivasCardNext; i++)
575 	{
576 		if (DivasCards[i].cfg.card_id == card_id)
577 		{
578 			return(&DivasCards[i]);
579 		}
580 	}
581 
582 	DPRINTF(("divas: get_card() : no such card id (%d)", card_id));
583 
584 	return NULL;
585 }
586 
DivasCardConfig(dia_config_t * config)587 int DivasCardConfig(dia_config_t *config)
588 {
589 	card_t *card;
590 	int status;
591 
592 	DPRINTF(("divas: configuring card"));
593 
594 	card = get_card(config->card_id);
595 	if (!card)
596 	{
597 		return -1;
598 	}
599 
600 	config = DivasConfig(card, config);
601 
602 	status = (*card->card_config)(card, config);
603 
604 	if (!status)
605 	{
606 		card->state = DIA_CONFIGURED;
607 	}
608 	return status;
609 }
610 
DivasCardLoad(dia_load_t * load)611 int DivasCardLoad(dia_load_t *load)
612 {
613 	card_t *card;
614 	int	status;
615 
616 	card = get_card(load->card_id);
617 	if (!card)
618 	{
619 		return -1;
620 	}
621 
622 	if (card->state == DIA_RUNNING)
623 	{
624 		(*card->card_reset)(card);
625 	}
626 
627 	status = (*card->card_load)(card, load);
628 	if (!status)
629 	{
630 		card->state = DIA_LOADED;
631 	}
632 	return status;
633 }
634 
idi_register(card_t * card,byte channels)635 static int idi_register(card_t *card, byte channels)
636 {
637     DESCRIPTOR d[32];
638     int length, num_entities;
639 
640 	DPRINTF(("divas: registering card with IDI"));
641 
642 	num_entities = (channels > 2) ? MAX_PENTITIES : MAX_ENTITIES;
643 	card->e_tbl = UxAlloc(sizeof(E_INFO) * num_entities);
644 
645 	if (!card->e_tbl)
646 	{
647 		KDPRINTF((KERN_WARNING "Divas: IDI register failed - no memory available"));
648 		return -1;
649 	}
650 
651 	memset(card->e_tbl, 0, sizeof(E_INFO) * num_entities);
652 	card->e_max = num_entities;
653 
654     DIVA_DIDD_Read(d, sizeof(d));
655 
656         for(length=0; length < DIM(d); length++)
657           if (d[length].type == 0) break;
658 
659 	if (length >= DIM(d))
660 	{
661 		KDPRINTF((KERN_WARNING "Divas: IDI register failed - table full"));
662 		return -1;
663 	}
664 
665 	switch (card->cfg.card_type)
666 	{
667 		case DIA_CARD_TYPE_DIVA_SERVER:
668 		d[length].type = IDI_ADAPTER_PR;
669 		/* d[length].serial = card->serial_no; */
670 		break;
671 
672 		case DIA_CARD_TYPE_DIVA_SERVER_B:
673 		d[length].type = IDI_ADAPTER_MAESTRA;
674 		/* d[length].serial = card->serial_no; */
675 		break;
676 
677 		// 4BRI is treated as 4 BRI adapters
678 		case DIA_CARD_TYPE_DIVA_SERVER_Q:
679 		d[length].type = IDI_ADAPTER_MAESTRA;
680 		/* d[length].serial = card->cfg.serial; */
681 	}
682 
683 	d[length].features = 0;
684 	d[length].features |= DI_FAX3|DI_MODEM|DI_POST|DI_V110|DI_V120;
685 
686 	if ( card->hw->features & PROTCAP_MANIF )
687 	{
688 		d[length].features |= DI_MANAGE ;
689 	}
690 	if ( card->hw->features & PROTCAP_V_42 )
691 	{
692 		d[length].features |= DI_V_42 ;
693 	}
694 	if ( card->hw->features & PROTCAP_EXTD_FAX )
695 	{
696 		d[length].features |= DI_EXTD_FAX ;
697 	}
698 
699 	d[length].channels = channels;
700 	d[length].request = DivasIdiRequest[card - DivasCards];
701 
702 	length++;
703 
704 	DIVA_DIDD_Write(d, sizeof(d));
705 
706     return 0;
707 }
708 
DivasCardStart(int card_id)709 int DivasCardStart(int card_id)
710 {
711 	card_t *card;
712 	byte channels;
713 	int status;
714 
715 	DPRINTF(("divas: starting card"));
716 
717 	card = get_card(card_id);
718 	if (!card)
719 	{
720 		return -1;
721 	}
722 
723 	status = (*card->card_start)(card, &channels);
724 	if (status)
725 	{
726 		return status;
727 	}
728 
729 	/* 4BRI == 4 x BRI so call idi_register 4 times each with 2 channels */
730 	if (card->cfg.card_type == DIA_CARD_TYPE_DIVA_SERVER_Q)
731 	{
732 		int i;
733 		card_t *FourBRISlave;
734 
735 		for (i=3; i >= 0; i--)
736 		{
737 			FourBRISlave = get_card(card_id - i); /* 0, 1, 2, 3 */
738 			if (FourBRISlave)
739 			{
740 				idi_register(FourBRISlave, 2);
741 				FourBRISlave->state = DIA_RUNNING;
742 			}
743 		}
744 		card->serial_no = card->cfg.serial;
745 
746 		DPRINTF(("divas: card id %d (4BRI), serial no. 0x%x ready with %d channels",
747 				card_id - 3, card->serial_no, (int) channels));
748 	}
749 	else
750 	{
751 		status = idi_register(card, channels);
752 		if (!status)
753 		{
754 			card->state = DIA_RUNNING;
755 			DPRINTF(("divas: card id %d, serial no. 0x%x ready with %d channels",
756 						card_id, card->serial_no, (int) channels));
757 		}
758 	}
759 
760 	return status;
761 }
762 
DivasGetMem(mem_block_t * mem_block)763 int DivasGetMem(mem_block_t *mem_block)
764 {
765 	card_t *card;
766 	word	card_id = mem_block->card_id;
767 
768 	card = get_card(card_id);
769 	if (!card)
770 	{
771 		return 0;
772 	}
773 
774 	return (*card->card_mem_get)(card, mem_block);
775 }
776 
777 
778 /*
779  * Deleyed Procedure Call for handling interrupts from card
780  */
781 
DivaDoCardDpc(card_t * card)782 void	DivaDoCardDpc(card_t *card)
783 {
784 	ADAPTER	*a;
785 
786 	a = &card->a;
787 
788 	if(UxInterlockedIncrement(card->hw, &card->dpc_reentered) > 1)
789 	{
790 		return;
791 	}
792 
793 	do{
794 		if((*(card->test_int))(a))
795 		{
796 			(*(card->dpc))(a);
797 			(*(card->clear_int))(a);
798 		}
799 			(*(card->out))(a);
800 	}while(UxInterlockedDecrement(card->hw, &card->dpc_reentered));
801 
802 }
803 
DivasDoDpc(void * pData)804 void	DivasDoDpc(void *pData)
805 {
806 	card_t	*card = DivasCards;
807 	int 	i = DivasCardNext;
808 
809 	while(i--)
810 	{
811             if (card->state == DIA_RUNNING)
812 		DivaDoCardDpc(card);
813             card++;
814 	}
815 }
816 
DivasDoRequestDpc(void * pData)817 void	DivasDoRequestDpc(void *pData)
818 {
819 	DivasDoDpc(pData);
820 }
821 
822 /*
823  * DivasGetNum
824  * Returns the number of active adapters
825  */
826 
DivasGetNum(void)827 int DivasGetNum(void)
828 {
829 	return(DivasCardNext);
830 }
831 
832 /*
833  * DivasGetList
834  * Returns a list of active adapters
835  */
DivasGetList(dia_card_list_t * card_list)836 int DivasGetList(dia_card_list_t *card_list)
837 {
838 	int i;
839 
840 	memset(card_list, 0, sizeof(dia_card_list_t));
841 
842 	for(i = 0; i < DivasCardNext; i++)
843 	{
844 		card_list->card_type = DivasCards[i].cfg.card_type;
845 		card_list->card_slot = DivasCards[i].cfg.slot;
846 		card_list->state     = DivasCards[i].state;
847 		card_list++;
848 	}
849 
850 	return 0;
851 
852 }
853 
854 /*
855  * control logging for specified card
856  */
857 
DivasLog(dia_log_t * log)858 void	DivasLog(dia_log_t *log)
859 {
860 	card_t *card;
861 
862 	card = get_card(log->card_id);
863 	if (!card)
864 	{
865 		return;
866 	}
867 
868 	card->log_types = log->log_types;
869 
870 	return;
871 }
872 
873