1 /* $Id: eicon_io.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
2 *
3 * ISDN low-level module for Eicon active ISDN-Cards.
4 * Code for communicating with hardware.
5 *
6 * Copyright 1999,2000 by Armin Schindler (mac@melware.de)
7 * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 *
12 * Thanks to Eicon Networks for
13 * documents, informations and hardware.
14 *
15 */
16
17 #include <linux/config.h>
18 #include "eicon.h"
19 #include "uxio.h"
20
21 void
eicon_io_rcv_dispatch(eicon_card * ccard)22 eicon_io_rcv_dispatch(eicon_card *ccard) {
23 ulong flags;
24 struct sk_buff *skb, *skb2, *skb_new;
25 eicon_IND *ind, *ind2, *ind_new;
26 eicon_chan *chan;
27
28 if (!ccard) {
29 eicon_log(ccard, 1, "eicon_err: NULL card in rcv_dispatch !\n");
30 return;
31 }
32
33 while((skb = skb_dequeue(&ccard->rcvq))) {
34 ind = (eicon_IND *)skb->data;
35
36 spin_lock_irqsave(&eicon_lock, flags);
37 if ((chan = ccard->IdTable[ind->IndId]) == NULL) {
38 spin_unlock_irqrestore(&eicon_lock, flags);
39 if (DebugVar & 1) {
40 switch(ind->Ind) {
41 case N_DISC_ACK:
42 /* doesn't matter if this happens */
43 break;
44 default:
45 eicon_log(ccard, 1, "idi: Indication for unknown channel Ind=%d Id=%x\n", ind->Ind, ind->IndId);
46 eicon_log(ccard, 1, "idi_hdl: Ch??: Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",
47 ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length);
48 }
49 }
50 dev_kfree_skb(skb);
51 continue;
52 }
53 spin_unlock_irqrestore(&eicon_lock, flags);
54
55 if (chan->e.complete) { /* check for rec-buffer chaining */
56 if (ind->MLength == ind->RBuffer.length) {
57 chan->e.complete = 1;
58 idi_handle_ind(ccard, skb);
59 continue;
60 }
61 else {
62 chan->e.complete = 0;
63 ind->Ind = ind->MInd;
64 skb_queue_tail(&chan->e.R, skb);
65 continue;
66 }
67 }
68 else {
69 if (!(skb2 = skb_dequeue(&chan->e.R))) {
70 chan->e.complete = 1;
71 eicon_log(ccard, 1, "eicon: buffer incomplete, but 0 in queue\n");
72 dev_kfree_skb(skb);
73 continue;
74 }
75 ind2 = (eicon_IND *)skb2->data;
76 skb_new = alloc_skb(((sizeof(eicon_IND)-1)+ind->RBuffer.length+ind2->RBuffer.length),
77 GFP_ATOMIC);
78 if (!skb_new) {
79 eicon_log(ccard, 1, "eicon_io: skb_alloc failed in rcv_dispatch()\n");
80 dev_kfree_skb(skb);
81 dev_kfree_skb(skb2);
82 continue;
83 }
84 ind_new = (eicon_IND *)skb_put(skb_new,
85 ((sizeof(eicon_IND)-1)+ind->RBuffer.length+ind2->RBuffer.length));
86 ind_new->Ind = ind2->Ind;
87 ind_new->IndId = ind2->IndId;
88 ind_new->IndCh = ind2->IndCh;
89 ind_new->MInd = ind2->MInd;
90 ind_new->MLength = ind2->MLength;
91 ind_new->RBuffer.length = ind2->RBuffer.length + ind->RBuffer.length;
92 memcpy(&ind_new->RBuffer.P, &ind2->RBuffer.P, ind2->RBuffer.length);
93 memcpy((&ind_new->RBuffer.P)+ind2->RBuffer.length, &ind->RBuffer.P, ind->RBuffer.length);
94 dev_kfree_skb(skb);
95 dev_kfree_skb(skb2);
96 if (ind->MLength == ind->RBuffer.length) {
97 chan->e.complete = 2;
98 idi_handle_ind(ccard, skb_new);
99 continue;
100 }
101 else {
102 chan->e.complete = 0;
103 skb_queue_tail(&chan->e.R, skb_new);
104 continue;
105 }
106 }
107 }
108 }
109
110 void
eicon_io_ack_dispatch(eicon_card * ccard)111 eicon_io_ack_dispatch(eicon_card *ccard) {
112 struct sk_buff *skb;
113
114 if (!ccard) {
115 eicon_log(ccard, 1, "eicon_err: NULL card in ack_dispatch!\n");
116 return;
117 }
118 while((skb = skb_dequeue(&ccard->rackq))) {
119 idi_handle_ack(ccard, skb);
120 }
121 }
122
123
124 /*
125 * IO-Functions for ISA cards
126 */
127
ram_inb(eicon_card * card,void * adr)128 u8 ram_inb(eicon_card *card, void *adr) {
129 u32 addr = (u32) adr;
130
131 return(readb(addr));
132 }
133
ram_inw(eicon_card * card,void * adr)134 u16 ram_inw(eicon_card *card, void *adr) {
135 u32 addr = (u32) adr;
136
137 return(readw(addr));
138 }
139
ram_outb(eicon_card * card,void * adr,u8 data)140 void ram_outb(eicon_card *card, void *adr, u8 data) {
141 u32 addr = (u32) adr;
142
143 writeb(data, addr);
144 }
145
ram_outw(eicon_card * card,void * adr,u16 data)146 void ram_outw(eicon_card *card, void *adr , u16 data) {
147 u32 addr = (u32) adr;
148
149 writew(data, addr);
150 }
151
ram_copyfromcard(eicon_card * card,void * adrto,void * adr,int len)152 void ram_copyfromcard(eicon_card *card, void *adrto, void *adr, int len) {
153 memcpy_fromio(adrto, adr, len);
154 }
155
ram_copytocard(eicon_card * card,void * adrto,void * adr,int len)156 void ram_copytocard(eicon_card *card, void *adrto, void *adr, int len) {
157 memcpy_toio(adrto, adr, len);
158 }
159
160
161 #ifdef CONFIG_ISDN_DRV_EICON_PCI
162 /*
163 * IDI-Callback function
164 */
165 void
eicon_idi_callback(ENTITY * de)166 eicon_idi_callback(ENTITY *de)
167 {
168 eicon_card *ccard = (eicon_card *)de->R;
169 struct sk_buff *skb;
170 eicon_RC *ack;
171 eicon_IND *ind;
172 int len = 0;
173
174 if (de->complete == 255) {
175 /* Return Code */
176 skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);
177 if (!skb) {
178 eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _idi_callback()\n");
179 } else {
180 ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
181 ack->Rc = de->Rc;
182 if (de->Rc == ASSIGN_OK) {
183 ack->RcId = de->Id;
184 de->user[1] = de->Id;
185 } else {
186 ack->RcId = de->user[1];
187 }
188 ack->RcCh = de->RcCh;
189 ack->Reference = de->user[0];
190 skb_queue_tail(&ccard->rackq, skb);
191 eicon_schedule_ack(ccard);
192 eicon_log(ccard, 128, "idi_cbk: Ch%d: Rc=%x Id=%x RLen=%x compl=%x\n",
193 de->user[0], de->Rc, ack->RcId, de->RLength, de->complete);
194 }
195 } else {
196 /* Indication */
197 if (de->complete) {
198 len = de->RLength;
199 } else {
200 len = 270;
201 if (de->RLength <= 270)
202 eicon_log(ccard, 1, "eicon_cbk: ind not complete but <= 270\n");
203 }
204 skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);
205 if (!skb) {
206 eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _idi_callback()\n");
207 } else {
208 ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
209 ind->Ind = de->Ind;
210 ind->IndId = de->user[1];
211 ind->IndCh = de->IndCh;
212 ind->MInd = de->Ind;
213 ind->RBuffer.length = len;
214 ind->MLength = de->RLength;
215 memcpy(&ind->RBuffer.P, &de->RBuffer->P, len);
216 skb_queue_tail(&ccard->rcvq, skb);
217 eicon_schedule_rx(ccard);
218 eicon_log(ccard, 128, "idi_cbk: Ch%d: Ind=%x Id=%x RLen=%x compl=%x\n",
219 de->user[0], de->Ind, ind->IndId, de->RLength, de->complete);
220 }
221 }
222
223 de->RNum = 0;
224 de->RNR = 0;
225 de->Rc = 0;
226 de->Ind = 0;
227 }
228 #endif /* CONFIG_ISDN_DRV_EICON_PCI */
229
230 /*
231 * Transmit-Function
232 */
233 void
eicon_io_transmit(eicon_card * ccard)234 eicon_io_transmit(eicon_card *ccard) {
235 eicon_isa_card *isa_card;
236 struct sk_buff *skb;
237 struct sk_buff *skb2;
238 unsigned long flags;
239 eicon_pr_ram *prram = 0;
240 eicon_isa_com *com = 0;
241 eicon_REQ *ReqOut = 0;
242 eicon_REQ *reqbuf = 0;
243 eicon_chan *chan;
244 eicon_chan_ptr *chan2;
245 int ReqCount;
246 int scom = 0;
247 int tmp = 0;
248 int tmpid = 0;
249 int quloop = 1;
250 int dlev = 0;
251 ENTITY *ep = 0;
252
253 isa_card = &ccard->hwif.isa;
254
255 if (!ccard) {
256 eicon_log(ccard, 1, "eicon_transmit: NULL card!\n");
257 return;
258 }
259
260 switch(ccard->type) {
261 #ifdef CONFIG_ISDN_DRV_EICON_ISA
262 case EICON_CTYPE_S:
263 case EICON_CTYPE_SX:
264 case EICON_CTYPE_SCOM:
265 case EICON_CTYPE_QUADRO:
266 scom = 1;
267 com = (eicon_isa_com *)isa_card->shmem;
268 break;
269 case EICON_CTYPE_S2M:
270 scom = 0;
271 prram = (eicon_pr_ram *)isa_card->shmem;
272 break;
273 #endif
274 #ifdef CONFIG_ISDN_DRV_EICON_PCI
275 case EICON_CTYPE_MAESTRAP:
276 scom = 2;
277 break;
278 case EICON_CTYPE_MAESTRAQ:
279 scom = 2;
280 break;
281 case EICON_CTYPE_MAESTRA:
282 scom = 2;
283 break;
284 #endif
285 default:
286 eicon_log(ccard, 1, "eicon_transmit: unsupported card-type!\n");
287 return;
288 }
289
290 ReqCount = 0;
291 if (!(skb2 = skb_dequeue(&ccard->sndq)))
292 quloop = 0;
293 while(quloop) {
294 spin_lock_irqsave(&eicon_lock, flags);
295 switch (scom) {
296 case 1:
297 if ((ram_inb(ccard, &com->Req)) || (ccard->ReadyInt)) {
298 if (!ccard->ReadyInt) {
299 tmp = ram_inb(ccard, &com->ReadyInt) + 1;
300 ram_outb(ccard, &com->ReadyInt, tmp);
301 ccard->ReadyInt++;
302 }
303 spin_unlock_irqrestore(&eicon_lock, flags);
304 skb_queue_head(&ccard->sndq, skb2);
305 eicon_log(ccard, 32, "eicon: transmit: Card not ready\n");
306 return;
307 }
308 break;
309 case 0:
310 if (!(ram_inb(ccard, &prram->ReqOutput) - ram_inb(ccard, &prram->ReqInput))) {
311 spin_unlock_irqrestore(&eicon_lock, flags);
312 skb_queue_head(&ccard->sndq, skb2);
313 eicon_log(ccard, 32, "eicon: transmit: Card not ready\n");
314 return;
315 }
316 break;
317 }
318 spin_unlock_irqrestore(&eicon_lock, flags);
319
320 chan2 = (eicon_chan_ptr *)skb2->data;
321 chan = chan2->ptr;
322 if (!chan->e.busy) {
323 if((skb = skb_dequeue(&chan->e.X))) {
324
325 reqbuf = (eicon_REQ *)skb->data;
326 if ((reqbuf->Reference) && (chan->e.B2Id == 0) && (reqbuf->ReqId & 0x1f)) {
327 eicon_log(ccard, 16, "eicon: transmit: error Id=0 on %d (Net)\n", chan->No);
328 } else {
329 spin_lock_irqsave(&eicon_lock, flags);
330
331 switch (scom) {
332 case 1:
333 ram_outw(ccard, &com->XBuffer.length, reqbuf->XBuffer.length);
334 ram_copytocard(ccard, &com->XBuffer.P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
335 ram_outb(ccard, &com->ReqCh, reqbuf->ReqCh);
336 break;
337 case 0:
338 /* get address of next available request buffer */
339 ReqOut = (eicon_REQ *)&prram->B[ram_inw(ccard, &prram->NextReq)];
340 ram_outw(ccard, &ReqOut->XBuffer.length, reqbuf->XBuffer.length);
341 ram_copytocard(ccard, &ReqOut->XBuffer.P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
342 ram_outb(ccard, &ReqOut->ReqCh, reqbuf->ReqCh);
343 ram_outb(ccard, &ReqOut->Req, reqbuf->Req);
344 break;
345 }
346
347 dlev = 160;
348
349 if (reqbuf->ReqId & 0x1f) { /* if this is no ASSIGN */
350
351 if (!reqbuf->Reference) { /* Signal Layer */
352 switch (scom) {
353 case 1:
354 ram_outb(ccard, &com->ReqId, chan->e.D3Id);
355 break;
356 case 0:
357 ram_outb(ccard, &ReqOut->ReqId, chan->e.D3Id);
358 break;
359 case 2:
360 ep = &chan->de;
361 break;
362 }
363 tmpid = chan->e.D3Id;
364 chan->e.ReqCh = 0;
365 }
366 else { /* Net Layer */
367 switch(scom) {
368 case 1:
369 ram_outb(ccard, &com->ReqId, chan->e.B2Id);
370 break;
371 case 0:
372 ram_outb(ccard, &ReqOut->ReqId, chan->e.B2Id);
373 break;
374 case 2:
375 ep = &chan->be;
376 break;
377 }
378 tmpid = chan->e.B2Id;
379 chan->e.ReqCh = 1;
380 if (((reqbuf->Req & 0x0f) == 0x08) ||
381 ((reqbuf->Req & 0x0f) == 0x01)) { /* Send Data */
382 chan->waitq = reqbuf->XBuffer.length;
383 chan->waitpq += reqbuf->XBuffer.length;
384 dlev = 128;
385 }
386 }
387
388 } else { /* It is an ASSIGN */
389
390 switch(scom) {
391 case 1:
392 ram_outb(ccard, &com->ReqId, reqbuf->ReqId);
393 break;
394 case 0:
395 ram_outb(ccard, &ReqOut->ReqId, reqbuf->ReqId);
396 break;
397 case 2:
398 if (!reqbuf->Reference)
399 ep = &chan->de;
400 else
401 ep = &chan->be;
402 ep->Id = reqbuf->ReqId;
403 break;
404 }
405 tmpid = reqbuf->ReqId;
406
407 if (!reqbuf->Reference)
408 chan->e.ReqCh = 0;
409 else
410 chan->e.ReqCh = 1;
411 }
412
413 switch(scom) {
414 case 1:
415 chan->e.ref = ccard->ref_out++;
416 break;
417 case 0:
418 chan->e.ref = ram_inw(ccard, &ReqOut->Reference);
419 break;
420 case 2:
421 chan->e.ref = chan->No;
422 break;
423 }
424
425 chan->e.Req = reqbuf->Req;
426 ReqCount++;
427
428 switch (scom) {
429 case 1:
430 ram_outb(ccard, &com->Req, reqbuf->Req);
431 break;
432 case 0:
433 ram_outw(ccard, &prram->NextReq, ram_inw(ccard, &ReqOut->next));
434 break;
435 case 2:
436 #ifdef CONFIG_ISDN_DRV_EICON_PCI
437 if (!ep) break;
438 ep->callback = eicon_idi_callback;
439 ep->R = (BUFFERS *)ccard;
440 ep->user[0] = (word)chan->No;
441 ep->user[1] = (word)tmpid;
442 ep->XNum = 1;
443 ep->RNum = 0;
444 ep->RNR = 0;
445 ep->Rc = 0;
446 ep->Ind = 0;
447 ep->X->PLength = reqbuf->XBuffer.length;
448 memcpy(ep->X->P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
449 ep->ReqCh = reqbuf->ReqCh;
450 ep->Req = reqbuf->Req;
451 #endif
452 break;
453 }
454
455 chan->e.busy = 1;
456 spin_unlock_irqrestore(&eicon_lock, flags);
457 eicon_log(ccard, dlev, "eicon: Req=%d Id=%x Ch=%d Len=%d Ref=%d\n",
458 reqbuf->Req, tmpid,
459 reqbuf->ReqCh, reqbuf->XBuffer.length,
460 chan->e.ref);
461 #ifdef CONFIG_ISDN_DRV_EICON_PCI
462 if (scom == 2) {
463 if (ep) {
464 ccard->d->request(ep);
465 if (ep->Rc)
466 eicon_idi_callback(ep);
467 }
468 }
469 #endif
470 }
471 dev_kfree_skb(skb);
472 }
473 dev_kfree_skb(skb2);
474 }
475 else {
476 skb_queue_tail(&ccard->sackq, skb2);
477 eicon_log(ccard, 128, "eicon: transmit: busy chan %d\n", chan->No);
478 }
479
480 switch(scom) {
481 case 1:
482 quloop = 0;
483 break;
484 case 0:
485 case 2:
486 if (!(skb2 = skb_dequeue(&ccard->sndq)))
487 quloop = 0;
488 break;
489 }
490
491 }
492 if (!scom)
493 ram_outb(ccard, &prram->ReqInput, (__u8)(ram_inb(ccard, &prram->ReqInput) + ReqCount));
494
495 while((skb = skb_dequeue(&ccard->sackq))) {
496 skb_queue_tail(&ccard->sndq, skb);
497 }
498 }
499
500 #ifdef CONFIG_ISDN_DRV_EICON_ISA
501 /*
502 * IRQ handler
503 */
504 void
eicon_irq(int irq,void * dev_id,struct pt_regs * regs)505 eicon_irq(int irq, void *dev_id, struct pt_regs *regs) {
506 eicon_card *ccard = (eicon_card *)dev_id;
507 eicon_isa_card *isa_card;
508 eicon_pr_ram *prram = 0;
509 eicon_isa_com *com = 0;
510 eicon_RC *RcIn;
511 eicon_IND *IndIn;
512 struct sk_buff *skb;
513 int Count = 0;
514 int Rc = 0;
515 int Ind = 0;
516 unsigned char *irqprobe = 0;
517 int scom = 0;
518 int tmp = 0;
519 int dlev = 0;
520
521
522 if (!ccard) {
523 eicon_log(ccard, 1, "eicon_irq: spurious interrupt %d\n", irq);
524 return;
525 }
526
527 if (ccard->type == EICON_CTYPE_QUADRO) {
528 tmp = 4;
529 while(tmp) {
530 com = (eicon_isa_com *)ccard->hwif.isa.shmem;
531 if ((readb(ccard->hwif.isa.intack))) { /* quadro found */
532 break;
533 }
534 ccard = ccard->qnext;
535 tmp--;
536 }
537 }
538
539 isa_card = &ccard->hwif.isa;
540
541 switch(ccard->type) {
542 case EICON_CTYPE_S:
543 case EICON_CTYPE_SX:
544 case EICON_CTYPE_SCOM:
545 case EICON_CTYPE_QUADRO:
546 scom = 1;
547 com = (eicon_isa_com *)isa_card->shmem;
548 irqprobe = &isa_card->irqprobe;
549 break;
550 case EICON_CTYPE_S2M:
551 scom = 0;
552 prram = (eicon_pr_ram *)isa_card->shmem;
553 irqprobe = &isa_card->irqprobe;
554 break;
555 default:
556 eicon_log(ccard, 1, "eicon_irq: unsupported card-type!\n");
557 return;
558 }
559
560 if (*irqprobe) {
561 switch(ccard->type) {
562 case EICON_CTYPE_S:
563 case EICON_CTYPE_SX:
564 case EICON_CTYPE_SCOM:
565 case EICON_CTYPE_QUADRO:
566 if (readb(isa_card->intack)) {
567 writeb(0, &com->Rc);
568 writeb(0, isa_card->intack);
569 }
570 (*irqprobe)++;
571 break;
572 case EICON_CTYPE_S2M:
573 if (readb(isa_card->intack)) {
574 writeb(0, &prram->RcOutput);
575 writeb(0, isa_card->intack);
576 }
577 (*irqprobe)++;
578 break;
579 }
580 return;
581 }
582
583 switch(ccard->type) {
584 case EICON_CTYPE_S:
585 case EICON_CTYPE_SX:
586 case EICON_CTYPE_SCOM:
587 case EICON_CTYPE_QUADRO:
588 case EICON_CTYPE_S2M:
589 if (!(readb(isa_card->intack))) { /* card did not interrupt */
590 eicon_log(ccard, 1, "eicon: IRQ: card reports no interrupt!\n");
591 return;
592 }
593 break;
594 }
595
596 if (scom) {
597
598 /* if a return code is available ... */
599 if ((tmp = ram_inb(ccard, &com->Rc))) {
600 eicon_RC *ack;
601 if (tmp == READY_INT) {
602 eicon_log(ccard, 64, "eicon: IRQ Rc=READY_INT\n");
603 if (ccard->ReadyInt) {
604 ccard->ReadyInt--;
605 ram_outb(ccard, &com->Rc, 0);
606 eicon_schedule_tx(ccard);
607 }
608 } else {
609 skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);
610 if (!skb) {
611 eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");
612 } else {
613 ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
614 ack->Rc = tmp;
615 ack->RcId = ram_inb(ccard, &com->RcId);
616 ack->RcCh = ram_inb(ccard, &com->RcCh);
617 ack->Reference = ccard->ref_in++;
618 eicon_log(ccard, 128, "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n",
619 tmp,ack->RcId,ack->RcCh,ack->Reference);
620 skb_queue_tail(&ccard->rackq, skb);
621 eicon_schedule_ack(ccard);
622 }
623 ram_outb(ccard, &com->Req, 0);
624 ram_outb(ccard, &com->Rc, 0);
625 }
626
627 } else {
628
629 /* if an indication is available ... */
630 if ((tmp = ram_inb(ccard, &com->Ind))) {
631 eicon_IND *ind;
632 int len = ram_inw(ccard, &com->RBuffer.length);
633 skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);
634 if (!skb) {
635 eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");
636 } else {
637 ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
638 ind->Ind = tmp;
639 ind->IndId = ram_inb(ccard, &com->IndId);
640 ind->IndCh = ram_inb(ccard, &com->IndCh);
641 ind->MInd = ram_inb(ccard, &com->MInd);
642 ind->MLength = ram_inw(ccard, &com->MLength);
643 ind->RBuffer.length = len;
644 if ((tmp == 1) || (tmp == 8))
645 dlev = 128;
646 else
647 dlev = 192;
648 eicon_log(ccard, dlev, "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",
649 tmp,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len);
650 ram_copyfromcard(ccard, &ind->RBuffer.P, &com->RBuffer.P, len);
651 skb_queue_tail(&ccard->rcvq, skb);
652 eicon_schedule_rx(ccard);
653 }
654 ram_outb(ccard, &com->Ind, 0);
655 }
656 }
657
658 } else {
659
660 /* if return codes are available ... */
661 if((Count = ram_inb(ccard, &prram->RcOutput))) {
662 eicon_RC *ack;
663 /* get the buffer address of the first return code */
664 RcIn = (eicon_RC *)&prram->B[ram_inw(ccard, &prram->NextRc)];
665 /* for all return codes do ... */
666 while(Count--) {
667
668 if((Rc=ram_inb(ccard, &RcIn->Rc))) {
669 skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);
670 if (!skb) {
671 eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");
672 } else {
673 ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
674 ack->Rc = Rc;
675 ack->RcId = ram_inb(ccard, &RcIn->RcId);
676 ack->RcCh = ram_inb(ccard, &RcIn->RcCh);
677 ack->Reference = ram_inw(ccard, &RcIn->Reference);
678 eicon_log(ccard, 128, "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n",
679 Rc,ack->RcId,ack->RcCh,ack->Reference);
680 skb_queue_tail(&ccard->rackq, skb);
681 eicon_schedule_ack(ccard);
682 }
683 ram_outb(ccard, &RcIn->Rc, 0);
684 }
685 /* get buffer address of next return code */
686 RcIn = (eicon_RC *)&prram->B[ram_inw(ccard, &RcIn->next)];
687 }
688 /* clear all return codes (no chaining!) */
689 ram_outb(ccard, &prram->RcOutput, 0);
690 }
691
692 /* if indications are available ... */
693 if((Count = ram_inb(ccard, &prram->IndOutput))) {
694 eicon_IND *ind;
695 /* get the buffer address of the first indication */
696 IndIn = (eicon_IND *)&prram->B[ram_inw(ccard, &prram->NextInd)];
697 /* for all indications do ... */
698 while(Count--) {
699 Ind = ram_inb(ccard, &IndIn->Ind);
700 if(Ind) {
701 int len = ram_inw(ccard, &IndIn->RBuffer.length);
702 skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);
703 if (!skb) {
704 eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _irq()\n");
705 } else {
706 ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
707 ind->Ind = Ind;
708 ind->IndId = ram_inb(ccard, &IndIn->IndId);
709 ind->IndCh = ram_inb(ccard, &IndIn->IndCh);
710 ind->MInd = ram_inb(ccard, &IndIn->MInd);
711 ind->MLength = ram_inw(ccard, &IndIn->MLength);
712 ind->RBuffer.length = len;
713 if ((Ind == 1) || (Ind == 8))
714 dlev = 128;
715 else
716 dlev = 192;
717 eicon_log(ccard, dlev, "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",
718 Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len);
719 ram_copyfromcard(ccard, &ind->RBuffer.P, &IndIn->RBuffer.P, len);
720 skb_queue_tail(&ccard->rcvq, skb);
721 eicon_schedule_rx(ccard);
722 }
723 ram_outb(ccard, &IndIn->Ind, 0);
724 }
725 /* get buffer address of next indication */
726 IndIn = (eicon_IND *)&prram->B[ram_inw(ccard, &IndIn->next)];
727 }
728 ram_outb(ccard, &prram->IndOutput, 0);
729 }
730
731 }
732
733 /* clear interrupt */
734 switch(ccard->type) {
735 case EICON_CTYPE_QUADRO:
736 writeb(0, isa_card->intack);
737 writeb(0, &com[0x401]);
738 break;
739 case EICON_CTYPE_S:
740 case EICON_CTYPE_SX:
741 case EICON_CTYPE_SCOM:
742 case EICON_CTYPE_S2M:
743 writeb(0, isa_card->intack);
744 break;
745 }
746
747 return;
748 }
749 #endif
750