2 * Copyright (C) Eicon Technology Corporation, 2000.
4 * Eicon File Revision : 1.15
6 * This software may be used and distributed according to the terms
7 * of the GNU General Public License, incorporated herein by reference.
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
26 #define TEST_INT_DIVAS 0x11
27 #define TEST_INT_DIVAS_BRI 0x12
28 #define TEST_INT_DIVAS_Q 0x13
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
36 #define DIVAS_SIGNATURE 0x4447
38 #define MP_PROTOCOL_ADDR 0xA0011000
41 #define DIVAS_IOBASE 1
49 dword reserved[(0x1020>>2)-6];
55 card_t DivasCards[MAX_CARDS];
57 dia_config_t *DivasConfig(card_t *, dia_config_t *);
60 DESCRIPTOR DIDD_Table[32];
62 void DIVA_DIDD_Read( DESCRIPTOR *table, int tablelength )
64 memset(table, 0, tablelength);
66 if (tablelength > sizeof(DIDD_Table))
67 tablelength = sizeof(DIDD_Table);
69 if(tablelength % sizeof(DESCRIPTOR)) {
70 tablelength /= sizeof(DESCRIPTOR);
71 tablelength *= sizeof(DESCRIPTOR);
75 memcpy((void *)table, (void *)DIDD_Table, tablelength);
80 void DIVA_DIDD_Write(DESCRIPTOR *table, int tablelength)
82 if (tablelength > sizeof(DIDD_Table))
83 tablelength = sizeof(DIDD_Table);
85 memcpy((void *)DIDD_Table, (void *)table, tablelength);
91 void init_idi_tab(void)
95 memset(d, 0, sizeof(d));
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;
102 DIVA_DIDD_Write(d, sizeof(d));
108 * I/O routines for memory mapped cards
111 byte mem_in(ADAPTER *a, void *adr)
113 card_t *card = a->io;
114 unsigned char *b, *m;
117 m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
119 m += (unsigned int) adr;
121 value = UxCardMemIn(card->hw, m);
123 UxCardMemDetach(card->hw, b);
128 word mem_inw(ADAPTER *a, void *adr)
130 card_t *card = a->io;
131 unsigned char *b, *m;
134 m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
136 m += (unsigned int) adr;
138 value = UxCardMemInW(card->hw, m);
140 UxCardMemDetach(card->hw, b);
145 void mem_in_buffer(ADAPTER *a, void *adr, void *P, word length)
147 card_t *card = a->io;
148 unsigned char *b, *m;
150 m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
152 m += (unsigned int) adr;
154 UxCardMemInBuffer(card->hw, m, P, length);
156 UxCardMemDetach(card->hw, b);
161 void mem_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
163 card_t *card = a->io;
164 unsigned char *b, *m;
166 m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
168 m += (dword) &RBuffer->length;
169 card->RBuffer.length = UxCardMemInW(card->hw, m);
172 m += (dword) &RBuffer->P;
173 UxCardMemInBuffer(card->hw, m, card->RBuffer.P, card->RBuffer.length);
175 e->RBuffer = (DBUFFER *) &card->RBuffer;
177 UxCardMemDetach(card->hw, b);
182 void mem_out(ADAPTER *a, void *adr, byte data)
184 card_t *card = a->io;
185 unsigned char *b, *m;
187 m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
189 m += (unsigned int) adr;
191 UxCardMemOut(card->hw, m, data);
193 UxCardMemDetach(card->hw, b);
198 void mem_outw(ADAPTER *a, void *adr, word data)
200 card_t *card = a->io;
201 unsigned char *b, *m;
203 m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
205 m += (unsigned int) adr;
207 UxCardMemOutW(card->hw, m, data);
209 UxCardMemDetach(card->hw, b);
214 void mem_out_buffer(ADAPTER *a, void *adr, void *P, word length)
216 card_t *card = a->io;
217 unsigned char *b, *m;
219 m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
221 m += (unsigned int) adr;
223 UxCardMemOutBuffer(card->hw, m, P, length);
225 UxCardMemDetach(card->hw, b);
230 void mem_inc(ADAPTER *a, void *adr)
233 card_t *card = a->io;
234 unsigned char *b, *m;
236 m = b = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
238 m += (unsigned int) adr;
240 value = UxCardMemInW(card->hw, m);
242 UxCardMemOutW(card->hw, m, value);
244 UxCardMemDetach(card->hw, b);
250 * I/O routines for I/O mapped cards
253 byte io_in(ADAPTER *a, void *adr)
255 card_t *card = a->io;
257 byte *DivasIOBase = NULL;
259 DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
261 value = UxCardIoIn(card->hw, DivasIOBase, adr);
263 UxCardMemDetach(card->hw, DivasIOBase);
268 word io_inw(ADAPTER *a, void *adr)
270 card_t *card = a->io;
272 byte *DivasIOBase = NULL;
274 DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
276 value = UxCardIoInW(card->hw, DivasIOBase, adr);
278 UxCardMemDetach(card->hw, DivasIOBase);
283 void io_in_buffer(ADAPTER *a, void *adr, void *P, word length)
285 card_t *card = a->io;
286 byte *DivasIOBase = NULL;
288 DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
290 UxCardIoInBuffer(card->hw, DivasIOBase, adr, P,length);
292 UxCardMemDetach(card->hw, DivasIOBase);
297 void io_look_ahead(ADAPTER *a, PBUFFER *RBuffer, ENTITY *e)
299 card_t *card = a->io;
300 byte *DivasIOBase = NULL;
302 DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
304 card->RBuffer.length = UxCardIoInW(card->hw, DivasIOBase, (byte *) RBuffer);
306 UxCardIoInBuffer(card->hw, DivasIOBase, &RBuffer->P, card->RBuffer.P, card->RBuffer.length);
308 UxCardMemDetach(card->hw, DivasIOBase);
310 e->RBuffer = (DBUFFER *) &card->RBuffer;
315 void io_out(ADAPTER *a, void *adr, byte data)
317 card_t *card = a->io;
318 byte *DivasIOBase = NULL;
320 DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
322 UxCardIoOut(card->hw, DivasIOBase, adr, data);
324 UxCardMemDetach(card->hw, DivasIOBase);
329 void io_outw(ADAPTER *a, void *adr, word data)
331 card_t *card = a->io;
332 byte *DivasIOBase = NULL;
334 DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
336 UxCardIoOutW(card->hw, DivasIOBase, adr, data);
338 UxCardMemDetach(card->hw, DivasIOBase);
343 void io_out_buffer(ADAPTER *a, void *adr, void *P, word length)
345 card_t *card = a->io;
346 byte *DivasIOBase = NULL;
348 DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
350 UxCardIoOutBuffer(card->hw, DivasIOBase, adr, P, length);
352 UxCardMemDetach(card->hw, DivasIOBase);
357 void io_inc(ADAPTER *a, void *adr)
360 card_t *card = a->io;
363 DivasIOBase = UxCardMemAttach(card->hw, DIVAS_IOBASE);
365 value = UxCardIoInW(card->hw, DivasIOBase, adr);
369 UxCardIoOutW(card->hw, DivasIOBase, adr, value);
371 UxCardMemDetach(card->hw, DivasIOBase);
377 void test_int(card_t *card)
380 byte *shared, *DivasIOBase;
382 switch (card->test_int_pend)
385 DPRINTF(("divas: test interrupt pending"));
386 shared = UxCardMemAttach(card->hw, DIVAS_SHARED_MEMORY);
388 if (UxCardMemIn(card->hw, &shared[0x3FE]))
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"));
399 UxCardMemDetach(card->hw, shared);
401 card->test_int_pend = 0;
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;
414 case TEST_INT_DIVAS_Q:
415 DPRINTF(("divas: 4BRI test interrupt pending"));
416 (*card->reset_int)(card);
417 card->test_int_pend = 0;
421 DPRINTF(("divas: unknown test interrupt pending"));
427 void card_isr (void *dev_id)
429 card_t *card = (card_t *) dev_id;
430 ADAPTER *a = &card->a;
433 if (card->test_int_pend)
435 ipl = UxCardLock(card->hw);
438 UxCardUnlock(card->hw,ipl);
444 (*(card->card_isr))(card);
448 ipl = UxCardLock(card->hw);
450 if ((card->test_int)(a))
452 (card->reset_int)(card);
455 UxCardUnlock(card->hw,ipl);
461 int DivasCardNew(dia_card_t *card_info)
464 static boolean_t first_call = TRUE;
465 boolean_t NeedISRandReset = FALSE;
467 DPRINTF(("divas: new card "));
475 DivasConfigGet(card_info);
477 if (DivasCardNext == DIM(DivasCards))
479 KDPRINTF((KERN_WARNING "Divas: no space available for new card"));
483 card = &DivasCards[DivasCardNext];
485 card->state = DIA_UNKNOWN;
487 card->cfg = *card_info;
491 if (UxCardHandleGet(&card->hw, card_info))
493 KDPRINTF((KERN_WARNING "Divas: cannot get OS specific handle for card"));
497 if (card_info->card_type == DIA_CARD_TYPE_DIVA_SERVER_B)
500 card_info->io_base = card->cfg.io_base;
503 switch (card_info->card_type)
505 case DIA_CARD_TYPE_DIVA_SERVER:
506 if (DivasPriInit(card, card_info))
510 NeedISRandReset = TRUE;
513 case DIA_CARD_TYPE_DIVA_SERVER_B:
514 if (DivasBriInit(card, card_info))
518 NeedISRandReset = TRUE;
521 case DIA_CARD_TYPE_DIVA_SERVER_Q:
522 if (Divas4BriInit(card, card_info))
527 if (card_info->name[6] == '0')
529 NeedISRandReset = TRUE;
531 else // Need to set paramater for ISR anyway
533 card->hw->user_isr_arg = card;
534 card->hw->user_isr = card_isr;
539 KDPRINTF((KERN_WARNING "Divas: unsupported card type (%d)", card_info->card_type));
545 if (UxIsrInstall(card->hw, card_isr, card))
547 KDPRINTF((KERN_WARNING "Divas: Install ISR failed (IRQ %d)", card->cfg.irq));
548 UxCardHandleFree(card->hw);
552 if (card_info->card_type != DIA_CARD_TYPE_DIVA_SERVER_Q)
554 if ((*card->card_reset)(card))
556 KDPRINTF((KERN_WARNING "Divas: Adapter reset failed"));
559 card->state = DIA_RESET;
562 NeedISRandReset = FALSE;
570 void *get_card(int card_id)
574 for (i=0; i < DivasCardNext; i++)
576 if (DivasCards[i].cfg.card_id == card_id)
578 return(&DivasCards[i]);
582 DPRINTF(("divas: get_card() : no such card id (%d)", card_id));
587 int DivasCardConfig(dia_config_t *config)
592 DPRINTF(("divas: configuring card"));
594 card = get_card(config->card_id);
600 config = DivasConfig(card, config);
602 status = (*card->card_config)(card, config);
606 card->state = DIA_CONFIGURED;
611 int DivasCardLoad(dia_load_t *load)
616 card = get_card(load->card_id);
622 if (card->state == DIA_RUNNING)
624 (*card->card_reset)(card);
627 status = (*card->card_load)(card, load);
630 card->state = DIA_LOADED;
635 static int idi_register(card_t *card, byte channels)
638 int length, num_entities;
640 DPRINTF(("divas: registering card with IDI"));
642 num_entities = (channels > 2) ? MAX_PENTITIES : MAX_ENTITIES;
643 card->e_tbl = UxAlloc(sizeof(E_INFO) * num_entities);
647 KDPRINTF((KERN_WARNING "Divas: IDI register failed - no memory available"));
651 memset(card->e_tbl, 0, sizeof(E_INFO) * num_entities);
652 card->e_max = num_entities;
654 DIVA_DIDD_Read(d, sizeof(d));
656 for(length=0; length < DIM(d); length++)
657 if (d[length].type == 0) break;
659 if (length >= DIM(d))
661 KDPRINTF((KERN_WARNING "Divas: IDI register failed - table full"));
665 switch (card->cfg.card_type)
667 case DIA_CARD_TYPE_DIVA_SERVER:
668 d[length].type = IDI_ADAPTER_PR;
669 /* d[length].serial = card->serial_no; */
672 case DIA_CARD_TYPE_DIVA_SERVER_B:
673 d[length].type = IDI_ADAPTER_MAESTRA;
674 /* d[length].serial = card->serial_no; */
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; */
683 d[length].features = 0;
684 d[length].features |= DI_FAX3|DI_MODEM|DI_POST|DI_V110|DI_V120;
686 if ( card->hw->features & PROTCAP_MANIF )
688 d[length].features |= DI_MANAGE ;
690 if ( card->hw->features & PROTCAP_V_42 )
692 d[length].features |= DI_V_42 ;
694 if ( card->hw->features & PROTCAP_EXTD_FAX )
696 d[length].features |= DI_EXTD_FAX ;
699 d[length].channels = channels;
700 d[length].request = DivasIdiRequest[card - DivasCards];
704 DIVA_DIDD_Write(d, sizeof(d));
709 int DivasCardStart(int card_id)
715 DPRINTF(("divas: starting card"));
717 card = get_card(card_id);
723 status = (*card->card_start)(card, &channels);
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)
733 card_t *FourBRISlave;
735 for (i=3; i >= 0; i--)
737 FourBRISlave = get_card(card_id - i); /* 0, 1, 2, 3 */
740 idi_register(FourBRISlave, 2);
741 FourBRISlave->state = DIA_RUNNING;
744 card->serial_no = card->cfg.serial;
746 DPRINTF(("divas: card id %d (4BRI), serial no. 0x%x ready with %d channels",
747 card_id - 3, card->serial_no, (int) channels));
751 status = idi_register(card, channels);
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));
763 int DivasGetMem(mem_block_t *mem_block)
766 word card_id = mem_block->card_id;
768 card = get_card(card_id);
774 return (*card->card_mem_get)(card, mem_block);
779 * Deleyed Procedure Call for handling interrupts from card
782 void DivaDoCardDpc(card_t *card)
788 if(UxInterlockedIncrement(card->hw, &card->dpc_reentered) > 1)
794 if((*(card->test_int))(a))
797 (*(card->clear_int))(a);
800 }while(UxInterlockedDecrement(card->hw, &card->dpc_reentered));
804 void DivasDoDpc(void *pData)
806 card_t *card = DivasCards;
807 int i = DivasCardNext;
811 if (card->state == DIA_RUNNING)
817 void DivasDoRequestDpc(void *pData)
824 * Returns the number of active adapters
827 int DivasGetNum(void)
829 return(DivasCardNext);
834 * Returns a list of active adapters
836 int DivasGetList(dia_card_list_t *card_list)
840 memset(card_list, 0, sizeof(dia_card_list_t));
842 for(i = 0; i < DivasCardNext; i++)
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;
855 * control logging for specified card
858 void DivasLog(dia_log_t *log)
862 card = get_card(log->card_id);
868 card->log_types = log->log_types;