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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [isdn/] [sc/] [init.c] - Blame information for rev 62

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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