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[ARRAY_SIZE(_4bri_bar_length)];
153
int v2 = _4bri_is_rev_2_card(a->CardOrdinal);
154
int tasks = _4bri_is_rev_2_bri_card(a->CardOrdinal) ? 1 : MQ_INSTANCE_COUNT;
155
int factor = (tasks == 1) ? 1 : 2;
158
if (_4bri_is_rev_2_bri_card(a->CardOrdinal)) {
159
memcpy(bar_length, _4bri_v2_bri_bar_length,
162
memcpy(bar_length, _4bri_v2_bar_length,
166
memcpy(bar_length, _4bri_bar_length, sizeof(bar_length));
168
DBG_TRC(("SDRAM_LENGTH=%08x, tasks=%d, factor=%d",
169
bar_length[2], tasks, factor))
173
The serial number of 4BRI is accessible in accordance with PCI spec
174
via command register located in configuration space, also we do not
175
have to map any BAR before we can access it
177
if (!_4bri_get_serial_number(a)) {
178
DBG_ERR(("A: 4BRI can't get Serial Number"))
179
diva_4bri_cleanup_adapter(a);
186
a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
187
DBG_LOG(("Load %s, SN:%ld, bus:%02x, func:%02x",
188
a->xdi_adapter.Properties.Name,
189
a->xdi_adapter.serialNo,
190
a->resources.pci.bus, a->resources.pci.func))
193
First initialization step: get and check hardware resoures.
194
Do not map resources and do not access card at this step
196
for (bar = 0; bar < 4; bar++) {
197
a->resources.pci.bar[bar] =
198
divasa_get_pci_bar(a->resources.pci.bus,
199
a->resources.pci.func, bar,
200
a->resources.pci.hdev);
201
if (!a->resources.pci.bar[bar]
202
|| (a->resources.pci.bar[bar] == 0xFFFFFFF0)) {
204
("A: invalid bar[%d]=%08x", bar,
205
a->resources.pci.bar[bar]))
209
a->resources.pci.irq =
210
(byte) divasa_get_pci_irq(a->resources.pci.bus,
211
a->resources.pci.func,
212
a->resources.pci.hdev);
213
if (!a->resources.pci.irq) {
214
DBG_ERR(("A: invalid irq"));
218
a->xdi_adapter.sdram_bar = a->resources.pci.bar[2];
223
for (bar = 0; bar < 4; bar++) {
224
if (bar != 1) { /* ignore I/O */
225
a->resources.pci.addr[bar] =
226
divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
228
if (!a->resources.pci.addr[bar]) {
229
DBG_ERR(("A: 4BRI: can't map bar[%d]", bar))
230
diva_4bri_cleanup_adapter(a);
239
sprintf(&a->port_name[0], "DIVA 4BRI %ld", (long) a->xdi_adapter.serialNo);
241
if (diva_os_register_io_port(a, 1, a->resources.pci.bar[1],
242
bar_length[1], &a->port_name[0], 1)) {
243
DBG_ERR(("A: 4BRI: can't register bar[1]"))
244
diva_4bri_cleanup_adapter(a);
248
a->resources.pci.addr[1] =
249
(void *) (unsigned long) a->resources.pci.bar[1];
252
Set cleanup pointer for base adapter only, so slave adapter
253
will be unable to get cleanup
255
a->interface.cleanup_adapter_proc = diva_4bri_cleanup_adapter;
258
Create slave adapters
261
if (!(a->slave_adapters[0] =
262
(diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
264
diva_4bri_cleanup_adapter(a);
267
if (!(a->slave_adapters[1] =
268
(diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
270
diva_os_free(0, a->slave_adapters[0]);
271
a->slave_adapters[0] = NULL;
272
diva_4bri_cleanup_adapter(a);
275
if (!(a->slave_adapters[2] =
276
(diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
278
diva_os_free(0, a->slave_adapters[0]);
279
diva_os_free(0, a->slave_adapters[1]);
280
a->slave_adapters[0] = NULL;
281
a->slave_adapters[1] = NULL;
282
diva_4bri_cleanup_adapter(a);
285
memset(a->slave_adapters[0], 0x00, sizeof(*a));
286
memset(a->slave_adapters[1], 0x00, sizeof(*a));
287
memset(a->slave_adapters[2], 0x00, sizeof(*a));
291
adapter_list[1] = a->slave_adapters[0];
292
adapter_list[2] = a->slave_adapters[1];
293
adapter_list[3] = a->slave_adapters[2];
299
(PADAPTER_LIST_ENTRY) diva_os_malloc(0, sizeof(*quadro_list));
300
if (!(a->slave_list = quadro_list)) {
301
for (i = 0; i < (tasks - 1); i++) {
302
diva_os_free(0, a->slave_adapters[i]);
303
a->slave_adapters[i] = NULL;
305
diva_4bri_cleanup_adapter(a);
308
memset(quadro_list, 0x00, sizeof(*quadro_list));
313
a->xdi_adapter.QuadroList = quadro_list;
314
for (i = 0; i < tasks; i++) {
315
adapter_list[i]->xdi_adapter.ControllerNumber = i;
316
adapter_list[i]->xdi_adapter.tasks = tasks;
317
quadro_list->QuadroAdapter[i] =
318
&adapter_list[i]->xdi_adapter;
321
for (i = 0; i < tasks; i++) {
322
diva_current = adapter_list[i];
324
diva_current->dsp_mask = 0x00000003;
326
diva_current->xdi_adapter.a.io =
327
&diva_current->xdi_adapter;
328
diva_current->xdi_adapter.DIRequest = request;
329
diva_current->interface.cmd_proc = diva_4bri_cmd_card_proc;
330
diva_current->xdi_adapter.Properties =
331
CardProperties[a->CardOrdinal];
332
diva_current->CardOrdinal = a->CardOrdinal;
334
diva_current->xdi_adapter.Channels =
335
CardProperties[a->CardOrdinal].Channels;
336
diva_current->xdi_adapter.e_max =
337
CardProperties[a->CardOrdinal].E_info;
338
diva_current->xdi_adapter.e_tbl =
340
diva_current->xdi_adapter.e_max *
343
if (!diva_current->xdi_adapter.e_tbl) {
344
diva_4bri_cleanup_slave_adapters(a);
345
diva_4bri_cleanup_adapter(a);
346
for (i = 1; i < (tasks - 1); i++) {
347
diva_os_free(0, adapter_list[i]);
351
memset(diva_current->xdi_adapter.e_tbl, 0x00,
352
diva_current->xdi_adapter.e_max * sizeof(E_INFO));
354
if (diva_os_initialize_spin_lock(&diva_current->xdi_adapter.isr_spin_lock, "isr")) {
355
diva_4bri_cleanup_slave_adapters(a);
356
diva_4bri_cleanup_adapter(a);
357
for (i = 1; i < (tasks - 1); i++) {
358
diva_os_free(0, adapter_list[i]);
362
if (diva_os_initialize_spin_lock(&diva_current->xdi_adapter.data_spin_lock, "data")) {
363
diva_4bri_cleanup_slave_adapters(a);
364
diva_4bri_cleanup_adapter(a);
365
for (i = 1; i < (tasks - 1); i++) {
366
diva_os_free(0, adapter_list[i]);
371
strcpy(diva_current->xdi_adapter.req_soft_isr. dpc_thread_name, "kdivas4brid");
373
if (diva_os_initialize_soft_isr (&diva_current->xdi_adapter.req_soft_isr, DIDpcRoutine,
374
&diva_current->xdi_adapter)) {
375
diva_4bri_cleanup_slave_adapters(a);
376
diva_4bri_cleanup_adapter(a);
377
for (i = 1; i < (tasks - 1); i++) {
378
diva_os_free(0, adapter_list[i]);
384
Do not initialize second DPC - only one thread will be created
386
diva_current->xdi_adapter.isr_soft_isr.object =
387
diva_current->xdi_adapter.req_soft_isr.object;
391
prepare_qBri2_functions(&a->xdi_adapter);
393
prepare_qBri_functions(&a->xdi_adapter);
396
for (i = 0; i < tasks; i++) {
397
diva_current = adapter_list[i];
399
memcpy(&diva_current->resources, &a->resources, sizeof(divas_card_resources_t));
400
diva_current->resources.pci.qoffset = (a->xdi_adapter.MemorySize >> factor);
404
Set up hardware related pointers
406
a->xdi_adapter.cfg = (void *) (unsigned long) a->resources.pci.bar[0]; /* BAR0 CONFIG */
407
a->xdi_adapter.port = (void *) (unsigned long) a->resources.pci.bar[1]; /* BAR1 */
408
a->xdi_adapter.ctlReg = (void *) (unsigned long) a->resources.pci.bar[3]; /* BAR3 CNTRL */
410
for (i = 0; i < tasks; i++) {
411
diva_current = adapter_list[i];
412
diva_4bri_set_addresses(diva_current);
413
Slave = a->xdi_adapter.QuadroList->QuadroAdapter[i];
414
Slave->MultiMaster = &a->xdi_adapter;
415
Slave->sdram_bar = a->xdi_adapter.sdram_bar;
417
Slave->serialNo = ((dword) (Slave->ControllerNumber << 24)) |
418
a->xdi_adapter.serialNo;
419
Slave->cardType = a->xdi_adapter.cardType;
424
reset contains the base address for the PLX 9054 register set
426
p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
427
WRITE_BYTE(&p[PLX9054_INTCSR], 0x00); /* disable PCI interrupts */
428
DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
433
a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
434
sprintf(a->xdi_adapter.irq_info.irq_name, "DIVA 4BRI %ld",
435
(long) a->xdi_adapter.serialNo);
437
if (diva_os_register_irq(a, a->xdi_adapter.irq_info.irq_nr,
438
a->xdi_adapter.irq_info.irq_name)) {
439
diva_4bri_cleanup_slave_adapters(a);
440
diva_4bri_cleanup_adapter(a);
441
for (i = 1; i < (tasks - 1); i++) {
442
diva_os_free(0, adapter_list[i]);
447
a->xdi_adapter.irq_info.registered = 1;
450
Add three slave adapters
453
diva_add_slave_adapter(adapter_list[1]);
454
diva_add_slave_adapter(adapter_list[2]);
455
diva_add_slave_adapter(adapter_list[3]);
458
diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name,
459
a->resources.pci.irq, a->xdi_adapter.serialNo);
465
** Cleanup function will be called for master adapter only
466
** this is guaranteed by design: cleanup callback is set
467
** by master adapter only
469
static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a)
474
Stop adapter if running
476
if (a->xdi_adapter.Initialized) {
477
diva_4bri_stop_adapter(a);
483
if (a->xdi_adapter.irq_info.registered) {
484
diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
486
a->xdi_adapter.irq_info.registered = 0;
489
Free DPC's and spin locks on all adapters
491
diva_4bri_cleanup_slave_adapters(a);
496
for (bar = 0; bar < 4; bar++) {
498
if (a->resources.pci.bar[bar]
499
&& a->resources.pci.addr[bar]) {
500
divasa_unmap_pci_bar(a->resources.pci.addr[bar]);
501
a->resources.pci.bar[bar] = 0;
502
a->resources.pci.addr[bar] = NULL;
510
if (a->resources.pci.bar[1] && a->resources.pci.addr[1]) {
511
diva_os_register_io_port(a, 0, a->resources.pci.bar[1],
512
_4bri_is_rev_2_card(a->
514
_4bri_v2_bar_length[1] :
516
&a->port_name[0], 1);
517
a->resources.pci.bar[1] = 0;
518
a->resources.pci.addr[1] = NULL;
522
diva_os_free(0, a->slave_list);
523
a->slave_list = NULL;
529
static int _4bri_get_serial_number(diva_os_xdi_adapter_t * a)
533
word addr, status, i, j;
537
Bus = a->resources.pci.bus;
538
Slot = a->resources.pci.func;
539
hdev = a->resources.pci.hdev;
541
for (i = 0; i < 64; ++i) {
543
for (j = 0; j < 5; ++j) {
544
PCIwrite(Bus, Slot, 0x4E, &addr, sizeof(addr),
547
PCIread(Bus, Slot, 0x4E, &status, sizeof(status),
553
DBG_ERR(("EEPROM[%d] read failed (0x%x)", i * 4, addr))
556
PCIread(Bus, Slot, 0x50, &data[i], sizeof(data[i]), hdev);
558
DBG_BLK(((char *) &data[0], sizeof(data)))
561
if (serNo == 0 || serNo == 0xffffffff)
565
DBG_LOG(("W: Serial Number == 0, create one serial number"));
566
serNo = a->resources.pci.bar[1] & 0xffff0000;
567
serNo |= a->resources.pci.bus << 8;
568
serNo |= a->resources.pci.func;
571
a->xdi_adapter.serialNo = serNo;
573
DBG_REG(("Serial No. : %ld", a->xdi_adapter.serialNo))
579
** Release resources of slave adapters
581
static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t * a)
583
diva_os_xdi_adapter_t *adapter_list[4];
584
diva_os_xdi_adapter_t *diva_current;
588
adapter_list[1] = a->slave_adapters[0];
589
adapter_list[2] = a->slave_adapters[1];
590
adapter_list[3] = a->slave_adapters[2];
592
for (i = 0; i < a->xdi_adapter.tasks; i++) {
593
diva_current = adapter_list[i];
595
diva_os_destroy_spin_lock(&diva_current->
597
isr_spin_lock, "unload");
598
diva_os_destroy_spin_lock(&diva_current->
603
diva_os_cancel_soft_isr(&diva_current->xdi_adapter.
605
diva_os_cancel_soft_isr(&diva_current->xdi_adapter.
608
diva_os_remove_soft_isr(&diva_current->xdi_adapter.
610
diva_current->xdi_adapter.isr_soft_isr.object = NULL;
612
if (diva_current->xdi_adapter.e_tbl) {
614
diva_current->xdi_adapter.
617
diva_current->xdi_adapter.e_tbl = NULL;
618
diva_current->xdi_adapter.e_max = 0;
619
diva_current->xdi_adapter.e_count = 0;
627
diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
628
diva_xdi_um_cfg_cmd_t * cmd, int length)
632
if (cmd->adapter != a->controller) {
633
DBG_ERR(("A: 4bri_cmd, invalid controller=%d != %d",
634
cmd->adapter, a->controller))
638
switch (cmd->command) {
639
case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
640
a->xdi_mbox.data_length = sizeof(dword);
642
diva_os_malloc(0, a->xdi_mbox.data_length);
643
if (a->xdi_mbox.data) {
644
*(dword *) a->xdi_mbox.data =
645
(dword) a->CardOrdinal;
646
a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
651
case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
652
a->xdi_mbox.data_length = sizeof(dword);
654
diva_os_malloc(0, a->xdi_mbox.data_length);
655
if (a->xdi_mbox.data) {
656
*(dword *) a->xdi_mbox.data =
657
(dword) a->xdi_adapter.serialNo;
658
a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
663
case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
664
if (!a->xdi_adapter.ControllerNumber) {
666
Only master adapter can access hardware config
668
a->xdi_mbox.data_length = sizeof(dword) * 9;
670
diva_os_malloc(0, a->xdi_mbox.data_length);
671
if (a->xdi_mbox.data) {
673
dword *data = (dword *) a->xdi_mbox.data;
675
for (i = 0; i < 8; i++) {
676
*data++ = a->resources.pci.bar[i];
678
*data++ = (dword) a->resources.pci.irq;
679
a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
685
case DIVA_XDI_UM_CMD_GET_CARD_STATE:
686
if (!a->xdi_adapter.ControllerNumber) {
687
a->xdi_mbox.data_length = sizeof(dword);
689
diva_os_malloc(0, a->xdi_mbox.data_length);
690
if (a->xdi_mbox.data) {
691
dword *data = (dword *) a->xdi_mbox.data;
692
if (!a->xdi_adapter.ram
693
|| !a->xdi_adapter.reset
694
|| !a->xdi_adapter.cfg) {
696
} else if (a->xdi_adapter.trapped) {
698
} else if (a->xdi_adapter.Initialized) {
703
a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
709
case DIVA_XDI_UM_CMD_WRITE_FPGA:
710
if (!a->xdi_adapter.ControllerNumber) {
712
diva_4bri_write_fpga_image(a,
720
case DIVA_XDI_UM_CMD_RESET_ADAPTER:
721
if (!a->xdi_adapter.ControllerNumber) {
722
ret = diva_4bri_reset_adapter(&a->xdi_adapter);
726
case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
727
if (!a->xdi_adapter.ControllerNumber) {
728
ret = diva_4bri_write_sdram_block(&a->xdi_adapter,
744
case DIVA_XDI_UM_CMD_START_ADAPTER:
745
if (!a->xdi_adapter.ControllerNumber) {
746
ret = diva_4bri_start_adapter(&a->xdi_adapter,
754
case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
755
if (!a->xdi_adapter.ControllerNumber) {
756
a->xdi_adapter.features =
757
cmd->command_data.features.features;
758
a->xdi_adapter.a.protocol_capabilities =
759
a->xdi_adapter.features;
760
DBG_TRC(("Set raw protocol features (%08x)",
761
a->xdi_adapter.features))
766
case DIVA_XDI_UM_CMD_STOP_ADAPTER:
767
if (!a->xdi_adapter.ControllerNumber) {
768
ret = diva_4bri_stop_adapter(a);
772
case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY:
773
ret = diva_card_read_xlog(a);
776
case DIVA_XDI_UM_CMD_READ_SDRAM:
777
if (!a->xdi_adapter.ControllerNumber
778
&& a->xdi_adapter.Address) {
780
(a->xdi_mbox.data_length =
781
cmd->command_data.read_sdram.length)) {
783
(a->xdi_mbox.data_length +
784
cmd->command_data.read_sdram.offset) <
785
a->xdi_adapter.MemorySize) {
790
if (a->xdi_mbox.data) {
791
byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
792
byte __iomem *src = p;
793
byte *dst = a->xdi_mbox.data;
794
dword len = a->xdi_mbox.data_length;
796
src += cmd->command_data.read_sdram.offset;
799
*dst++ = READ_BYTE(src++);
801
DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
802
a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
811
DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller,
818
void *xdiLoadFile(char *FileName, dword *FileLength,
821
void *ret = diva_xdiLoadFileFile;
824
*FileLength = diva_xdiLoadFileLength;
826
diva_xdiLoadFileFile = NULL;
827
diva_xdiLoadFileLength = 0;
832
void diva_os_set_qBri_functions(PISDN_ADAPTER IoAdapter)
836
void diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter)
841
diva_4bri_write_fpga_image(diva_os_xdi_adapter_t * a, byte * data,
846
diva_xdiLoadFileFile = data;
847
diva_xdiLoadFileLength = length;
849
ret = qBri_FPGA_download(&a->xdi_adapter);
851
diva_xdiLoadFileFile = NULL;
852
diva_xdiLoadFileLength = 0;
854
return (ret ? 0 : -1);
857
static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter)
862
if (!IoAdapter->Address || !IoAdapter->reset) {
865
if (IoAdapter->Initialized) {
866
DBG_ERR(("A: A(%d) can't reset 4BRI adapter - please stop first",
872
Forget all entities on all adapters
874
for (i = 0; ((i < IoAdapter->tasks) && IoAdapter->QuadroList); i++) {
875
Slave = IoAdapter->QuadroList->QuadroAdapter[i];
878
memset(Slave->e_tbl, 0x00,
879
Slave->e_max * sizeof(E_INFO));
886
memset(&Slave->a.IdTable[0], 0x00,
887
sizeof(Slave->a.IdTable));
888
memset(&Slave->a.IdTypeTable[0], 0x00,
889
sizeof(Slave->a.IdTypeTable));
890
memset(&Slave->a.FlowControlIdTable[0], 0x00,
891
sizeof(Slave->a.FlowControlIdTable));
892
memset(&Slave->a.FlowControlSkipTable[0], 0x00,
893
sizeof(Slave->a.FlowControlSkipTable));
894
memset(&Slave->a.misc_flags_table[0], 0x00,
895
sizeof(Slave->a.misc_flags_table));
896
memset(&Slave->a.rx_stream[0], 0x00,
897
sizeof(Slave->a.rx_stream));
898
memset(&Slave->a.tx_stream[0], 0x00,
899
sizeof(Slave->a.tx_stream));
900
memset(&Slave->a.tx_pos[0], 0x00, sizeof(Slave->a.tx_pos));
901
memset(&Slave->a.rx_pos[0], 0x00, sizeof(Slave->a.rx_pos));
909
diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
911
const byte * data, dword length, dword limit)
913
byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
914
byte __iomem *mem = p;
916
if (((address + length) >= limit) || !mem) {
917
DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
918
DBG_ERR(("A: A(%d) write 4BRI address=0x%08lx",
919
IoAdapter->ANum, address + length))
925
WRITE_BYTE(mem++, *data++);
928
DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
933
diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
934
dword start_address, dword features)
936
volatile word __iomem *signature;
944
start_qBri_hardware(IoAdapter);
946
p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
948
wait for signature in shared memory (max. 3 seconds)
950
signature = (volatile word __iomem *) (&p[0x1E]);
952
for (i = 0; i < 300; ++i) {
954
if (READ_WORD(&signature[0]) == 0x4447) {
955
DBG_TRC(("Protocol startup time %d.%02d seconds",
956
(i / 100), (i % 100)))
962
for (i = 1; i < IoAdapter->tasks; i++) {
963
IoAdapter->QuadroList->QuadroAdapter[i]->features =
965
IoAdapter->QuadroList->QuadroAdapter[i]->a.
966
protocol_capabilities = IoAdapter->features;
970
DBG_FTL(("%s: Adapter selftest failed, signature=%04x",
971
IoAdapter->Properties.Name,
972
READ_WORD(&signature[0])))
973
DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
974
(*(IoAdapter->trapFnc)) (IoAdapter);
975
IoAdapter->stop(IoAdapter);
978
DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
980
for (i = 0; i < IoAdapter->tasks; i++) {
981
IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 1;
982
IoAdapter->QuadroList->QuadroAdapter[i]->IrqCount = 0;
985
if (check_qBri_interrupt(IoAdapter)) {
986
DBG_ERR(("A: A(%d) interrupt test failed",
988
for (i = 0; i < IoAdapter->tasks; i++) {
989
IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0;
991
IoAdapter->stop(IoAdapter);
995
IoAdapter->Properties.Features = (word) features;
996
diva_xdi_display_adapter_features(IoAdapter->ANum);
998
for (i = 0; i < IoAdapter->tasks; i++) {
999
DBG_LOG(("A(%d) %s adapter successfully started",
1000
IoAdapter->QuadroList->QuadroAdapter[i]->ANum,
1001
(IoAdapter->tasks == 1) ? "BRI 2.0" : "4BRI"))
1002
diva_xdi_didd_register_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum);
1003
IoAdapter->QuadroList->QuadroAdapter[i]->Properties.Features = (word) features;
1009
static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter)
1011
#ifdef SUPPORT_INTERRUPT_TEST_ON_4BRI
1013
ADAPTER *a = &IoAdapter->a;
1016
IoAdapter->IrqCount = 0;
1018
if (IoAdapter->ControllerNumber > 0)
1021
p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
1022
WRITE_BYTE(&p[PLX9054_INTCSR], PLX9054_INT_ENABLE);
1023
DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
1028
a->ram_out(a, &PR_RAM->ReadyInt, 1);
1030
for (i = 100; !IoAdapter->IrqCount && (i-- > 0); diva_os_wait(10));
1032
return ((IoAdapter->IrqCount > 0) ? 0 : -1);
1034
dword volatile __iomem *qBriIrq;
1037
Reset on-board interrupt register
1039
IoAdapter->IrqCount = 0;
1040
p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
1041
qBriIrq = (dword volatile __iomem *) (&p[_4bri_is_rev_2_card
1043
cardType) ? (MQ2_BREG_IRQ_TEST)
1044
: (MQ_BREG_IRQ_TEST)]);
1046
WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF);
1047
DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
1049
p = DIVA_OS_MEM_ATTACH_RESET(IoAdapter);
1050
WRITE_BYTE(&p[PLX9054_INTCSR], PLX9054_INT_ENABLE);
1051
DIVA_OS_MEM_DETACH_RESET(IoAdapter, p);
1056
#endif /* SUPPORT_INTERRUPT_TEST_ON_4BRI */
1059
static void diva_4bri_clear_interrupts(diva_os_xdi_adapter_t * a)
1061
PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
1064
clear any pending interrupt
1066
IoAdapter->disIrq(IoAdapter);
1068
IoAdapter->tst_irq(&IoAdapter->a);
1069
IoAdapter->clr_irq(&IoAdapter->a);
1070
IoAdapter->tst_irq(&IoAdapter->a);
1075
diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
1076
diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
1079
static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a)
1081
PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
1084
if (!IoAdapter->ram) {
1088
if (!IoAdapter->Initialized) {
1089
DBG_ERR(("A: A(%d) can't stop PRI adapter - not running",
1091
return (-1); /* nothing to stop */
1094
for (i = 0; i < IoAdapter->tasks; i++) {
1095
IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0;
1099
Disconnect Adapters from DIDD
1101
for (i = 0; i < IoAdapter->tasks; i++) {
1102
diva_xdi_didd_remove_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum);
1110
a->clear_interrupts_proc = diva_4bri_clear_interrupts;
1111
IoAdapter->a.ReadyInt = 1;
1112
IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
1115
} while (i-- && a->clear_interrupts_proc);
1117
if (a->clear_interrupts_proc) {
1118
diva_4bri_clear_interrupts(a);
1119
a->clear_interrupts_proc = NULL;
1120
DBG_ERR(("A: A(%d) no final interrupt from 4BRI adapter",
1123
IoAdapter->a.ReadyInt = 0;
1126
Stop and reset adapter
1128
IoAdapter->stop(IoAdapter);