initial commit with v2.6.9
[linux-2.6.9-moxart.git] / drivers / isdn / hardware / eicon / os_bri.c
blobe8f023d2df8982782c3bc207316ce3ed77dd096f
1 /* $Id: os_bri.c,v 1.21 2004/03/21 17:26:01 armin Exp $ */
3 #include "platform.h"
4 #include "debuglib.h"
5 #include "cardtype.h"
6 #include "pc.h"
7 #include "pr_pc.h"
8 #include "di_defs.h"
9 #include "dsp_defs.h"
10 #include "di.h"
11 #include "io.h"
13 #include "xdi_msg.h"
14 #include "xdi_adapter.h"
15 #include "os_bri.h"
16 #include "diva_pci.h"
17 #include "mi_pc.h"
18 #include "pc_maint.h"
21 ** IMPORTS
23 extern void prepare_maestra_functions(PISDN_ADAPTER IoAdapter);
24 extern void diva_xdi_display_adapter_features(int card);
25 extern int diva_card_read_xlog(diva_os_xdi_adapter_t * a);
28 ** LOCALS
30 static int bri_bar_length[3] = {
31 0x80,
32 0x80,
33 0x20
35 static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t * a);
36 static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t * a);
37 static int diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
38 diva_xdi_um_cfg_cmd_t * cmd, int length);
39 static int diva_bri_reregister_io(diva_os_xdi_adapter_t * a);
40 static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter);
41 static int diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
42 dword address,
43 const byte * data, dword length);
44 static int diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
45 dword start_address, dword features);
46 static int diva_bri_stop_adapter(diva_os_xdi_adapter_t * a);
48 static void diva_bri_set_addresses(diva_os_xdi_adapter_t * a)
50 a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
51 a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 1;
52 a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2;
53 a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 1;
54 a->resources.pci.mem_type_id[MEM_TYPE_PORT] = 2;
55 a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 2;
57 a->xdi_adapter.ram = a->resources.pci.addr[0];
58 a->xdi_adapter.cfg = a->resources.pci.addr[1];
59 a->xdi_adapter.Address = a->resources.pci.addr[2];
61 a->xdi_adapter.reset = a->xdi_adapter.cfg;
62 a->xdi_adapter.port = a->xdi_adapter.Address;
64 a->xdi_adapter.ctlReg = a->xdi_adapter.port + M_PCI_RESET;
66 a->xdi_adapter.reset += 0x4C; /* PLX 9050 !! */
70 ** BAR0 - MEM Addr - 0x80 - NOT USED
71 ** BAR1 - I/O Addr - 0x80
72 ** BAR2 - I/O Addr - 0x20
74 int diva_bri_init_card(diva_os_xdi_adapter_t * a)
76 int bar;
77 dword bar2 = 0, bar2_length = 0xffffffff;
78 word cmd = 0, cmd_org;
79 byte Bus, Slot;
80 void *hdev;
81 byte *p;
84 Set properties
86 a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
87 DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name))
90 Get resources
92 for (bar = 0; bar < 3; bar++) {
93 a->resources.pci.bar[bar] =
94 divasa_get_pci_bar(a->resources.pci.bus,
95 a->resources.pci.func, bar,
96 a->resources.pci.hdev);
97 if (!a->resources.pci.bar[bar]) {
98 DBG_ERR(("A: can't get BAR[%d]", bar))
99 return (-1);
103 a->resources.pci.irq =
104 (byte) divasa_get_pci_irq(a->resources.pci.bus,
105 a->resources.pci.func,
106 a->resources.pci.hdev);
107 if (!a->resources.pci.irq) {
108 DBG_ERR(("A: invalid irq"));
109 return (-1);
113 Get length of I/O bar 2 - it is different by older
114 EEPROM version
116 Bus = a->resources.pci.bus;
117 Slot = a->resources.pci.func;
118 hdev = a->resources.pci.hdev;
121 Get plain original values of the BAR2 CDM registers
123 PCIread(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev);
124 PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
126 Disable device and get BAR2 length
128 PCIwrite(Bus, Slot, 0x04, &cmd, sizeof(cmd), hdev);
129 PCIwrite(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev);
130 PCIread(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev);
132 Restore BAR2 and CMD registers
134 PCIwrite(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev);
135 PCIwrite(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
138 Calculate BAR2 length
140 bar2_length = (~(bar2_length & ~7)) + 1;
141 DBG_LOG(("BAR[2] length=%lx", bar2_length))
144 Map and register resources
146 if (!(a->resources.pci.addr[0] =
147 divasa_remap_pci_bar(a, 0, a->resources.pci.bar[0],
148 bri_bar_length[0]))) {
149 DBG_ERR(("A: BRI, can't map BAR[0]"))
150 diva_bri_cleanup_adapter(a);
151 return (-1);
154 sprintf(&a->port_name[0], "BRI %02x:%02x",
155 a->resources.pci.bus, a->resources.pci.func);
157 if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
158 bri_bar_length[1], &a->port_name[0], 1)) {
159 DBG_ERR(("A: BRI, can't register BAR[1]"))
160 diva_bri_cleanup_adapter(a);
161 return (-1);
163 a->resources.pci.addr[1] = (void *) (unsigned long) a->resources.pci.bar[1];
164 a->resources.pci.length[1] = bri_bar_length[1];
166 if (diva_os_register_io_port(a, 1, a->resources.pci.bar[2],
167 bar2_length, &a->port_name[0], 2)) {
168 DBG_ERR(("A: BRI, can't register BAR[2]"))
169 diva_bri_cleanup_adapter(a);
170 return (-1);
172 a->resources.pci.addr[2] = (void *) (unsigned long) a->resources.pci.bar[2];
173 a->resources.pci.length[2] = bar2_length;
176 Set all memory areas
178 diva_bri_set_addresses(a);
181 Get Serial Number
183 a->xdi_adapter.serialNo = diva_bri_get_serial_number(a);
186 Register I/O ports with correct name now
188 if (diva_bri_reregister_io(a)) {
189 diva_bri_cleanup_adapter(a);
190 return (-1);
194 Initialize OS dependent objects
196 if (diva_os_initialize_spin_lock
197 (&a->xdi_adapter.isr_spin_lock, "isr")) {
198 diva_bri_cleanup_adapter(a);
199 return (-1);
201 if (diva_os_initialize_spin_lock
202 (&a->xdi_adapter.data_spin_lock, "data")) {
203 diva_bri_cleanup_adapter(a);
204 return (-1);
207 strcpy(a->xdi_adapter.req_soft_isr.dpc_thread_name, "kdivasbrid");
209 if (diva_os_initialize_soft_isr(&a->xdi_adapter.req_soft_isr,
210 DIDpcRoutine, &a->xdi_adapter)) {
211 diva_bri_cleanup_adapter(a);
212 return (-1);
215 Do not initialize second DPC - only one thread will be created
217 a->xdi_adapter.isr_soft_isr.object = a->xdi_adapter.req_soft_isr.object;
220 Create entity table
222 a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels;
223 a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info;
224 a->xdi_adapter.e_tbl = diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO));
225 if (!a->xdi_adapter.e_tbl) {
226 diva_bri_cleanup_adapter(a);
227 return (-1);
229 memset(a->xdi_adapter.e_tbl, 0x00, a->xdi_adapter.e_max * sizeof(E_INFO));
232 Set up interface
234 a->xdi_adapter.a.io = &a->xdi_adapter;
235 a->xdi_adapter.DIRequest = request;
236 a->interface.cleanup_adapter_proc = diva_bri_cleanup_adapter;
237 a->interface.cmd_proc = diva_bri_cmd_card_proc;
239 p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
240 outpp(p, 0x41);
241 DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
243 prepare_maestra_functions(&a->xdi_adapter);
245 a->dsp_mask = 0x00000003;
248 Set IRQ handler
250 a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
251 sprintf(a->xdi_adapter.irq_info.irq_name, "DIVA BRI %ld",
252 (long) a->xdi_adapter.serialNo);
253 if (diva_os_register_irq(a, a->xdi_adapter.irq_info.irq_nr,
254 a->xdi_adapter.irq_info.irq_name)) {
255 diva_bri_cleanup_adapter(a);
256 return (-1);
258 a->xdi_adapter.irq_info.registered = 1;
260 diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name,
261 a->resources.pci.irq, a->xdi_adapter.serialNo);
263 return (0);
267 static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t * a)
269 int i;
271 if (a->xdi_adapter.Initialized) {
272 diva_bri_stop_adapter(a);
276 Remove ISR Handler
278 if (a->xdi_adapter.irq_info.registered) {
279 diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
281 a->xdi_adapter.irq_info.registered = 0;
283 if (a->resources.pci.addr[0] && a->resources.pci.bar[0]) {
284 divasa_unmap_pci_bar(a->resources.pci.addr[0]);
285 a->resources.pci.addr[0] = NULL;
286 a->resources.pci.bar[0] = 0;
289 for (i = 1; i < 3; i++) {
290 if (a->resources.pci.addr[i] && a->resources.pci.bar[i]) {
291 diva_os_register_io_port(a, 0,
292 a->resources.pci.bar[i],
293 a->resources.pci.
294 length[i],
295 &a->port_name[0], i);
296 a->resources.pci.addr[i] = NULL;
297 a->resources.pci.bar[i] = 0;
302 Free OS objects
304 diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr);
305 diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr);
307 diva_os_remove_soft_isr(&a->xdi_adapter.req_soft_isr);
308 a->xdi_adapter.isr_soft_isr.object = NULL;
310 diva_os_destroy_spin_lock(&a->xdi_adapter.isr_spin_lock, "rm");
311 diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm");
314 Free memory
316 if (a->xdi_adapter.e_tbl) {
317 diva_os_free(0, a->xdi_adapter.e_tbl);
318 a->xdi_adapter.e_tbl = NULL;
321 return (0);
324 void diva_os_prepare_maestra_functions(PISDN_ADAPTER IoAdapter)
329 ** Get serial number
331 static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t * a)
333 dword serNo = 0;
334 byte *confIO;
335 word serHi, serLo, *confMem;
337 confIO = (byte *) DIVA_OS_MEM_ATTACH_CFG(&a->xdi_adapter);
338 serHi = (word) (inppw(&confIO[0x22]) & 0x0FFF);
339 serLo = (word) (inppw(&confIO[0x26]) & 0x0FFF);
340 serNo = ((dword) serHi << 16) | (dword) serLo;
341 DIVA_OS_MEM_DETACH_CFG(&a->xdi_adapter, confIO);
343 if ((serNo == 0) || (serNo == 0xFFFFFFFF)) {
344 DBG_FTL(("W: BRI use BAR[0] to get card serial number"))
346 confMem = (word *) DIVA_OS_MEM_ATTACH_RAM(&a->xdi_adapter);
347 serHi = (word) (READ_WORD(&confMem[0x11]) & 0x0FFF);
348 serLo = (word) (READ_WORD(&confMem[0x13]) & 0x0FFF);
349 serNo = (((dword) serHi) << 16) | ((dword) serLo);
350 DIVA_OS_MEM_DETACH_RAM(&a->xdi_adapter, confMem);
353 DBG_LOG(("Serial Number=%ld", serNo))
355 return (serNo);
359 ** Unregister I/O and register it with new name,
360 ** based on Serial Number
362 static int diva_bri_reregister_io(diva_os_xdi_adapter_t * a)
364 int i;
366 for (i = 1; i < 3; i++) {
367 diva_os_register_io_port(a, 0, a->resources.pci.bar[i],
368 a->resources.pci.length[i],
369 &a->port_name[0], i);
370 a->resources.pci.addr[i] = NULL;
373 sprintf(a->port_name, "DIVA BRI %ld",
374 (long) a->xdi_adapter.serialNo);
376 for (i = 1; i < 3; i++) {
377 if (diva_os_register_io_port(a, 1, a->resources.pci.bar[i],
378 a->resources.pci.length[i],
379 &a->port_name[0], i)) {
380 DBG_ERR(("A: failed to reregister BAR[%d]", i))
381 return (-1);
383 a->resources.pci.addr[i] =
384 (void *) (unsigned long) a->resources.pci.bar[i];
387 return (0);
391 ** Process command from user mode
393 static int
394 diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
395 diva_xdi_um_cfg_cmd_t * cmd, int length)
397 int ret = -1;
399 if (cmd->adapter != a->controller) {
400 DBG_ERR(("A: pri_cmd, invalid controller=%d != %d",
401 cmd->adapter, a->controller))
402 return (-1);
405 switch (cmd->command) {
406 case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
407 a->xdi_mbox.data_length = sizeof(dword);
408 a->xdi_mbox.data =
409 diva_os_malloc(0, a->xdi_mbox.data_length);
410 if (a->xdi_mbox.data) {
411 *(dword *) a->xdi_mbox.data =
412 (dword) a->CardOrdinal;
413 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
414 ret = 0;
416 break;
418 case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
419 a->xdi_mbox.data_length = sizeof(dword);
420 a->xdi_mbox.data =
421 diva_os_malloc(0, a->xdi_mbox.data_length);
422 if (a->xdi_mbox.data) {
423 *(dword *) a->xdi_mbox.data =
424 (dword) a->xdi_adapter.serialNo;
425 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
426 ret = 0;
428 break;
430 case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
431 a->xdi_mbox.data_length = sizeof(dword) * 9;
432 a->xdi_mbox.data =
433 diva_os_malloc(0, a->xdi_mbox.data_length);
434 if (a->xdi_mbox.data) {
435 int i;
436 dword *data = (dword *) a->xdi_mbox.data;
438 for (i = 0; i < 8; i++) {
439 *data++ = a->resources.pci.bar[i];
441 *data++ = (dword) a->resources.pci.irq;
442 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
443 ret = 0;
445 break;
447 case DIVA_XDI_UM_CMD_GET_CARD_STATE:
448 a->xdi_mbox.data_length = sizeof(dword);
449 a->xdi_mbox.data =
450 diva_os_malloc(0, a->xdi_mbox.data_length);
451 if (a->xdi_mbox.data) {
452 dword *data = (dword *) a->xdi_mbox.data;
453 if (!a->xdi_adapter.port) {
454 *data = 3;
455 } else if (a->xdi_adapter.trapped) {
456 *data = 2;
457 } else if (a->xdi_adapter.Initialized) {
458 *data = 1;
459 } else {
460 *data = 0;
462 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
463 ret = 0;
465 break;
467 case DIVA_XDI_UM_CMD_RESET_ADAPTER:
468 ret = diva_bri_reset_adapter(&a->xdi_adapter);
469 break;
471 case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
472 ret = diva_bri_write_sdram_block(&a->xdi_adapter,
473 cmd->command_data.
474 write_sdram.offset,
475 (byte *) & cmd[1],
476 cmd->command_data.
477 write_sdram.length);
478 break;
480 case DIVA_XDI_UM_CMD_START_ADAPTER:
481 ret = diva_bri_start_adapter(&a->xdi_adapter,
482 cmd->command_data.start.
483 offset,
484 cmd->command_data.start.
485 features);
486 break;
488 case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
489 a->xdi_adapter.features =
490 cmd->command_data.features.features;
491 a->xdi_adapter.a.protocol_capabilities =
492 a->xdi_adapter.features;
493 DBG_TRC(
494 ("Set raw protocol features (%08x)",
495 a->xdi_adapter.features)) ret = 0;
496 break;
498 case DIVA_XDI_UM_CMD_STOP_ADAPTER:
499 ret = diva_bri_stop_adapter(a);
500 break;
502 case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY:
503 ret = diva_card_read_xlog(a);
504 break;
506 default:
507 DBG_ERR(
508 ("A: A(%d) invalid cmd=%d", a->controller,
509 cmd->command))}
511 return (ret);
514 static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter)
516 byte *addrHi, *addrLo, *ioaddr;
517 dword i;
518 byte *Port;
520 if (!IoAdapter->port) {
521 return (-1);
523 if (IoAdapter->Initialized) {
524 DBG_ERR(("A: A(%d) can't reset BRI adapter - please stop first",
525 IoAdapter->ANum)) return (-1);
527 (*(IoAdapter->rstFnc)) (IoAdapter);
528 diva_os_wait(100);
529 Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
530 addrHi = Port +
531 ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
532 addrLo = Port + ADDR;
533 ioaddr = Port + DATA;
535 recover
537 outpp(addrHi, (byte) 0);
538 outppw(addrLo, (word) 0);
539 outppw(ioaddr, (word) 0);
541 clear shared memory
543 outpp(addrHi,
544 (byte) (
545 (IoAdapter->MemoryBase + IoAdapter->MemorySize -
546 BRI_SHARED_RAM_SIZE) >> 16));
547 outppw(addrLo, 0);
548 for (i = 0; i < 0x8000; outppw(ioaddr, 0), ++i);
549 diva_os_wait(100);
552 clear signature
554 outpp(addrHi,
555 (byte) (
556 (IoAdapter->MemoryBase + IoAdapter->MemorySize -
557 BRI_SHARED_RAM_SIZE) >> 16));
558 outppw(addrLo, 0x1e);
559 outpp(ioaddr, 0);
560 outpp(ioaddr, 0);
562 outpp(addrHi, (byte) 0);
563 outppw(addrLo, (word) 0);
564 outppw(ioaddr, (word) 0);
566 DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
569 Forget all outstanding entities
571 IoAdapter->e_count = 0;
572 if (IoAdapter->e_tbl) {
573 memset(IoAdapter->e_tbl, 0x00,
574 IoAdapter->e_max * sizeof(E_INFO));
576 IoAdapter->head = 0;
577 IoAdapter->tail = 0;
578 IoAdapter->assign = 0;
579 IoAdapter->trapped = 0;
581 memset(&IoAdapter->a.IdTable[0], 0x00,
582 sizeof(IoAdapter->a.IdTable));
583 memset(&IoAdapter->a.IdTypeTable[0], 0x00,
584 sizeof(IoAdapter->a.IdTypeTable));
585 memset(&IoAdapter->a.FlowControlIdTable[0], 0x00,
586 sizeof(IoAdapter->a.FlowControlIdTable));
587 memset(&IoAdapter->a.FlowControlSkipTable[0], 0x00,
588 sizeof(IoAdapter->a.FlowControlSkipTable));
589 memset(&IoAdapter->a.misc_flags_table[0], 0x00,
590 sizeof(IoAdapter->a.misc_flags_table));
591 memset(&IoAdapter->a.rx_stream[0], 0x00,
592 sizeof(IoAdapter->a.rx_stream));
593 memset(&IoAdapter->a.tx_stream[0], 0x00,
594 sizeof(IoAdapter->a.tx_stream));
595 memset(&IoAdapter->a.tx_pos[0], 0x00, sizeof(IoAdapter->a.tx_pos));
596 memset(&IoAdapter->a.rx_pos[0], 0x00, sizeof(IoAdapter->a.rx_pos));
598 return (0);
601 static int
602 diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
603 dword address, const byte * data, dword length)
605 byte *addrHi, *addrLo, *ioaddr;
606 byte *Port;
608 if (!IoAdapter->port) {
609 return (-1);
612 Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
613 addrHi = Port +
614 ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
615 addrLo = Port + ADDR;
616 ioaddr = Port + DATA;
618 while (length--) {
619 outpp(addrHi, (word) (address >> 16));
620 outppw(addrLo, (word) (address & 0x0000ffff));
621 outpp(ioaddr, *data++);
622 address++;
625 DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
626 return (0);
629 static int
630 diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
631 dword start_address, dword features)
633 byte *Port;
634 dword i, test;
635 byte *addrHi, *addrLo, *ioaddr;
636 int started = 0;
637 ADAPTER *a = &IoAdapter->a;
639 if (IoAdapter->Initialized) {
640 DBG_ERR(
641 ("A: A(%d) bri_start_adapter, adapter already running",
642 IoAdapter->ANum)) return (-1);
644 if (!IoAdapter->port) {
645 DBG_ERR(("A: A(%d) bri_start_adapter, adapter not mapped",
646 IoAdapter->ANum)) return (-1);
649 sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
650 DBG_LOG(("A(%d) start BRI", IoAdapter->ANum))
652 Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
653 addrHi = Port +
654 ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
655 addrLo = Port + ADDR;
656 ioaddr = Port + DATA;
658 outpp(addrHi,
659 (byte) (
660 (IoAdapter->MemoryBase + IoAdapter->MemorySize -
661 BRI_SHARED_RAM_SIZE) >> 16));
662 outppw(addrLo, 0x1e);
663 outppw(ioaddr, 0x00);
664 DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
667 start the protocol code
669 Port = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
670 outpp(Port, 0x08);
671 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, Port);
673 Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
674 addrHi = Port +
675 ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
676 addrLo = Port + ADDR;
677 ioaddr = Port + DATA;
679 wait for signature (max. 3 seconds)
681 for (i = 0; i < 300; ++i) {
682 diva_os_wait(10);
683 outpp(addrHi,
684 (byte) (
685 (IoAdapter->MemoryBase +
686 IoAdapter->MemorySize -
687 BRI_SHARED_RAM_SIZE) >> 16));
688 outppw(addrLo, 0x1e);
689 test = (dword) inppw(ioaddr);
690 if (test == 0x4447) {
691 DBG_LOG(
692 ("Protocol startup time %d.%02d seconds",
693 (i / 100), (i % 100)))
694 started = 1;
695 break;
698 DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
700 if (!started) {
701 DBG_FTL(("A: A(%d) %s: Adapter selftest failed 0x%04X",
702 IoAdapter->ANum, IoAdapter->Properties.Name,
703 test))
704 (*(IoAdapter->trapFnc)) (IoAdapter);
705 return (-1);
708 IoAdapter->Initialized = 1;
711 Check Interrupt
713 IoAdapter->IrqCount = 0;
714 a->ReadyInt = 1;
716 if (IoAdapter->reset) {
717 Port = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
718 outpp(Port, 0x41);
719 DIVA_OS_MEM_DETACH_RESET(IoAdapter, Port);
722 a->ram_out(a, &PR_RAM->ReadyInt, 1);
723 for (i = 0; ((!IoAdapter->IrqCount) && (i < 100)); i++) {
724 diva_os_wait(10);
726 if (!IoAdapter->IrqCount) {
727 DBG_ERR(
728 ("A: A(%d) interrupt test failed",
729 IoAdapter->ANum))
730 IoAdapter->Initialized = 0;
731 IoAdapter->stop(IoAdapter);
732 return (-1);
735 IoAdapter->Properties.Features = (word) features;
736 diva_xdi_display_adapter_features(IoAdapter->ANum);
737 DBG_LOG(("A(%d) BRI adapter successfull started", IoAdapter->ANum))
739 Register with DIDD
741 diva_xdi_didd_register_adapter(IoAdapter->ANum);
743 return (0);
746 static void diva_bri_clear_interrupts(diva_os_xdi_adapter_t * a)
748 PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
751 clear any pending interrupt
753 IoAdapter->disIrq(IoAdapter);
755 IoAdapter->tst_irq(&IoAdapter->a);
756 IoAdapter->clr_irq(&IoAdapter->a);
757 IoAdapter->tst_irq(&IoAdapter->a);
760 kill pending dpcs
762 diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
763 diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
767 ** Stop card
769 static int diva_bri_stop_adapter(diva_os_xdi_adapter_t * a)
771 PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
772 int i = 100;
774 if (!IoAdapter->port) {
775 return (-1);
777 if (!IoAdapter->Initialized) {
778 DBG_ERR(("A: A(%d) can't stop BRI adapter - not running",
779 IoAdapter->ANum))
780 return (-1); /* nothing to stop */
782 IoAdapter->Initialized = 0;
785 Disconnect Adapter from DIDD
787 diva_xdi_didd_remove_adapter(IoAdapter->ANum);
790 Stop interrupts
792 a->clear_interrupts_proc = diva_bri_clear_interrupts;
793 IoAdapter->a.ReadyInt = 1;
794 IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
795 do {
796 diva_os_sleep(10);
797 } while (i-- && a->clear_interrupts_proc);
798 if (a->clear_interrupts_proc) {
799 diva_bri_clear_interrupts(a);
800 a->clear_interrupts_proc = NULL;
801 DBG_ERR(("A: A(%d) no final interrupt from BRI adapter",
802 IoAdapter->ANum))
804 IoAdapter->a.ReadyInt = 0;
807 Stop and reset adapter
809 IoAdapter->stop(IoAdapter);
811 return (0);