patch-2.2.19 linux/drivers/isdn/eicon/eicon_io.c

Next file: linux/drivers/isdn/eicon/eicon_isa.c
Previous file: linux/drivers/isdn/eicon/eicon_idi.h
Back to the patch index
Back to the overall index

diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.18/drivers/isdn/eicon/eicon_io.c linux/drivers/isdn/eicon/eicon_io.c
@@ -1,4 +1,4 @@
-/* $Id: eicon_io.c,v 1.10 2000/01/23 21:21:23 armin Exp $
+/* $Id: eicon_io.c,v 1.13.6.1 2001/02/16 09:09:50 armin Exp $
  *
  * ISDN low-level module for Eicon active ISDN-Cards.
  * Code for communicating with hardware.
@@ -6,7 +6,7 @@
  * Copyright 1999,2000  by Armin Schindler (mac@melware.de)
  * Copyright 1999,2000  Cytronics & Melware (info@melware.de)
  *
- * Thanks to	Eicon Technology GmbH & Co. oHG for 
+ * Thanks to	Eicon Networks for 
  *		documents, informations and hardware. 
  *
  * This program is free software; you can redistribute it and/or modify
@@ -23,52 +23,12 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
- * $Log: eicon_io.c,v $
- * Revision 1.10  2000/01/23 21:21:23  armin
- * Added new trace capability and some updates.
- * DIVA Server BRI now supports data for ISDNLOG.
- *
- * Revision 1.9  1999/11/18 20:55:25  armin
- * Ready_Int fix of ISA cards.
- *
- * Revision 1.8  1999/10/08 22:09:34  armin
- * Some fixes of cards interface handling.
- * Bugfix of NULL pointer occurence.
- * Changed a few log outputs.
- *
- * Revision 1.7  1999/09/26 14:17:53  armin
- * Improved debug and log via readstat()
- *
- * Revision 1.6  1999/09/21 20:35:43  armin
- * added more error checking.
- *
- * Revision 1.5  1999/08/31 11:20:11  paul
- * various spelling corrections (new checksums may be needed, Karsten!)
- *
- * Revision 1.4  1999/08/22 20:26:47  calle
- * backported changes from kernel 2.3.14:
- * - several #include "config.h" gone, others come.
- * - "struct device" changed to "struct net_device" in 2.3.14, added a
- *   define in isdn_compat.h for older kernel versions.
- *
- * Revision 1.3  1999/08/18 20:17:01  armin
- * Added XLOG function for all cards.
- * Bugfix of alloc_skb NULL pointer.
- *
- * Revision 1.2  1999/07/25 15:12:05  armin
- * fix of some debug logs.
- * enabled ISA-cards option.
- *
- * Revision 1.1  1999/03/29 11:19:45  armin
- * I/O stuff now in seperate file (eicon_io.c)
- * Old ISA type cards (S,SX,SCOM,Quadro,S2M) implemented.
- *
- *
  */
 
 
 #include <linux/config.h>
 #include "eicon.h"
+#include "uxio.h"
 
 void
 eicon_io_rcv_dispatch(eicon_card *ccard) {
@@ -85,12 +45,12 @@
 	while((skb = skb_dequeue(&ccard->rcvq))) {
         	ind = (eicon_IND *)skb->data;
 
-		save_flags(flags);
-		cli();
+		spin_lock_irqsave(&eicon_lock, flags);
         	if ((chan = ccard->IdTable[ind->IndId]) == NULL) {
+			spin_unlock_irqrestore(&eicon_lock, flags);
 			if (DebugVar & 1) {
 				switch(ind->Ind) {
-					case IDI_N_DISC_ACK: 
+					case N_DISC_ACK: 
 						/* doesn't matter if this happens */ 
 						break;
 					default: 
@@ -99,11 +59,10 @@
 							ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length);
 				}
 			}
-			restore_flags(flags);
 	                dev_kfree_skb(skb);
 	                continue;
 	        }
-		restore_flags(flags);
+		spin_unlock_irqrestore(&eicon_lock, flags);
 
 		if (chan->e.complete) { /* check for rec-buffer chaining */
 			if (ind->MLength == ind->RBuffer.length) {
@@ -119,12 +78,9 @@
 			}
 		}
 		else {
-			save_flags(flags);
-			cli();
 			if (!(skb2 = skb_dequeue(&chan->e.R))) {
 				chan->e.complete = 1;
                 		eicon_log(ccard, 1, "eicon: buffer incomplete, but 0 in queue\n");
-				restore_flags(flags);
 	                	dev_kfree_skb(skb);
 				continue;	
 			}
@@ -133,7 +89,6 @@
 					GFP_ATOMIC);
 			if (!skb_new) {
                 		eicon_log(ccard, 1, "eicon_io: skb_alloc failed in rcv_dispatch()\n");
-				restore_flags(flags);
 	                	dev_kfree_skb(skb);
 	                	dev_kfree_skb(skb2);
 				continue;	
@@ -152,14 +107,12 @@
                 	dev_kfree_skb(skb2);
 			if (ind->MLength == ind->RBuffer.length) {
 				chan->e.complete = 2;
-				restore_flags(flags);
 				idi_handle_ind(ccard, skb_new);
 				continue;
 			}
 			else {
 				chan->e.complete = 0;
 				skb_queue_tail(&chan->e.R, skb_new);
-				restore_flags(flags);
 				continue;
 			}
 		}
@@ -181,242 +134,120 @@
 
 
 /*
- *  IO-Functions for different card-types
+ *  IO-Functions for ISA cards
  */
 
 u8 ram_inb(eicon_card *card, void *adr) {
-        eicon_pci_card *pcard;
-        eicon_isa_card *icard;
         u32 addr = (u32) adr;
 	
-	pcard = &card->hwif.pci;
-	icard = &card->hwif.isa;
-
-        switch(card->type) {
-                case EICON_CTYPE_MAESTRA:
-                        outw((u16)addr, (u16)pcard->PCIreg + M_ADDR);
-                        return(inb((u16)pcard->PCIreg + M_DATA));
-                case EICON_CTYPE_MAESTRAP:
-                case EICON_CTYPE_S2M:
-		case EICON_CTYPE_S:
-		case EICON_CTYPE_SX:
-		case EICON_CTYPE_SCOM:
-		case EICON_CTYPE_QUADRO:
-                        return(readb(addr));
-        }
- return(0);
+	return(readb(addr));
 }
 
 u16 ram_inw(eicon_card *card, void *adr) {
-        eicon_pci_card *pcard;
-        eicon_isa_card *icard;
         u32 addr = (u32) adr;
-	
-	pcard = &card->hwif.pci;
-	icard = &card->hwif.isa;
 
-        switch(card->type) {
-                case EICON_CTYPE_MAESTRA:
-                        outw((u16)addr, (u16)pcard->PCIreg + M_ADDR);
-                        return(inw((u16)pcard->PCIreg + M_DATA));
-                case EICON_CTYPE_MAESTRAP:
-                case EICON_CTYPE_S2M:
-		case EICON_CTYPE_S:
-		case EICON_CTYPE_SX:
-		case EICON_CTYPE_SCOM:
-		case EICON_CTYPE_QUADRO:
-                        return(readw(addr));
-        }
- return(0);
+	return(readw(addr));
 }
 
 void ram_outb(eicon_card *card, void *adr, u8 data) {
-        eicon_pci_card *pcard;
-        eicon_isa_card *icard;
         u32 addr = (u32) adr;
 
-	pcard = &card->hwif.pci;
-	icard = &card->hwif.isa;
-
-        switch(card->type) {
-                case EICON_CTYPE_MAESTRA:
-                        outw((u16)addr, (u16)pcard->PCIreg + M_ADDR);
-                        outb((u8)data, (u16)pcard->PCIreg + M_DATA);
-                        break;
-                case EICON_CTYPE_MAESTRAP:
-                case EICON_CTYPE_S2M:
-		case EICON_CTYPE_S:
-		case EICON_CTYPE_SX:
-		case EICON_CTYPE_SCOM:
-		case EICON_CTYPE_QUADRO:
-                        writeb(data, addr);
-                        break;
-        }
+	writeb(data, addr);
 }
 
 void ram_outw(eicon_card *card, void *adr , u16 data) {
-        eicon_pci_card *pcard;
-        eicon_isa_card *icard;
         u32 addr = (u32) adr;
 
-	pcard = &card->hwif.pci;
-	icard = &card->hwif.isa;
-
-        switch(card->type) {
-                case EICON_CTYPE_MAESTRA:
-                        outw((u16)addr, (u16)pcard->PCIreg + M_ADDR);
-                        outw((u16)data, (u16)pcard->PCIreg + M_DATA);
-                        break;
-                case EICON_CTYPE_MAESTRAP:
-                case EICON_CTYPE_S2M:
-		case EICON_CTYPE_S:
-		case EICON_CTYPE_SX:
-		case EICON_CTYPE_SCOM:
-		case EICON_CTYPE_QUADRO:
-                        writew(data, addr);
-                        break;
-        }
+	writew(data, addr);
 }
 
 void ram_copyfromcard(eicon_card *card, void *adrto, void *adr, int len) {
-        int i;
-        switch(card->type) {
-                case EICON_CTYPE_MAESTRA:
-                        for(i = 0; i < len; i++) {
-                                writeb(ram_inb(card, adr + i), adrto + i);
-                        }
-                        break;
-                case EICON_CTYPE_MAESTRAP:
-                        memcpy(adrto, adr, len);
-                        break;
-                case EICON_CTYPE_S2M:
-		case EICON_CTYPE_S:
-		case EICON_CTYPE_SX:
-		case EICON_CTYPE_SCOM:
-		case EICON_CTYPE_QUADRO:
-                        memcpy_fromio(adrto, adr, len);
-                        break;
-        }
+	memcpy_fromio(adrto, adr, len);
 }
 
 void ram_copytocard(eicon_card *card, void *adrto, void *adr, int len) {
-        int i;
-        switch(card->type) {
-                case EICON_CTYPE_MAESTRA:
-                        for(i = 0; i < len; i++) {
-                                ram_outb(card, adrto + i, readb(adr + i));
-                        }
-                        break;
-                case EICON_CTYPE_MAESTRAP:
-                        memcpy(adrto, adr, len);
-                        break;
-                case EICON_CTYPE_S2M:
-		case EICON_CTYPE_S:
-		case EICON_CTYPE_SX:
-		case EICON_CTYPE_SCOM:
-		case EICON_CTYPE_QUADRO:
-                        memcpy_toio(adrto, adr, len);
-                        break;
-        }
+	memcpy_toio(adrto, adr, len);
 }
 
+
+#ifdef CONFIG_ISDN_DRV_EICON_PCI
 /*
- * XLOG
+ *  IDI-Callback function
  */
-int
-eicon_get_xlog(eicon_card *card, xlogreq_t *xlogreq)
+void
+eicon_idi_callback(ENTITY *de)
 {
-	int timeout, i;
-	int divas_shared_offset = 0;
+	eicon_card *ccard = (eicon_card *)de->R;
+	struct sk_buff *skb;
+	eicon_RC *ack;
+	eicon_IND *ind;
 	int len = 0;
-	int stype = 0;
-	__u32 time = 0;
-	mi_pc_maint_t	*pcm = &xlogreq->pcm;
-        eicon_pci_card *pci_card = &card->hwif.pci;
-        eicon_isa_card *isa_card = &card->hwif.isa;
-	eicon_pr_ram  *prram = 0;
-        char *ram;
 
-	switch(card->type) {
-		case EICON_CTYPE_MAESTRAP:
-			ram = (char *)pci_card->PCIram;
-			prram = (eicon_pr_ram *)ram;
-			divas_shared_offset = DIVAS_SHARED_OFFSET;
-			len = sizeof(mi_pc_maint_t);
-			break;
-		case EICON_CTYPE_MAESTRA:
-			prram = 0;
-			divas_shared_offset = 0;
-			len = sizeof(mi_pc_maint_t);
-			break;
-		case EICON_CTYPE_S:
-		case EICON_CTYPE_SX:
-		case EICON_CTYPE_SCOM:
-		case EICON_CTYPE_QUADRO:
-		case EICON_CTYPE_S2M:
-			prram = (eicon_pr_ram *)isa_card->shmem;
-			divas_shared_offset = 0xfb80;
-			len = sizeof(mi_pc_maint_t) - 78;
-			stype = 1;
-			break;
-		default:
-			return -ENODEV;
-	}
-
-        memset(&(xlogreq->pcm), 0, sizeof(mi_pc_maint_t));
-
-        xlogreq->pcm.rc = 0;
-        xlogreq->pcm.req = 1; /* DO_LOG */
-
-        ram = ((char *)prram) + MIPS_MAINT_OFFS - divas_shared_offset;
-
-	ram_outb(card, ram+1, pcm->rc); 
-	ram_outb(card, ram+0, pcm->req); 
-
-        timeout = jiffies + 50;
-        while (timeout > jiffies) {
-		pcm->rc = ram_inb(card, ram+1);
-		pcm->req = ram_inb(card, ram+0);
-                if (!pcm->req) break;
-                SLEEP(10);
-        }
-
-	if (pcm->req) {
-		return XLOG_ERR_TIMEOUT;
-	}
-
-	if (pcm->rc != OK) {
-		return XLOG_ERR_DONE;
-	}
-	
-	ram_copyfromcard(card, pcm, ram, len);
-
-	if (stype) {
-		for (i=0; i<8; i++)
-			((__u8 *)pcm)[11-i] = ((__u8 *)pcm)[9-i];
-		time =	(__u32)pcm->data.w[2] * 3600 	* 1000 +
-			(__u32)pcm->data.w[1] 		* 1000 +
-			(__u32)pcm->data.b[1] 		* 20 +
-			(__u32)pcm->data.b[0]		;
-		pcm->data.w[1] = (__u16) (time >> 16);
-		pcm->data.w[2] = (__u16) (time & 0x0000ffff);
-		pcm->data.w[0] = 2;
+	if (de->complete == 255) {
+		/* Return Code */
+		skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);
+		if (!skb) {
+			eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _idi_callback()\n");
+		} else {
+			ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
+			ack->Rc = de->Rc;
+			if (de->Rc == ASSIGN_OK) {
+				ack->RcId = de->Id;
+				de->user[1] = de->Id;
+			} else {
+				ack->RcId = de->user[1];
+			}
+			ack->RcCh = de->RcCh;
+			ack->Reference = de->user[0];
+			skb_queue_tail(&ccard->rackq, skb);
+			eicon_schedule_ack(ccard);
+			eicon_log(ccard, 128, "idi_cbk: Ch%d: Rc=%x Id=%x RLen=%x compl=%x\n",
+				de->user[0], de->Rc, ack->RcId, de->RLength, de->complete);
+		}
+	} else {
+		/* Indication */
+		if (de->complete) {
+			len = de->RLength;
+		} else {
+			len = 270;
+			if (de->RLength <= 270)
+				eicon_log(ccard, 1, "eicon_cbk: ind not complete but <= 270\n");
+		}
+		skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);
+		if (!skb) {
+			eicon_log(ccard, 1, "eicon_io: skb_alloc failed in _idi_callback()\n");
+		} else {
+			ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
+			ind->Ind = de->Ind;
+			ind->IndId = de->user[1];
+			ind->IndCh = de->IndCh;
+			ind->MInd  = de->Ind;
+			ind->RBuffer.length = len;
+			ind->MLength = de->RLength;
+			memcpy(&ind->RBuffer.P, &de->RBuffer->P, len);
+			skb_queue_tail(&ccard->rcvq, skb);
+			eicon_schedule_rx(ccard);
+			eicon_log(ccard, 128, "idi_cbk: Ch%d: Ind=%x Id=%x RLen=%x compl=%x\n",
+				de->user[0], de->Ind, ind->IndId, de->RLength, de->complete);
+		}
 	}
 
-	return XLOG_OK;
+	de->RNum = 0;
+	de->RNR = 0;
+	de->Rc = 0;
+	de->Ind = 0;
 }
+#endif /* CONFIG_ISDN_DRV_EICON_PCI */
 
 /*
  *  Transmit-Function
  */
 void
 eicon_io_transmit(eicon_card *ccard) {
-        eicon_pci_card *pci_card;
         eicon_isa_card *isa_card;
         struct sk_buff *skb;
         struct sk_buff *skb2;
         unsigned long flags;
-        char *ram, *reg, *cfg;
 	eicon_pr_ram  *prram = 0;
 	eicon_isa_com	*com = 0;
 	eicon_REQ *ReqOut = 0;
@@ -426,10 +257,11 @@
 	int ReqCount;
 	int scom = 0;
 	int tmp = 0;
+	int tmpid = 0;
 	int quloop = 1;
 	int dlev = 0;
+	ENTITY *ep = 0;
 
-	pci_card = &ccard->hwif.pci;
 	isa_card = &ccard->hwif.isa;
 
         if (!ccard) {
@@ -451,20 +283,17 @@
 			prram = (eicon_pr_ram *)isa_card->shmem;
 			break;
 #endif
+#ifdef CONFIG_ISDN_DRV_EICON_PCI
 		case EICON_CTYPE_MAESTRAP:
-			scom = 0;
-        		ram = (char *)pci_card->PCIram;
-		        reg = (char *)pci_card->PCIreg;
-        		cfg = (char *)pci_card->PCIcfg;
-			prram = (eicon_pr_ram *)ram;
+			scom = 2;
+			break;
+		case EICON_CTYPE_MAESTRAQ:
+			scom = 2;
 			break;
 		case EICON_CTYPE_MAESTRA:
-			scom = 0;
-        		ram = (char *)pci_card->PCIram;
-		        reg = (char *)pci_card->PCIreg;
-        		cfg = (char *)pci_card->PCIcfg;
-			prram = 0;
+			scom = 2;
 			break;
+#endif
 		default:
                 	eicon_log(ccard, 1, "eicon_transmit: unsupported card-type!\n");
 			return;
@@ -474,69 +303,91 @@
 	if (!(skb2 = skb_dequeue(&ccard->sndq)))
 		quloop = 0; 
 	while(quloop) { 
-                save_flags(flags);
-                cli();
-		if (scom) {
+		spin_lock_irqsave(&eicon_lock, flags);
+		switch (scom) {
+		  case 1:
 			if ((ram_inb(ccard, &com->Req)) || (ccard->ReadyInt)) {
 				if (!ccard->ReadyInt) {
 					tmp = ram_inb(ccard, &com->ReadyInt) + 1;
 					ram_outb(ccard, &com->ReadyInt, tmp);
 					ccard->ReadyInt++;
 				}
-        	                restore_flags(flags);
+				spin_unlock_irqrestore(&eicon_lock, flags);
                 	        skb_queue_head(&ccard->sndq, skb2);
        	                	eicon_log(ccard, 32, "eicon: transmit: Card not ready\n");
 	                        return;
 			}
-		} else {
+			break;
+		  case 0:
 	                if (!(ram_inb(ccard, &prram->ReqOutput) - ram_inb(ccard, &prram->ReqInput))) {
-        	                restore_flags(flags);
+				spin_unlock_irqrestore(&eicon_lock, flags);
                 	        skb_queue_head(&ccard->sndq, skb2);
        	                	eicon_log(ccard, 32, "eicon: transmit: Card not ready\n");
 	                        return;
         	        }
+			break;
 		}
-		restore_flags(flags);
+		spin_unlock_irqrestore(&eicon_lock, flags);
+
 		chan2 = (eicon_chan_ptr *)skb2->data;
 		chan = chan2->ptr;
 		if (!chan->e.busy) {
 		 if((skb = skb_dequeue(&chan->e.X))) { 
-		  save_flags(flags);
-		  cli();
+
 		  reqbuf = (eicon_REQ *)skb->data;
 		  if ((reqbuf->Reference) && (chan->e.B2Id == 0) && (reqbuf->ReqId & 0x1f)) {
 			eicon_log(ccard, 16, "eicon: transmit: error Id=0 on %d (Net)\n", chan->No); 
 		  } else {
-			if (scom) {
+			spin_lock_irqsave(&eicon_lock, flags);
+
+			switch (scom) {
+			  case 1:
 				ram_outw(ccard, &com->XBuffer.length, reqbuf->XBuffer.length);
 				ram_copytocard(ccard, &com->XBuffer.P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
 				ram_outb(ccard, &com->ReqCh, reqbuf->ReqCh);
-				
-			} else {
+				break;	
+			  case 0:
 				/* get address of next available request buffer */
 				ReqOut = (eicon_REQ *)&prram->B[ram_inw(ccard, &prram->NextReq)];
 				ram_outw(ccard, &ReqOut->XBuffer.length, reqbuf->XBuffer.length);
 				ram_copytocard(ccard, &ReqOut->XBuffer.P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
 				ram_outb(ccard, &ReqOut->ReqCh, reqbuf->ReqCh);
 				ram_outb(ccard, &ReqOut->Req, reqbuf->Req); 
+				break;
 			}
+
 			dlev = 160;
+
 			if (reqbuf->ReqId & 0x1f) { /* if this is no ASSIGN */
 
 				if (!reqbuf->Reference) { /* Signal Layer */
-					if (scom)
+					switch (scom) {
+					  case 1:
 						ram_outb(ccard, &com->ReqId, chan->e.D3Id); 
-					else
+						break;
+					  case 0:
 						ram_outb(ccard, &ReqOut->ReqId, chan->e.D3Id); 
-
+						break;
+					  case 2:
+						ep = &chan->de;
+						break;
+					}
+					tmpid = chan->e.D3Id;
 					chan->e.ReqCh = 0; 
 				}
 				else {			/* Net Layer */
-					if (scom)
+					switch(scom) {
+					  case 1:
 						ram_outb(ccard, &com->ReqId, chan->e.B2Id); 
-					else
+						break;
+					  case 0:
 						ram_outb(ccard, &ReqOut->ReqId, chan->e.B2Id); 
-
+						break;
+					  case 2:
+						ep = &chan->be;
+						break;
+					}
+					tmpid = chan->e.B2Id;
 					chan->e.ReqCh = 1;
 					if (((reqbuf->Req & 0x0f) == 0x08) ||
 					   ((reqbuf->Req & 0x0f) == 0x01)) { /* Send Data */
@@ -548,51 +399,106 @@
 
 			} else {	/* It is an ASSIGN */
 
-				if (scom)
+				switch(scom) {
+				  case 1:
 					ram_outb(ccard, &com->ReqId, reqbuf->ReqId); 
-				else
+					break;
+				  case 0:
 					ram_outb(ccard, &ReqOut->ReqId, reqbuf->ReqId); 
+					break;
+				  case 2:
+					if (!reqbuf->Reference) 
+						ep = &chan->de;
+					else
+						ep = &chan->be;
+					ep->Id = reqbuf->ReqId;
+					break;
+				}
+				tmpid = reqbuf->ReqId;
 
 				if (!reqbuf->Reference) 
 					chan->e.ReqCh = 0; 
 				 else
 					chan->e.ReqCh = 1; 
 			} 
-			if (scom)
+
+			switch(scom) {
+			  case 1:
 			 	chan->e.ref = ccard->ref_out++;
-			else
+				break;
+			  case 0:
 			 	chan->e.ref = ram_inw(ccard, &ReqOut->Reference);
+				break;
+			  case 2:
+				chan->e.ref = chan->No;
+				break;
+			}
 
 			chan->e.Req = reqbuf->Req;
 			ReqCount++; 
-			if (scom)
+
+			switch (scom) {
+			  case 1:
 				ram_outb(ccard, &com->Req, reqbuf->Req); 
-			else
+				break;
+			  case 0:
 				ram_outw(ccard, &prram->NextReq, ram_inw(ccard, &ReqOut->next)); 
+				break;
+			  case 2:
+#ifdef CONFIG_ISDN_DRV_EICON_PCI
+				if (!ep) break;
+				ep->callback = eicon_idi_callback;
+				ep->R = (BUFFERS *)ccard;
+				ep->user[0] = (word)chan->No;
+				ep->user[1] = (word)tmpid;
+				ep->XNum = 1;
+				ep->RNum = 0;
+				ep->RNR = 0;
+				ep->Rc = 0;
+				ep->Ind = 0;
+				ep->X->PLength = reqbuf->XBuffer.length;
+				memcpy(ep->X->P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
+				ep->ReqCh = reqbuf->ReqCh;
+				ep->Req = reqbuf->Req;
+#endif
+				break;
+			}
 
 			chan->e.busy = 1;
+			spin_unlock_irqrestore(&eicon_lock, flags);
 	               	eicon_log(ccard, dlev, "eicon: Req=%d Id=%x Ch=%d Len=%d Ref=%d\n", 
-					reqbuf->Req, 
-					(scom) ? ram_inb(ccard, &com->ReqId) :
-						ram_inb(ccard, &ReqOut->ReqId),
+					reqbuf->Req, tmpid, 
 					reqbuf->ReqCh, reqbuf->XBuffer.length,
 					chan->e.ref); 
+#ifdef CONFIG_ISDN_DRV_EICON_PCI
+			if (scom == 2) {
+				if (ep) {
+					ccard->d->request(ep);
+					if (ep->Rc)
+						eicon_idi_callback(ep);
+				}
+			}
+#endif
 		  }
-		  restore_flags(flags);
 		  dev_kfree_skb(skb);
 		 }
 		 dev_kfree_skb(skb2);
 		} 
 		else {
-		skb_queue_tail(&ccard->sackq, skb2);
-               	eicon_log(ccard, 128, "eicon: transmit: busy chan %d\n", chan->No); 
+			skb_queue_tail(&ccard->sackq, skb2);
+        	       	eicon_log(ccard, 128, "eicon: transmit: busy chan %d\n", chan->No); 
 		}
 
-		if (scom)
-			quloop = 0;
-		else
-			if (!(skb2 = skb_dequeue(&ccard->sndq)))
+		switch(scom) {
+			case 1:
 				quloop = 0;
+				break;
+			case 0:
+			case 2:
+				if (!(skb2 = skb_dequeue(&ccard->sndq)))
+					quloop = 0;
+				break;
+		}
 
 	}
 	if (!scom)
@@ -603,18 +509,14 @@
 	}
 }
 
-
+#ifdef CONFIG_ISDN_DRV_EICON_ISA
 /*
  * IRQ handler 
  */
 void
 eicon_irq(int irq, void *dev_id, struct pt_regs *regs) {
 	eicon_card *ccard = (eicon_card *)dev_id;
-        eicon_pci_card *pci_card;
         eicon_isa_card *isa_card;
-    	char *ram = 0;
-	char *reg = 0;
-	char *cfg = 0;	
 	eicon_pr_ram  *prram = 0;
 	eicon_isa_com	*com = 0;
         eicon_RC *RcIn;
@@ -646,11 +548,9 @@
 		}
 	}
 
-	pci_card = &ccard->hwif.pci;
 	isa_card = &ccard->hwif.isa;
 
 	switch(ccard->type) {
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
 		case EICON_CTYPE_S:
 		case EICON_CTYPE_SX:
 		case EICON_CTYPE_SCOM:
@@ -664,23 +564,6 @@
 			prram = (eicon_pr_ram *)isa_card->shmem;
 			irqprobe = &isa_card->irqprobe;
 			break;
-#endif
-		case EICON_CTYPE_MAESTRAP:
-			scom = 0;
-			ram = (char *)pci_card->PCIram;
-			reg = (char *)pci_card->PCIreg;
-			cfg = (char *)pci_card->PCIcfg;
-			irqprobe = &pci_card->irqprobe;
-			prram = (eicon_pr_ram *)ram;
-			break;
-		case EICON_CTYPE_MAESTRA:
-			scom = 0;
-			ram = (char *)pci_card->PCIram;
-			reg = (char *)pci_card->PCIreg;
-			cfg = (char *)pci_card->PCIcfg;
-			irqprobe = &pci_card->irqprobe;
-			prram = 0;
-			break;
 		default:
                 	eicon_log(ccard, 1, "eicon_irq: unsupported card-type!\n");
 			return;
@@ -688,7 +571,6 @@
 
 	if (*irqprobe) {
 		switch(ccard->type) {
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
 			case EICON_CTYPE_S:
 			case EICON_CTYPE_SX:
 			case EICON_CTYPE_SCOM:
@@ -706,26 +588,11 @@
 				}
 				(*irqprobe)++;
 				break;
-#endif
-			case EICON_CTYPE_MAESTRAP:
-	        		if (readb(&ram[0x3fe])) { 
-        		               	writeb(0, &prram->RcOutput);
-				        writew(MP_IRQ_RESET_VAL, &cfg[MP_IRQ_RESET]);
-				        writew(0, &cfg[MP_IRQ_RESET + 2]);
-					writeb(0, &ram[0x3fe]);
-       			        } 
-				*irqprobe = 0;
-				break;
-			case EICON_CTYPE_MAESTRA:
-				outb(0x08, pci_card->PCIreg + M_RESET);
-				*irqprobe = 0;
-				break;
 		}
 		return;
 	}
 
 	switch(ccard->type) {
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
 		case EICON_CTYPE_S:
 		case EICON_CTYPE_SX:
 		case EICON_CTYPE_SCOM:
@@ -736,20 +603,6 @@
 				return;
 			} 
 			break;
-#endif
-		case EICON_CTYPE_MAESTRAP:
-			if (!(readb(&ram[0x3fe]))) { /* card did not interrupt */
-				eicon_log(ccard, 1, "eicon: IRQ: card reports no interrupt!\n");
-				return;
-			} 
-			break;
-		case EICON_CTYPE_MAESTRA:
-			outw(0x3fe, pci_card->PCIreg + M_ADDR);
-			if (!(inb(pci_card->PCIreg + M_DATA))) { /* card did not interrupt */
-				eicon_log(ccard, 1, "eicon: IRQ: card reports no interrupt!\n");
-				return;
-			} 
-			break;
 	}
 
     if (scom) {
@@ -891,7 +744,6 @@
 
 	/* clear interrupt */
 	switch(ccard->type) {
-#ifdef CONFIG_ISDN_DRV_EICON_ISA
 		case EICON_CTYPE_QUADRO:
 			writeb(0, isa_card->intack);
 			writeb(0, &com[0x401]);
@@ -902,19 +754,8 @@
 		case EICON_CTYPE_S2M:
 			writeb(0, isa_card->intack);
 			break;
-#endif
-		case EICON_CTYPE_MAESTRAP:
-			writew(MP_IRQ_RESET_VAL, &cfg[MP_IRQ_RESET]);
-			writew(0, &cfg[MP_IRQ_RESET + 2]); 
-			writeb(0, &ram[0x3fe]); 
-			break;
-		case EICON_CTYPE_MAESTRA:
-			outb(0x08, pci_card->PCIreg + M_RESET);
-			outw(0x3fe, pci_card->PCIreg + M_ADDR);
-			outb(0, pci_card->PCIreg + M_DATA);
-			break;
 	}
 
   return;
 }
-
+#endif

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)