~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/isdn/hardware/eicon/os_4bri.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: os_4bri.c,v 1.28.4.4 2005/02/11 19:40:25 armin Exp $ */
 
2
 
 
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"
 
12
 
 
13
#include "xdi_msg.h"
 
14
#include "xdi_adapter.h"
 
15
#include "os_4bri.h"
 
16
#include "diva_pci.h"
 
17
#include "mi_pc.h"
 
18
#include "dsrv4bri.h"
 
19
#include "helpers.h"
 
20
 
 
21
static void *diva_xdiLoadFileFile = NULL;
 
22
static dword diva_xdiLoadFileLength = 0;
 
23
 
 
24
/*
 
25
**  IMPORTS
 
26
*/
 
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);
 
31
 
 
32
extern int qBri_FPGA_download(PISDN_ADAPTER IoAdapter);
 
33
extern void start_qBri_hardware(PISDN_ADAPTER IoAdapter);
 
34
 
 
35
extern int diva_card_read_xlog(diva_os_xdi_adapter_t * a);
 
36
 
 
37
/*
 
38
**  LOCALS
 
39
*/
 
40
static unsigned long _4bri_bar_length[4] = {
 
41
        0x100,
 
42
        0x100,                  /* I/O */
 
43
        MQ_MEMORY_SIZE,
 
44
        0x2000
 
45
};
 
46
static unsigned long _4bri_v2_bar_length[4] = {
 
47
        0x100,
 
48
        0x100,                  /* I/O */
 
49
        MQ2_MEMORY_SIZE,
 
50
        0x10000
 
51
};
 
52
static unsigned long _4bri_v2_bri_bar_length[4] = {
 
53
        0x100,
 
54
        0x100,                  /* I/O */
 
55
        BRI2_MEMORY_SIZE,
 
56
        0x10000
 
57
};
 
58
 
 
59
 
 
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,
 
64
                                   int length);
 
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,
 
70
                                       dword address,
 
71
                                       const byte * data,
 
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);
 
77
 
 
78
static int _4bri_is_rev_2_card(int card_ordinal)
 
79
{
 
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:
 
86
                return (1);
 
87
        }
 
88
        return (0);
 
89
}
 
90
 
 
91
static int _4bri_is_rev_2_bri_card(int card_ordinal)
 
92
{
 
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:
 
97
                return (1);
 
98
        }
 
99
        return (0);
 
100
}
 
101
 
 
102
static void diva_4bri_set_addresses(diva_os_xdi_adapter_t *a)
 
103
{
 
104
        dword offset = a->resources.pci.qoffset;
 
105
        dword c_offset = offset * a->xdi_adapter.ControllerNumber;
 
106
 
 
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;
 
113
 
 
114
        /*
 
115
           Set up hardware related pointers
 
116
         */
 
117
        a->xdi_adapter.Address = a->resources.pci.addr[2];      /* BAR2 SDRAM  */
 
118
        a->xdi_adapter.Address += c_offset;
 
119
 
 
120
        a->xdi_adapter.Control = a->resources.pci.addr[2];      /* BAR2 SDRAM  */
 
121
 
 
122
        a->xdi_adapter.ram = a->resources.pci.addr[2];  /* BAR2 SDRAM  */
 
123
        a->xdi_adapter.ram += c_offset + (offset - MQ_SHARED_RAM_SIZE);
 
124
        
 
125
        a->xdi_adapter.reset = a->resources.pci.addr[0];        /* BAR0 CONFIG */
 
126
        /*
 
127
           ctlReg contains the register address for the MIPS CPU reset control
 
128
         */
 
129
        a->xdi_adapter.ctlReg = a->resources.pci.addr[3];       /* BAR3 CNTRL  */
 
130
        /*
 
131
           prom contains the register address for FPGA and EEPROM programming
 
132
         */
 
133
        a->xdi_adapter.prom = &a->xdi_adapter.reset[0x6E];
 
134
}
 
135
 
 
136
/*
 
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
 
141
**
 
142
**  Called by master adapter, that will initialize and add slave adapters
 
143
*/
 
144
int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
 
145
{
 
146
        int bar, i;
 
147
        byte __iomem *p;
 
148
        PADAPTER_LIST_ENTRY quadro_list;
 
149
        diva_os_xdi_adapter_t *diva_current;
 
150
        diva_os_xdi_adapter_t *adapter_list[4];
 
151
        PISDN_ADAPTER Slave;
 
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;
 
156
 
 
157
        if (v2) {
 
158
                if (_4bri_is_rev_2_bri_card(a->CardOrdinal)) {
 
159
                        memcpy(bar_length, _4bri_v2_bri_bar_length,
 
160
                               sizeof(bar_length));
 
161
                } else {
 
162
                        memcpy(bar_length, _4bri_v2_bar_length,
 
163
                               sizeof(bar_length));
 
164
                }
 
165
        } else {
 
166
                memcpy(bar_length, _4bri_bar_length, sizeof(bar_length));
 
167
        }
 
168
        DBG_TRC(("SDRAM_LENGTH=%08x, tasks=%d, factor=%d",
 
169
                 bar_length[2], tasks, factor))
 
170
 
 
171
        /*
 
172
           Get Serial Number
 
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
 
176
         */
 
177
        if (!_4bri_get_serial_number(a)) {
 
178
                DBG_ERR(("A: 4BRI can't get Serial Number"))
 
179
                diva_4bri_cleanup_adapter(a);
 
180
                return (-1);
 
181
        }
 
182
 
 
183
        /*
 
184
           Set properties
 
185
         */
 
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))
 
191
 
 
192
        /*
 
193
           First initialization step: get and check hardware resoures.
 
194
           Do not map resources and do not access card at this step
 
195
         */
 
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)) {
 
203
                        DBG_ERR(
 
204
                                ("A: invalid bar[%d]=%08x", bar,
 
205
                                 a->resources.pci.bar[bar]))
 
206
                        return (-1);
 
207
                }
 
208
        }
 
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"));
 
215
                return (-1);
 
216
        }
 
217
 
 
218
        a->xdi_adapter.sdram_bar = a->resources.pci.bar[2];
 
219
 
 
220
        /*
 
221
           Map all MEMORY BAR's
 
222
         */
 
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],
 
227
                                                 bar_length[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);
 
231
                                return (-1);
 
232
                        }
 
233
                }
 
234
        }
 
235
 
 
236
        /*
 
237
           Register I/O port
 
238
         */
 
239
        sprintf(&a->port_name[0], "DIVA 4BRI %ld", (long) a->xdi_adapter.serialNo);
 
240
 
 
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);
 
245
                return (-1);
 
246
        }
 
247
 
 
248
        a->resources.pci.addr[1] =
 
249
                (void *) (unsigned long) a->resources.pci.bar[1];
 
250
 
 
251
        /*
 
252
           Set cleanup pointer for base adapter only, so slave adapter
 
253
           will be unable to get cleanup
 
254
         */
 
255
        a->interface.cleanup_adapter_proc = diva_4bri_cleanup_adapter;
 
256
 
 
257
        /*
 
258
           Create slave adapters
 
259
         */
 
260
        if (tasks > 1) {
 
261
                if (!(a->slave_adapters[0] =
 
262
                     (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
 
263
                {
 
264
                        diva_4bri_cleanup_adapter(a);
 
265
                        return (-1);
 
266
                }
 
267
                if (!(a->slave_adapters[1] =
 
268
                     (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
 
269
                {
 
270
                        diva_os_free(0, a->slave_adapters[0]);
 
271
                        a->slave_adapters[0] = NULL;
 
272
                        diva_4bri_cleanup_adapter(a);
 
273
                        return (-1);
 
274
                }
 
275
                if (!(a->slave_adapters[2] =
 
276
                     (diva_os_xdi_adapter_t *) diva_os_malloc(0, sizeof(*a))))
 
277
                {
 
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);
 
283
                        return (-1);
 
284
                }
 
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));
 
288
        }
 
289
 
 
290
        adapter_list[0] = 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];
 
294
 
 
295
        /*
 
296
           Allocate slave list
 
297
         */
 
298
        quadro_list =
 
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;
 
304
                }
 
305
                diva_4bri_cleanup_adapter(a);
 
306
                return (-1);
 
307
        }
 
308
        memset(quadro_list, 0x00, sizeof(*quadro_list));
 
309
 
 
310
        /*
 
311
           Set interfaces
 
312
         */
 
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;
 
319
        }
 
320
 
 
321
        for (i = 0; i < tasks; i++) {
 
322
                diva_current = adapter_list[i];
 
323
 
 
324
                diva_current->dsp_mask = 0x00000003;
 
325
 
 
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;
 
333
 
 
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 =
 
339
                    diva_os_malloc(0,
 
340
                                   diva_current->xdi_adapter.e_max *
 
341
                                   sizeof(E_INFO));
 
342
 
 
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]);
 
348
                        }
 
349
                        return (-1);
 
350
                }
 
351
                memset(diva_current->xdi_adapter.e_tbl, 0x00,
 
352
                       diva_current->xdi_adapter.e_max * sizeof(E_INFO));
 
353
 
 
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]);
 
359
                        }
 
360
                        return (-1);
 
361
                }
 
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]);
 
367
                        }
 
368
                        return (-1);
 
369
                }
 
370
 
 
371
                strcpy(diva_current->xdi_adapter.req_soft_isr. dpc_thread_name, "kdivas4brid");
 
372
 
 
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]);
 
379
                        }
 
380
                        return (-1);
 
381
                }
 
382
 
 
383
                /*
 
384
                   Do not initialize second DPC - only one thread will be created
 
385
                 */
 
386
                diva_current->xdi_adapter.isr_soft_isr.object =
 
387
                    diva_current->xdi_adapter.req_soft_isr.object;
 
388
        }
 
389
 
 
390
        if (v2) {
 
391
                prepare_qBri2_functions(&a->xdi_adapter);
 
392
        } else {
 
393
                prepare_qBri_functions(&a->xdi_adapter);
 
394
        }
 
395
 
 
396
        for (i = 0; i < tasks; i++) {
 
397
                diva_current = adapter_list[i];
 
398
                if (i)
 
399
                        memcpy(&diva_current->resources, &a->resources, sizeof(divas_card_resources_t));
 
400
                diva_current->resources.pci.qoffset = (a->xdi_adapter.MemorySize >> factor); 
 
401
        }
 
402
 
 
403
        /*
 
404
           Set up hardware related pointers
 
405
         */
 
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  */
 
409
 
 
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;
 
416
                if (i) {
 
417
                        Slave->serialNo = ((dword) (Slave->ControllerNumber << 24)) |
 
418
                                        a->xdi_adapter.serialNo;
 
419
                        Slave->cardType = a->xdi_adapter.cardType;
 
420
                }
 
421
        }
 
422
 
 
423
        /*
 
424
           reset contains the base address for the PLX 9054 register set
 
425
         */
 
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);
 
429
 
 
430
        /*
 
431
           Set IRQ handler
 
432
         */
 
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);
 
436
 
 
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]);
 
443
                }
 
444
                return (-1);
 
445
        }
 
446
 
 
447
        a->xdi_adapter.irq_info.registered = 1;
 
448
 
 
449
        /*
 
450
           Add three slave adapters
 
451
         */
 
452
        if (tasks > 1) {
 
453
                diva_add_slave_adapter(adapter_list[1]);
 
454
                diva_add_slave_adapter(adapter_list[2]);
 
455
                diva_add_slave_adapter(adapter_list[3]);
 
456
        }
 
457
 
 
458
        diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name,
 
459
                      a->resources.pci.irq, a->xdi_adapter.serialNo);
 
460
 
 
461
        return (0);
 
462
}
 
463
 
 
464
/*
 
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
 
468
*/
 
469
static int diva_4bri_cleanup_adapter(diva_os_xdi_adapter_t * a)
 
470
{
 
471
        int bar;
 
472
 
 
473
        /*
 
474
           Stop adapter if running
 
475
         */
 
476
        if (a->xdi_adapter.Initialized) {
 
477
                diva_4bri_stop_adapter(a);
 
478
        }
 
479
 
 
480
        /*
 
481
           Remove IRQ handler
 
482
         */
 
483
        if (a->xdi_adapter.irq_info.registered) {
 
484
                diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
 
485
        }
 
486
        a->xdi_adapter.irq_info.registered = 0;
 
487
 
 
488
        /*
 
489
           Free DPC's and spin locks on all adapters
 
490
         */
 
491
        diva_4bri_cleanup_slave_adapters(a);
 
492
 
 
493
        /*
 
494
           Unmap all BARS
 
495
         */
 
496
        for (bar = 0; bar < 4; bar++) {
 
497
                if (bar != 1) {
 
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;
 
503
                        }
 
504
                }
 
505
        }
 
506
 
 
507
        /*
 
508
           Unregister I/O
 
509
         */
 
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->
 
513
                                                             CardOrdinal) ?
 
514
                                         _4bri_v2_bar_length[1] :
 
515
                                         _4bri_bar_length[1],
 
516
                                         &a->port_name[0], 1);
 
517
                a->resources.pci.bar[1] = 0;
 
518
                a->resources.pci.addr[1] = NULL;
 
519
        }
 
520
 
 
521
        if (a->slave_list) {
 
522
                diva_os_free(0, a->slave_list);
 
523
                a->slave_list = NULL;
 
524
        }
 
525
 
 
526
        return (0);
 
527
}
 
528
 
 
529
static int _4bri_get_serial_number(diva_os_xdi_adapter_t * a)
 
530
{
 
531
        dword data[64];
 
532
        dword serNo;
 
533
        word addr, status, i, j;
 
534
        byte Bus, Slot;
 
535
        void *hdev;
 
536
 
 
537
        Bus = a->resources.pci.bus;
 
538
        Slot = a->resources.pci.func;
 
539
        hdev = a->resources.pci.hdev;
 
540
 
 
541
        for (i = 0; i < 64; ++i) {
 
542
                addr = i * 4;
 
543
                for (j = 0; j < 5; ++j) {
 
544
                        PCIwrite(Bus, Slot, 0x4E, &addr, sizeof(addr),
 
545
                                 hdev);
 
546
                        diva_os_wait(1);
 
547
                        PCIread(Bus, Slot, 0x4E, &status, sizeof(status),
 
548
                                hdev);
 
549
                        if (status & 0x8000)
 
550
                                break;
 
551
                }
 
552
                if (j >= 5) {
 
553
                        DBG_ERR(("EEPROM[%d] read failed (0x%x)", i * 4, addr))
 
554
                        return (0);
 
555
                }
 
556
                PCIread(Bus, Slot, 0x50, &data[i], sizeof(data[i]), hdev);
 
557
        }
 
558
        DBG_BLK(((char *) &data[0], sizeof(data)))
 
559
 
 
560
        serNo = data[32];
 
561
        if (serNo == 0 || serNo == 0xffffffff)
 
562
                serNo = data[63];
 
563
 
 
564
        if (!serNo) {
 
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;
 
569
        }
 
570
 
 
571
        a->xdi_adapter.serialNo = serNo;
 
572
 
 
573
        DBG_REG(("Serial No.          : %ld", a->xdi_adapter.serialNo))
 
574
 
 
575
        return (serNo);
 
576
}
 
577
 
 
578
/*
 
579
**  Release resources of slave adapters
 
580
*/
 
581
static int diva_4bri_cleanup_slave_adapters(diva_os_xdi_adapter_t * a)
 
582
{
 
583
        diva_os_xdi_adapter_t *adapter_list[4];
 
584
        diva_os_xdi_adapter_t *diva_current;
 
585
        int i;
 
586
 
 
587
        adapter_list[0] = a;
 
588
        adapter_list[1] = a->slave_adapters[0];
 
589
        adapter_list[2] = a->slave_adapters[1];
 
590
        adapter_list[3] = a->slave_adapters[2];
 
591
 
 
592
        for (i = 0; i < a->xdi_adapter.tasks; i++) {
 
593
                diva_current = adapter_list[i];
 
594
                if (diva_current) {
 
595
                        diva_os_destroy_spin_lock(&diva_current->
 
596
                                                  xdi_adapter.
 
597
                                                  isr_spin_lock, "unload");
 
598
                        diva_os_destroy_spin_lock(&diva_current->
 
599
                                                  xdi_adapter.
 
600
                                                  data_spin_lock,
 
601
                                                  "unload");
 
602
 
 
603
                        diva_os_cancel_soft_isr(&diva_current->xdi_adapter.
 
604
                                                req_soft_isr);
 
605
                        diva_os_cancel_soft_isr(&diva_current->xdi_adapter.
 
606
                                                isr_soft_isr);
 
607
 
 
608
                        diva_os_remove_soft_isr(&diva_current->xdi_adapter.
 
609
                                                req_soft_isr);
 
610
                        diva_current->xdi_adapter.isr_soft_isr.object = NULL;
 
611
 
 
612
                        if (diva_current->xdi_adapter.e_tbl) {
 
613
                                diva_os_free(0,
 
614
                                             diva_current->xdi_adapter.
 
615
                                             e_tbl);
 
616
                        }
 
617
                        diva_current->xdi_adapter.e_tbl = NULL;
 
618
                        diva_current->xdi_adapter.e_max = 0;
 
619
                        diva_current->xdi_adapter.e_count = 0;
 
620
                }
 
621
        }
 
622
 
 
623
        return (0);
 
624
}
 
625
 
 
626
static int
 
627
diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
 
628
                        diva_xdi_um_cfg_cmd_t * cmd, int length)
 
629
{
 
630
        int ret = -1;
 
631
 
 
632
        if (cmd->adapter != a->controller) {
 
633
                DBG_ERR(("A: 4bri_cmd, invalid controller=%d != %d",
 
634
                         cmd->adapter, a->controller))
 
635
                return (-1);
 
636
        }
 
637
 
 
638
        switch (cmd->command) {
 
639
        case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
 
640
                a->xdi_mbox.data_length = sizeof(dword);
 
641
                a->xdi_mbox.data =
 
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;
 
647
                        ret = 0;
 
648
                }
 
649
                break;
 
650
 
 
651
        case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
 
652
                a->xdi_mbox.data_length = sizeof(dword);
 
653
                a->xdi_mbox.data =
 
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;
 
659
                        ret = 0;
 
660
                }
 
661
                break;
 
662
 
 
663
        case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
 
664
                if (!a->xdi_adapter.ControllerNumber) {
 
665
                        /*
 
666
                           Only master adapter can access hardware config
 
667
                         */
 
668
                        a->xdi_mbox.data_length = sizeof(dword) * 9;
 
669
                        a->xdi_mbox.data =
 
670
                            diva_os_malloc(0, a->xdi_mbox.data_length);
 
671
                        if (a->xdi_mbox.data) {
 
672
                                int i;
 
673
                                dword *data = (dword *) a->xdi_mbox.data;
 
674
 
 
675
                                for (i = 0; i < 8; i++) {
 
676
                                        *data++ = a->resources.pci.bar[i];
 
677
                                }
 
678
                                *data++ = (dword) a->resources.pci.irq;
 
679
                                a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
 
680
                                ret = 0;
 
681
                        }
 
682
                }
 
683
                break;
 
684
 
 
685
        case DIVA_XDI_UM_CMD_GET_CARD_STATE:
 
686
                if (!a->xdi_adapter.ControllerNumber) {
 
687
                        a->xdi_mbox.data_length = sizeof(dword);
 
688
                        a->xdi_mbox.data =
 
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) {
 
695
                                        *data = 3;
 
696
                                } else if (a->xdi_adapter.trapped) {
 
697
                                        *data = 2;
 
698
                                } else if (a->xdi_adapter.Initialized) {
 
699
                                        *data = 1;
 
700
                                } else {
 
701
                                        *data = 0;
 
702
                                }
 
703
                                a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
 
704
                                ret = 0;
 
705
                        }
 
706
                }
 
707
                break;
 
708
 
 
709
        case DIVA_XDI_UM_CMD_WRITE_FPGA:
 
710
                if (!a->xdi_adapter.ControllerNumber) {
 
711
                        ret =
 
712
                            diva_4bri_write_fpga_image(a,
 
713
                                                       (byte *) & cmd[1],
 
714
                                                       cmd->command_data.
 
715
                                                       write_fpga.
 
716
                                                       image_length);
 
717
                }
 
718
                break;
 
719
 
 
720
        case DIVA_XDI_UM_CMD_RESET_ADAPTER:
 
721
                if (!a->xdi_adapter.ControllerNumber) {
 
722
                        ret = diva_4bri_reset_adapter(&a->xdi_adapter);
 
723
                }
 
724
                break;
 
725
 
 
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,
 
729
                                                          cmd->
 
730
                                                          command_data.
 
731
                                                          write_sdram.
 
732
                                                          offset,
 
733
                                                          (byte *) &
 
734
                                                          cmd[1],
 
735
                                                          cmd->
 
736
                                                          command_data.
 
737
                                                          write_sdram.
 
738
                                                          length,
 
739
                                                          a->xdi_adapter.
 
740
                                                          MemorySize);
 
741
                }
 
742
                break;
 
743
 
 
744
        case DIVA_XDI_UM_CMD_START_ADAPTER:
 
745
                if (!a->xdi_adapter.ControllerNumber) {
 
746
                        ret = diva_4bri_start_adapter(&a->xdi_adapter,
 
747
                                                      cmd->command_data.
 
748
                                                      start.offset,
 
749
                                                      cmd->command_data.
 
750
                                                      start.features);
 
751
                }
 
752
                break;
 
753
 
 
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))
 
762
                        ret = 0;
 
763
                }
 
764
                break;
 
765
 
 
766
        case DIVA_XDI_UM_CMD_STOP_ADAPTER:
 
767
                if (!a->xdi_adapter.ControllerNumber) {
 
768
                        ret = diva_4bri_stop_adapter(a);
 
769
                }
 
770
                break;
 
771
 
 
772
        case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY:
 
773
                ret = diva_card_read_xlog(a);
 
774
                break;
 
775
 
 
776
        case DIVA_XDI_UM_CMD_READ_SDRAM:
 
777
                if (!a->xdi_adapter.ControllerNumber
 
778
                    && a->xdi_adapter.Address) {
 
779
                        if (
 
780
                            (a->xdi_mbox.data_length =
 
781
                             cmd->command_data.read_sdram.length)) {
 
782
                                if (
 
783
                                    (a->xdi_mbox.data_length +
 
784
                                     cmd->command_data.read_sdram.offset) <
 
785
                                    a->xdi_adapter.MemorySize) {
 
786
                                        a->xdi_mbox.data =
 
787
                                            diva_os_malloc(0,
 
788
                                                           a->xdi_mbox.
 
789
                                                           data_length);
 
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;
 
795
 
 
796
                                                src += cmd->command_data.read_sdram.offset;
 
797
 
 
798
                                                while (len--) {
 
799
                                                        *dst++ = READ_BYTE(src++);
 
800
                                                }
 
801
                                                DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
 
802
                                                a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
 
803
                                                ret = 0;
 
804
                                        }
 
805
                                }
 
806
                        }
 
807
                }
 
808
                break;
 
809
 
 
810
        default:
 
811
                DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller,
 
812
                         cmd->command))
 
813
        }
 
814
 
 
815
        return (ret);
 
816
}
 
817
 
 
818
void *xdiLoadFile(char *FileName, dword *FileLength,
 
819
                  unsigned long lim)
 
820
{
 
821
        void *ret = diva_xdiLoadFileFile;
 
822
 
 
823
        if (FileLength) {
 
824
                *FileLength = diva_xdiLoadFileLength;
 
825
        }
 
826
        diva_xdiLoadFileFile = NULL;
 
827
        diva_xdiLoadFileLength = 0;
 
828
 
 
829
        return (ret);
 
830
}
 
831
 
 
832
void diva_os_set_qBri_functions(PISDN_ADAPTER IoAdapter)
 
833
{
 
834
}
 
835
 
 
836
void diva_os_set_qBri2_functions(PISDN_ADAPTER IoAdapter)
 
837
{
 
838
}
 
839
 
 
840
static int
 
841
diva_4bri_write_fpga_image(diva_os_xdi_adapter_t * a, byte * data,
 
842
                           dword length)
 
843
{
 
844
        int ret;
 
845
 
 
846
        diva_xdiLoadFileFile = data;
 
847
        diva_xdiLoadFileLength = length;
 
848
 
 
849
        ret = qBri_FPGA_download(&a->xdi_adapter);
 
850
 
 
851
        diva_xdiLoadFileFile = NULL;
 
852
        diva_xdiLoadFileLength = 0;
 
853
 
 
854
        return (ret ? 0 : -1);
 
855
}
 
856
 
 
857
static int diva_4bri_reset_adapter(PISDN_ADAPTER IoAdapter)
 
858
{
 
859
        PISDN_ADAPTER Slave;
 
860
        int i;
 
861
 
 
862
        if (!IoAdapter->Address || !IoAdapter->reset) {
 
863
                return (-1);
 
864
        }
 
865
        if (IoAdapter->Initialized) {
 
866
                DBG_ERR(("A: A(%d) can't reset 4BRI adapter - please stop first",
 
867
                         IoAdapter->ANum))
 
868
                return (-1);
 
869
        }
 
870
 
 
871
        /*
 
872
           Forget all entities on all adapters
 
873
         */
 
874
        for (i = 0; ((i < IoAdapter->tasks) && IoAdapter->QuadroList); i++) {
 
875
                Slave = IoAdapter->QuadroList->QuadroAdapter[i];
 
876
                Slave->e_count = 0;
 
877
                if (Slave->e_tbl) {
 
878
                        memset(Slave->e_tbl, 0x00,
 
879
                               Slave->e_max * sizeof(E_INFO));
 
880
                }
 
881
                Slave->head = 0;
 
882
                Slave->tail = 0;
 
883
                Slave->assign = 0;
 
884
                Slave->trapped = 0;
 
885
 
 
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));
 
902
        }
 
903
 
 
904
        return (0);
 
905
}
 
906
 
 
907
 
 
908
static int
 
909
diva_4bri_write_sdram_block(PISDN_ADAPTER IoAdapter,
 
910
                            dword address,
 
911
                            const byte * data, dword length, dword limit)
 
912
{
 
913
        byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
 
914
        byte __iomem *mem = p;
 
915
 
 
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))
 
920
                return (-1);
 
921
        }
 
922
        mem += address;
 
923
 
 
924
        while (length--) {
 
925
                WRITE_BYTE(mem++, *data++);
 
926
        }
 
927
 
 
928
        DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
 
929
        return (0);
 
930
}
 
931
 
 
932
static int
 
933
diva_4bri_start_adapter(PISDN_ADAPTER IoAdapter,
 
934
                        dword start_address, dword features)
 
935
{
 
936
        volatile word __iomem *signature;
 
937
        int started = 0;
 
938
        int i;
 
939
        byte __iomem *p;
 
940
 
 
941
        /*
 
942
           start adapter
 
943
         */
 
944
        start_qBri_hardware(IoAdapter);
 
945
 
 
946
        p = DIVA_OS_MEM_ATTACH_RAM(IoAdapter);
 
947
        /*
 
948
           wait for signature in shared memory (max. 3 seconds)
 
949
         */
 
950
        signature = (volatile word __iomem *) (&p[0x1E]);
 
951
 
 
952
        for (i = 0; i < 300; ++i) {
 
953
                diva_os_wait(10);
 
954
                if (READ_WORD(&signature[0]) == 0x4447) {
 
955
                        DBG_TRC(("Protocol startup time %d.%02d seconds",
 
956
                                 (i / 100), (i % 100)))
 
957
                        started = 1;
 
958
                        break;
 
959
                }
 
960
        }
 
961
 
 
962
        for (i = 1; i < IoAdapter->tasks; i++) {
 
963
                IoAdapter->QuadroList->QuadroAdapter[i]->features =
 
964
                    IoAdapter->features;
 
965
                IoAdapter->QuadroList->QuadroAdapter[i]->a.
 
966
                    protocol_capabilities = IoAdapter->features;
 
967
        }
 
968
 
 
969
        if (!started) {
 
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);
 
976
                return (-1);
 
977
        }
 
978
        DIVA_OS_MEM_DETACH_RAM(IoAdapter, p);
 
979
 
 
980
        for (i = 0; i < IoAdapter->tasks; i++) {
 
981
                IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 1;
 
982
                IoAdapter->QuadroList->QuadroAdapter[i]->IrqCount = 0;
 
983
        }
 
984
 
 
985
        if (check_qBri_interrupt(IoAdapter)) {
 
986
                DBG_ERR(("A: A(%d) interrupt test failed",
 
987
                         IoAdapter->ANum))
 
988
                for (i = 0; i < IoAdapter->tasks; i++) {
 
989
                        IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0;
 
990
                }
 
991
                IoAdapter->stop(IoAdapter);
 
992
                return (-1);
 
993
        }
 
994
 
 
995
        IoAdapter->Properties.Features = (word) features;
 
996
        diva_xdi_display_adapter_features(IoAdapter->ANum);
 
997
 
 
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;
 
1004
        }
 
1005
 
 
1006
        return (0);
 
1007
}
 
1008
 
 
1009
static int check_qBri_interrupt(PISDN_ADAPTER IoAdapter)
 
1010
{
 
1011
#ifdef  SUPPORT_INTERRUPT_TEST_ON_4BRI
 
1012
        int i;
 
1013
        ADAPTER *a = &IoAdapter->a;
 
1014
        byte __iomem *p;
 
1015
 
 
1016
        IoAdapter->IrqCount = 0;
 
1017
 
 
1018
        if (IoAdapter->ControllerNumber > 0)
 
1019
                return (-1);
 
1020
 
 
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);
 
1024
        /*
 
1025
           interrupt test
 
1026
         */
 
1027
        a->ReadyInt = 1;
 
1028
        a->ram_out(a, &PR_RAM->ReadyInt, 1);
 
1029
 
 
1030
        for (i = 100; !IoAdapter->IrqCount && (i-- > 0); diva_os_wait(10));
 
1031
 
 
1032
        return ((IoAdapter->IrqCount > 0) ? 0 : -1);
 
1033
#else
 
1034
        dword volatile __iomem *qBriIrq;
 
1035
        byte __iomem *p;
 
1036
        /*
 
1037
           Reset on-board interrupt register
 
1038
         */
 
1039
        IoAdapter->IrqCount = 0;
 
1040
        p = DIVA_OS_MEM_ATTACH_CTLREG(IoAdapter);
 
1041
        qBriIrq = (dword volatile __iomem *) (&p[_4bri_is_rev_2_card
 
1042
                                       (IoAdapter->
 
1043
                                        cardType) ? (MQ2_BREG_IRQ_TEST)
 
1044
                                       : (MQ_BREG_IRQ_TEST)]);
 
1045
 
 
1046
        WRITE_DWORD(qBriIrq, MQ_IRQ_REQ_OFF);
 
1047
        DIVA_OS_MEM_DETACH_CTLREG(IoAdapter, p);
 
1048
 
 
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);
 
1052
 
 
1053
        diva_os_wait(100);
 
1054
 
 
1055
        return (0);
 
1056
#endif                          /* SUPPORT_INTERRUPT_TEST_ON_4BRI */
 
1057
}
 
1058
 
 
1059
static void diva_4bri_clear_interrupts(diva_os_xdi_adapter_t * a)
 
1060
{
 
1061
        PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
 
1062
 
 
1063
        /*
 
1064
           clear any pending interrupt
 
1065
         */
 
1066
        IoAdapter->disIrq(IoAdapter);
 
1067
 
 
1068
        IoAdapter->tst_irq(&IoAdapter->a);
 
1069
        IoAdapter->clr_irq(&IoAdapter->a);
 
1070
        IoAdapter->tst_irq(&IoAdapter->a);
 
1071
 
 
1072
        /*
 
1073
           kill pending dpcs
 
1074
         */
 
1075
        diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
 
1076
        diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
 
1077
}
 
1078
 
 
1079
static int diva_4bri_stop_adapter(diva_os_xdi_adapter_t * a)
 
1080
{
 
1081
        PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
 
1082
        int i;
 
1083
 
 
1084
        if (!IoAdapter->ram) {
 
1085
                return (-1);
 
1086
        }
 
1087
 
 
1088
        if (!IoAdapter->Initialized) {
 
1089
                DBG_ERR(("A: A(%d) can't stop PRI adapter - not running",
 
1090
                         IoAdapter->ANum))
 
1091
                return (-1);    /* nothing to stop */
 
1092
        }
 
1093
 
 
1094
        for (i = 0; i < IoAdapter->tasks; i++) {
 
1095
                IoAdapter->QuadroList->QuadroAdapter[i]->Initialized = 0;
 
1096
        }
 
1097
 
 
1098
        /*
 
1099
           Disconnect Adapters from DIDD
 
1100
         */
 
1101
        for (i = 0; i < IoAdapter->tasks; i++) {
 
1102
                diva_xdi_didd_remove_adapter(IoAdapter->QuadroList->QuadroAdapter[i]->ANum);
 
1103
        }
 
1104
 
 
1105
        i = 100;
 
1106
 
 
1107
        /*
 
1108
           Stop interrupts
 
1109
         */
 
1110
        a->clear_interrupts_proc = diva_4bri_clear_interrupts;
 
1111
        IoAdapter->a.ReadyInt = 1;
 
1112
        IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
 
1113
        do {
 
1114
                diva_os_sleep(10);
 
1115
        } while (i-- && a->clear_interrupts_proc);
 
1116
 
 
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",
 
1121
                         IoAdapter->ANum))
 
1122
        }
 
1123
        IoAdapter->a.ReadyInt = 0;
 
1124
 
 
1125
        /*
 
1126
           Stop and reset adapter
 
1127
         */
 
1128
        IoAdapter->stop(IoAdapter);
 
1129
 
 
1130
        return (0);
 
1131
}