Merge tag 'riscv-for-linus-4.15-rc2_cleanups' of git://git.kernel.org/pub/scm/linux...
[linux/fpc-iii.git] / drivers / isdn / hardware / eicon / os_bri.c
blobde93090bcacb1f68c74008bfc19934a5d27ad909
1 // SPDX-License-Identifier: GPL-2.0
2 /* $Id: os_bri.c,v 1.21 2004/03/21 17:26:01 armin Exp $ */
4 #include "platform.h"
5 #include "debuglib.h"
6 #include "cardtype.h"
7 #include "pc.h"
8 #include "pr_pc.h"
9 #include "di_defs.h"
10 #include "dsp_defs.h"
11 #include "di.h"
12 #include "io.h"
14 #include "xdi_msg.h"
15 #include "xdi_adapter.h"
16 #include "os_bri.h"
17 #include "diva_pci.h"
18 #include "mi_pc.h"
19 #include "pc_maint.h"
20 #include "dsrv_bri.h"
23 ** IMPORTS
25 extern void prepare_maestra_functions(PISDN_ADAPTER IoAdapter);
26 extern void diva_xdi_display_adapter_features(int card);
27 extern int diva_card_read_xlog(diva_os_xdi_adapter_t *a);
30 ** LOCALS
32 static int bri_bar_length[3] = {
33 0x80,
34 0x80,
35 0x20
37 static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t *a);
38 static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t *a);
39 static int diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
40 diva_xdi_um_cfg_cmd_t *cmd, int length);
41 static int diva_bri_reregister_io(diva_os_xdi_adapter_t *a);
42 static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter);
43 static int diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
44 dword address,
45 const byte *data, dword length);
46 static int diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
47 dword start_address, dword features);
48 static int diva_bri_stop_adapter(diva_os_xdi_adapter_t *a);
50 static void diva_bri_set_addresses(diva_os_xdi_adapter_t *a)
52 a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
53 a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 1;
54 a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 2;
55 a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 1;
56 a->resources.pci.mem_type_id[MEM_TYPE_PORT] = 2;
57 a->resources.pci.mem_type_id[MEM_TYPE_CTLREG] = 2;
59 a->xdi_adapter.ram = a->resources.pci.addr[0];
60 a->xdi_adapter.cfg = a->resources.pci.addr[1];
61 a->xdi_adapter.Address = a->resources.pci.addr[2];
63 a->xdi_adapter.reset = a->xdi_adapter.cfg;
64 a->xdi_adapter.port = a->xdi_adapter.Address;
66 a->xdi_adapter.ctlReg = a->xdi_adapter.port + M_PCI_RESET;
68 a->xdi_adapter.reset += 0x4C; /* PLX 9050 !! */
72 ** BAR0 - MEM Addr - 0x80 - NOT USED
73 ** BAR1 - I/O Addr - 0x80
74 ** BAR2 - I/O Addr - 0x20
76 int diva_bri_init_card(diva_os_xdi_adapter_t *a)
78 int bar;
79 dword bar2 = 0, bar2_length = 0xffffffff;
80 word cmd = 0, cmd_org;
81 byte Bus, Slot;
82 void *hdev;
83 byte __iomem *p;
86 Set properties
88 a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
89 DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name))
92 Get resources
94 for (bar = 0; bar < 3; bar++) {
95 a->resources.pci.bar[bar] =
96 divasa_get_pci_bar(a->resources.pci.bus,
97 a->resources.pci.func, bar,
98 a->resources.pci.hdev);
99 if (!a->resources.pci.bar[bar]) {
100 DBG_ERR(("A: can't get BAR[%d]", bar))
101 return (-1);
105 a->resources.pci.irq =
106 (byte) divasa_get_pci_irq(a->resources.pci.bus,
107 a->resources.pci.func,
108 a->resources.pci.hdev);
109 if (!a->resources.pci.irq) {
110 DBG_ERR(("A: invalid irq"));
111 return (-1);
115 Get length of I/O bar 2 - it is different by older
116 EEPROM version
118 Bus = a->resources.pci.bus;
119 Slot = a->resources.pci.func;
120 hdev = a->resources.pci.hdev;
123 Get plain original values of the BAR2 CDM registers
125 PCIread(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev);
126 PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
128 Disable device and get BAR2 length
130 PCIwrite(Bus, Slot, 0x04, &cmd, sizeof(cmd), hdev);
131 PCIwrite(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev);
132 PCIread(Bus, Slot, 0x18, &bar2_length, sizeof(bar2_length), hdev);
134 Restore BAR2 and CMD registers
136 PCIwrite(Bus, Slot, 0x18, &bar2, sizeof(bar2), hdev);
137 PCIwrite(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
140 Calculate BAR2 length
142 bar2_length = (~(bar2_length & ~7)) + 1;
143 DBG_LOG(("BAR[2] length=%lx", bar2_length))
146 Map and register resources
148 if (!(a->resources.pci.addr[0] =
149 divasa_remap_pci_bar(a, 0, a->resources.pci.bar[0],
150 bri_bar_length[0]))) {
151 DBG_ERR(("A: BRI, can't map BAR[0]"))
152 diva_bri_cleanup_adapter(a);
153 return (-1);
156 sprintf(&a->port_name[0], "BRI %02x:%02x",
157 a->resources.pci.bus, a->resources.pci.func);
159 if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
160 bri_bar_length[1], &a->port_name[0], 1)) {
161 DBG_ERR(("A: BRI, can't register BAR[1]"))
162 diva_bri_cleanup_adapter(a);
163 return (-1);
165 a->resources.pci.addr[1] = (void *) (unsigned long) a->resources.pci.bar[1];
166 a->resources.pci.length[1] = bri_bar_length[1];
168 if (diva_os_register_io_port(a, 1, a->resources.pci.bar[2],
169 bar2_length, &a->port_name[0], 2)) {
170 DBG_ERR(("A: BRI, can't register BAR[2]"))
171 diva_bri_cleanup_adapter(a);
172 return (-1);
174 a->resources.pci.addr[2] = (void *) (unsigned long) a->resources.pci.bar[2];
175 a->resources.pci.length[2] = bar2_length;
178 Set all memory areas
180 diva_bri_set_addresses(a);
183 Get Serial Number
185 a->xdi_adapter.serialNo = diva_bri_get_serial_number(a);
188 Register I/O ports with correct name now
190 if (diva_bri_reregister_io(a)) {
191 diva_bri_cleanup_adapter(a);
192 return (-1);
196 Initialize OS dependent objects
198 if (diva_os_initialize_spin_lock
199 (&a->xdi_adapter.isr_spin_lock, "isr")) {
200 diva_bri_cleanup_adapter(a);
201 return (-1);
203 if (diva_os_initialize_spin_lock
204 (&a->xdi_adapter.data_spin_lock, "data")) {
205 diva_bri_cleanup_adapter(a);
206 return (-1);
209 strcpy(a->xdi_adapter.req_soft_isr.dpc_thread_name, "kdivasbrid");
211 if (diva_os_initialize_soft_isr(&a->xdi_adapter.req_soft_isr,
212 DIDpcRoutine, &a->xdi_adapter)) {
213 diva_bri_cleanup_adapter(a);
214 return (-1);
217 Do not initialize second DPC - only one thread will be created
219 a->xdi_adapter.isr_soft_isr.object = a->xdi_adapter.req_soft_isr.object;
222 Create entity table
224 a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels;
225 a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info;
226 a->xdi_adapter.e_tbl = diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO));
227 if (!a->xdi_adapter.e_tbl) {
228 diva_bri_cleanup_adapter(a);
229 return (-1);
231 memset(a->xdi_adapter.e_tbl, 0x00, a->xdi_adapter.e_max * sizeof(E_INFO));
234 Set up interface
236 a->xdi_adapter.a.io = &a->xdi_adapter;
237 a->xdi_adapter.DIRequest = request;
238 a->interface.cleanup_adapter_proc = diva_bri_cleanup_adapter;
239 a->interface.cmd_proc = diva_bri_cmd_card_proc;
241 p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
242 outpp(p, 0x41);
243 DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
245 prepare_maestra_functions(&a->xdi_adapter);
247 a->dsp_mask = 0x00000003;
250 Set IRQ handler
252 a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
253 sprintf(a->xdi_adapter.irq_info.irq_name, "DIVA BRI %ld",
254 (long) a->xdi_adapter.serialNo);
255 if (diva_os_register_irq(a, a->xdi_adapter.irq_info.irq_nr,
256 a->xdi_adapter.irq_info.irq_name)) {
257 diva_bri_cleanup_adapter(a);
258 return (-1);
260 a->xdi_adapter.irq_info.registered = 1;
262 diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name,
263 a->resources.pci.irq, a->xdi_adapter.serialNo);
265 return (0);
269 static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t *a)
271 int i;
273 if (a->xdi_adapter.Initialized) {
274 diva_bri_stop_adapter(a);
278 Remove ISR Handler
280 if (a->xdi_adapter.irq_info.registered) {
281 diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
283 a->xdi_adapter.irq_info.registered = 0;
285 if (a->resources.pci.addr[0] && a->resources.pci.bar[0]) {
286 divasa_unmap_pci_bar(a->resources.pci.addr[0]);
287 a->resources.pci.addr[0] = NULL;
288 a->resources.pci.bar[0] = 0;
291 for (i = 1; i < 3; i++) {
292 if (a->resources.pci.addr[i] && a->resources.pci.bar[i]) {
293 diva_os_register_io_port(a, 0,
294 a->resources.pci.bar[i],
295 a->resources.pci.
296 length[i],
297 &a->port_name[0], i);
298 a->resources.pci.addr[i] = NULL;
299 a->resources.pci.bar[i] = 0;
304 Free OS objects
306 diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr);
307 diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr);
309 diva_os_remove_soft_isr(&a->xdi_adapter.req_soft_isr);
310 a->xdi_adapter.isr_soft_isr.object = NULL;
312 diva_os_destroy_spin_lock(&a->xdi_adapter.isr_spin_lock, "rm");
313 diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm");
316 Free memory
318 if (a->xdi_adapter.e_tbl) {
319 diva_os_free(0, a->xdi_adapter.e_tbl);
320 a->xdi_adapter.e_tbl = NULL;
323 return (0);
326 void diva_os_prepare_maestra_functions(PISDN_ADAPTER IoAdapter)
331 ** Get serial number
333 static dword diva_bri_get_serial_number(diva_os_xdi_adapter_t *a)
335 dword serNo = 0;
336 byte __iomem *confIO;
337 word serHi, serLo;
338 word __iomem *confMem;
340 confIO = DIVA_OS_MEM_ATTACH_CFG(&a->xdi_adapter);
341 serHi = (word) (inppw(&confIO[0x22]) & 0x0FFF);
342 serLo = (word) (inppw(&confIO[0x26]) & 0x0FFF);
343 serNo = ((dword) serHi << 16) | (dword) serLo;
344 DIVA_OS_MEM_DETACH_CFG(&a->xdi_adapter, confIO);
346 if ((serNo == 0) || (serNo == 0xFFFFFFFF)) {
347 DBG_FTL(("W: BRI use BAR[0] to get card serial number"))
349 confMem = (word __iomem *)DIVA_OS_MEM_ATTACH_RAM(&a->xdi_adapter);
350 serHi = (word) (READ_WORD(&confMem[0x11]) & 0x0FFF);
351 serLo = (word) (READ_WORD(&confMem[0x13]) & 0x0FFF);
352 serNo = (((dword) serHi) << 16) | ((dword) serLo);
353 DIVA_OS_MEM_DETACH_RAM(&a->xdi_adapter, confMem);
356 DBG_LOG(("Serial Number=%ld", serNo))
358 return (serNo);
362 ** Unregister I/O and register it with new name,
363 ** based on Serial Number
365 static int diva_bri_reregister_io(diva_os_xdi_adapter_t *a)
367 int i;
369 for (i = 1; i < 3; i++) {
370 diva_os_register_io_port(a, 0, a->resources.pci.bar[i],
371 a->resources.pci.length[i],
372 &a->port_name[0], i);
373 a->resources.pci.addr[i] = NULL;
376 sprintf(a->port_name, "DIVA BRI %ld",
377 (long) a->xdi_adapter.serialNo);
379 for (i = 1; i < 3; i++) {
380 if (diva_os_register_io_port(a, 1, a->resources.pci.bar[i],
381 a->resources.pci.length[i],
382 &a->port_name[0], i)) {
383 DBG_ERR(("A: failed to reregister BAR[%d]", i))
384 return (-1);
386 a->resources.pci.addr[i] =
387 (void *) (unsigned long) a->resources.pci.bar[i];
390 return (0);
394 ** Process command from user mode
396 static int
397 diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
398 diva_xdi_um_cfg_cmd_t *cmd, int length)
400 int ret = -1;
402 if (cmd->adapter != a->controller) {
403 DBG_ERR(("A: pri_cmd, invalid controller=%d != %d",
404 cmd->adapter, a->controller))
405 return (-1);
408 switch (cmd->command) {
409 case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
410 a->xdi_mbox.data_length = sizeof(dword);
411 a->xdi_mbox.data =
412 diva_os_malloc(0, a->xdi_mbox.data_length);
413 if (a->xdi_mbox.data) {
414 *(dword *) a->xdi_mbox.data =
415 (dword) a->CardOrdinal;
416 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
417 ret = 0;
419 break;
421 case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
422 a->xdi_mbox.data_length = sizeof(dword);
423 a->xdi_mbox.data =
424 diva_os_malloc(0, a->xdi_mbox.data_length);
425 if (a->xdi_mbox.data) {
426 *(dword *) a->xdi_mbox.data =
427 (dword) a->xdi_adapter.serialNo;
428 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
429 ret = 0;
431 break;
433 case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
434 a->xdi_mbox.data_length = sizeof(dword) * 9;
435 a->xdi_mbox.data =
436 diva_os_malloc(0, a->xdi_mbox.data_length);
437 if (a->xdi_mbox.data) {
438 int i;
439 dword *data = (dword *) a->xdi_mbox.data;
441 for (i = 0; i < 8; i++) {
442 *data++ = a->resources.pci.bar[i];
444 *data++ = (dword) a->resources.pci.irq;
445 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
446 ret = 0;
448 break;
450 case DIVA_XDI_UM_CMD_GET_CARD_STATE:
451 a->xdi_mbox.data_length = sizeof(dword);
452 a->xdi_mbox.data =
453 diva_os_malloc(0, a->xdi_mbox.data_length);
454 if (a->xdi_mbox.data) {
455 dword *data = (dword *) a->xdi_mbox.data;
456 if (!a->xdi_adapter.port) {
457 *data = 3;
458 } else if (a->xdi_adapter.trapped) {
459 *data = 2;
460 } else if (a->xdi_adapter.Initialized) {
461 *data = 1;
462 } else {
463 *data = 0;
465 a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
466 ret = 0;
468 break;
470 case DIVA_XDI_UM_CMD_RESET_ADAPTER:
471 ret = diva_bri_reset_adapter(&a->xdi_adapter);
472 break;
474 case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
475 ret = diva_bri_write_sdram_block(&a->xdi_adapter,
476 cmd->command_data.
477 write_sdram.offset,
478 (byte *)&cmd[1],
479 cmd->command_data.
480 write_sdram.length);
481 break;
483 case DIVA_XDI_UM_CMD_START_ADAPTER:
484 ret = diva_bri_start_adapter(&a->xdi_adapter,
485 cmd->command_data.start.
486 offset,
487 cmd->command_data.start.
488 features);
489 break;
491 case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
492 a->xdi_adapter.features =
493 cmd->command_data.features.features;
494 a->xdi_adapter.a.protocol_capabilities =
495 a->xdi_adapter.features;
496 DBG_TRC(
497 ("Set raw protocol features (%08x)",
498 a->xdi_adapter.features)) ret = 0;
499 break;
501 case DIVA_XDI_UM_CMD_STOP_ADAPTER:
502 ret = diva_bri_stop_adapter(a);
503 break;
505 case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY:
506 ret = diva_card_read_xlog(a);
507 break;
509 default:
510 DBG_ERR(
511 ("A: A(%d) invalid cmd=%d", a->controller,
512 cmd->command))}
514 return (ret);
517 static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter)
519 byte __iomem *addrHi, *addrLo, *ioaddr;
520 dword i;
521 byte __iomem *Port;
523 if (!IoAdapter->port) {
524 return (-1);
526 if (IoAdapter->Initialized) {
527 DBG_ERR(("A: A(%d) can't reset BRI adapter - please stop first",
528 IoAdapter->ANum)) return (-1);
530 (*(IoAdapter->rstFnc)) (IoAdapter);
531 diva_os_wait(100);
532 Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
533 addrHi = Port +
534 ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
535 addrLo = Port + ADDR;
536 ioaddr = Port + DATA;
538 recover
540 outpp(addrHi, (byte) 0);
541 outppw(addrLo, (word) 0);
542 outppw(ioaddr, (word) 0);
544 clear shared memory
546 outpp(addrHi,
547 (byte) (
548 (IoAdapter->MemoryBase + IoAdapter->MemorySize -
549 BRI_SHARED_RAM_SIZE) >> 16));
550 outppw(addrLo, 0);
551 for (i = 0; i < 0x8000; outppw(ioaddr, 0), ++i);
552 diva_os_wait(100);
555 clear signature
557 outpp(addrHi,
558 (byte) (
559 (IoAdapter->MemoryBase + IoAdapter->MemorySize -
560 BRI_SHARED_RAM_SIZE) >> 16));
561 outppw(addrLo, 0x1e);
562 outpp(ioaddr, 0);
563 outpp(ioaddr, 0);
565 outpp(addrHi, (byte) 0);
566 outppw(addrLo, (word) 0);
567 outppw(ioaddr, (word) 0);
569 DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
572 Forget all outstanding entities
574 IoAdapter->e_count = 0;
575 if (IoAdapter->e_tbl) {
576 memset(IoAdapter->e_tbl, 0x00,
577 IoAdapter->e_max * sizeof(E_INFO));
579 IoAdapter->head = 0;
580 IoAdapter->tail = 0;
581 IoAdapter->assign = 0;
582 IoAdapter->trapped = 0;
584 memset(&IoAdapter->a.IdTable[0], 0x00,
585 sizeof(IoAdapter->a.IdTable));
586 memset(&IoAdapter->a.IdTypeTable[0], 0x00,
587 sizeof(IoAdapter->a.IdTypeTable));
588 memset(&IoAdapter->a.FlowControlIdTable[0], 0x00,
589 sizeof(IoAdapter->a.FlowControlIdTable));
590 memset(&IoAdapter->a.FlowControlSkipTable[0], 0x00,
591 sizeof(IoAdapter->a.FlowControlSkipTable));
592 memset(&IoAdapter->a.misc_flags_table[0], 0x00,
593 sizeof(IoAdapter->a.misc_flags_table));
594 memset(&IoAdapter->a.rx_stream[0], 0x00,
595 sizeof(IoAdapter->a.rx_stream));
596 memset(&IoAdapter->a.tx_stream[0], 0x00,
597 sizeof(IoAdapter->a.tx_stream));
598 memset(&IoAdapter->a.tx_pos[0], 0x00, sizeof(IoAdapter->a.tx_pos));
599 memset(&IoAdapter->a.rx_pos[0], 0x00, sizeof(IoAdapter->a.rx_pos));
601 return (0);
604 static int
605 diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
606 dword address, const byte *data, dword length)
608 byte __iomem *addrHi, *addrLo, *ioaddr;
609 byte __iomem *Port;
611 if (!IoAdapter->port) {
612 return (-1);
615 Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
616 addrHi = Port +
617 ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
618 addrLo = Port + ADDR;
619 ioaddr = Port + DATA;
621 while (length--) {
622 outpp(addrHi, (word) (address >> 16));
623 outppw(addrLo, (word) (address & 0x0000ffff));
624 outpp(ioaddr, *data++);
625 address++;
628 DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
629 return (0);
632 static int
633 diva_bri_start_adapter(PISDN_ADAPTER IoAdapter,
634 dword start_address, dword features)
636 byte __iomem *Port;
637 dword i, test;
638 byte __iomem *addrHi, *addrLo, *ioaddr;
639 int started = 0;
640 ADAPTER *a = &IoAdapter->a;
642 if (IoAdapter->Initialized) {
643 DBG_ERR(
644 ("A: A(%d) bri_start_adapter, adapter already running",
645 IoAdapter->ANum)) return (-1);
647 if (!IoAdapter->port) {
648 DBG_ERR(("A: A(%d) bri_start_adapter, adapter not mapped",
649 IoAdapter->ANum)) return (-1);
652 sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
653 DBG_LOG(("A(%d) start BRI", IoAdapter->ANum))
655 Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
656 addrHi = Port +
657 ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
658 addrLo = Port + ADDR;
659 ioaddr = Port + DATA;
661 outpp(addrHi,
662 (byte) (
663 (IoAdapter->MemoryBase + IoAdapter->MemorySize -
664 BRI_SHARED_RAM_SIZE) >> 16));
665 outppw(addrLo, 0x1e);
666 outppw(ioaddr, 0x00);
667 DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
670 start the protocol code
672 Port = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
673 outpp(Port, 0x08);
674 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, Port);
676 Port = DIVA_OS_MEM_ATTACH_PORT(IoAdapter);
677 addrHi = Port +
678 ((IoAdapter->Properties.Bus == BUS_PCI) ? M_PCI_ADDRH : ADDRH);
679 addrLo = Port + ADDR;
680 ioaddr = Port + DATA;
682 wait for signature (max. 3 seconds)
684 for (i = 0; i < 300; ++i) {
685 diva_os_wait(10);
686 outpp(addrHi,
687 (byte) (
688 (IoAdapter->MemoryBase +
689 IoAdapter->MemorySize -
690 BRI_SHARED_RAM_SIZE) >> 16));
691 outppw(addrLo, 0x1e);
692 test = (dword) inppw(ioaddr);
693 if (test == 0x4447) {
694 DBG_LOG(
695 ("Protocol startup time %d.%02d seconds",
696 (i / 100), (i % 100)))
697 started = 1;
698 break;
701 DIVA_OS_MEM_DETACH_PORT(IoAdapter, Port);
703 if (!started) {
704 DBG_FTL(("A: A(%d) %s: Adapter selftest failed 0x%04X",
705 IoAdapter->ANum, IoAdapter->Properties.Name,
706 test))
707 (*(IoAdapter->trapFnc)) (IoAdapter);
708 return (-1);
711 IoAdapter->Initialized = 1;
714 Check Interrupt
716 IoAdapter->IrqCount = 0;
717 a->ReadyInt = 1;
719 if (IoAdapter->reset) {
720 Port = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
721 outpp(Port, 0x41);
722 DIVA_OS_MEM_DETACH_RESET(IoAdapter, Port);
725 a->ram_out(a, &PR_RAM->ReadyInt, 1);
726 for (i = 0; ((!IoAdapter->IrqCount) && (i < 100)); i++) {
727 diva_os_wait(10);
729 if (!IoAdapter->IrqCount) {
730 DBG_ERR(
731 ("A: A(%d) interrupt test failed",
732 IoAdapter->ANum))
733 IoAdapter->Initialized = 0;
734 IoAdapter->stop(IoAdapter);
735 return (-1);
738 IoAdapter->Properties.Features = (word) features;
739 diva_xdi_display_adapter_features(IoAdapter->ANum);
740 DBG_LOG(("A(%d) BRI adapter successfully started", IoAdapter->ANum))
742 Register with DIDD
744 diva_xdi_didd_register_adapter(IoAdapter->ANum);
746 return (0);
749 static void diva_bri_clear_interrupts(diva_os_xdi_adapter_t *a)
751 PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
754 clear any pending interrupt
756 IoAdapter->disIrq(IoAdapter);
758 IoAdapter->tst_irq(&IoAdapter->a);
759 IoAdapter->clr_irq(&IoAdapter->a);
760 IoAdapter->tst_irq(&IoAdapter->a);
763 kill pending dpcs
765 diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
766 diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
770 ** Stop card
772 static int diva_bri_stop_adapter(diva_os_xdi_adapter_t *a)
774 PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
775 int i = 100;
777 if (!IoAdapter->port) {
778 return (-1);
780 if (!IoAdapter->Initialized) {
781 DBG_ERR(("A: A(%d) can't stop BRI adapter - not running",
782 IoAdapter->ANum))
783 return (-1); /* nothing to stop */
785 IoAdapter->Initialized = 0;
788 Disconnect Adapter from DIDD
790 diva_xdi_didd_remove_adapter(IoAdapter->ANum);
793 Stop interrupts
795 a->clear_interrupts_proc = diva_bri_clear_interrupts;
796 IoAdapter->a.ReadyInt = 1;
797 IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
798 do {
799 diva_os_sleep(10);
800 } while (i-- && a->clear_interrupts_proc);
801 if (a->clear_interrupts_proc) {
802 diva_bri_clear_interrupts(a);
803 a->clear_interrupts_proc = NULL;
804 DBG_ERR(("A: A(%d) no final interrupt from BRI adapter",
805 IoAdapter->ANum))
807 IoAdapter->a.ReadyInt = 0;
810 Stop and reset adapter
812 IoAdapter->stop(IoAdapter);
814 return (0);