OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [isdn/] [hardware/] [eicon/] [os_pri.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* $Id: os_pri.c,v 1.32 2004/03/21 17:26:01 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_pri.h"
16
#include "diva_pci.h"
17
#include "mi_pc.h"
18
#include "pc_maint.h"
19
#include "dsp_tst.h"
20
#include "diva_dma.h"
21
#include "dsrv_pri.h"
22
 
23
/* --------------------------------------------------------------------------
24
   OS Dependent part of XDI driver for DIVA PRI Adapter
25
 
26
   DSP detection/validation by Anthony Booth (Eicon Networks, www.eicon.com)
27
-------------------------------------------------------------------------- */
28
 
29
#define DIVA_PRI_NO_PCI_BIOS_WORKAROUND 1
30
 
31
extern int diva_card_read_xlog(diva_os_xdi_adapter_t * a);
32
 
33
/*
34
**  IMPORTS
35
*/
36
extern void prepare_pri_functions(PISDN_ADAPTER IoAdapter);
37
extern void prepare_pri2_functions(PISDN_ADAPTER IoAdapter);
38
extern void diva_xdi_display_adapter_features(int card);
39
 
40
static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a);
41
static int diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
42
                                  diva_xdi_um_cfg_cmd_t * cmd, int length);
43
static int pri_get_serial_number(diva_os_xdi_adapter_t * a);
44
static int diva_pri_stop_adapter(diva_os_xdi_adapter_t * a);
45
static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t * a);
46
 
47
/*
48
**  Check card revision
49
*/
50
static int pri_is_rev_2_card(int card_ordinal)
51
{
52
        switch (card_ordinal) {
53
        case CARDTYPE_DIVASRV_P_30M_V2_PCI:
54
        case CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI:
55
                return (1);
56
        }
57
        return (0);
58
}
59
 
60
static void diva_pri_set_addresses(diva_os_xdi_adapter_t * a)
61
{
62
        a->resources.pci.mem_type_id[MEM_TYPE_ADDRESS] = 0;
63
        a->resources.pci.mem_type_id[MEM_TYPE_CONTROL] = 2;
64
        a->resources.pci.mem_type_id[MEM_TYPE_CONFIG] = 4;
65
        a->resources.pci.mem_type_id[MEM_TYPE_RAM] = 0;
66
        a->resources.pci.mem_type_id[MEM_TYPE_RESET] = 2;
67
        a->resources.pci.mem_type_id[MEM_TYPE_CFG] = 4;
68
        a->resources.pci.mem_type_id[MEM_TYPE_PROM] = 3;
69
 
70
        a->xdi_adapter.Address = a->resources.pci.addr[0];
71
        a->xdi_adapter.Control = a->resources.pci.addr[2];
72
        a->xdi_adapter.Config = a->resources.pci.addr[4];
73
 
74
        a->xdi_adapter.ram = a->resources.pci.addr[0];
75
        a->xdi_adapter.ram += MP_SHARED_RAM_OFFSET;
76
 
77
        a->xdi_adapter.reset = a->resources.pci.addr[2];
78
        a->xdi_adapter.reset += MP_RESET;
79
 
80
        a->xdi_adapter.cfg = a->resources.pci.addr[4];
81
        a->xdi_adapter.cfg += MP_IRQ_RESET;
82
 
83
        a->xdi_adapter.sdram_bar = a->resources.pci.bar[0];
84
 
85
        a->xdi_adapter.prom = a->resources.pci.addr[3];
86
}
87
 
88
/*
89
**  BAR0 - SDRAM, MP_MEMORY_SIZE, MP2_MEMORY_SIZE by Rev.2
90
**  BAR1 - DEVICES,                             0x1000
91
**  BAR2 - CONTROL (REG), 0x2000
92
**  BAR3 - FLASH (REG),         0x8000
93
**  BAR4 - CONFIG (CFG),        0x1000
94
*/
95
int diva_pri_init_card(diva_os_xdi_adapter_t * a)
96
{
97
        int bar = 0;
98
        int pri_rev_2;
99
        unsigned long bar_length[5] = {
100
                MP_MEMORY_SIZE,
101
                0x1000,
102
                0x2000,
103
                0x8000,
104
                0x1000
105
        };
106
 
107
        pri_rev_2 = pri_is_rev_2_card(a->CardOrdinal);
108
 
109
        if (pri_rev_2) {
110
                bar_length[0] = MP2_MEMORY_SIZE;
111
        }
112
        /*
113
           Set properties
114
         */
115
        a->xdi_adapter.Properties = CardProperties[a->CardOrdinal];
116
        DBG_LOG(("Load %s", a->xdi_adapter.Properties.Name))
117
 
118
        /*
119
           First initialization step: get and check hardware resoures.
120
           Do not map resources and do not acecess card at this step
121
         */
122
        for (bar = 0; bar < 5; bar++) {
123
                a->resources.pci.bar[bar] =
124
                    divasa_get_pci_bar(a->resources.pci.bus,
125
                                       a->resources.pci.func, bar,
126
                                       a->resources.pci.hdev);
127
                if (!a->resources.pci.bar[bar]
128
                    || (a->resources.pci.bar[bar] == 0xFFFFFFF0)) {
129
                        DBG_ERR(("A: invalid bar[%d]=%08x", bar,
130
                                 a->resources.pci.bar[bar]))
131
                        return (-1);
132
                }
133
        }
134
        a->resources.pci.irq =
135
            (byte) divasa_get_pci_irq(a->resources.pci.bus,
136
                                      a->resources.pci.func,
137
                                      a->resources.pci.hdev);
138
        if (!a->resources.pci.irq) {
139
                DBG_ERR(("A: invalid irq"));
140
                return (-1);
141
        }
142
 
143
        /*
144
           Map all BAR's
145
         */
146
        for (bar = 0; bar < 5; bar++) {
147
                a->resources.pci.addr[bar] =
148
                    divasa_remap_pci_bar(a, bar, a->resources.pci.bar[bar],
149
                                         bar_length[bar]);
150
                if (!a->resources.pci.addr[bar]) {
151
                        DBG_ERR(("A: A(%d), can't map bar[%d]",
152
                                 a->controller, bar))
153
                        diva_pri_cleanup_adapter(a);
154
                        return (-1);
155
                }
156
        }
157
 
158
        /*
159
           Set all memory areas
160
         */
161
        diva_pri_set_addresses(a);
162
 
163
        /*
164
           Get Serial Number of this adapter
165
         */
166
        if (pri_get_serial_number(a)) {
167
                dword serNo;
168
                serNo = a->resources.pci.bar[1] & 0xffff0000;
169
                serNo |= ((dword) a->resources.pci.bus) << 8;
170
                serNo += (a->resources.pci.func + a->controller + 1);
171
                a->xdi_adapter.serialNo = serNo & ~0xFF000000;
172
                DBG_ERR(("A: A(%d) can't get Serial Number, generated serNo=%ld",
173
                         a->controller, a->xdi_adapter.serialNo))
174
        }
175
 
176
 
177
        /*
178
           Initialize os objects
179
         */
180
        if (diva_os_initialize_spin_lock(&a->xdi_adapter.isr_spin_lock, "isr")) {
181
                diva_pri_cleanup_adapter(a);
182
                return (-1);
183
        }
184
        if (diva_os_initialize_spin_lock
185
            (&a->xdi_adapter.data_spin_lock, "data")) {
186
                diva_pri_cleanup_adapter(a);
187
                return (-1);
188
        }
189
 
190
        strcpy(a->xdi_adapter.req_soft_isr.dpc_thread_name, "kdivasprid");
191
 
192
        if (diva_os_initialize_soft_isr(&a->xdi_adapter.req_soft_isr,
193
                                        DIDpcRoutine, &a->xdi_adapter)) {
194
                diva_pri_cleanup_adapter(a);
195
                return (-1);
196
        }
197
 
198
        /*
199
           Do not initialize second DPC - only one thread will be created
200
         */
201
        a->xdi_adapter.isr_soft_isr.object =
202
            a->xdi_adapter.req_soft_isr.object;
203
 
204
        /*
205
           Next step of card initialization:
206
           set up all interface pointers
207
         */
208
        a->xdi_adapter.Channels = CardProperties[a->CardOrdinal].Channels;
209
        a->xdi_adapter.e_max = CardProperties[a->CardOrdinal].E_info;
210
 
211
        a->xdi_adapter.e_tbl =
212
            diva_os_malloc(0, a->xdi_adapter.e_max * sizeof(E_INFO));
213
        if (!a->xdi_adapter.e_tbl) {
214
                diva_pri_cleanup_adapter(a);
215
                return (-1);
216
        }
217
        memset(a->xdi_adapter.e_tbl, 0x00, a->xdi_adapter.e_max * sizeof(E_INFO));
218
 
219
        a->xdi_adapter.a.io = &a->xdi_adapter;
220
        a->xdi_adapter.DIRequest = request;
221
        a->interface.cleanup_adapter_proc = diva_pri_cleanup_adapter;
222
        a->interface.cmd_proc = diva_pri_cmd_card_proc;
223
 
224
        if (pri_rev_2) {
225
                prepare_pri2_functions(&a->xdi_adapter);
226
        } else {
227
                prepare_pri_functions(&a->xdi_adapter);
228
        }
229
 
230
        a->dsp_mask = diva_pri_detect_dsps(a);
231
 
232
        /*
233
           Allocate DMA map
234
         */
235
        if (pri_rev_2) {
236
                diva_init_dma_map(a->resources.pci.hdev,
237
                                  (struct _diva_dma_map_entry **) &a->xdi_adapter.dma_map, 32);
238
        }
239
 
240
        /*
241
           Set IRQ handler
242
         */
243
        a->xdi_adapter.irq_info.irq_nr = a->resources.pci.irq;
244
        sprintf(a->xdi_adapter.irq_info.irq_name,
245
                "DIVA PRI %ld", (long) a->xdi_adapter.serialNo);
246
 
247
        if (diva_os_register_irq(a, a->xdi_adapter.irq_info.irq_nr,
248
                                 a->xdi_adapter.irq_info.irq_name)) {
249
                diva_pri_cleanup_adapter(a);
250
                return (-1);
251
        }
252
        a->xdi_adapter.irq_info.registered = 1;
253
 
254
        diva_log_info("%s IRQ:%d SerNo:%d", a->xdi_adapter.Properties.Name,
255
                      a->resources.pci.irq, a->xdi_adapter.serialNo);
256
 
257
        return (0);
258
}
259
 
260
static int diva_pri_cleanup_adapter(diva_os_xdi_adapter_t * a)
261
{
262
        int bar = 0;
263
 
264
        /*
265
           Stop Adapter if adapter is running
266
         */
267
        if (a->xdi_adapter.Initialized) {
268
                diva_pri_stop_adapter(a);
269
        }
270
 
271
        /*
272
           Remove ISR Handler
273
         */
274
        if (a->xdi_adapter.irq_info.registered) {
275
                diva_os_remove_irq(a, a->xdi_adapter.irq_info.irq_nr);
276
        }
277
        a->xdi_adapter.irq_info.registered = 0;
278
 
279
        /*
280
           Step 1: unmap all BAR's, if any was mapped
281
         */
282
        for (bar = 0; bar < 5; bar++) {
283
                if (a->resources.pci.bar[bar]
284
                    && a->resources.pci.addr[bar]) {
285
                        divasa_unmap_pci_bar(a->resources.pci.addr[bar]);
286
                        a->resources.pci.bar[bar] = 0;
287
                        a->resources.pci.addr[bar] = NULL;
288
                }
289
        }
290
 
291
        /*
292
           Free OS objects
293
         */
294
        diva_os_cancel_soft_isr(&a->xdi_adapter.isr_soft_isr);
295
        diva_os_cancel_soft_isr(&a->xdi_adapter.req_soft_isr);
296
 
297
        diva_os_remove_soft_isr(&a->xdi_adapter.req_soft_isr);
298
        a->xdi_adapter.isr_soft_isr.object = NULL;
299
 
300
        diva_os_destroy_spin_lock(&a->xdi_adapter.isr_spin_lock, "rm");
301
        diva_os_destroy_spin_lock(&a->xdi_adapter.data_spin_lock, "rm");
302
 
303
        /*
304
           Free memory accupied by XDI adapter
305
         */
306
        if (a->xdi_adapter.e_tbl) {
307
                diva_os_free(0, a->xdi_adapter.e_tbl);
308
                a->xdi_adapter.e_tbl = NULL;
309
        }
310
        a->xdi_adapter.Channels = 0;
311
        a->xdi_adapter.e_max = 0;
312
 
313
 
314
        /*
315
           Free adapter DMA map
316
         */
317
        diva_free_dma_map(a->resources.pci.hdev,
318
                          (struct _diva_dma_map_entry *) a->xdi_adapter.
319
                          dma_map);
320
        a->xdi_adapter.dma_map = NULL;
321
 
322
 
323
        /*
324
           Detach this adapter from debug driver
325
         */
326
 
327
        return (0);
328
}
329
 
330
/*
331
**  Activate On Board Boot Loader
332
*/
333
static int diva_pri_reset_adapter(PISDN_ADAPTER IoAdapter)
334
{
335
        dword i;
336
        struct mp_load __iomem *boot;
337
 
338
        if (!IoAdapter->Address || !IoAdapter->reset) {
339
                return (-1);
340
        }
341
        if (IoAdapter->Initialized) {
342
                DBG_ERR(("A: A(%d) can't reset PRI adapter - please stop first",
343
                         IoAdapter->ANum))
344
                return (-1);
345
        }
346
 
347
        boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
348
        WRITE_DWORD(&boot->err, 0);
349
        DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
350
 
351
        IoAdapter->rstFnc(IoAdapter);
352
 
353
        diva_os_wait(10);
354
 
355
        boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
356
        i = READ_DWORD(&boot->live);
357
 
358
        diva_os_wait(10);
359
        if (i == READ_DWORD(&boot->live)) {
360
                DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
361
                DBG_ERR(("A: A(%d) CPU on PRI %ld is not alive!",
362
                         IoAdapter->ANum, IoAdapter->serialNo))
363
                return (-1);
364
        }
365
        if (READ_DWORD(&boot->err)) {
366
                DBG_ERR(("A: A(%d) PRI %ld Board Selftest failed, error=%08lx",
367
                         IoAdapter->ANum, IoAdapter->serialNo,
368
                         READ_DWORD(&boot->err)))
369
                DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
370
                return (-1);
371
        }
372
        DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
373
 
374
        /*
375
           Forget all outstanding entities
376
         */
377
        IoAdapter->e_count = 0;
378
        if (IoAdapter->e_tbl) {
379
                memset(IoAdapter->e_tbl, 0x00,
380
                       IoAdapter->e_max * sizeof(E_INFO));
381
        }
382
        IoAdapter->head = 0;
383
        IoAdapter->tail = 0;
384
        IoAdapter->assign = 0;
385
        IoAdapter->trapped = 0;
386
 
387
        memset(&IoAdapter->a.IdTable[0], 0x00,
388
               sizeof(IoAdapter->a.IdTable));
389
        memset(&IoAdapter->a.IdTypeTable[0], 0x00,
390
               sizeof(IoAdapter->a.IdTypeTable));
391
        memset(&IoAdapter->a.FlowControlIdTable[0], 0x00,
392
               sizeof(IoAdapter->a.FlowControlIdTable));
393
        memset(&IoAdapter->a.FlowControlSkipTable[0], 0x00,
394
               sizeof(IoAdapter->a.FlowControlSkipTable));
395
        memset(&IoAdapter->a.misc_flags_table[0], 0x00,
396
               sizeof(IoAdapter->a.misc_flags_table));
397
        memset(&IoAdapter->a.rx_stream[0], 0x00,
398
               sizeof(IoAdapter->a.rx_stream));
399
        memset(&IoAdapter->a.tx_stream[0], 0x00,
400
               sizeof(IoAdapter->a.tx_stream));
401
        memset(&IoAdapter->a.tx_pos[0], 0x00, sizeof(IoAdapter->a.tx_pos));
402
        memset(&IoAdapter->a.rx_pos[0], 0x00, sizeof(IoAdapter->a.rx_pos));
403
 
404
        return (0);
405
}
406
 
407
static int
408
diva_pri_write_sdram_block(PISDN_ADAPTER IoAdapter,
409
                           dword address,
410
                           const byte * data, dword length, dword limit)
411
{
412
        byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
413
        byte __iomem *mem = p;
414
 
415
        if (((address + length) >= limit) || !mem) {
416
                DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
417
                DBG_ERR(("A: A(%d) write PRI address=0x%08lx",
418
                         IoAdapter->ANum, address + length))
419
                return (-1);
420
        }
421
        mem += address;
422
 
423
        /* memcpy_toio(), maybe? */
424
        while (length--) {
425
                WRITE_BYTE(mem++, *data++);
426
        }
427
 
428
        DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, p);
429
        return (0);
430
}
431
 
432
static int
433
diva_pri_start_adapter(PISDN_ADAPTER IoAdapter,
434
                       dword start_address, dword features)
435
{
436
        dword i;
437
        int started = 0;
438
        byte __iomem *p;
439
        struct mp_load __iomem *boot = (struct mp_load __iomem *) DIVA_OS_MEM_ATTACH_ADDRESS(IoAdapter);
440
        ADAPTER *a = &IoAdapter->a;
441
 
442
        if (IoAdapter->Initialized) {
443
                DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
444
                DBG_ERR(("A: A(%d) pri_start_adapter, adapter already running",
445
                         IoAdapter->ANum))
446
                return (-1);
447
        }
448
        if (!boot) {
449
                DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
450
                DBG_ERR(("A: PRI %ld can't start, adapter not mapped",
451
                         IoAdapter->serialNo))
452
                return (-1);
453
        }
454
 
455
        sprintf(IoAdapter->Name, "A(%d)", (int) IoAdapter->ANum);
456
        DBG_LOG(("A(%d) start PRI at 0x%08lx", IoAdapter->ANum,
457
                 start_address))
458
 
459
        WRITE_DWORD(&boot->addr, start_address);
460
        WRITE_DWORD(&boot->cmd, 3);
461
 
462
        for (i = 0; i < 300; ++i) {
463
                diva_os_wait(10);
464
                if ((READ_DWORD(&boot->signature) >> 16) == 0x4447) {
465
                        DBG_LOG(("A(%d) Protocol startup time %d.%02d seconds",
466
                                 IoAdapter->ANum, (i / 100), (i % 100)))
467
                        started = 1;
468
                        break;
469
                }
470
        }
471
 
472
        if (!started) {
473
                byte __iomem *p = (byte __iomem *)boot;
474
                dword TrapId;
475
                dword debug;
476
                TrapId = READ_DWORD(&p[0x80]);
477
                debug = READ_DWORD(&p[0x1c]);
478
                DBG_ERR(("A(%d) Adapter start failed 0x%08lx, TrapId=%08lx, debug=%08lx",
479
                         IoAdapter->ANum, READ_DWORD(&boot->signature),
480
                         TrapId, debug))
481
                DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
482
                if (IoAdapter->trapFnc) {
483
                        (*(IoAdapter->trapFnc)) (IoAdapter);
484
                }
485
                IoAdapter->stop(IoAdapter);
486
                return (-1);
487
        }
488
        DIVA_OS_MEM_DETACH_ADDRESS(IoAdapter, boot);
489
 
490
        IoAdapter->Initialized = true;
491
 
492
        /*
493
           Check Interrupt
494
         */
495
        IoAdapter->IrqCount = 0;
496
        p = DIVA_OS_MEM_ATTACH_CFG(IoAdapter);
497
        WRITE_DWORD(p, (dword) ~ 0x03E00000);
498
        DIVA_OS_MEM_DETACH_CFG(IoAdapter, p);
499
        a->ReadyInt = 1;
500
        a->ram_out(a, &PR_RAM->ReadyInt, 1);
501
 
502
        for (i = 100; !IoAdapter->IrqCount && (i-- > 0); diva_os_wait(10));
503
 
504
        if (!IoAdapter->IrqCount) {
505
                DBG_ERR(("A: A(%d) interrupt test failed",
506
                         IoAdapter->ANum))
507
                IoAdapter->Initialized = false;
508
                IoAdapter->stop(IoAdapter);
509
                return (-1);
510
        }
511
 
512
        IoAdapter->Properties.Features = (word) features;
513
 
514
        diva_xdi_display_adapter_features(IoAdapter->ANum);
515
 
516
        DBG_LOG(("A(%d) PRI adapter successfull started", IoAdapter->ANum))
517
        /*
518
           Register with DIDD
519
         */
520
        diva_xdi_didd_register_adapter(IoAdapter->ANum);
521
 
522
        return (0);
523
}
524
 
525
static void diva_pri_clear_interrupts(diva_os_xdi_adapter_t * a)
526
{
527
        PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
528
 
529
        /*
530
           clear any pending interrupt
531
         */
532
        IoAdapter->disIrq(IoAdapter);
533
 
534
        IoAdapter->tst_irq(&IoAdapter->a);
535
        IoAdapter->clr_irq(&IoAdapter->a);
536
        IoAdapter->tst_irq(&IoAdapter->a);
537
 
538
        /*
539
           kill pending dpcs
540
         */
541
        diva_os_cancel_soft_isr(&IoAdapter->req_soft_isr);
542
        diva_os_cancel_soft_isr(&IoAdapter->isr_soft_isr);
543
}
544
 
545
/*
546
**  Stop Adapter, but do not unmap/unregister - adapter
547
**  will be restarted later
548
*/
549
static int diva_pri_stop_adapter(diva_os_xdi_adapter_t * a)
550
{
551
        PISDN_ADAPTER IoAdapter = &a->xdi_adapter;
552
        int i = 100;
553
 
554
        if (!IoAdapter->ram) {
555
                return (-1);
556
        }
557
        if (!IoAdapter->Initialized) {
558
                DBG_ERR(("A: A(%d) can't stop PRI adapter - not running",
559
                         IoAdapter->ANum))
560
                return (-1);    /* nothing to stop */
561
        }
562
        IoAdapter->Initialized = 0;
563
 
564
        /*
565
           Disconnect Adapter from DIDD
566
         */
567
        diva_xdi_didd_remove_adapter(IoAdapter->ANum);
568
 
569
        /*
570
           Stop interrupts
571
         */
572
        a->clear_interrupts_proc = diva_pri_clear_interrupts;
573
        IoAdapter->a.ReadyInt = 1;
574
        IoAdapter->a.ram_inc(&IoAdapter->a, &PR_RAM->ReadyInt);
575
        do {
576
                diva_os_sleep(10);
577
        } while (i-- && a->clear_interrupts_proc);
578
 
579
        if (a->clear_interrupts_proc) {
580
                diva_pri_clear_interrupts(a);
581
                a->clear_interrupts_proc = NULL;
582
                DBG_ERR(("A: A(%d) no final interrupt from PRI adapter",
583
                         IoAdapter->ANum))
584
        }
585
        IoAdapter->a.ReadyInt = 0;
586
 
587
        /*
588
           Stop and reset adapter
589
         */
590
        IoAdapter->stop(IoAdapter);
591
 
592
        return (0);
593
}
594
 
595
/*
596
**  Process commands form configuration/download framework and from
597
**  user mode
598
**
599
**  return 0 on success
600
*/
601
static int
602
diva_pri_cmd_card_proc(struct _diva_os_xdi_adapter *a,
603
                       diva_xdi_um_cfg_cmd_t * cmd, int length)
604
{
605
        int ret = -1;
606
 
607
        if (cmd->adapter != a->controller) {
608
                DBG_ERR(("A: pri_cmd, invalid controller=%d != %d",
609
                         cmd->adapter, a->controller))
610
                return (-1);
611
        }
612
 
613
        switch (cmd->command) {
614
        case DIVA_XDI_UM_CMD_GET_CARD_ORDINAL:
615
                a->xdi_mbox.data_length = sizeof(dword);
616
                a->xdi_mbox.data =
617
                    diva_os_malloc(0, a->xdi_mbox.data_length);
618
                if (a->xdi_mbox.data) {
619
                        *(dword *) a->xdi_mbox.data =
620
                            (dword) a->CardOrdinal;
621
                        a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
622
                        ret = 0;
623
                }
624
                break;
625
 
626
        case DIVA_XDI_UM_CMD_GET_SERIAL_NR:
627
                a->xdi_mbox.data_length = sizeof(dword);
628
                a->xdi_mbox.data =
629
                    diva_os_malloc(0, a->xdi_mbox.data_length);
630
                if (a->xdi_mbox.data) {
631
                        *(dword *) a->xdi_mbox.data =
632
                            (dword) a->xdi_adapter.serialNo;
633
                        a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
634
                        ret = 0;
635
                }
636
                break;
637
 
638
        case DIVA_XDI_UM_CMD_GET_PCI_HW_CONFIG:
639
                a->xdi_mbox.data_length = sizeof(dword) * 9;
640
                a->xdi_mbox.data =
641
                    diva_os_malloc(0, a->xdi_mbox.data_length);
642
                if (a->xdi_mbox.data) {
643
                        int i;
644
                        dword *data = (dword *) a->xdi_mbox.data;
645
 
646
                        for (i = 0; i < 8; i++) {
647
                                *data++ = a->resources.pci.bar[i];
648
                        }
649
                        *data++ = (dword) a->resources.pci.irq;
650
                        a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
651
                        ret = 0;
652
                }
653
                break;
654
 
655
        case DIVA_XDI_UM_CMD_RESET_ADAPTER:
656
                ret = diva_pri_reset_adapter(&a->xdi_adapter);
657
                break;
658
 
659
        case DIVA_XDI_UM_CMD_WRITE_SDRAM_BLOCK:
660
                ret = diva_pri_write_sdram_block(&a->xdi_adapter,
661
                                                 cmd->command_data.
662
                                                 write_sdram.offset,
663
                                                 (byte *) & cmd[1],
664
                                                 cmd->command_data.
665
                                                 write_sdram.length,
666
                                                 pri_is_rev_2_card(a->
667
                                                                   CardOrdinal)
668
                                                 ? MP2_MEMORY_SIZE :
669
                                                 MP_MEMORY_SIZE);
670
                break;
671
 
672
        case DIVA_XDI_UM_CMD_STOP_ADAPTER:
673
                ret = diva_pri_stop_adapter(a);
674
                break;
675
 
676
        case DIVA_XDI_UM_CMD_START_ADAPTER:
677
                ret = diva_pri_start_adapter(&a->xdi_adapter,
678
                                             cmd->command_data.start.
679
                                             offset,
680
                                             cmd->command_data.start.
681
                                             features);
682
                break;
683
 
684
        case DIVA_XDI_UM_CMD_SET_PROTOCOL_FEATURES:
685
                a->xdi_adapter.features =
686
                    cmd->command_data.features.features;
687
                a->xdi_adapter.a.protocol_capabilities =
688
                    a->xdi_adapter.features;
689
                DBG_TRC(("Set raw protocol features (%08x)",
690
                         a->xdi_adapter.features))
691
                ret = 0;
692
                break;
693
 
694
        case DIVA_XDI_UM_CMD_GET_CARD_STATE:
695
                a->xdi_mbox.data_length = sizeof(dword);
696
                a->xdi_mbox.data =
697
                    diva_os_malloc(0, a->xdi_mbox.data_length);
698
                if (a->xdi_mbox.data) {
699
                        dword *data = (dword *) a->xdi_mbox.data;
700
                        if (!a->xdi_adapter.ram ||
701
                                !a->xdi_adapter.reset ||
702
                            !a->xdi_adapter.cfg) {
703
                                *data = 3;
704
                        } else if (a->xdi_adapter.trapped) {
705
                                *data = 2;
706
                        } else if (a->xdi_adapter.Initialized) {
707
                                *data = 1;
708
                        } else {
709
                                *data = 0;
710
                        }
711
                        a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
712
                        ret = 0;
713
                }
714
                break;
715
 
716
        case DIVA_XDI_UM_CMD_READ_XLOG_ENTRY:
717
                ret = diva_card_read_xlog(a);
718
                break;
719
 
720
        case DIVA_XDI_UM_CMD_READ_SDRAM:
721
                if (a->xdi_adapter.Address) {
722
                        if (
723
                            (a->xdi_mbox.data_length =
724
                             cmd->command_data.read_sdram.length)) {
725
                                if (
726
                                    (a->xdi_mbox.data_length +
727
                                     cmd->command_data.read_sdram.offset) <
728
                                    a->xdi_adapter.MemorySize) {
729
                                        a->xdi_mbox.data =
730
                                            diva_os_malloc(0,
731
                                                           a->xdi_mbox.
732
                                                           data_length);
733
                                        if (a->xdi_mbox.data) {
734
                                                byte __iomem *p = DIVA_OS_MEM_ATTACH_ADDRESS(&a->xdi_adapter);
735
                                                byte __iomem *src = p;
736
                                                byte *dst = a->xdi_mbox.data;
737
                                                dword len = a->xdi_mbox.data_length;
738
 
739
                                                src += cmd->command_data.read_sdram.offset;
740
 
741
                                                while (len--) {
742
                                                        *dst++ = READ_BYTE(src++);
743
                                                }
744
                                                a->xdi_mbox.status = DIVA_XDI_MBOX_BUSY;
745
                                                DIVA_OS_MEM_DETACH_ADDRESS(&a->xdi_adapter, p);
746
                                                ret = 0;
747
                                        }
748
                                }
749
                        }
750
                }
751
                break;
752
 
753
        default:
754
                DBG_ERR(("A: A(%d) invalid cmd=%d", a->controller,
755
                         cmd->command))
756
        }
757
 
758
        return (ret);
759
}
760
 
761
/*
762
**  Get Serial Number
763
*/
764
static int pri_get_serial_number(diva_os_xdi_adapter_t * a)
765
{
766
        byte data[64];
767
        int i;
768
        dword len = sizeof(data);
769
        volatile byte __iomem *config;
770
        volatile byte __iomem *flash;
771
        byte c;
772
 
773
/*
774
 *  First set some GT6401x config registers before accessing the BOOT-ROM
775
 */
776
        config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
777
        c = READ_BYTE(&config[0xc3c]);
778
        if (!(c & 0x08)) {
779
                WRITE_BYTE(&config[0xc3c], c);  /* Base Address enable register */
780
        }
781
        WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0x00);
782
        WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
783
        DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
784
/*
785
 *  Read only the last 64 bytes of manufacturing data
786
 */
787
        memset(data, '\0', len);
788
        flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
789
        for (i = 0; i < len; i++) {
790
                data[i] = READ_BYTE(&flash[0x8000 - len + i]);
791
        }
792
        DIVA_OS_MEM_DETACH_PROM(&a->xdi_adapter, flash);
793
 
794
        config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
795
        WRITE_BYTE(&config[LOW_BOOTCS_DREG], 0xFC);     /* Disable FLASH EPROM access */
796
        WRITE_BYTE(&config[HI_BOOTCS_DREG], 0xFF);
797
        DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
798
 
799
        if (memcmp(&data[48], "DIVAserverPR", 12)) {
800
#if !defined(DIVA_PRI_NO_PCI_BIOS_WORKAROUND)   /* { */
801
                word cmd = 0, cmd_org;
802
                void *addr;
803
                dword addr1, addr3, addr4;
804
                byte Bus, Slot;
805
                void *hdev;
806
                addr4 = a->resources.pci.bar[4];
807
                addr3 = a->resources.pci.bar[3];        /* flash  */
808
                addr1 = a->resources.pci.bar[1];        /* unused */
809
 
810
                DBG_ERR(("A: apply Compaq BIOS workaround"))
811
                DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
812
                             data[0], data[1], data[2], data[3],
813
                             data[4], data[5], data[6], data[7]))
814
 
815
                Bus = a->resources.pci.bus;
816
                Slot = a->resources.pci.func;
817
                hdev = a->resources.pci.hdev;
818
                PCIread(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
819
                PCIwrite(Bus, Slot, 0x04, &cmd, sizeof(cmd), hdev);
820
 
821
                PCIwrite(Bus, Slot, 0x14, &addr4, sizeof(addr4), hdev);
822
                PCIwrite(Bus, Slot, 0x20, &addr1, sizeof(addr1), hdev);
823
 
824
                PCIwrite(Bus, Slot, 0x04, &cmd_org, sizeof(cmd_org), hdev);
825
 
826
                addr = a->resources.pci.addr[1];
827
                a->resources.pci.addr[1] = a->resources.pci.addr[4];
828
                a->resources.pci.addr[4] = addr;
829
 
830
                addr1 = a->resources.pci.bar[1];
831
                a->resources.pci.bar[1] = a->resources.pci.bar[4];
832
                a->resources.pci.bar[4] = addr1;
833
 
834
                /*
835
                   Try to read Flash again
836
                 */
837
                len = sizeof(data);
838
 
839
                config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
840
                if (!(config[0xc3c] & 0x08)) {
841
                        config[0xc3c] |= 0x08;  /* Base Address enable register */
842
                }
843
                config[LOW_BOOTCS_DREG] = 0x00;
844
                config[HI_BOOTCS_DREG] = 0xFF;
845
                DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
846
 
847
                memset(data, '\0', len);
848
                flash = DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter);
849
                for (i = 0; i < len; i++) {
850
                        data[i] = flash[0x8000 - len + i];
851
                }
852
                DIVA_OS_MEM_ATTACH_PROM(&a->xdi_adapter, flash);
853
                config = DIVA_OS_MEM_ATTACH_CONFIG(&a->xdi_adapter);
854
                config[LOW_BOOTCS_DREG] = 0xFC;
855
                config[HI_BOOTCS_DREG] = 0xFF;
856
                DIVA_OS_MEM_DETACH_CONFIG(&a->xdi_adapter, config);
857
 
858
                if (memcmp(&data[48], "DIVAserverPR", 12)) {
859
                        DBG_ERR(("A: failed to read serial number"))
860
                        DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
861
                                     data[0], data[1], data[2], data[3],
862
                                     data[4], data[5], data[6], data[7]))
863
                        return (-1);
864
                }
865
#else                           /* } { */
866
                DBG_ERR(("A: failed to read DIVA signature word"))
867
                DBG_LOG(("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
868
                             data[0], data[1], data[2], data[3],
869
                             data[4], data[5], data[6], data[7]))
870
                DBG_LOG(("%02x:%02x:%02x:%02x", data[47], data[46],
871
                             data[45], data[44]))
872
#endif                          /* } */
873
        }
874
 
875
        a->xdi_adapter.serialNo =
876
            (data[47] << 24) | (data[46] << 16) | (data[45] << 8) |
877
            data[44];
878
        if (!a->xdi_adapter.serialNo
879
            || (a->xdi_adapter.serialNo == 0xffffffff)) {
880
                a->xdi_adapter.serialNo = 0;
881
                DBG_ERR(("A: failed to read serial number"))
882
                return (-1);
883
        }
884
 
885
        DBG_LOG(("Serial No.          : %ld", a->xdi_adapter.serialNo))
886
        DBG_TRC(("Board Revision      : %d.%02d", (int) data[41],
887
                     (int) data[40]))
888
        DBG_TRC(("PLD revision        : %d.%02d", (int) data[33],
889
                     (int) data[32]))
890
        DBG_TRC(("Boot loader version : %d.%02d", (int) data[37],
891
                     (int) data[36]))
892
 
893
        DBG_TRC(("Manufacturing Date  : %d/%02d/%02d  (yyyy/mm/dd)",
894
                     (int) ((data[28] > 90) ? 1900 : 2000) +
895
                     (int) data[28], (int) data[29], (int) data[30]))
896
 
897
        return (0);
898
}
899
 
900
void diva_os_prepare_pri2_functions(PISDN_ADAPTER IoAdapter)
901
{
902
}
903
 
904
void diva_os_prepare_pri_functions(PISDN_ADAPTER IoAdapter)
905
{
906
}
907
 
908
/*
909
**  Checks presence of DSP on board
910
*/
911
static int
912
dsp_check_presence(volatile byte __iomem * addr, volatile byte __iomem * data, int dsp)
913
{
914
        word pattern;
915
 
916
        WRITE_WORD(addr, 0x4000);
917
        WRITE_WORD(data, DSP_SIGNATURE_PROBE_WORD);
918
 
919
        WRITE_WORD(addr, 0x4000);
920
        pattern = READ_WORD(data);
921
 
922
        if (pattern != DSP_SIGNATURE_PROBE_WORD) {
923
                DBG_TRC(("W: DSP[%d] %04x(is) != %04x(should)",
924
                         dsp, pattern, DSP_SIGNATURE_PROBE_WORD))
925
                return (-1);
926
        }
927
 
928
        WRITE_WORD(addr, 0x4000);
929
        WRITE_WORD(data, ~DSP_SIGNATURE_PROBE_WORD);
930
 
931
        WRITE_WORD(addr, 0x4000);
932
        pattern = READ_WORD(data);
933
 
934
        if (pattern != (word) ~ DSP_SIGNATURE_PROBE_WORD) {
935
                DBG_ERR(("A: DSP[%d] %04x(is) != %04x(should)",
936
                         dsp, pattern, (word) ~ DSP_SIGNATURE_PROBE_WORD))
937
                return (-2);
938
        }
939
 
940
        DBG_TRC(("DSP[%d] present", dsp))
941
 
942
        return (0);
943
}
944
 
945
 
946
/*
947
**  Check if DSP's are present and operating
948
**  Information about detected DSP's is returned as bit mask
949
**  Bit 0  - DSP1
950
**  ...
951
**  ...
952
**  ...
953
**  Bit 29 - DSP30
954
*/
955
static dword diva_pri_detect_dsps(diva_os_xdi_adapter_t * a)
956
{
957
        byte __iomem *base;
958
        byte __iomem *p;
959
        dword ret = 0;
960
        dword row_offset[7] = {
961
                0x00000000,
962
                0x00000800,     /* 1 - ROW 1 */
963
                0x00000840,     /* 2 - ROW 2 */
964
                0x00001000,     /* 3 - ROW 3 */
965
                0x00001040,     /* 4 - ROW 4 */
966
                0x00000000      /* 5 - ROW 0 */
967
        };
968
 
969
        byte __iomem *dsp_addr_port;
970
        byte __iomem *dsp_data_port;
971
        byte row_state;
972
        int dsp_row = 0, dsp_index, dsp_num;
973
 
974
        if (!a->xdi_adapter.Control || !a->xdi_adapter.reset) {
975
                return (0);
976
        }
977
 
978
        p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
979
        WRITE_BYTE(p, _MP_RISC_RESET | _MP_DSP_RESET);
980
        DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
981
        diva_os_wait(5);
982
 
983
        base = DIVA_OS_MEM_ATTACH_CONTROL(&a->xdi_adapter);
984
 
985
        for (dsp_num = 0; dsp_num < 30; dsp_num++) {
986
                dsp_row = dsp_num / 7 + 1;
987
                dsp_index = dsp_num % 7;
988
 
989
                dsp_data_port = base;
990
                dsp_addr_port = base;
991
 
992
                dsp_data_port += row_offset[dsp_row];
993
                dsp_addr_port += row_offset[dsp_row];
994
 
995
                dsp_data_port += (dsp_index * 8);
996
                dsp_addr_port += (dsp_index * 8) + 0x80;
997
 
998
                if (!dsp_check_presence
999
                    (dsp_addr_port, dsp_data_port, dsp_num + 1)) {
1000
                        ret |= (1 << dsp_num);
1001
                }
1002
        }
1003
        DIVA_OS_MEM_DETACH_CONTROL(&a->xdi_adapter, base);
1004
 
1005
        p = DIVA_OS_MEM_ATTACH_RESET(&a->xdi_adapter);
1006
        WRITE_BYTE(p, _MP_RISC_RESET | _MP_LED1 | _MP_LED2);
1007
        DIVA_OS_MEM_DETACH_RESET(&a->xdi_adapter, p);
1008
        diva_os_wait(5);
1009
 
1010
        /*
1011
           Verify modules
1012
         */
1013
        for (dsp_row = 0; dsp_row < 4; dsp_row++) {
1014
                row_state = ((ret >> (dsp_row * 7)) & 0x7F);
1015
                if (row_state && (row_state != 0x7F)) {
1016
                        for (dsp_index = 0; dsp_index < 7; dsp_index++) {
1017
                                if (!(row_state & (1 << dsp_index))) {
1018
                                        DBG_ERR(("A: MODULE[%d]-DSP[%d] failed",
1019
                                                 dsp_row + 1,
1020
                                                 dsp_index + 1))
1021
                                }
1022
                        }
1023
                }
1024
        }
1025
 
1026
        if (!(ret & 0x10000000)) {
1027
                DBG_ERR(("A: ON BOARD-DSP[1] failed"))
1028
        }
1029
        if (!(ret & 0x20000000)) {
1030
                DBG_ERR(("A: ON BOARD-DSP[2] failed"))
1031
        }
1032
 
1033
        /*
1034
           Print module population now
1035
         */
1036
        DBG_LOG(("+-----------------------+"))
1037
        DBG_LOG(("| DSP MODULE POPULATION |"))
1038
        DBG_LOG(("+-----------------------+"))
1039
        DBG_LOG(("|  1  |  2  |  3  |  4  |"))
1040
        DBG_LOG(("+-----------------------+"))
1041
        DBG_LOG(("|  %s  |  %s  |  %s  |  %s  |",
1042
                 ((ret >> (0 * 7)) & 0x7F) ? "Y" : "N",
1043
                 ((ret >> (1 * 7)) & 0x7F) ? "Y" : "N",
1044
                 ((ret >> (2 * 7)) & 0x7F) ? "Y" : "N",
1045
                 ((ret >> (3 * 7)) & 0x7F) ? "Y" : "N"))
1046
        DBG_LOG(("+-----------------------+"))
1047
 
1048
        DBG_LOG(("DSP's(present-absent):%08x-%08x", ret,
1049
                 ~ret & 0x3fffffff))
1050
 
1051
        return (ret);
1052
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.