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