1 /* $Id: os_4bri.c,v 1.28.4.4 2005/02/11 19:40:25 armin Exp $ */
14 #include "xdi_adapter.h"
21 static void *diva_xdiLoadFileFile
= NULL
;
22 static dword diva_xdiLoadFileLength
= 0;
27 extern void prepare_qBri_functions(PISDN_ADAPTER IoAdapter
);
28 extern void prepare_qBri2_functions(PISDN_ADAPTER IoAdapter
);
29 extern void diva_xdi_display_adapter_features(int card
);
30 extern void diva_add_slave_adapter(diva_os_xdi_adapter_t
* a
);
32 extern int qBri_FPGA_download(PISDN_ADAPTER IoAdapter
);
33 extern void start_qBri_hardware(PISDN_ADAPTER IoAdapter
);
35 extern int diva_card_read_xlog(diva_os_xdi_adapter_t
* a
);
40 static unsigned long _4bri_bar_length
[4] = {
46 static unsigned long _4bri_v2_bar_length
[4] = {
52 static unsigned long _4bri_v2_bri_bar_length
[4] = {
60 static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t
* a
);
61 static int _4bri_get_serial_number(diva_os_xdi_adapter_t
* a
);
62 static int diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter
*a
,
63 diva_xdi_um_cfg_cmd_t
* cmd
,
65 static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t
* a
);
66 static int diva_4bri_write_fpga_image(diva_os_xdi_adapter_t
* a
,
67 byte
* data
, dword length
);
68 static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter
);
69 static int diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter
,
72 dword length
, dword limit
);
73 static int diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter
,
74 dword start_address
, dword features
);
75 static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter
);
76 static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t
* a
);
78 static int _4bri_is_rev_2_card(int card_ordinal
)
80 switch (card_ordinal
) {
81 case CARDTYPE_DIVASRV_Q_8M_V2_PCI
:
82 case CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI
:
83 case CARDTYPE_DIVASRV_B_2M_V2_PCI
:
84 case CARDTYPE_DIVASRV_B_2F_PCI
:
85 case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI
:
91 static int _4bri_is_rev_2_bri_card(int card_ordinal
)
93 switch (card_ordinal
) {
94 case CARDTYPE_DIVASRV_B_2M_V2_PCI
:
95 case CARDTYPE_DIVASRV_B_2F_PCI
:
96 case CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI
:
102 static void diva_4bri_set_addresses(diva_os_xdi_adapter_t
*a
)
104 dword offset
= a
->resources
.pci
.qoffset
;
105 dword c_offset
= offset
* a
->xdi_adapter
.ControllerNumber
;
107 a
->resources
.pci
.mem_type_id
[MEM_TYPE_RAM
] = 2;
108 a
->resources
.pci
.mem_type_id
[MEM_TYPE_ADDRESS
] = 2;
109 a
->resources
.pci
.mem_type_id
[MEM_TYPE_CONTROL
] = 2;
110 a
->resources
.pci
.mem_type_id
[MEM_TYPE_RESET
] = 0;
111 a
->resources
.pci
.mem_type_id
[MEM_TYPE_CTLREG
] = 3;
112 a
->resources
.pci
.mem_type_id
[MEM_TYPE_PROM
] = 0;
115 Set up hardware related pointers
117 a
->xdi_adapter
.Address
= a
->resources
.pci
.addr
[2]; /* BAR2 SDRAM */
118 a
->xdi_adapter
.Address
+= c_offset
;
120 a
->xdi_adapter
.Control
= a
->resources
.pci
.addr
[2]; /* BAR2 SDRAM */
122 a
->xdi_adapter
.ram
= a
->resources
.pci
.addr
[2]; /* BAR2 SDRAM */
123 a
->xdi_adapter
.ram
+= c_offset
+ (offset
- MQ_SHARED_RAM_SIZE
);
125 a
->xdi_adapter
.reset
= a
->resources
.pci
.addr
[0]; /* BAR0 CONFIG */
127 ctlReg contains the register address for the MIPS CPU reset control
129 a
->xdi_adapter
.ctlReg
= a
->resources
.pci
.addr
[3]; /* BAR3 CNTRL */
131 prom contains the register address for FPGA and EEPROM programming
133 a
->xdi_adapter
.prom
= &a
->xdi_adapter
.reset
[0x6E];
137 ** BAR0 - MEM - 0x100 - CONFIG MEM
138 ** BAR1 - I/O - 0x100 - UNUSED
139 ** BAR2 - MEM - MQ_MEMORY_SIZE (MQ2_MEMORY_SIZE on Rev.2) - SDRAM
140 ** BAR3 - MEM - 0x2000 (0x10000 on Rev.2) - CNTRL
142 ** Called by master adapter, that will initialize and add slave adapters
144 int diva_4bri_init_card(diva_os_xdi_adapter_t
* a
)
148 PADAPTER_LIST_ENTRY quadro_list
;
149 diva_os_xdi_adapter_t
*diva_current
;
150 diva_os_xdi_adapter_t
*adapter_list
[4];
152 unsigned long bar_length
[sizeof(_4bri_bar_length
) /
153 sizeof(_4bri_bar_length
[0])];
154 int v2
= _4bri_is_rev_2_card(a
->CardOrdinal
);
155 int tasks
= _4bri_is_rev_2_bri_card(a
->CardOrdinal
) ? 1 : MQ_INSTANCE_COUNT
;
156 int factor
= (tasks
== 1) ? 1 : 2;
159 if (_4bri_is_rev_2_bri_card(a
->CardOrdinal
)) {
160 memcpy(bar_length
, _4bri_v2_bri_bar_length
,
163 memcpy(bar_length
, _4bri_v2_bar_length
,
167 memcpy(bar_length
, _4bri_bar_length
, sizeof(bar_length
));
169 DBG_TRC(("SDRAM_LENGTH=%08x, tasks=%d, factor=%d",
170 bar_length
[2], tasks
, factor
))
174 The serial number of 4BRI is accessible in accordance with PCI spec
175 via command register located in configuration space, also we do not
176 have to map any BAR before we can access it
178 if (!_4bri_get_serial_number(a
)) {
179 DBG_ERR(("A: 4BRI can't get Serial Number"))
180 diva_4bri_cleanup_adapter(a
);
187 a
->xdi_adapter
.Properties
= CardProperties
[a
->CardOrdinal
];
188 DBG_LOG(("Load %s, SN:%ld, bus:%02x, func:%02x",
189 a
->xdi_adapter
.Properties
.Name
,
190 a
->xdi_adapter
.serialNo
,
191 a
->resources
.pci
.bus
, a
->resources
.pci
.func
))
194 First initialization step: get and check hardware resoures.
195 Do not map resources and do not access card at this step
197 for (bar
= 0; bar
< 4; bar
++) {
198 a
->resources
.pci
.bar
[bar
] =
199 divasa_get_pci_bar(a
->resources
.pci
.bus
,
200 a
->resources
.pci
.func
, bar
,
201 a
->resources
.pci
.hdev
);
202 if (!a
->resources
.pci
.bar
[bar
]
203 || (a
->resources
.pci
.bar
[bar
] == 0xFFFFFFF0)) {
205 ("A: invalid bar[%d]=%08x", bar
,
206 a
->resources
.pci
.bar
[bar
]))
210 a
->resources
.pci
.irq
=
211 (byte
) divasa_get_pci_irq(a
->resources
.pci
.bus
,
212 a
->resources
.pci
.func
,
213 a
->resources
.pci
.hdev
);
214 if (!a
->resources
.pci
.irq
) {
215 DBG_ERR(("A: invalid irq"));
219 a
->xdi_adapter
.sdram_bar
= a
->resources
.pci
.bar
[2];
224 for (bar
= 0; bar
< 4; bar
++) {
225 if (bar
!= 1) { /* ignore I/O */
226 a
->resources
.pci
.addr
[bar
] =
227 divasa_remap_pci_bar(a
, bar
, a
->resources
.pci
.bar
[bar
],
229 if (!a
->resources
.pci
.addr
[bar
]) {
230 DBG_ERR(("A: 4BRI: can't map bar[%d]", bar
))
231 diva_4bri_cleanup_adapter(a
);
240 sprintf(&a
->port_name
[0], "DIVA 4BRI %ld", (long) a
->xdi_adapter
.serialNo
);
242 if (diva_os_register_io_port(a
, 1, a
->resources
.pci
.bar
[1],
243 bar_length
[1], &a
->port_name
[0], 1)) {
244 DBG_ERR(("A: 4BRI: can't register bar[1]"))
245 diva_4bri_cleanup_adapter(a
);
249 a
->resources
.pci
.addr
[1] =
250 (void *) (unsigned long) a
->resources
.pci
.bar
[1];
253 Set cleanup pointer for base adapter only, so slave adapter
254 will be unable to get cleanup
256 a
->interface
.cleanup_adapter_proc
= diva_4bri_cleanup_adapter
;
259 Create slave adapters
262 if (!(a
->slave_adapters
[0] =
263 (diva_os_xdi_adapter_t
*) diva_os_malloc(0, sizeof(*a
))))
265 diva_4bri_cleanup_adapter(a
);
268 if (!(a
->slave_adapters
[1] =
269 (diva_os_xdi_adapter_t
*) diva_os_malloc(0, sizeof(*a
))))
271 diva_os_free(0, a
->slave_adapters
[0]);
272 a
->slave_adapters
[0] = NULL
;
273 diva_4bri_cleanup_adapter(a
);
276 if (!(a
->slave_adapters
[2] =
277 (diva_os_xdi_adapter_t
*) diva_os_malloc(0, sizeof(*a
))))
279 diva_os_free(0, a
->slave_adapters
[0]);
280 diva_os_free(0, a
->slave_adapters
[1]);
281 a
->slave_adapters
[0] = NULL
;
282 a
->slave_adapters
[1] = NULL
;
283 diva_4bri_cleanup_adapter(a
);
286 memset(a
->slave_adapters
[0], 0x00, sizeof(*a
));
287 memset(a
->slave_adapters
[1], 0x00, sizeof(*a
));
288 memset(a
->slave_adapters
[2], 0x00, sizeof(*a
));
292 adapter_list
[1] = a
->slave_adapters
[0];
293 adapter_list
[2] = a
->slave_adapters
[1];
294 adapter_list
[3] = a
->slave_adapters
[2];
300 (PADAPTER_LIST_ENTRY
) diva_os_malloc(0, sizeof(*quadro_list
));
301 if (!(a
->slave_list
= quadro_list
)) {
302 for (i
= 0; i
< (tasks
- 1); i
++) {
303 diva_os_free(0, a
->slave_adapters
[i
]);
304 a
->slave_adapters
[i
] = NULL
;
306 diva_4bri_cleanup_adapter(a
);
309 memset(quadro_list
, 0x00, sizeof(*quadro_list
));
314 a
->xdi_adapter
.QuadroList
= quadro_list
;
315 for (i
= 0; i
< tasks
; i
++) {
316 adapter_list
[i
]->xdi_adapter
.ControllerNumber
= i
;
317 adapter_list
[i
]->xdi_adapter
.tasks
= tasks
;
318 quadro_list
->QuadroAdapter
[i
] =
319 &adapter_list
[i
]->xdi_adapter
;
322 for (i
= 0; i
< tasks
; i
++) {
323 diva_current
= adapter_list
[i
];
325 diva_current
->dsp_mask
= 0x00000003;
327 diva_current
->xdi_adapter
.a
.io
=
328 &diva_current
->xdi_adapter
;
329 diva_current
->xdi_adapter
.DIRequest
= request
;
330 diva_current
->interface
.cmd_proc
= diva_4bri_cmd_card_proc
;
331 diva_current
->xdi_adapter
.Properties
=
332 CardProperties
[a
->CardOrdinal
];
333 diva_current
->CardOrdinal
= a
->CardOrdinal
;
335 diva_current
->xdi_adapter
.Channels
=
336 CardProperties
[a
->CardOrdinal
].Channels
;
337 diva_current
->xdi_adapter
.e_max
=
338 CardProperties
[a
->CardOrdinal
].E_info
;
339 diva_current
->xdi_adapter
.e_tbl
=
341 diva_current
->xdi_adapter
.e_max
*
344 if (!diva_current
->xdi_adapter
.e_tbl
) {
345 diva_4bri_cleanup_slave_adapters(a
);
346 diva_4bri_cleanup_adapter(a
);
347 for (i
= 1; i
< (tasks
- 1); i
++) {
348 diva_os_free(0, adapter_list
[i
]);
352 memset(diva_current
->xdi_adapter
.e_tbl
, 0x00,
353 diva_current
->xdi_adapter
.e_max
* sizeof(E_INFO
));
355 if (diva_os_initialize_spin_lock(&diva_current
->xdi_adapter
.isr_spin_lock
, "isr")) {
356 diva_4bri_cleanup_slave_adapters(a
);
357 diva_4bri_cleanup_adapter(a
);
358 for (i
= 1; i
< (tasks
- 1); i
++) {
359 diva_os_free(0, adapter_list
[i
]);
363 if (diva_os_initialize_spin_lock(&diva_current
->xdi_adapter
.data_spin_lock
, "data")) {
364 diva_4bri_cleanup_slave_adapters(a
);
365 diva_4bri_cleanup_adapter(a
);
366 for (i
= 1; i
< (tasks
- 1); i
++) {
367 diva_os_free(0, adapter_list
[i
]);
372 strcpy(diva_current
->xdi_adapter
.req_soft_isr
. dpc_thread_name
, "kdivas4brid");
374 if (diva_os_initialize_soft_isr (&diva_current
->xdi_adapter
.req_soft_isr
, DIDpcRoutine
,
375 &diva_current
->xdi_adapter
)) {
376 diva_4bri_cleanup_slave_adapters(a
);
377 diva_4bri_cleanup_adapter(a
);
378 for (i
= 1; i
< (tasks
- 1); i
++) {
379 diva_os_free(0, adapter_list
[i
]);
385 Do not initialize second DPC - only one thread will be created
387 diva_current
->xdi_adapter
.isr_soft_isr
.object
=
388 diva_current
->xdi_adapter
.req_soft_isr
.object
;
392 prepare_qBri2_functions(&a
->xdi_adapter
);
394 prepare_qBri_functions(&a
->xdi_adapter
);
397 for (i
= 0; i
< tasks
; i
++) {
398 diva_current
= adapter_list
[i
];
400 memcpy(&diva_current
->resources
, &a
->resources
, sizeof(divas_card_resources_t
));
401 diva_current
->resources
.pci
.qoffset
= (a
->xdi_adapter
.MemorySize
>> factor
);
405 Set up hardware related pointers
407 a
->xdi_adapter
.cfg
= (void *) (unsigned long) a
->resources
.pci
.bar
[0]; /* BAR0 CONFIG */
408 a
->xdi_adapter
.port
= (void *) (unsigned long) a
->resources
.pci
.bar
[1]; /* BAR1 */
409 a
->xdi_adapter
.ctlReg
= (void *) (unsigned long) a
->resources
.pci
.bar
[3]; /* BAR3 CNTRL */
411 for (i
= 0; i
< tasks
; i
++) {
412 diva_current
= adapter_list
[i
];
413 diva_4bri_set_addresses(diva_current
);
414 Slave
= a
->xdi_adapter
.QuadroList
->QuadroAdapter
[i
];
415 Slave
->MultiMaster
= &a
->xdi_adapter
;
416 Slave
->sdram_bar
= a
->xdi_adapter
.sdram_bar
;
418 Slave
->serialNo
= ((dword
) (Slave
->ControllerNumber
<< 24)) |
419 a
->xdi_adapter
.serialNo
;
420 Slave
->cardType
= a
->xdi_adapter
.cardType
;
425 reset contains the base address for the PLX 9054 register set
427 p
= DIVA_OS_MEM_ATTACH_RESET(&a
->xdi_adapter
);
428 WRITE_BYTE(&p
[PLX9054_INTCSR
], 0x00); /* disable PCI interrupts */
429 DIVA_OS_MEM_DETACH_RESET(&a
->xdi_adapter
, p
);
434 a
->xdi_adapter
.irq_info
.irq_nr
= a
->resources
.pci
.irq
;
435 sprintf(a
->xdi_adapter
.irq_info
.irq_name
, "DIVA 4BRI %ld",
436 (long) a
->xdi_adapter
.serialNo
);
438 if (diva_os_register_irq(a
, a
->xdi_adapter
.irq_info
.irq_nr
,
439 a
->xdi_adapter
.irq_info
.irq_name
)) {
440 diva_4bri_cleanup_slave_adapters(a
);
441 diva_4bri_cleanup_adapter(a
);
442 for (i
= 1; i
< (tasks
- 1); i
++) {
443 diva_os_free(0, adapter_list
[i
]);
448 a
->xdi_adapter
.irq_info
.registered
= 1;
451 Add three slave adapters
454 diva_add_slave_adapter(adapter_list
[1]);
455 diva_add_slave_adapter(adapter_list
[2]);
456 diva_add_slave_adapter(adapter_list
[3]);
459 diva_log_info("%s IRQ:%d SerNo:%d", a
->xdi_adapter
.Properties
.Name
,
460 a
->resources
.pci
.irq
, a
->xdi_adapter
.serialNo
);
466 ** Cleanup function will be called for master adapter only
467 ** this is guaranteed by design: cleanup callback is set
468 ** by master adapter only
470 static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t
* a
)
475 Stop adapter if running
477 if (a
->xdi_adapter
.Initialized
) {
478 diva_4bri_stop_adapter(a
);
484 if (a
->xdi_adapter
.irq_info
.registered
) {
485 diva_os_remove_irq(a
, a
->xdi_adapter
.irq_info
.irq_nr
);
487 a
->xdi_adapter
.irq_info
.registered
= 0;
490 Free DPC's and spin locks on all adapters
492 diva_4bri_cleanup_slave_adapters(a
);
497 for (bar
= 0; bar
< 4; bar
++) {
499 if (a
->resources
.pci
.bar
[bar
]
500 && a
->resources
.pci
.addr
[bar
]) {
501 divasa_unmap_pci_bar(a
->resources
.pci
.addr
[bar
]);
502 a
->resources
.pci
.bar
[bar
] = 0;
503 a
->resources
.pci
.addr
[bar
] = NULL
;
511 if (a
->resources
.pci
.bar
[1] && a
->resources
.pci
.addr
[1]) {
512 diva_os_register_io_port(a
, 0, a
->resources
.pci
.bar
[1],
513 _4bri_is_rev_2_card(a
->
515 _4bri_v2_bar_length
[1] :
517 &a
->port_name
[0], 1);
518 a
->resources
.pci
.bar
[1] = 0;
519 a
->resources
.pci
.addr
[1] = NULL
;
523 diva_os_free(0, a
->slave_list
);
524 a
->slave_list
= NULL
;
530 static int _4bri_get_serial_number(diva_os_xdi_adapter_t
* a
)
534 word addr
, status
, i
, j
;
538 Bus
= a
->resources
.pci
.bus
;
539 Slot
= a
->resources
.pci
.func
;
540 hdev
= a
->resources
.pci
.hdev
;
542 for (i
= 0; i
< 64; ++i
) {
544 for (j
= 0; j
< 5; ++j
) {
545 PCIwrite(Bus
, Slot
, 0x4E, &addr
, sizeof(addr
),
548 PCIread(Bus
, Slot
, 0x4E, &status
, sizeof(status
),
554 DBG_ERR(("EEPROM[%d] read failed (0x%x)", i
* 4, addr
))
557 PCIread(Bus
, Slot
, 0x50, &data
[i
], sizeof(data
[i
]), hdev
);
559 DBG_BLK(((char *) &data
[0], sizeof(data
)))
562 if (serNo
== 0 || serNo
== 0xffffffff)
566 DBG_LOG(("W: Serial Number == 0, create one serial number"));
567 serNo
= a
->resources
.pci
.bar
[1] & 0xffff0000;
568 serNo
|= a
->resources
.pci
.bus
<< 8;
569 serNo
|= a
->resources
.pci
.func
;
572 a
->xdi_adapter
.serialNo
= serNo
;
574 DBG_REG(("Serial No. : %ld", a
->xdi_adapter
.serialNo
))
580 ** Release resources of slave adapters
582 static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t
* a
)
584 diva_os_xdi_adapter_t
*adapter_list
[4];
585 diva_os_xdi_adapter_t
*diva_current
;
589 adapter_list
[1] = a
->slave_adapters
[0];
590 adapter_list
[2] = a
->slave_adapters
[1];
591 adapter_list
[3] = a
->slave_adapters
[2];
593 for (i
= 0; i
< a
->xdi_adapter
.tasks
; i
++) {
594 diva_current
= adapter_list
[i
];
596 diva_os_destroy_spin_lock(&diva_current
->
598 isr_spin_lock
, "unload");
599 diva_os_destroy_spin_lock(&diva_current
->
604 diva_os_cancel_soft_isr(&diva_current
->xdi_adapter
.
606 diva_os_cancel_soft_isr(&diva_current
->xdi_adapter
.
609 diva_os_remove_soft_isr(&diva_current
->xdi_adapter
.
611 diva_current
->xdi_adapter
.isr_soft_isr
.object
= NULL
;
613 if (diva_current
->xdi_adapter
.e_tbl
) {
615 diva_current
->xdi_adapter
.
618 diva_current
->xdi_adapter
.e_tbl
= NULL
;
619 diva_current
->xdi_adapter
.e_max
= 0;
620 diva_current
->xdi_adapter
.e_count
= 0;
628 diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter
*a
,
629 diva_xdi_um_cfg_cmd_t
* cmd
, int length
)
633 if (cmd
->adapter
!= a
->controller
) {
634 DBG_ERR(("A: 4bri_cmd, invalid controller=%d != %d",
635 cmd
->adapter
, a
->controller
))
639 switch (cmd
->command
) {
640 case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL
:
641 a
->xdi_mbox
.data_length
= sizeof(dword
);
643 diva_os_malloc(0, a
->xdi_mbox
.data_length
);
644 if (a
->xdi_mbox
.data
) {
645 *(dword
*) a
->xdi_mbox
.data
=
646 (dword
) a
->CardOrdinal
;
647 a
->xdi_mbox
.status
= DIVA_XDI_MBOX_BUSY
;
652 case DIVA_XDI_UM_CMD_GET_SERIAL_NR
:
653 a
->xdi_mbox
.data_length
= sizeof(dword
);
655 diva_os_malloc(0, a
->xdi_mbox
.data_length
);
656 if (a
->xdi_mbox
.data
) {
657 *(dword
*) a
->xdi_mbox
.data
=
658 (dword
) a
->xdi_adapter
.serialNo
;
659 a
->xdi_mbox
.status
= DIVA_XDI_MBOX_BUSY
;
664 case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG
:
665 if (!a
->xdi_adapter
.ControllerNumber
) {
667 Only master adapter can access hardware config
669 a
->xdi_mbox
.data_length
= sizeof(dword
) * 9;
671 diva_os_malloc(0, a
->xdi_mbox
.data_length
);
672 if (a
->xdi_mbox
.data
) {
674 dword
*data
= (dword
*) a
->xdi_mbox
.data
;
676 for (i
= 0; i
< 8; i
++) {
677 *data
++ = a
->resources
.pci
.bar
[i
];
679 *data
++ = (dword
) a
->resources
.pci
.irq
;
680 a
->xdi_mbox
.status
= DIVA_XDI_MBOX_BUSY
;
686 case DIVA_XDI_UM_CMD_GET_CARD_STATE
:
687 if (!a
->xdi_adapter
.ControllerNumber
) {
688 a
->xdi_mbox
.data_length
= sizeof(dword
);
690 diva_os_malloc(0, a
->xdi_mbox
.data_length
);
691 if (a
->xdi_mbox
.data
) {
692 dword
*data
= (dword
*) a
->xdi_mbox
.data
;
693 if (!a
->xdi_adapter
.ram
694 || !a
->xdi_adapter
.reset
695 || !a
->xdi_adapter
.cfg
) {
697 } else if (a
->xdi_adapter
.trapped
) {
699 } else if (a
->xdi_adapter
.Initialized
) {
704 a
->xdi_mbox
.status
= DIVA_XDI_MBOX_BUSY
;
710 case DIVA_XDI_UM_CMD_WRITE_FPGA
:
711 if (!a
->xdi_adapter
.ControllerNumber
) {
713 diva_4bri_write_fpga_image(a
,
721 case DIVA_XDI_UM_CMD_RESET_ADAPTER
:
722 if (!a
->xdi_adapter
.ControllerNumber
) {
723 ret
= diva_4bri_reset_adapter(&a
->xdi_adapter
);
727 case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK
:
728 if (!a
->xdi_adapter
.ControllerNumber
) {
729 ret
= diva_4bri_write_sdram_block(&a
->xdi_adapter
,
745 case DIVA_XDI_UM_CMD_START_ADAPTER
:
746 if (!a
->xdi_adapter
.ControllerNumber
) {
747 ret
= diva_4bri_start_adapter(&a
->xdi_adapter
,
755 case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES
:
756 if (!a
->xdi_adapter
.ControllerNumber
) {
757 a
->xdi_adapter
.features
=
758 cmd
->command_data
.features
.features
;
759 a
->xdi_adapter
.a
.protocol_capabilities
=
760 a
->xdi_adapter
.features
;
761 DBG_TRC(("Set raw protocol features (%08x)",
762 a
->xdi_adapter
.features
))
767 case DIVA_XDI_UM_CMD_STOP_ADAPTER
:
768 if (!a
->xdi_adapter
.ControllerNumber
) {
769 ret
= diva_4bri_stop_adapter(a
);
773 case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY
:
774 ret
= diva_card_read_xlog(a
);
777 case DIVA_XDI_UM_CMD_READ_SDRAM
:
778 if (!a
->xdi_adapter
.ControllerNumber
779 && a
->xdi_adapter
.Address
) {
781 (a
->xdi_mbox
.data_length
=
782 cmd
->command_data
.read_sdram
.length
)) {
784 (a
->xdi_mbox
.data_length
+
785 cmd
->command_data
.read_sdram
.offset
) <
786 a
->xdi_adapter
.MemorySize
) {
791 if (a
->xdi_mbox
.data
) {
792 byte __iomem
*p
= DIVA_OS_MEM_ATTACH_ADDRESS(&a
->xdi_adapter
);
793 byte __iomem
*src
= p
;
794 byte
*dst
= a
->xdi_mbox
.data
;
795 dword len
= a
->xdi_mbox
.data_length
;
797 src
+= cmd
->command_data
.read_sdram
.offset
;
800 *dst
++ = READ_BYTE(src
++);
802 DIVA_OS_MEM_DETACH_ADDRESS(&a
->xdi_adapter
, p
);
803 a
->xdi_mbox
.status
= DIVA_XDI_MBOX_BUSY
;
812 DBG_ERR(("A: A(%d) invalid cmd=%d", a
->controller
,
819 void *xdiLoadFile(char *FileName
, dword
*FileLength
,
822 void *ret
= diva_xdiLoadFileFile
;
825 *FileLength
= diva_xdiLoadFileLength
;
827 diva_xdiLoadFileFile
= NULL
;
828 diva_xdiLoadFileLength
= 0;
833 void diva_os_set_qBri_functions(PISDN_ADAPTER IoAdapter
)
837 void diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter
)
842 diva_4bri_write_fpga_image(diva_os_xdi_adapter_t
* a
, byte
* data
,
847 diva_xdiLoadFileFile
= data
;
848 diva_xdiLoadFileLength
= length
;
850 ret
= qBri_FPGA_download(&a
->xdi_adapter
);
852 diva_xdiLoadFileFile
= NULL
;
853 diva_xdiLoadFileLength
= 0;
855 return (ret
? 0 : -1);
858 static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter
)
863 if (!IoAdapter
->Address
|| !IoAdapter
->reset
) {
866 if (IoAdapter
->Initialized
) {
867 DBG_ERR(("A: A(%d) can't reset 4BRI adapter - please stop first",
873 Forget all entities on all adapters
875 for (i
= 0; ((i
< IoAdapter
->tasks
) && IoAdapter
->QuadroList
); i
++) {
876 Slave
= IoAdapter
->QuadroList
->QuadroAdapter
[i
];
879 memset(Slave
->e_tbl
, 0x00,
880 Slave
->e_max
* sizeof(E_INFO
));
887 memset(&Slave
->a
.IdTable
[0], 0x00,
888 sizeof(Slave
->a
.IdTable
));
889 memset(&Slave
->a
.IdTypeTable
[0], 0x00,
890 sizeof(Slave
->a
.IdTypeTable
));
891 memset(&Slave
->a
.FlowControlIdTable
[0], 0x00,
892 sizeof(Slave
->a
.FlowControlIdTable
));
893 memset(&Slave
->a
.FlowControlSkipTable
[0], 0x00,
894 sizeof(Slave
->a
.FlowControlSkipTable
));
895 memset(&Slave
->a
.misc_flags_table
[0], 0x00,
896 sizeof(Slave
->a
.misc_flags_table
));
897 memset(&Slave
->a
.rx_stream
[0], 0x00,
898 sizeof(Slave
->a
.rx_stream
));
899 memset(&Slave
->a
.tx_stream
[0], 0x00,
900 sizeof(Slave
->a
.tx_stream
));
901 memset(&Slave
->a
.tx_pos
[0], 0x00, sizeof(Slave
->a
.tx_pos
));
902 memset(&Slave
->a
.rx_pos
[0], 0x00, sizeof(Slave
->a
.rx_pos
));
910 diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter
,
912 const byte
* data
, dword length
, dword limit
)
914 byte __iomem
*p
= DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter
);
915 byte __iomem
*mem
= p
;
917 if (((address
+ length
) >= limit
) || !mem
) {
918 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter
, p
);
919 DBG_ERR(("A: A(%d) write 4BRI address=0x%08lx",
920 IoAdapter
->ANum
, address
+ length
))
926 WRITE_BYTE(mem
++, *data
++);
929 DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter
, p
);
934 diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter
,
935 dword start_address
, dword features
)
937 volatile word __iomem
*signature
;
945 start_qBri_hardware(IoAdapter
);
947 p
= DIVA_OS_MEM_ATTACH_RAM(IoAdapter
);
949 wait for signature in shared memory (max. 3 seconds)
951 signature
= (volatile word __iomem
*) (&p
[0x1E]);
953 for (i
= 0; i
< 300; ++i
) {
955 if (READ_WORD(&signature
[0]) == 0x4447) {
956 DBG_TRC(("Protocol startup time %d.%02d seconds",
957 (i
/ 100), (i
% 100)))
963 for (i
= 1; i
< IoAdapter
->tasks
; i
++) {
964 IoAdapter
->QuadroList
->QuadroAdapter
[i
]->features
=
966 IoAdapter
->QuadroList
->QuadroAdapter
[i
]->a
.
967 protocol_capabilities
= IoAdapter
->features
;
971 DBG_FTL(("%s: Adapter selftest failed, signature=%04x",
972 IoAdapter
->Properties
.Name
,
973 READ_WORD(&signature
[0])))
974 DIVA_OS_MEM_DETACH_RAM(IoAdapter
, p
);
975 (*(IoAdapter
->trapFnc
)) (IoAdapter
);
976 IoAdapter
->stop(IoAdapter
);
979 DIVA_OS_MEM_DETACH_RAM(IoAdapter
, p
);
981 for (i
= 0; i
< IoAdapter
->tasks
; i
++) {
982 IoAdapter
->QuadroList
->QuadroAdapter
[i
]->Initialized
= 1;
983 IoAdapter
->QuadroList
->QuadroAdapter
[i
]->IrqCount
= 0;
986 if (check_qBri_interrupt(IoAdapter
)) {
987 DBG_ERR(("A: A(%d) interrupt test failed",
989 for (i
= 0; i
< IoAdapter
->tasks
; i
++) {
990 IoAdapter
->QuadroList
->QuadroAdapter
[i
]->Initialized
= 0;
992 IoAdapter
->stop(IoAdapter
);
996 IoAdapter
->Properties
.Features
= (word
) features
;
997 diva_xdi_display_adapter_features(IoAdapter
->ANum
);
999 for (i
= 0; i
< IoAdapter
->tasks
; i
++) {
1000 DBG_LOG(("A(%d) %s adapter successfull started",
1001 IoAdapter
->QuadroList
->QuadroAdapter
[i
]->ANum
,
1002 (IoAdapter
->tasks
== 1) ? "BRI 2.0" : "4BRI"))
1003 diva_xdi_didd_register_adapter(IoAdapter
->QuadroList
->QuadroAdapter
[i
]->ANum
);
1004 IoAdapter
->QuadroList
->QuadroAdapter
[i
]->Properties
.Features
= (word
) features
;
1010 static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter
)
1012 #ifdef SUPPORT_INTERRUPT_TEST_ON_4BRI
1014 ADAPTER
*a
= &IoAdapter
->a
;
1017 IoAdapter
->IrqCount
= 0;
1019 if (IoAdapter
->ControllerNumber
> 0)
1022 p
= DIVA_OS_MEM_ATTACH_RESET(IoAdapter
);
1023 WRITE_BYTE(&p
[PLX9054_INTCSR
], PLX9054_INT_ENABLE
);
1024 DIVA_OS_MEM_DETACH_RESET(IoAdapter
, p
);
1029 a
->ram_out(a
, &PR_RAM
->ReadyInt
, 1);
1031 for (i
= 100; !IoAdapter
->IrqCount
&& (i
-- > 0); diva_os_wait(10));
1033 return ((IoAdapter
->IrqCount
> 0) ? 0 : -1);
1035 dword
volatile __iomem
*qBriIrq
;
1038 Reset on-board interrupt register
1040 IoAdapter
->IrqCount
= 0;
1041 p
= DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter
);
1042 qBriIrq
= (dword
volatile __iomem
*) (&p
[_4bri_is_rev_2_card
1044 cardType
) ? (MQ2_BREG_IRQ_TEST
)
1045 : (MQ_BREG_IRQ_TEST
)]);
1047 WRITE_DWORD(qBriIrq
, MQ_IRQ_REQ_OFF
);
1048 DIVA_OS_MEM_DETACH_CTLREG(IoAdapter
, p
);
1050 p
= DIVA_OS_MEM_ATTACH_RESET(IoAdapter
);
1051 WRITE_BYTE(&p
[PLX9054_INTCSR
], PLX9054_INT_ENABLE
);
1052 DIVA_OS_MEM_DETACH_RESET(IoAdapter
, p
);
1057 #endif /* SUPPORT_INTERRUPT_TEST_ON_4BRI */
1060 static void diva_4bri_clear_interrupts(diva_os_xdi_adapter_t
* a
)
1062 PISDN_ADAPTER IoAdapter
= &a
->xdi_adapter
;
1065 clear any pending interrupt
1067 IoAdapter
->disIrq(IoAdapter
);
1069 IoAdapter
->tst_irq(&IoAdapter
->a
);
1070 IoAdapter
->clr_irq(&IoAdapter
->a
);
1071 IoAdapter
->tst_irq(&IoAdapter
->a
);
1076 diva_os_cancel_soft_isr(&IoAdapter
->req_soft_isr
);
1077 diva_os_cancel_soft_isr(&IoAdapter
->isr_soft_isr
);
1080 static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t
* a
)
1082 PISDN_ADAPTER IoAdapter
= &a
->xdi_adapter
;
1085 if (!IoAdapter
->ram
) {
1089 if (!IoAdapter
->Initialized
) {
1090 DBG_ERR(("A: A(%d) can't stop PRI adapter - not running",
1092 return (-1); /* nothing to stop */
1095 for (i
= 0; i
< IoAdapter
->tasks
; i
++) {
1096 IoAdapter
->QuadroList
->QuadroAdapter
[i
]->Initialized
= 0;
1100 Disconnect Adapters from DIDD
1102 for (i
= 0; i
< IoAdapter
->tasks
; i
++) {
1103 diva_xdi_didd_remove_adapter(IoAdapter
->QuadroList
->QuadroAdapter
[i
]->ANum
);
1111 a
->clear_interrupts_proc
= diva_4bri_clear_interrupts
;
1112 IoAdapter
->a
.ReadyInt
= 1;
1113 IoAdapter
->a
.ram_inc(&IoAdapter
->a
, &PR_RAM
->ReadyInt
);
1116 } while (i
-- && a
->clear_interrupts_proc
);
1118 if (a
->clear_interrupts_proc
) {
1119 diva_4bri_clear_interrupts(a
);
1120 a
->clear_interrupts_proc
= NULL
;
1121 DBG_ERR(("A: A(%d) no final interrupt from 4BRI adapter",
1124 IoAdapter
->a
.ReadyInt
= 0;
1127 Stop and reset adapter
1129 IoAdapter
->stop(IoAdapter
);