Linux-2.4.0-test2
[davej-history.git] / drivers / isdn / eicon / eicon_io.c
blob4f4180ed6effcb2b6925cdd6f4c50445b6279ae8
1 /* $Id: eicon_io.c,v 1.10 2000/01/23 21:21:23 armin Exp $
3 * ISDN low-level module for Eicon active ISDN-Cards.
4 * Code for communicating with hardware.
6 * Copyright 1999,2000 by Armin Schindler (mac@melware.de)
7 * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
9 * Thanks to Eicon Technology GmbH & Co. oHG for
10 * documents, informations and hardware.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * $Log: eicon_io.c,v $
27 * Revision 1.10 2000/01/23 21:21:23 armin
28 * Added new trace capability and some updates.
29 * DIVA Server BRI now supports data for ISDNLOG.
31 * Revision 1.9 1999/11/18 20:55:25 armin
32 * Ready_Int fix of ISA cards.
34 * Revision 1.8 1999/10/08 22:09:34 armin
35 * Some fixes of cards interface handling.
36 * Bugfix of NULL pointer occurence.
37 * Changed a few log outputs.
39 * Revision 1.7 1999/09/26 14:17:53 armin
40 * Improved debug and log via readstat()
42 * Revision 1.6 1999/09/21 20:35:43 armin
43 * added more error checking.
45 * Revision 1.5 1999/08/31 11:20:11 paul
46 * various spelling corrections (new checksums may be needed, Karsten!)
48 * Revision 1.4 1999/08/22 20:26:47 calle
49 * backported changes from kernel 2.3.14:
50 * - several #include "config.h" gone, others come.
51 * - "struct device" changed to "struct net_device" in 2.3.14, added a
52 * define in isdn_compat.h for older kernel versions.
54 * Revision 1.3 1999/08/18 20:17:01 armin
55 * Added XLOG function for all cards.
56 * Bugfix of alloc_skb NULL pointer.
58 * Revision 1.2 1999/07/25 15:12:05 armin
59 * fix of some debug logs.
60 * enabled ISA-cards option.
62 * Revision 1.1 1999/03/29 11:19:45 armin
63 * I/O stuff now in seperate file (eicon_io.c)
64 * Old ISA type cards (S,SX,SCOM,Quadro,S2M) implemented.
70 #include <linux/config.h>
71 #include "eicon.h"
73 void
74 eicon_io_rcv_dispatch(eicon_card *ccard) {
75 ulong flags;
76 struct sk_buff *skb, *skb2, *skb_new;
77 eicon_IND *ind, *ind2, *ind_new;
78 eicon_chan *chan;
80 if (!ccard) {
81 eicon_log(ccard, 1, "eicon_err: NULL card in rcv_dispatch !\n");
82 return;
85 while((skb = skb_dequeue(&ccard->rcvq))) {
86 ind = (eicon_IND *)skb->data;
88 save_flags(flags);
89 cli();
90 if ((chan = ccard->IdTable[ind->IndId]) == NULL) {
91 if (DebugVar & 1) {
92 switch(ind->Ind) {
93 case IDI_N_DISC_ACK:
94 /* doesn't matter if this happens */
95 break;
96 default:
97 eicon_log(ccard, 1, "idi: Indication for unknown channel Ind=%d Id=%x\n", ind->Ind, ind->IndId);
98 eicon_log(ccard, 1, "idi_hdl: Ch??: Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",
99 ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length);
102 restore_flags(flags);
103 dev_kfree_skb(skb);
104 continue;
106 restore_flags(flags);
108 if (chan->e.complete) { /* check for rec-buffer chaining */
109 if (ind->MLength == ind->RBuffer.length) {
110 chan->e.complete = 1;
111 idi_handle_ind(ccard, skb);
112 continue;
114 else {
115 chan->e.complete = 0;
116 ind->Ind = ind->MInd;
117 skb_queue_tail(&chan->e.R, skb);
118 continue;
121 else {
122 save_flags(flags);
123 cli();
124 if (!(skb2 = skb_dequeue(&chan->e.R))) {
125 chan->e.complete = 1;
126 eicon_log(ccard, 1, "eicon: buffer incomplete, but 0 in queue\n");
127 restore_flags(flags);
128 dev_kfree_skb(skb);
129 continue;
131 ind2 = (eicon_IND *)skb2->data;
132 skb_new = alloc_skb(((sizeof(eicon_IND)-1)+ind->RBuffer.length+ind2->RBuffer.length),
133 GFP_ATOMIC);
134 if (!skb_new) {
135 eicon_log(ccard, 1, "eicon_io: skb_alloc failed in rcv_dispatch()\n");
136 restore_flags(flags);
137 dev_kfree_skb(skb);
138 dev_kfree_skb(skb2);
139 continue;
141 ind_new = (eicon_IND *)skb_put(skb_new,
142 ((sizeof(eicon_IND)-1)+ind->RBuffer.length+ind2->RBuffer.length));
143 ind_new->Ind = ind2->Ind;
144 ind_new->IndId = ind2->IndId;
145 ind_new->IndCh = ind2->IndCh;
146 ind_new->MInd = ind2->MInd;
147 ind_new->MLength = ind2->MLength;
148 ind_new->RBuffer.length = ind2->RBuffer.length + ind->RBuffer.length;
149 memcpy(&ind_new->RBuffer.P, &ind2->RBuffer.P, ind2->RBuffer.length);
150 memcpy((&ind_new->RBuffer.P)+ind2->RBuffer.length, &ind->RBuffer.P, ind->RBuffer.length);
151 dev_kfree_skb(skb);
152 dev_kfree_skb(skb2);
153 if (ind->MLength == ind->RBuffer.length) {
154 chan->e.complete = 2;
155 restore_flags(flags);
156 idi_handle_ind(ccard, skb_new);
157 continue;
159 else {
160 chan->e.complete = 0;
161 skb_queue_tail(&chan->e.R, skb_new);
162 restore_flags(flags);
163 continue;
169 void
170 eicon_io_ack_dispatch(eicon_card *ccard) {
171 struct sk_buff *skb;
173 if (!ccard) {
174 eicon_log(ccard, 1, "eicon_err: NULL card in ack_dispatch!\n");
175 return;
177 while((skb = skb_dequeue(&ccard->rackq))) {
178 idi_handle_ack(ccard, skb);
184 * IO-Functions for different card-types
187 u8 ram_inb(eicon_card *card, void *adr) {
188 eicon_pci_card *pcard;
189 eicon_isa_card *icard;
190 u32 addr = (u32) adr;
192 pcard = &card->hwif.pci;
193 icard = &card->hwif.isa;
195 switch(card->type) {
196 case EICON_CTYPE_MAESTRA:
197 outw((u16)addr, (u16)pcard->PCIreg + M_ADDR);
198 return(inb((u16)pcard->PCIreg + M_DATA));
199 case EICON_CTYPE_MAESTRAP:
200 case EICON_CTYPE_S2M:
201 case EICON_CTYPE_S:
202 case EICON_CTYPE_SX:
203 case EICON_CTYPE_SCOM:
204 case EICON_CTYPE_QUADRO:
205 return(readb(addr));
207 return(0);
210 u16 ram_inw(eicon_card *card, void *adr) {
211 eicon_pci_card *pcard;
212 eicon_isa_card *icard;
213 u32 addr = (u32) adr;
215 pcard = &card->hwif.pci;
216 icard = &card->hwif.isa;
218 switch(card->type) {
219 case EICON_CTYPE_MAESTRA:
220 outw((u16)addr, (u16)pcard->PCIreg + M_ADDR);
221 return(inw((u16)pcard->PCIreg + M_DATA));
222 case EICON_CTYPE_MAESTRAP:
223 case EICON_CTYPE_S2M:
224 case EICON_CTYPE_S:
225 case EICON_CTYPE_SX:
226 case EICON_CTYPE_SCOM:
227 case EICON_CTYPE_QUADRO:
228 return(readw(addr));
230 return(0);
233 void ram_outb(eicon_card *card, void *adr, u8 data) {
234 eicon_pci_card *pcard;
235 eicon_isa_card *icard;
236 u32 addr = (u32) adr;
238 pcard = &card->hwif.pci;
239 icard = &card->hwif.isa;
241 switch(card->type) {
242 case EICON_CTYPE_MAESTRA:
243 outw((u16)addr, (u16)pcard->PCIreg + M_ADDR);
244 outb((u8)data, (u16)pcard->PCIreg + M_DATA);
245 break;
246 case EICON_CTYPE_MAESTRAP:
247 case EICON_CTYPE_S2M:
248 case EICON_CTYPE_S:
249 case EICON_CTYPE_SX:
250 case EICON_CTYPE_SCOM:
251 case EICON_CTYPE_QUADRO:
252 writeb(data, addr);
253 break;
257 void ram_outw(eicon_card *card, void *adr , u16 data) {
258 eicon_pci_card *pcard;
259 eicon_isa_card *icard;
260 u32 addr = (u32) adr;
262 pcard = &card->hwif.pci;
263 icard = &card->hwif.isa;
265 switch(card->type) {
266 case EICON_CTYPE_MAESTRA:
267 outw((u16)addr, (u16)pcard->PCIreg + M_ADDR);
268 outw((u16)data, (u16)pcard->PCIreg + M_DATA);
269 break;
270 case EICON_CTYPE_MAESTRAP:
271 case EICON_CTYPE_S2M:
272 case EICON_CTYPE_S:
273 case EICON_CTYPE_SX:
274 case EICON_CTYPE_SCOM:
275 case EICON_CTYPE_QUADRO:
276 writew(data, addr);
277 break;
281 void ram_copyfromcard(eicon_card *card, void *adrto, void *adr, int len) {
282 int i;
283 switch(card->type) {
284 case EICON_CTYPE_MAESTRA:
285 for(i = 0; i < len; i++) {
286 writeb(ram_inb(card, adr + i), adrto + i);
288 break;
289 case EICON_CTYPE_MAESTRAP:
290 memcpy(adrto, adr, len);
291 break;
292 case EICON_CTYPE_S2M:
293 case EICON_CTYPE_S:
294 case EICON_CTYPE_SX:
295 case EICON_CTYPE_SCOM:
296 case EICON_CTYPE_QUADRO:
297 memcpy_fromio(adrto, adr, len);
298 break;
302 void ram_copytocard(eicon_card *card, void *adrto, void *adr, int len) {
303 int i;
304 switch(card->type) {
305 case EICON_CTYPE_MAESTRA:
306 for(i = 0; i < len; i++) {
307 ram_outb(card, adrto + i, readb(adr + i));
309 break;
310 case EICON_CTYPE_MAESTRAP:
311 memcpy(adrto, adr, len);
312 break;
313 case EICON_CTYPE_S2M:
314 case EICON_CTYPE_S:
315 case EICON_CTYPE_SX:
316 case EICON_CTYPE_SCOM:
317 case EICON_CTYPE_QUADRO:
318 memcpy_toio(adrto, adr, len);
319 break;
324 * XLOG
327 eicon_get_xlog(eicon_card *card, xlogreq_t *xlogreq)
329 int timeout, i;
330 int divas_shared_offset = 0;
331 int len = 0;
332 int stype = 0;
333 __u32 time = 0;
334 mi_pc_maint_t *pcm = &xlogreq->pcm;
335 eicon_pci_card *pci_card = &card->hwif.pci;
336 eicon_isa_card *isa_card = &card->hwif.isa;
337 eicon_pr_ram *prram = 0;
338 char *ram;
340 switch(card->type) {
341 case EICON_CTYPE_MAESTRAP:
342 ram = (char *)pci_card->PCIram;
343 prram = (eicon_pr_ram *)ram;
344 divas_shared_offset = DIVAS_SHARED_OFFSET;
345 len = sizeof(mi_pc_maint_t);
346 break;
347 case EICON_CTYPE_MAESTRA:
348 prram = 0;
349 divas_shared_offset = 0;
350 len = sizeof(mi_pc_maint_t);
351 break;
352 case EICON_CTYPE_S:
353 case EICON_CTYPE_SX:
354 case EICON_CTYPE_SCOM:
355 case EICON_CTYPE_QUADRO:
356 case EICON_CTYPE_S2M:
357 prram = (eicon_pr_ram *)isa_card->shmem;
358 divas_shared_offset = 0xfb80;
359 len = sizeof(mi_pc_maint_t) - 78;
360 stype = 1;
361 break;
362 default:
363 return -ENODEV;
366 memset(&(xlogreq->pcm), 0, sizeof(mi_pc_maint_t));
368 xlogreq->pcm.rc = 0;
369 xlogreq->pcm.req = 1; /* DO_LOG */
371 ram = ((char *)prram) + MIPS_MAINT_OFFS - divas_shared_offset;
373 ram_outb(card, ram+1, pcm->rc);
374 ram_outb(card, ram+0, pcm->req);
376 timeout = jiffies + 50;
377 while (timeout > jiffies) {
378 pcm->rc = ram_inb(card, ram+1);
379 pcm->req = ram_inb(card, ram+0);
380 if (!pcm->req) break;
381 SLEEP(10);
384 if (pcm->req) {
385 return XLOG_ERR_TIMEOUT;
388 if (pcm->rc != OK) {
389 return XLOG_ERR_DONE;
392 ram_copyfromcard(card, pcm, ram, len);
394 if (stype) {
395 for (i=0; i<8; i++)
396 ((__u8 *)pcm)[11-i] = ((__u8 *)pcm)[9-i];
397 time = (__u32)pcm->data.w[2] * 3600 * 1000 +
398 (__u32)pcm->data.w[1] * 1000 +
399 (__u32)pcm->data.b[1] * 20 +
400 (__u32)pcm->data.b[0] ;
401 pcm->data.w[1] = (__u16) (time >> 16);
402 pcm->data.w[2] = (__u16) (time & 0x0000ffff);
403 pcm->data.w[0] = 2;
406 return XLOG_OK;
410 * Transmit-Function
412 void
413 eicon_io_transmit(eicon_card *ccard) {
414 eicon_pci_card *pci_card;
415 eicon_isa_card *isa_card;
416 struct sk_buff *skb;
417 struct sk_buff *skb2;
418 unsigned long flags;
419 char *ram, *reg, *cfg;
420 eicon_pr_ram *prram = 0;
421 eicon_isa_com *com = 0;
422 eicon_REQ *ReqOut = 0;
423 eicon_REQ *reqbuf = 0;
424 eicon_chan *chan;
425 eicon_chan_ptr *chan2;
426 int ReqCount;
427 int scom = 0;
428 int tmp = 0;
429 int quloop = 1;
430 int dlev = 0;
432 pci_card = &ccard->hwif.pci;
433 isa_card = &ccard->hwif.isa;
435 if (!ccard) {
436 eicon_log(ccard, 1, "eicon_transmit: NULL card!\n");
437 return;
440 switch(ccard->type) {
441 #ifdef CONFIG_ISDN_DRV_EICON_ISA
442 case EICON_CTYPE_S:
443 case EICON_CTYPE_SX:
444 case EICON_CTYPE_SCOM:
445 case EICON_CTYPE_QUADRO:
446 scom = 1;
447 com = (eicon_isa_com *)isa_card->shmem;
448 break;
449 case EICON_CTYPE_S2M:
450 scom = 0;
451 prram = (eicon_pr_ram *)isa_card->shmem;
452 break;
453 #endif
454 case EICON_CTYPE_MAESTRAP:
455 scom = 0;
456 ram = (char *)pci_card->PCIram;
457 reg = (char *)pci_card->PCIreg;
458 cfg = (char *)pci_card->PCIcfg;
459 prram = (eicon_pr_ram *)ram;
460 break;
461 case EICON_CTYPE_MAESTRA:
462 scom = 0;
463 ram = (char *)pci_card->PCIram;
464 reg = (char *)pci_card->PCIreg;
465 cfg = (char *)pci_card->PCIcfg;
466 prram = 0;
467 break;
468 default:
469 eicon_log(ccard, 1, "eicon_transmit: unsupported card-type!\n");
470 return;
473 ReqCount = 0;
474 if (!(skb2 = skb_dequeue(&ccard->sndq)))
475 quloop = 0;
476 while(quloop) {
477 save_flags(flags);
478 cli();
479 if (scom) {
480 if ((ram_inb(ccard, &com->Req)) || (ccard->ReadyInt)) {
481 if (!ccard->ReadyInt) {
482 tmp = ram_inb(ccard, &com->ReadyInt) + 1;
483 ram_outb(ccard, &com->ReadyInt, tmp);
484 ccard->ReadyInt++;
486 restore_flags(flags);
487 skb_queue_head(&ccard->sndq, skb2);
488 eicon_log(ccard, 32, "eicon: transmit: Card not ready\n");
489 return;
491 } else {
492 if (!(ram_inb(ccard, &prram->ReqOutput) - ram_inb(ccard, &prram->ReqInput))) {
493 restore_flags(flags);
494 skb_queue_head(&ccard->sndq, skb2);
495 eicon_log(ccard, 32, "eicon: transmit: Card not ready\n");
496 return;
499 restore_flags(flags);
500 chan2 = (eicon_chan_ptr *)skb2->data;
501 chan = chan2->ptr;
502 if (!chan->e.busy) {
503 if((skb = skb_dequeue(&chan->e.X))) {
504 save_flags(flags);
505 cli();
506 reqbuf = (eicon_REQ *)skb->data;
507 if ((reqbuf->Reference) && (chan->e.B2Id == 0) && (reqbuf->ReqId & 0x1f)) {
508 eicon_log(ccard, 16, "eicon: transmit: error Id=0 on %d (Net)\n", chan->No);
509 } else {
510 if (scom) {
511 ram_outw(ccard, &com->XBuffer.length, reqbuf->XBuffer.length);
512 ram_copytocard(ccard, &com->XBuffer.P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
513 ram_outb(ccard, &com->ReqCh, reqbuf->ReqCh);
515 } else {
516 /* get address of next available request buffer */
517 ReqOut = (eicon_REQ *)&prram->B[ram_inw(ccard, &prram->NextReq)];
518 ram_outw(ccard, &ReqOut->XBuffer.length, reqbuf->XBuffer.length);
519 ram_copytocard(ccard, &ReqOut->XBuffer.P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
520 ram_outb(ccard, &ReqOut->ReqCh, reqbuf->ReqCh);
521 ram_outb(ccard, &ReqOut->Req, reqbuf->Req);
523 dlev = 160;
524 if (reqbuf->ReqId & 0x1f) { /* if this is no ASSIGN */
526 if (!reqbuf->Reference) { /* Signal Layer */
527 if (scom)
528 ram_outb(ccard, &com->ReqId, chan->e.D3Id);
529 else
530 ram_outb(ccard, &ReqOut->ReqId, chan->e.D3Id);
532 chan->e.ReqCh = 0;
534 else { /* Net Layer */
535 if (scom)
536 ram_outb(ccard, &com->ReqId, chan->e.B2Id);
537 else
538 ram_outb(ccard, &ReqOut->ReqId, chan->e.B2Id);
540 chan->e.ReqCh = 1;
541 if (((reqbuf->Req & 0x0f) == 0x08) ||
542 ((reqbuf->Req & 0x0f) == 0x01)) { /* Send Data */
543 chan->waitq = reqbuf->XBuffer.length;
544 chan->waitpq += reqbuf->XBuffer.length;
545 dlev = 128;
549 } else { /* It is an ASSIGN */
551 if (scom)
552 ram_outb(ccard, &com->ReqId, reqbuf->ReqId);
553 else
554 ram_outb(ccard, &ReqOut->ReqId, reqbuf->ReqId);
556 if (!reqbuf->Reference)
557 chan->e.ReqCh = 0;
558 else
559 chan->e.ReqCh = 1;
561 if (scom)
562 chan->e.ref = ccard->ref_out++;
563 else
564 chan->e.ref = ram_inw(ccard, &ReqOut->Reference);
566 chan->e.Req = reqbuf->Req;
567 ReqCount++;
568 if (scom)
569 ram_outb(ccard, &com->Req, reqbuf->Req);
570 else
571 ram_outw(ccard, &prram->NextReq, ram_inw(ccard, &ReqOut->next));
573 chan->e.busy = 1;
574 eicon_log(ccard, dlev, "eicon: Req=%d Id=%x Ch=%d Len=%d Ref=%d\n",
575 reqbuf->Req,
576 (scom) ? ram_inb(ccard, &com->ReqId) :
577 ram_inb(ccard, &ReqOut->ReqId),
578 reqbuf->ReqCh, reqbuf->XBuffer.length,
579 chan->e.ref);
581 restore_flags(flags);
582 dev_kfree_skb(skb);
584 dev_kfree_skb(skb2);
586 else {
587 skb_queue_tail(&ccard->sackq, skb2);
588 eicon_log(ccard, 128, "eicon: transmit: busy chan %d\n", chan->No);
591 if (scom)
592 quloop = 0;
593 else
594 if (!(skb2 = skb_dequeue(&ccard->sndq)))
595 quloop = 0;
598 if (!scom)
599 ram_outb(ccard, &prram->ReqInput, (__u8)(ram_inb(ccard, &prram->ReqInput) + ReqCount));
601 while((skb = skb_dequeue(&ccard->sackq))) {
602 skb_queue_tail(&ccard->sndq, skb);
608 * IRQ handler
610 void
611 eicon_irq(int irq, void *dev_id, struct pt_regs *regs) {
612 eicon_card *ccard = (eicon_card *)dev_id;
613 eicon_pci_card *pci_card;
614 eicon_isa_card *isa_card;
615 char *ram = 0;
616 char *reg = 0;
617 char *cfg = 0;
618 eicon_pr_ram *prram = 0;
619 eicon_isa_com *com = 0;
620 eicon_RC *RcIn;
621 eicon_IND *IndIn;
622 struct sk_buff *skb;
623 int Count = 0;
624 int Rc = 0;
625 int Ind = 0;
626 unsigned char *irqprobe = 0;
627 int scom = 0;
628 int tmp = 0;
629 int dlev = 0;
632 if (!ccard) {
633 eicon_log(ccard, 1, "eicon_irq: spurious interrupt %d\n", irq);
634 return;
637 if (ccard->type == EICON_CTYPE_QUADRO) {
638 tmp = 4;
639 while(tmp) {
640 com = (eicon_isa_com *)ccard->hwif.isa.shmem;
641 if ((readb(ccard->hwif.isa.intack))) { /* quadro found */
642 break;
644 ccard = ccard->qnext;
645 tmp--;
649 pci_card = &ccard->hwif.pci;
650 isa_card = &ccard->hwif.isa;
652 switch(ccard->type) {
653 #ifdef CONFIG_ISDN_DRV_EICON_ISA
654 case EICON_CTYPE_S:
655 case EICON_CTYPE_SX:
656 case EICON_CTYPE_SCOM:
657 case EICON_CTYPE_QUADRO:
658 scom = 1;
659 com = (eicon_isa_com *)isa_card->shmem;
660 irqprobe = &isa_card->irqprobe;
661 break;
662 case EICON_CTYPE_S2M:
663 scom = 0;
664 prram = (eicon_pr_ram *)isa_card->shmem;
665 irqprobe = &isa_card->irqprobe;
666 break;
667 #endif
668 case EICON_CTYPE_MAESTRAP:
669 scom = 0;
670 ram = (char *)pci_card->PCIram;
671 reg = (char *)pci_card->PCIreg;
672 cfg = (char *)pci_card->PCIcfg;
673 irqprobe = &pci_card->irqprobe;
674 prram = (eicon_pr_ram *)ram;
675 break;
676 case EICON_CTYPE_MAESTRA:
677 scom = 0;
678 ram = (char *)pci_card->PCIram;
679 reg = (char *)pci_card->PCIreg;
680 cfg = (char *)pci_card->PCIcfg;
681 irqprobe = &pci_card->irqprobe;
682 prram = 0;
683 break;
684 default:
685 eicon_log(ccard, 1, "eicon_irq: unsupported card-type!\n");
686 return;
689 if (*irqprobe) {
690 switch(ccard->type) {
691 #ifdef CONFIG_ISDN_DRV_EICON_ISA
692 case EICON_CTYPE_S:
693 case EICON_CTYPE_SX:
694 case EICON_CTYPE_SCOM:
695 case EICON_CTYPE_QUADRO:
696 if (readb(isa_card->intack)) {
697 writeb(0, &com->Rc);
698 writeb(0, isa_card->intack);
700 (*irqprobe)++;
701 break;
702 case EICON_CTYPE_S2M:
703 if (readb(isa_card->intack)) {
704 writeb(0, &prram->RcOutput);
705 writeb(0, isa_card->intack);
707 (*irqprobe)++;
708 break;
709 #endif
710 case EICON_CTYPE_MAESTRAP:
711 if (readb(&ram[0x3fe])) {
712 writeb(0, &prram->RcOutput);
713 writew(MP_IRQ_RESET_VAL, &cfg[MP_IRQ_RESET]);
714 writew(0, &cfg[MP_IRQ_RESET + 2]);
715 writeb(0, &ram[0x3fe]);
717 *irqprobe = 0;
718 break;
719 case EICON_CTYPE_MAESTRA:
720 outb(0x08, pci_card->PCIreg + M_RESET);
721 *irqprobe = 0;
722 break;
724 return;
727 switch(ccard->type) {
728 #ifdef CONFIG_ISDN_DRV_EICON_ISA
729 case EICON_CTYPE_S:
730 case EICON_CTYPE_SX:
731 case EICON_CTYPE_SCOM:
732 case EICON_CTYPE_QUADRO:
733 case EICON_CTYPE_S2M:
734 if (!(readb(isa_card->intack))) { /* card did not interrupt */
735 eicon_log(ccard, 1, "eicon: IRQ: card reports no interrupt!\n");
736 return;
738 break;
739 #endif
740 case EICON_CTYPE_MAESTRAP:
741 if (!(readb(&ram[0x3fe]))) { /* card did not interrupt */
742 eicon_log(ccard, 1, "eicon: IRQ: card reports no interrupt!\n");
743 return;
745 break;
746 case EICON_CTYPE_MAESTRA:
747 outw(0x3fe, pci_card->PCIreg + M_ADDR);
748 if (!(inb(pci_card->PCIreg + M_DATA))) { /* card did not interrupt */
749 eicon_log(ccard, 1, "eicon: IRQ: card reports no interrupt!\n");
750 return;
752 break;
755 if (scom) {
757 /* if a return code is available ... */
758 if ((tmp = ram_inb(ccard, &com->Rc))) {
759 eicon_RC *ack;
760 if (tmp == READY_INT) {
761 eicon_log(ccard, 64, "eicon: IRQ Rc=READY_INT\n");
762 if (ccard->ReadyInt) {
763 ccard->ReadyInt--;
764 ram_outb(ccard, &com->Rc, 0);
765 eicon_schedule_tx(ccard);
767 } else {
768 skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);
769 if (!skb) {
770 eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");
771 } else {
772 ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
773 ack->Rc = tmp;
774 ack->RcId = ram_inb(ccard, &com->RcId);
775 ack->RcCh = ram_inb(ccard, &com->RcCh);
776 ack->Reference = ccard->ref_in++;
777 eicon_log(ccard, 128, "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n",
778 tmp,ack->RcId,ack->RcCh,ack->Reference);
779 skb_queue_tail(&ccard->rackq, skb);
780 eicon_schedule_ack(ccard);
782 ram_outb(ccard, &com->Req, 0);
783 ram_outb(ccard, &com->Rc, 0);
786 } else {
788 /* if an indication is available ... */
789 if ((tmp = ram_inb(ccard, &com->Ind))) {
790 eicon_IND *ind;
791 int len = ram_inw(ccard, &com->RBuffer.length);
792 skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);
793 if (!skb) {
794 eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");
795 } else {
796 ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
797 ind->Ind = tmp;
798 ind->IndId = ram_inb(ccard, &com->IndId);
799 ind->IndCh = ram_inb(ccard, &com->IndCh);
800 ind->MInd = ram_inb(ccard, &com->MInd);
801 ind->MLength = ram_inw(ccard, &com->MLength);
802 ind->RBuffer.length = len;
803 if ((tmp == 1) || (tmp == 8))
804 dlev = 128;
805 else
806 dlev = 192;
807 eicon_log(ccard, dlev, "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",
808 tmp,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len);
809 ram_copyfromcard(ccard, &ind->RBuffer.P, &com->RBuffer.P, len);
810 skb_queue_tail(&ccard->rcvq, skb);
811 eicon_schedule_rx(ccard);
813 ram_outb(ccard, &com->Ind, 0);
817 } else {
819 /* if return codes are available ... */
820 if((Count = ram_inb(ccard, &prram->RcOutput))) {
821 eicon_RC *ack;
822 /* get the buffer address of the first return code */
823 RcIn = (eicon_RC *)&prram->B[ram_inw(ccard, &prram->NextRc)];
824 /* for all return codes do ... */
825 while(Count--) {
827 if((Rc=ram_inb(ccard, &RcIn->Rc))) {
828 skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);
829 if (!skb) {
830 eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");
831 } else {
832 ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
833 ack->Rc = Rc;
834 ack->RcId = ram_inb(ccard, &RcIn->RcId);
835 ack->RcCh = ram_inb(ccard, &RcIn->RcCh);
836 ack->Reference = ram_inw(ccard, &RcIn->Reference);
837 eicon_log(ccard, 128, "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n",
838 Rc,ack->RcId,ack->RcCh,ack->Reference);
839 skb_queue_tail(&ccard->rackq, skb);
840 eicon_schedule_ack(ccard);
842 ram_outb(ccard, &RcIn->Rc, 0);
844 /* get buffer address of next return code */
845 RcIn = (eicon_RC *)&prram->B[ram_inw(ccard, &RcIn->next)];
847 /* clear all return codes (no chaining!) */
848 ram_outb(ccard, &prram->RcOutput, 0);
851 /* if indications are available ... */
852 if((Count = ram_inb(ccard, &prram->IndOutput))) {
853 eicon_IND *ind;
854 /* get the buffer address of the first indication */
855 IndIn = (eicon_IND *)&prram->B[ram_inw(ccard, &prram->NextInd)];
856 /* for all indications do ... */
857 while(Count--) {
858 Ind = ram_inb(ccard, &IndIn->Ind);
859 if(Ind) {
860 int len = ram_inw(ccard, &IndIn->RBuffer.length);
861 skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);
862 if (!skb) {
863 eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");
864 } else {
865 ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
866 ind->Ind = Ind;
867 ind->IndId = ram_inb(ccard, &IndIn->IndId);
868 ind->IndCh = ram_inb(ccard, &IndIn->IndCh);
869 ind->MInd = ram_inb(ccard, &IndIn->MInd);
870 ind->MLength = ram_inw(ccard, &IndIn->MLength);
871 ind->RBuffer.length = len;
872 if ((Ind == 1) || (Ind == 8))
873 dlev = 128;
874 else
875 dlev = 192;
876 eicon_log(ccard, dlev, "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",
877 Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len);
878 ram_copyfromcard(ccard, &ind->RBuffer.P, &IndIn->RBuffer.P, len);
879 skb_queue_tail(&ccard->rcvq, skb);
880 eicon_schedule_rx(ccard);
882 ram_outb(ccard, &IndIn->Ind, 0);
884 /* get buffer address of next indication */
885 IndIn = (eicon_IND *)&prram->B[ram_inw(ccard, &IndIn->next)];
887 ram_outb(ccard, &prram->IndOutput, 0);
892 /* clear interrupt */
893 switch(ccard->type) {
894 #ifdef CONFIG_ISDN_DRV_EICON_ISA
895 case EICON_CTYPE_QUADRO:
896 writeb(0, isa_card->intack);
897 writeb(0, &com[0x401]);
898 break;
899 case EICON_CTYPE_S:
900 case EICON_CTYPE_SX:
901 case EICON_CTYPE_SCOM:
902 case EICON_CTYPE_S2M:
903 writeb(0, isa_card->intack);
904 break;
905 #endif
906 case EICON_CTYPE_MAESTRAP:
907 writew(MP_IRQ_RESET_VAL, &cfg[MP_IRQ_RESET]);
908 writew(0, &cfg[MP_IRQ_RESET + 2]);
909 writeb(0, &ram[0x3fe]);
910 break;
911 case EICON_CTYPE_MAESTRA:
912 outb(0x08, pci_card->PCIreg + M_RESET);
913 outw(0x3fe, pci_card->PCIreg + M_ADDR);
914 outb(0, pci_card->PCIreg + M_DATA);
915 break;
918 return;