1 /* $Id: eicon_isa.c,v 1.1.4.1.2.3 2002/10/01 11:29:13 armin Exp $
3 * ISDN low-level module for Eicon active ISDN-Cards.
4 * Hardware-specific code for old ISA cards.
6 * Copyright 1998 by Fritz Elfert (fritz@isdn4linux.de)
7 * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
8 * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
10 * This software may be used and distributed according to the terms
11 * of the GNU General Public License, incorporated herein by reference.
15 #include <linux/config.h>
17 #include "eicon_isa.h"
19 #define check_shmem check_region
20 #define release_shmem release_region
21 #define request_shmem request_region
23 char *eicon_isa_revision
= "$Revision: 1.1.4.1.2.3 $";
25 #undef EICON_MCA_DEBUG
27 #ifdef CONFIG_ISDN_DRV_EICON_ISA
29 /* Mask for detecting invalid IRQ parameter */
30 static int eicon_isa_valid_irq
[] = {
31 0x1c1c, /* 2, 3, 4, 10, 11, 12 (S)*/
32 0x1c1c, /* 2, 3, 4, 10, 11, 12 (SX) */
33 0x1cbc, /* 2, 3, 4, 5, 7, 10, 11, 12 (SCOM) */
34 0x1cbc, /* 2, 3, 4, 5, 6, 10, 11, 12 (Quadro) */
35 0x1cbc /* 2, 3, 4, 5, 7, 10, 11, 12 (S2M) */
39 eicon_isa_release_shmem(eicon_isa_card
*card
) {
42 release_mem_region(card
->physmem
, card
->ramsize
);
48 eicon_isa_release_irq(eicon_isa_card
*card
) {
52 free_irq(card
->irq
, card
);
57 eicon_isa_release(eicon_isa_card
*card
) {
58 eicon_isa_release_irq(card
);
59 eicon_isa_release_shmem(card
);
63 eicon_isa_printpar(eicon_isa_card
*card
) {
67 case EICON_CTYPE_SCOM
:
68 case EICON_CTYPE_QUADRO
:
70 printk(KERN_INFO
"Eicon %s at 0x%lx, irq %d.\n",
71 eicon_ctype_name
[card
->type
],
78 eicon_isa_find_card(int Mem
, int Irq
, char * Id
)
89 /* Check for valid membase address */
90 if ((Mem
< 0x0c0000) ||
93 printk(KERN_WARNING
"eicon_isa: invalid membase 0x%x for %s\n",
97 if (check_mem_region(Mem
, RAMSIZE
)) {
98 printk(KERN_WARNING
"eicon_isa_boot: memory at 0x%x already in use.\n", Mem
);
102 amem
= (unsigned long) ioremap(Mem
, RAMSIZE
);
103 writew(0x55aa, amem
+ 0x402);
104 if (readw(amem
+ 0x402) != 0x55aa) primary
= 0;
105 writew(0, amem
+ 0x402);
106 if (readw(amem
+ 0x402) != 0) primary
= 0;
108 printk(KERN_INFO
"Eicon: Driver-ID: %s\n", Id
);
110 printk(KERN_INFO
"Eicon: assuming pri card at 0x%x\n", Mem
);
111 writeb(0, amem
+ 0x3ffe);
112 iounmap((unsigned char *)amem
);
113 return EICON_CTYPE_ISAPRI
;
115 printk(KERN_INFO
"Eicon: assuming bri card at 0x%x\n", Mem
);
116 writeb(0, amem
+ 0x400);
117 iounmap((unsigned char *)amem
);
118 return EICON_CTYPE_ISABRI
;
124 eicon_isa_bootload(eicon_isa_card
*card
, eicon_isa_codebuf
*cb
) {
126 unsigned long timeout
;
127 eicon_isa_codebuf cbuf
;
129 eicon_isa_boot
*boot
;
131 if (copy_from_user(&cbuf
, cb
, sizeof(eicon_isa_codebuf
)))
134 /* Allocate code-buffer and copy code from userspace */
135 if (cbuf
.bootstrap_len
> 1024) {
136 printk(KERN_WARNING
"eicon_isa_boot: Invalid startup-code size %ld\n",
140 if (!(code
= kmalloc(cbuf
.bootstrap_len
, GFP_KERNEL
))) {
141 printk(KERN_WARNING
"eicon_isa_boot: Couldn't allocate code buffer\n");
144 if (copy_from_user(code
, &cb
->code
, cbuf
.bootstrap_len
)) {
149 if (card
->type
== EICON_CTYPE_ISAPRI
)
150 card
->ramsize
= RAMSIZE_P
;
152 card
->ramsize
= RAMSIZE
;
154 if (check_mem_region(card
->physmem
, card
->ramsize
)) {
155 printk(KERN_WARNING
"eicon_isa_boot: memory at 0x%lx already in use.\n",
160 request_mem_region(card
->physmem
, card
->ramsize
, "Eicon ISA ISDN");
161 card
->shmem
= (eicon_isa_shmem
*) ioremap(card
->physmem
, card
->ramsize
);
162 #ifdef EICON_MCA_DEBUG
163 printk(KERN_INFO
"eicon_isa_boot: card->ramsize = %d.\n", card
->ramsize
);
170 case EICON_CTYPE_SCOM
:
171 case EICON_CTYPE_QUADRO
:
172 case EICON_CTYPE_ISABRI
:
173 card
->intack
= (__u8
*)card
->shmem
+ INTACK
;
174 card
->startcpu
= (__u8
*)card
->shmem
+ STARTCPU
;
175 card
->stopcpu
= (__u8
*)card
->shmem
+ STOPCPU
;
177 case EICON_CTYPE_S2M
:
178 case EICON_CTYPE_ISAPRI
:
179 card
->intack
= (__u8
*)card
->shmem
+ INTACK_P
;
180 card
->startcpu
= (__u8
*)card
->shmem
+ STARTCPU_P
;
181 card
->stopcpu
= (__u8
*)card
->shmem
+ STOPCPU_P
;
184 printk(KERN_WARNING
"eicon_isa_boot: Invalid card type %d\n", card
->type
);
185 eicon_isa_release_shmem(card
);
190 /* clear any pending irq's */
194 if (card
->type
== EICON_CTYPE_SCOM
) {
195 outb_p(0,card
->io
+1);
198 printk(KERN_WARNING
"eicon_isa_boot: Card type not supported yet.\n");
199 eicon_isa_release_shmem(card
);
203 #ifdef EICON_MCA_DEBUG
204 printk(KERN_INFO
"eicon_isa_boot: card->io = %x.\n", card
->io
);
205 printk(KERN_INFO
"eicon_isa_boot: card->irq = %d.\n", (int)card
->irq
);
209 /* set reset-line active */
210 writeb(0, card
->stopcpu
);
211 #endif /* CONFIG_MCA */
212 /* clear irq-requests */
213 writeb(0, card
->intack
);
216 /* Copy code into card */
217 memcpy_toio(&card
->shmem
->c
, code
, cbuf
.bootstrap_len
);
219 /* Check for properly loaded code */
220 if (!check_signature((unsigned long)&card
->shmem
->c
, code
, 1020)) {
221 printk(KERN_WARNING
"eicon_isa_boot: Could not load startup-code\n");
222 eicon_isa_release_shmem(card
);
226 /* if 16k-ramsize, duplicate the reset-jump-code */
227 if (card
->ramsize
== RAMSIZE_P
)
228 memcpy_toio((__u8
*)card
->shmem
+ 0x3ff0, &code
[0x3f0], 12);
231 boot
= &card
->shmem
->boot
;
237 writeb(cbuf
.boot_opt
, &boot
->ctrl
);
243 writeb(0, card
->startcpu
);
244 #endif /* CONFIG_MCA */
249 timeout
= jiffies
+ (HZ
* 22);
250 while (time_before(jiffies
, timeout
)) {
251 if (readb(&boot
->ctrl
) == 0)
255 if (readb(&boot
->ctrl
) != 0) {
256 printk(KERN_WARNING
"eicon_isa_boot: CPU test failed.\n");
257 #ifdef EICON_MCA_DEBUG
258 printk(KERN_INFO
"eicon_isa_boot: &boot->ctrl = %d.\n",
261 eicon_isa_release_shmem(card
);
265 /* Check for memory-test errors */
266 if (readw(&boot
->ebit
)) {
267 printk(KERN_WARNING
"eicon_isa_boot: memory test failed (bit 0x%04x at 0x%08x)\n",
268 readw(&boot
->ebit
), readl(&boot
->eloc
));
269 eicon_isa_release_shmem(card
);
273 /* Check card type and memory size */
274 tmp
= readb(&boot
->card
);
275 if ((tmp
< 0) || (tmp
> 4)) {
276 printk(KERN_WARNING
"eicon_isa_boot: Type detect failed\n");
277 eicon_isa_release_shmem(card
);
281 ((eicon_card
*)card
->card
)->type
= tmp
;
283 tmp
= readb(&boot
->msize
);
284 if (tmp
!= 8 && tmp
!= 16 && tmp
!= 24 &&
285 tmp
!= 32 && tmp
!= 48 && tmp
!= 60) {
286 printk(KERN_WARNING
"eicon_isa_boot: invalid memsize\n");
287 eicon_isa_release_shmem(card
);
290 printk(KERN_INFO
"%s: startup-code loaded\n", eicon_ctype_name
[card
->type
]);
291 if ((card
->type
== EICON_CTYPE_QUADRO
) && (card
->master
)) {
292 tmp
= eicon_addcard(card
->type
, card
->physmem
, card
->irq
,
293 ((eicon_card
*)card
->card
)->regname
, 0);
294 printk(KERN_INFO
"Eicon: %d adapters added\n", tmp
);
300 eicon_isa_load(eicon_isa_card
*card
, eicon_isa_codebuf
*cb
) {
301 eicon_isa_boot
*boot
;
303 unsigned long timeout
;
305 eicon_isa_codebuf cbuf
;
309 if (copy_from_user(&cbuf
, cb
, sizeof(eicon_isa_codebuf
)))
312 if (!(code
= kmalloc(cbuf
.firmware_len
, GFP_KERNEL
))) {
313 printk(KERN_WARNING
"eicon_isa_load: Couldn't allocate code buffer\n");
317 if (copy_from_user(code
, &cb
->code
, cbuf
.firmware_len
)) {
322 boot
= &card
->shmem
->boot
;
324 if ((!card
->ivalid
) && card
->master
) {
326 /* Check for valid IRQ */
327 if ((card
->irq
< 0) || (card
->irq
> 15) ||
328 (!((1 << card
->irq
) & eicon_isa_valid_irq
[card
->type
& 0x0f]))) {
329 printk(KERN_WARNING
"eicon_isa_load: invalid irq: %d\n", card
->irq
);
330 eicon_isa_release_shmem(card
);
335 if (!request_irq(card
->irq
, &eicon_irq
, 0, "Eicon ISA ISDN", card
))
338 printk(KERN_WARNING
"eicon_isa_load: irq %d already in use.\n",
340 eicon_isa_release_shmem(card
);
346 tmp
= readb(&boot
->msize
);
347 if (tmp
!= 8 && tmp
!= 16 && tmp
!= 24 &&
348 tmp
!= 32 && tmp
!= 48 && tmp
!= 60) {
349 printk(KERN_WARNING
"eicon_isa_load: invalid memsize\n");
350 eicon_isa_release_shmem(card
);
354 eicon_isa_printpar(card
);
356 /* Download firmware */
357 printk(KERN_INFO
"%s %dkB, loading firmware ...\n",
358 eicon_ctype_name
[card
->type
],
360 tmp
= cbuf
.firmware_len
>> 8;
363 memcpy_toio(&boot
->b
, p
, 256);
364 writeb(1, &boot
->ctrl
);
365 timeout
= jiffies
+ HZ
/ 10;
366 while (time_before(jiffies
, timeout
)) {
367 if (readb(&boot
->ctrl
) == 0)
371 if (readb(&boot
->ctrl
)) {
372 printk(KERN_WARNING
"eicon_isa_load: download timeout at 0x%x\n", p
-code
);
373 eicon_isa_release(card
);
381 /* Initialize firmware parameters */
382 memcpy_toio(&card
->shmem
->c
[8], &cbuf
.tei
, 14);
383 memcpy_toio(&card
->shmem
->c
[32], &cbuf
.oad
, 96);
384 memcpy_toio(&card
->shmem
->c
[128], &cbuf
.oad
, 96);
386 /* Start firmware, wait for signature */
387 writeb(2, &boot
->ctrl
);
388 timeout
= jiffies
+ (5*HZ
);
389 while (time_before(jiffies
, timeout
)) {
390 if (readw(&boot
->signature
) == 0x4447)
394 if (readw(&boot
->signature
) != 0x4447) {
395 printk(KERN_WARNING
"eicon_isa_load: firmware selftest failed %04x\n",
396 readw(&boot
->signature
));
397 eicon_isa_release(card
);
401 card
->channels
= readb(&card
->shmem
->c
[0x3f6]);
403 /* clear irq-requests, reset irq-count */
405 writeb(0, card
->intack
);
409 /* Trigger an interrupt and check if it is delivered */
410 tmp
= readb(&card
->shmem
->com
.ReadyInt
);
412 writeb(tmp
, &card
->shmem
->com
.ReadyInt
);
413 timeout
= jiffies
+ HZ
/ 5;
414 while (time_before(jiffies
, timeout
)) {
415 if (card
->irqprobe
> 1)
419 if (card
->irqprobe
== 1) {
420 printk(KERN_WARNING
"eicon_isa_load: IRQ # %d test failed\n", card
->irq
);
421 eicon_isa_release(card
);
425 #ifdef EICON_MCA_DEBUG
426 printk(KERN_INFO
"eicon_isa_load: IRQ # %d test succeeded.\n", card
->irq
);
429 writeb(card
->irq
, &card
->shmem
->com
.Int
);
431 /* initializing some variables */
432 ((eicon_card
*)card
->card
)->ReadyInt
= 0;
433 ((eicon_card
*)card
->card
)->ref_in
= 1;
434 ((eicon_card
*)card
->card
)->ref_out
= 1;
435 for(j
=0; j
<256; j
++) ((eicon_card
*)card
->card
)->IdTable
[j
] = NULL
;
436 for(j
=0; j
< (card
->channels
+ 1); j
++) {
437 ((eicon_card
*)card
->card
)->bch
[j
].e
.busy
= 0;
438 ((eicon_card
*)card
->card
)->bch
[j
].e
.D3Id
= 0;
439 ((eicon_card
*)card
->card
)->bch
[j
].e
.B2Id
= 0;
440 ((eicon_card
*)card
->card
)->bch
[j
].e
.ref
= 0;
441 ((eicon_card
*)card
->card
)->bch
[j
].e
.Req
= 0;
442 ((eicon_card
*)card
->card
)->bch
[j
].e
.complete
= 1;
443 ((eicon_card
*)card
->card
)->bch
[j
].fsm_state
= EICON_STATE_NULL
;
446 printk(KERN_INFO
"Eicon: Supported channels: %d\n", card
->channels
);
447 printk(KERN_INFO
"%s successfully started\n", eicon_ctype_name
[card
->type
]);
449 /* Enable normal IRQ processing */
454 #endif /* CONFIG_ISDN_DRV_EICON_ISA */