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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [isdn/] [sc/] [init.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
#include "includes.h"
2
#include "hardware.h"
3
#include "card.h"
4
 
5
board *adapter[MAX_CARDS];
6
int cinst;
7
 
8
static char devname[] = "scX";
9
const char version[] = "2.0b1";
10
 
11
const char *boardname[] = { "DataCommute/BRI", "DataCommute/PRI", "TeleCommute/BRI" };
12
 
13
/* insmod set parameters */
14
unsigned int io[] = {0,0,0,0};
15
unsigned char irq[] = {0,0,0,0};
16
unsigned long ram[] = {0,0,0,0};
17
int do_reset = 0;
18
 
19
static int sup_irq[] = { 11, 10, 9, 5, 12, 14, 7, 3, 4, 6 };
20
#define MAX_IRQS        10
21
 
22
extern void interrupt_handler(int, void *, struct pt_regs *);
23
extern int sndpkt(int, int, struct sk_buff *);
24
extern int command(isdn_ctrl *);
25
extern int indicate_status(int, int, ulong, char*);
26
extern int reset(int);
27
 
28
int identify_board(unsigned long, unsigned int);
29
 
30
int irq_supported(int irq_x)
31
{
32
        int i;
33
        for(i=0 ; i < MAX_IRQS ; i++) {
34
                if(sup_irq[i] == irq_x)
35
                        return 1;
36
        }
37
        return 0;
38
}
39
 
40
#ifdef MODULE
41
#if (LINUX_VERSION_CODE > 0x020111)
42
MODULE_PARM(io, "1-4i");
43
MODULE_PARM(irq, "1-4i");
44
MODULE_PARM(ram, "1-4i");
45
MODULE_PARM(do_reset, "i");
46
#endif
47
#define init_sc init_module
48
#else
49
/*
50
Initialization code for non-module version to be included
51
 
52
void sc_setup(char *str, int *ints)
53
{
54
}
55
*/
56
#endif
57
 
58
int init_sc(void)
59
{
60
        int b = -1;
61
        int i, j;
62
        int status = -ENODEV;
63
 
64
        unsigned long memsize = 0;
65
        unsigned long features = 0;
66
        isdn_if *interface;
67
        unsigned char channels;
68
        unsigned char pgport;
69
        unsigned long magic;
70
        int model;
71
        int last_base = IOBASE_MIN;
72
        int probe_exhasted = 0;
73
 
74
#ifdef MODULE
75
        pr_info("SpellCaster ISA ISDN Adapter Driver rev. %s Loaded\n", version);
76
#else
77
        pr_info("SpellCaster ISA ISDN Adapter Driver rev. %s\n", version);
78
#endif
79
        pr_info("Copyright (C) 1996 SpellCaster Telecommunications Inc.\n");
80
 
81
        while(b++ < MAX_CARDS - 1) {
82
                pr_debug("Probing for adapter #%d\n", b);
83
                /*
84
                 * Initialize reusable variables
85
                 */
86
                model = -1;
87
                magic = 0;
88
                channels = 0;
89
                pgport = 0;
90
 
91
                /*
92
                 * See if we should probe for IO base
93
                 */
94
                pr_debug("I/O Base for board %d is 0x%x, %s probe\n", b, io[b],
95
                        io[b] == 0 ? "will" : "won't");
96
                if(io[b]) {
97
                        /*
98
                         * No, I/O Base has been provided
99
                         */
100
                        for (i = 0 ; i < MAX_IO_REGS - 1 ; i++) {
101
                                if(check_region(io[b] + i * 0x400, 1)) {
102
                                        pr_debug("check_region for 0x%x failed\n", io[b] + i * 0x400);
103
                                        io[b] = 0;
104
                                        break;
105
                                }
106
                        }
107
 
108
                        /*
109
                         * Confirm the I/O Address with a test
110
                         */
111
                        if(io[b] == 0) {
112
                                pr_debug("I/O Address 0x%x is in use.\n");
113
                                continue;
114
                        }
115
 
116
                        outb(0x18, io[b] + 0x400 * EXP_PAGE0);
117
                        if(inb(io[b] + 0x400 * EXP_PAGE0) != 0x18) {
118
                                pr_debug("I/O Base 0x%x fails test\n");
119
                                continue;
120
                        }
121
                }
122
                else {
123
                        /*
124
                         * Yes, probe for I/O Base
125
                         */
126
                        if(probe_exhasted) {
127
                                pr_debug("All probe addresses exhasted, skipping\n");
128
                                continue;
129
                        }
130
                        pr_debug("Probing for I/O...\n");
131
                        for (i = last_base ; i <= IOBASE_MAX ; i += IOBASE_OFFSET) {
132
                                int found_io = 1;
133
                                if (i == IOBASE_MAX) {
134
                                        probe_exhasted = 1; /* No more addresses to probe */
135
                                        pr_debug("End of Probes\n");
136
                                }
137
                                last_base = i + IOBASE_OFFSET;
138
                                pr_debug("  checking 0x%x...", i);
139
                                for ( j = 0 ; j < MAX_IO_REGS - 1 ; j++) {
140
                                        if(check_region(i + j * 0x400, 1)) {
141
                                                pr_debug("Failed\n");
142
                                                found_io = 0;
143
                                                break;
144
                                        }
145
                                }
146
 
147
                                if(found_io) {
148
                                        io[b] = i;
149
                                        outb(0x18, io[b] + 0x400 * EXP_PAGE0);
150
                                        if(inb(io[b] + 0x400 * EXP_PAGE0) != 0x18) {
151
                                                pr_debug("Failed by test\n");
152
                                                continue;
153
                                        }
154
                                        pr_debug("Passed\n");
155
                                        break;
156
                                }
157
                        }
158
                        if(probe_exhasted) {
159
                                continue;
160
                        }
161
                }
162
 
163
                /*
164
                 * See if we should probe for shared RAM
165
                 */
166
                if(do_reset) {
167
                        pr_debug("Doing a SAFE probe reset\n");
168
                        outb(0xFF, io[b] + RESET_OFFSET);
169
                        current->state = TASK_INTERRUPTIBLE;
170
                        current->timeout = jiffies + milliseconds(10000);
171
                        schedule();
172
                }
173
                pr_debug("RAM Base for board %d is 0x%x, %s probe\n", b, ram[b],
174
                        ram[b] == 0 ? "will" : "won't");
175
 
176
                if(ram[b]) {
177
                        /*
178
                         * No, the RAM base has been provided
179
                         * Just look for a signature and ID the
180
                         * board model
181
                         */
182
                        if(!check_region(ram[b], SRAM_PAGESIZE)) {
183
                                pr_debug("check_region for RAM base 0x%x succeeded\n", ram[b]);
184
                                model = identify_board(ram[b], io[b]);
185
                        }
186
                }
187
                else {
188
                        /*
189
                         * Yes, probe for free RAM and look for
190
                         * a signature and id the board model
191
                         */
192
                        for (i = SRAM_MIN ; i < SRAM_MAX ; i += SRAM_PAGESIZE) {
193
                                pr_debug("Checking RAM address 0x%x...\n", i);
194
                                if(!check_region(i, SRAM_PAGESIZE)) {
195
                                        pr_debug("  check_region succeeded\n");
196
                                        model = identify_board(i, io[b]);
197
                                        if (model >= 0) {
198
                                                pr_debug("  Identified a %s\n",
199
                                                        boardname[model]);
200
                                                ram[b] = i;
201
                                                break;
202
                                        }
203
                                        pr_debug("  Unidentifed or inaccessible\n");
204
                                        continue;
205
                                }
206
                                pr_debug("  check_region failed\n");
207
                        }
208
                }
209
                /*
210
                 * See if we found free RAM and the board model
211
                 */
212
                if(!ram[b] || model < 0) {
213
                        /*
214
                         * Nope, there was no place in RAM for the
215
                         * board, or it couldn't be identified
216
                         */
217
                         pr_debug("Failed to find an adapter at 0x%x\n", ram[b]);
218
                         continue;
219
                }
220
 
221
                /*
222
                 * Set the board's magic number, memory size and page register
223
                 */
224
                switch(model) {
225
                case PRI_BOARD:
226
                        channels = 23;
227
                        magic = 0x20000;
228
                        memsize = 0x100000;
229
                        features = PRI_FEATURES;
230
                        break;
231
 
232
                case BRI_BOARD:
233
                case POTS_BOARD:
234
                        channels = 2;
235
                        magic = 0x60000;
236
                        memsize = 0x10000;
237
                        features = BRI_FEATURES;
238
                        break;
239
                }
240
                switch(ram[b] >> 12 & 0x0F) {
241
                case 0x0:
242
                        pr_debug("RAM Page register set to EXP_PAGE0\n");
243
                        pgport = EXP_PAGE0;
244
                        break;
245
 
246
                case 0x4:
247
                        pr_debug("RAM Page register set to EXP_PAGE1\n");
248
                        pgport = EXP_PAGE1;
249
                        break;
250
 
251
                case 0x8:
252
                        pr_debug("RAM Page register set to EXP_PAGE2\n");
253
                        pgport = EXP_PAGE2;
254
                        break;
255
 
256
                case 0xC:
257
                        pr_debug("RAM Page register set to EXP_PAGE3\n");
258
                        pgport = EXP_PAGE3;
259
                        break;
260
 
261
                default:
262
                        pr_debug("RAM base address doesn't fall on 16K boundary\n");
263
                        continue;
264
                }
265
 
266
                pr_debug("current IRQ: %d  b: %d\n",irq[b],b);
267
                /*
268
                 * See if we should probe for an irq
269
                 */
270
                if(irq[b]) {
271
                        /*
272
                         * No we were given one
273
                         * See that it is supported and free
274
                         */
275
                        pr_debug("Trying for IRQ: %d\n",irq[b]);
276
                        if (irq_supported(irq[b])) {
277
                                if(REQUEST_IRQ(irq[b], interrupt_handler,
278
                                        SA_PROBE, "sc_probe", NULL)) {
279
                                        pr_debug("IRQ %d is already in use\n",
280
                                                irq[b]);
281
                                        continue;
282
                                }
283
                                FREE_IRQ(irq[b], NULL);
284
                        }
285
                }
286
                else {
287
                        /*
288
                         * Yes, we need to probe for an IRQ
289
                         */
290
                        pr_debug("Probing for IRQ...\n");
291
                        for (i = 0; i < MAX_IRQS ; i++) {
292
                                if(!REQUEST_IRQ(sup_irq[i], interrupt_handler, SA_PROBE, "sc_probe", NULL)) {
293
                                        pr_debug("Probed for and found IRQ %d\n", sup_irq[i]);
294
                                        FREE_IRQ(sup_irq[i], NULL);
295
                                        irq[b] = sup_irq[i];
296
                                        break;
297
                                }
298
                        }
299
                }
300
 
301
                /*
302
                 * Make sure we got an IRQ
303
                 */
304
                if(!irq[b]) {
305
                        /*
306
                         * No interrupt could be used
307
                         */
308
                        pr_debug("Failed to aquire an IRQ line\n");
309
                        continue;
310
                }
311
 
312
                /*
313
                 * Horray! We found a board, Make sure we can register
314
                 * it with ISDN4Linux
315
                 */
316
                interface = kmalloc(sizeof(isdn_if), GFP_KERNEL);
317
                if (interface == NULL) {
318
                        /*
319
                         * Oops, can't malloc isdn_if
320
                         */
321
                        continue;
322
                }
323
                memset(interface, 0, sizeof(isdn_if));
324
 
325
                interface->hl_hdrlen = 0;
326
                interface->channels = channels;
327
                interface->maxbufsize = BUFFER_SIZE;
328
                interface->features = features;
329
                interface->writebuf_skb = sndpkt;
330
                interface->writecmd = NULL;
331
                interface->command = command;
332
                strcpy(interface->id, devname);
333
                interface->id[2] = '0' + cinst;
334
 
335
                /*
336
                 * Allocate the board structure
337
                 */
338
                adapter[cinst] = kmalloc(sizeof(board), GFP_KERNEL);
339
                if (adapter[cinst] == NULL) {
340
                        /*
341
                         * Oops, can't alloc memory for the board
342
                         */
343
                        kfree(interface);
344
                        continue;
345
                }
346
                memset(adapter[cinst], 0, sizeof(board));
347
 
348
                if(!register_isdn(interface)) {
349
                        /*
350
                         * Oops, couldn't register for some reason
351
                         */
352
                        kfree(interface);
353
                        kfree(adapter[cinst]);
354
                        continue;
355
                }
356
 
357
                adapter[cinst]->card = interface;
358
                adapter[cinst]->driverId = interface->channels;
359
                strcpy(adapter[cinst]->devicename, interface->id);
360
                adapter[cinst]->nChannels = channels;
361
                adapter[cinst]->ramsize = memsize;
362
                adapter[cinst]->shmem_magic = magic;
363
                adapter[cinst]->shmem_pgport = pgport;
364
                adapter[cinst]->StartOnReset = 1;
365
 
366
                /*
367
                 * Allocate channels status structures
368
                 */
369
                adapter[cinst]->channel = kmalloc(sizeof(bchan) * channels, GFP_KERNEL);
370
                if (adapter[cinst]->channel == NULL) {
371
                        /*
372
                         * Oops, can't alloc memory for the channels
373
                         */
374
                        indicate_status(cinst, ISDN_STAT_UNLOAD, 0, NULL);       /* Fix me */
375
                        kfree(interface);
376
                        kfree(adapter[cinst]);
377
                        continue;
378
                }
379
                memset(adapter[cinst]->channel, 0, sizeof(bchan) * channels);
380
 
381
                /*
382
                 * Lock down the hardware resources
383
                 */
384
                adapter[cinst]->interrupt = irq[b];
385
                REQUEST_IRQ(adapter[cinst]->interrupt, interrupt_handler, SA_INTERRUPT,
386
                        interface->id, NULL);
387
                adapter[cinst]->iobase = io[b];
388
                for(i = 0 ; i < MAX_IO_REGS - 1 ; i++) {
389
                        adapter[cinst]->ioport[i] = io[b] + i * 0x400;
390
                        request_region(adapter[cinst]->ioport[i], 1, interface->id);
391
                        pr_debug("Requesting I/O Port %#x\n", adapter[cinst]->ioport[i]);
392
                }
393
                adapter[cinst]->ioport[IRQ_SELECT] = io[b] + 0x2;
394
                request_region(adapter[cinst]->ioport[IRQ_SELECT], 1, interface->id);
395
                pr_debug("Requesting I/O Port %#x\n", adapter[cinst]->ioport[IRQ_SELECT]);
396
                adapter[cinst]->rambase = ram[b];
397
                request_region(adapter[cinst]->rambase, SRAM_PAGESIZE, interface->id);
398
 
399
                pr_info("  %s (%d) - %s %d channels IRQ %d, I/O Base 0x%x, RAM Base 0x%lx\n",
400
                        adapter[cinst]->devicename, adapter[cinst]->driverId,
401
                        boardname[model], channels, irq[b], io[b], ram[b]);
402
 
403
                /*
404
                 * reset the adapter to put things in motion
405
                 */
406
                reset(cinst);
407
 
408
                cinst++;
409
                status = 0;
410
        }
411
        if (status)
412
                pr_info("Failed to find any adapters, driver unloaded\n");
413
        return status;
414
}
415
 
416
#ifdef MODULE
417
void cleanup_module(void)
418
{
419
        int i, j;
420
 
421
        for(i = 0 ; i < cinst ; i++) {
422
                pr_debug("Cleaning up after adapter %d\n", i);
423
                /*
424
                 * kill the timers
425
                 */
426
                del_timer(&(adapter[i]->reset_timer));
427
                del_timer(&(adapter[i]->stat_timer));
428
 
429
                /*
430
                 * Tell I4L we're toast
431
                 */
432
                indicate_status(i, ISDN_STAT_STOP, 0, NULL);
433
                indicate_status(i, ISDN_STAT_UNLOAD, 0, NULL);
434
 
435
                /*
436
                 * Release shared RAM
437
                 */
438
                release_region(adapter[i]->rambase, SRAM_PAGESIZE);
439
 
440
                /*
441
                 * Release the IRQ
442
                 */
443
                FREE_IRQ(adapter[i]->interrupt, NULL);
444
 
445
                /*
446
                 * Reset for a clean start
447
                 */
448
                outb(0xFF, adapter[i]->ioport[SFT_RESET]);
449
 
450
                /*
451
                 * Release the I/O Port regions
452
                 */
453
                for(j = 0 ; j < MAX_IO_REGS - 1; j++) {
454
                        release_region(adapter[i]->ioport[j], 1);
455
                        pr_debug("Releasing I/O Port %#x\n", adapter[i]->ioport[j]);
456
                }
457
                release_region(adapter[i]->ioport[IRQ_SELECT], 1);
458
                pr_debug("Releasing I/O Port %#x\n", adapter[i]->ioport[IRQ_SELECT]);
459
 
460
                /*
461
                 * Release any memory we alloced
462
                 */
463
                kfree(adapter[i]->channel);
464
                kfree(adapter[i]->card);
465
                kfree(adapter[i]);
466
        }
467
        pr_info("SpellCaster ISA ISDN Adapter Driver Unloaded.\n");
468
}
469
#endif
470
 
471
int identify_board(unsigned long rambase, unsigned int iobase)
472
{
473
        unsigned int pgport;
474
        unsigned long sig;
475
        DualPortMemory *dpm;
476
        RspMessage rcvmsg;
477
        ReqMessage sndmsg;
478
        HWConfig_pl hwci;
479
        int x;
480
 
481
        pr_debug("Attempting to identify adapter @ 0x%x io 0x%x\n",
482
                rambase, iobase);
483
 
484
        /*
485
         * Enable the base pointer
486
         */
487
        outb(rambase >> 12, iobase + 0x2c00);
488
 
489
        switch(rambase >> 12 & 0x0F) {
490
        case 0x0:
491
                pgport = iobase + PG0_OFFSET;
492
                pr_debug("Page Register offset is 0x%x\n", PG0_OFFSET);
493
                break;
494
 
495
        case 0x4:
496
                pgport = iobase + PG1_OFFSET;
497
                pr_debug("Page Register offset is 0x%x\n", PG1_OFFSET);
498
                break;
499
 
500
        case 0x8:
501
                pgport = iobase + PG2_OFFSET;
502
                pr_debug("Page Register offset is 0x%x\n", PG2_OFFSET);
503
                break;
504
 
505
        case 0xC:
506
                pgport = iobase + PG3_OFFSET;
507
                pr_debug("Page Register offset is 0x%x\n", PG3_OFFSET);
508
                break;
509
        default:
510
                pr_debug("Invalid rambase 0x%lx\n", rambase);
511
                return -1;
512
        }
513
 
514
        /*
515
         * Try to identify a PRI card
516
         */
517
        outb(PRI_BASEPG_VAL, pgport);
518
        current->state = TASK_INTERRUPTIBLE;
519
        current->timeout = jiffies + HZ;
520
        schedule();
521
        sig = readl(rambase + SIG_OFFSET);
522
        pr_debug("Looking for a signature, got 0x%x\n", sig);
523
#if 0
524
/*
525
 * For Gary:
526
 * If it's a timing problem, it should be gone with the above schedule()
527
 * Another possible reason may be the missing volatile in the original
528
 * code. readl() does this for us.
529
 */
530
        printk("");     /* Hack! Doesn't work without this !!!??? */
531
#endif
532
        if(sig == SIGNATURE)
533
                return PRI_BOARD;
534
 
535
        /*
536
         * Try to identify a PRI card
537
         */
538
        outb(BRI_BASEPG_VAL, pgport);
539
        current->state = TASK_INTERRUPTIBLE;
540
        current->timeout = jiffies + HZ;
541
        schedule();
542
        sig = readl(rambase + SIG_OFFSET);
543
        pr_debug("Looking for a signature, got 0x%x\n", sig);
544
#if 0
545
        printk("");     /* Hack! Doesn't work without this !!!??? */
546
#endif
547
        if(sig == SIGNATURE)
548
                return BRI_BOARD;
549
 
550
        return -1;
551
 
552
        /*
553
         * Try to spot a card
554
         */
555
        sig = readl(rambase + SIG_OFFSET);
556
        pr_debug("Looking for a signature, got 0x%x\n", sig);
557
        if(sig != SIGNATURE)
558
                return -1;
559
 
560
        dpm = (DualPortMemory *) rambase;
561
 
562
        memset(&sndmsg, 0, MSG_LEN);
563
        sndmsg.msg_byte_cnt = 3;
564
        sndmsg.type = cmReqType1;
565
        sndmsg.class = cmReqClass0;
566
        sndmsg.code = cmReqHWConfig;
567
        memcpy_toio(&(dpm->req_queue[dpm->req_head++]), &sndmsg, MSG_LEN);
568
        outb(0, iobase + 0x400);
569
        pr_debug("Sent HWConfig message\n");
570
        /*
571
         * Wait for the response
572
         */
573
        x = 0;
574
        while((inb(iobase + FIFOSTAT_OFFSET) & RF_HAS_DATA) && x < 100) {
575
                current->state = TASK_INTERRUPTIBLE;
576
                current->timeout = jiffies + 1;
577
                schedule();
578
                x++;
579
        }
580
        if(x == 100) {
581
                pr_debug("Timeout waiting for response\n");
582
                return -1;
583
        }
584
 
585
        memcpy_fromio(&rcvmsg, &(dpm->rsp_queue[dpm->rsp_tail]), MSG_LEN);
586
        pr_debug("Got HWConfig response, status = 0x%x\n", rcvmsg.rsp_status);
587
        memcpy(&hwci, &(rcvmsg.msg_data.HWCresponse), sizeof(HWConfig_pl));
588
        pr_debug("Hardware Config: Interface: %s, RAM Size: %d, Serial: %s\n"
589
                 "                 Part: %s, Rev: %s\n",
590
                 hwci.st_u_sense ? "S/T" : "U", hwci.ram_size,
591
                 hwci.serial_no, hwci.part_no, hwci.rev_no);
592
 
593
        if(!strncmp(PRI_PARTNO, hwci.part_no, 6))
594
                return PRI_BOARD;
595
        if(!strncmp(BRI_PARTNO, hwci.part_no, 6))
596
                return BRI_BOARD;
597
 
598
        return -1;
599
}

powered by: WebSVN 2.1.0

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