1 // SPDX-License-Identifier: GPL-2.0
2 /* $Id: os_bri.c,v 1.21 2004/03/21 17:26:01 armin Exp $ */
15 #include "xdi_adapter.h"
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
);
32 static int bri_bar_length
[3] = {
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
,
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
)
79 dword bar2
= 0, bar2_length
= 0xffffffff;
80 word cmd
= 0, cmd_org
;
88 a
->xdi_adapter
.Properties
= CardProperties
[a
->CardOrdinal
];
89 DBG_LOG(("Load %s", a
->xdi_adapter
.Properties
.Name
))
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
))
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"));
115 Get length of I/O bar 2 - it is different by older
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
);
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
);
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
);
174 a
->resources
.pci
.addr
[2] = (void *) (unsigned long) a
->resources
.pci
.bar
[2];
175 a
->resources
.pci
.length
[2] = bar2_length
;
180 diva_bri_set_addresses(a
);
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
);
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
);
203 if (diva_os_initialize_spin_lock
204 (&a
->xdi_adapter
.data_spin_lock
, "data")) {
205 diva_bri_cleanup_adapter(a
);
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
);
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
;
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
);
231 memset(a
->xdi_adapter
.e_tbl
, 0x00, a
->xdi_adapter
.e_max
* sizeof(E_INFO
));
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
);
243 DIVA_OS_MEM_DETACH_RESET(&a
->xdi_adapter
, p
);
245 prepare_maestra_functions(&a
->xdi_adapter
);
247 a
->dsp_mask
= 0x00000003;
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
);
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
);
269 static int diva_bri_cleanup_adapter(diva_os_xdi_adapter_t
*a
)
273 if (a
->xdi_adapter
.Initialized
) {
274 diva_bri_stop_adapter(a
);
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
],
297 &a
->port_name
[0], i
);
298 a
->resources
.pci
.addr
[i
] = NULL
;
299 a
->resources
.pci
.bar
[i
] = 0;
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");
318 if (a
->xdi_adapter
.e_tbl
) {
319 diva_os_free(0, a
->xdi_adapter
.e_tbl
);
320 a
->xdi_adapter
.e_tbl
= NULL
;
326 void diva_os_prepare_maestra_functions(PISDN_ADAPTER IoAdapter
)
333 static dword
diva_bri_get_serial_number(diva_os_xdi_adapter_t
*a
)
336 byte __iomem
*confIO
;
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
))
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
)
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
))
386 a
->resources
.pci
.addr
[i
] =
387 (void *) (unsigned long) a
->resources
.pci
.bar
[i
];
394 ** Process command from user mode
397 diva_bri_cmd_card_proc(struct _diva_os_xdi_adapter
*a
,
398 diva_xdi_um_cfg_cmd_t
*cmd
, int length
)
402 if (cmd
->adapter
!= a
->controller
) {
403 DBG_ERR(("A: pri_cmd, invalid controller=%d != %d",
404 cmd
->adapter
, a
->controller
))
408 switch (cmd
->command
) {
409 case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL
:
410 a
->xdi_mbox
.data_length
= sizeof(dword
);
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
;
421 case DIVA_XDI_UM_CMD_GET_SERIAL_NR
:
422 a
->xdi_mbox
.data_length
= sizeof(dword
);
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
;
433 case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG
:
434 a
->xdi_mbox
.data_length
= sizeof(dword
) * 9;
436 diva_os_malloc(0, a
->xdi_mbox
.data_length
);
437 if (a
->xdi_mbox
.data
) {
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
;
450 case DIVA_XDI_UM_CMD_GET_CARD_STATE
:
451 a
->xdi_mbox
.data_length
= sizeof(dword
);
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
) {
458 } else if (a
->xdi_adapter
.trapped
) {
460 } else if (a
->xdi_adapter
.Initialized
) {
465 a
->xdi_mbox
.status
= DIVA_XDI_MBOX_BUSY
;
470 case DIVA_XDI_UM_CMD_RESET_ADAPTER
:
471 ret
= diva_bri_reset_adapter(&a
->xdi_adapter
);
474 case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK
:
475 ret
= diva_bri_write_sdram_block(&a
->xdi_adapter
,
483 case DIVA_XDI_UM_CMD_START_ADAPTER
:
484 ret
= diva_bri_start_adapter(&a
->xdi_adapter
,
485 cmd
->command_data
.start
.
487 cmd
->command_data
.start
.
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
;
497 ("Set raw protocol features (%08x)",
498 a
->xdi_adapter
.features
)) ret
= 0;
501 case DIVA_XDI_UM_CMD_STOP_ADAPTER
:
502 ret
= diva_bri_stop_adapter(a
);
505 case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY
:
506 ret
= diva_card_read_xlog(a
);
511 ("A: A(%d) invalid cmd=%d", a
->controller
,
517 static int diva_bri_reset_adapter(PISDN_ADAPTER IoAdapter
)
519 byte __iomem
*addrHi
, *addrLo
, *ioaddr
;
523 if (!IoAdapter
->port
) {
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
);
532 Port
= DIVA_OS_MEM_ATTACH_PORT(IoAdapter
);
534 ((IoAdapter
->Properties
.Bus
== BUS_PCI
) ? M_PCI_ADDRH
: ADDRH
);
535 addrLo
= Port
+ ADDR
;
536 ioaddr
= Port
+ DATA
;
540 outpp(addrHi
, (byte
) 0);
541 outppw(addrLo
, (word
) 0);
542 outppw(ioaddr
, (word
) 0);
548 (IoAdapter
->MemoryBase
+ IoAdapter
->MemorySize
-
549 BRI_SHARED_RAM_SIZE
) >> 16));
551 for (i
= 0; i
< 0x8000; outppw(ioaddr
, 0), ++i
);
559 (IoAdapter
->MemoryBase
+ IoAdapter
->MemorySize
-
560 BRI_SHARED_RAM_SIZE
) >> 16));
561 outppw(addrLo
, 0x1e);
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
));
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
));
605 diva_bri_write_sdram_block(PISDN_ADAPTER IoAdapter
,
606 dword address
, const byte
*data
, dword length
)
608 byte __iomem
*addrHi
, *addrLo
, *ioaddr
;
611 if (!IoAdapter
->port
) {
615 Port
= DIVA_OS_MEM_ATTACH_PORT(IoAdapter
);
617 ((IoAdapter
->Properties
.Bus
== BUS_PCI
) ? M_PCI_ADDRH
: ADDRH
);
618 addrLo
= Port
+ ADDR
;
619 ioaddr
= Port
+ DATA
;
622 outpp(addrHi
, (word
) (address
>> 16));
623 outppw(addrLo
, (word
) (address
& 0x0000ffff));
624 outpp(ioaddr
, *data
++);
628 DIVA_OS_MEM_DETACH_PORT(IoAdapter
, Port
);
633 diva_bri_start_adapter(PISDN_ADAPTER IoAdapter
,
634 dword start_address
, dword features
)
638 byte __iomem
*addrHi
, *addrLo
, *ioaddr
;
640 ADAPTER
*a
= &IoAdapter
->a
;
642 if (IoAdapter
->Initialized
) {
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
);
657 ((IoAdapter
->Properties
.Bus
== BUS_PCI
) ? M_PCI_ADDRH
: ADDRH
);
658 addrLo
= Port
+ ADDR
;
659 ioaddr
= Port
+ DATA
;
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
);
674 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter
, Port
);
676 Port
= DIVA_OS_MEM_ATTACH_PORT(IoAdapter
);
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
) {
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) {
695 ("Protocol startup time %d.%02d seconds",
696 (i
/ 100), (i
% 100)))
701 DIVA_OS_MEM_DETACH_PORT(IoAdapter
, Port
);
704 DBG_FTL(("A: A(%d) %s: Adapter selftest failed 0x%04X",
705 IoAdapter
->ANum
, IoAdapter
->Properties
.Name
,
707 (*(IoAdapter
->trapFnc
)) (IoAdapter
);
711 IoAdapter
->Initialized
= 1;
716 IoAdapter
->IrqCount
= 0;
719 if (IoAdapter
->reset
) {
720 Port
= DIVA_OS_MEM_ATTACH_RESET(IoAdapter
);
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
++) {
729 if (!IoAdapter
->IrqCount
) {
731 ("A: A(%d) interrupt test failed",
733 IoAdapter
->Initialized
= 0;
734 IoAdapter
->stop(IoAdapter
);
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
))
744 diva_xdi_didd_register_adapter(IoAdapter
->ANum
);
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
);
765 diva_os_cancel_soft_isr(&IoAdapter
->req_soft_isr
);
766 diva_os_cancel_soft_isr(&IoAdapter
->isr_soft_isr
);
772 static int diva_bri_stop_adapter(diva_os_xdi_adapter_t
*a
)
774 PISDN_ADAPTER IoAdapter
= &a
->xdi_adapter
;
777 if (!IoAdapter
->port
) {
780 if (!IoAdapter
->Initialized
) {
781 DBG_ERR(("A: A(%d) can't stop BRI adapter - not running",
783 return (-1); /* nothing to stop */
785 IoAdapter
->Initialized
= 0;
788 Disconnect Adapter from DIDD
790 diva_xdi_didd_remove_adapter(IoAdapter
->ANum
);
795 a
->clear_interrupts_proc
= diva_bri_clear_interrupts
;
796 IoAdapter
->a
.ReadyInt
= 1;
797 IoAdapter
->a
.ram_inc(&IoAdapter
->a
, &PR_RAM
->ReadyInt
);
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",
807 IoAdapter
->a
.ReadyInt
= 0;
810 Stop and reset adapter
812 IoAdapter
->stop(IoAdapter
);