patch-2.2.13 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
- Lines: 369
- Date:
Tue Oct 19 17:14:00 1999
- Orig file:
v2.2.12/linux/drivers/isdn/eicon/eicon_io.c
- Orig date:
Tue Oct 19 17:10:37 1999
diff -u --recursive --new-file v2.2.12/linux/drivers/isdn/eicon/eicon_io.c linux/drivers/isdn/eicon/eicon_io.c
@@ -1,4 +1,4 @@
-/* $Id: eicon_io.c,v 1.2 1999/07/25 15:12:05 armin Exp $
+/* $Id: eicon_io.c,v 1.5 1999/08/31 11:20:11 paul Exp $
*
* ISDN low-level module for Eicon.Diehl active ISDN-Cards.
* Code for communicating with hardware.
@@ -24,6 +24,19 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: eicon_io.c,v $
+ * 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.
@@ -36,6 +49,7 @@
*/
+#include <linux/config.h>
#include "eicon.h"
void
@@ -60,7 +74,7 @@
/* doesn't matter if this happens */
break;
default:
- printk(KERN_ERR "idi: Indication for unknown channel Ind=%d Id=%d\n", ind->Ind, ind->IndId);
+ printk(KERN_ERR "idi: Indication for unknown channel Ind=%d Id=%x\n", ind->Ind, ind->IndId);
printk(KERN_DEBUG "idi_hdl: Ch??: Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",
ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length);
}
@@ -88,12 +102,18 @@
if (DebugVar & 1)
printk(KERN_ERR "eicon: buffer incomplete, but 0 in queue\n");
dev_kfree_skb(skb);
- dev_kfree_skb(skb2);
continue;
}
ind2 = (eicon_IND *)skb2->data;
skb_new = alloc_skb(((sizeof(eicon_IND)-1)+ind->RBuffer.length+ind2->RBuffer.length),
GFP_ATOMIC);
+ if (!skb_new) {
+ if (DebugVar & 1)
+ printk(KERN_ERR "eicon_io: skb_alloc failed in rcv_dispatch()\n");
+ dev_kfree_skb(skb);
+ dev_kfree_skb(skb2);
+ continue;
+ }
ind_new = (eicon_IND *)skb_put(skb_new,
((sizeof(eicon_IND)-1)+ind->RBuffer.length+ind2->RBuffer.length));
ind_new->Ind = ind2->Ind;
@@ -276,6 +296,92 @@
}
/*
+ * XLOG
+ */
+int
+eicon_get_xlog(eicon_card *card, xlogreq_t *xlogreq)
+{
+ int timeout, i;
+ int divas_shared_offset = 0;
+ 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;
+ }
+
+ return XLOG_OK;
+}
+
+/*
* Transmit-Function
*/
void
@@ -372,9 +478,13 @@
chan = chan2->ptr;
if (!chan->e.busy) {
if((skb = skb_dequeue(&chan->e.X))) {
- save_flags(flags);
- cli();
- reqbuf = (eicon_REQ *)skb->data;
+ save_flags(flags);
+ cli();
+ reqbuf = (eicon_REQ *)skb->data;
+ if ((reqbuf->Reference) && (chan->e.B2Id == 0) && (reqbuf->ReqId & 0x1f)) {
+ if (DebugVar & 16)
+ printk(KERN_WARNING "eicon: transmit: error Id=0 on %d (Net)\n", chan->No);
+ } else {
if (scom) {
ram_outw(ccard, &com->XBuffer.length, reqbuf->XBuffer.length);
ram_copytocard(ccard, &com->XBuffer.P, &reqbuf->XBuffer.P, reqbuf->XBuffer.length);
@@ -389,7 +499,7 @@
ram_outb(ccard, &ReqOut->Req, reqbuf->Req);
}
- if (reqbuf->ReqId &0x1f) { /* if this is no ASSIGN */
+ if (reqbuf->ReqId & 0x1f) { /* if this is no ASSIGN */
if (!reqbuf->Reference) { /* Signal Layer */
if (scom)
@@ -438,14 +548,15 @@
ram_outw(ccard, &prram->NextReq, ram_inw(ccard, &ReqOut->next));
chan->e.busy = 1;
- restore_flags(flags);
if (DebugVar & 32)
printk(KERN_DEBUG "eicon: Req=%d Id=%x Ch=%d Len=%d Ref=%d\n",
reqbuf->Req,
ram_inb(ccard, &ReqOut->ReqId),
reqbuf->ReqCh, reqbuf->XBuffer.length,
chan->e.ref);
- dev_kfree_skb(skb);
+ }
+ restore_flags(flags);
+ dev_kfree_skb(skb);
}
dev_kfree_skb(skb2);
}
@@ -599,7 +710,7 @@
case EICON_CTYPE_S2M:
if (!(readb(isa_card->intack))) { /* card did not interrupt */
if (DebugVar & 1)
- printk(KERN_DEBUG "eicon: IRQ: card tells no interrupt!\n");
+ printk(KERN_DEBUG "eicon: IRQ: card reports no interrupt!\n");
return;
}
break;
@@ -607,7 +718,7 @@
case EICON_CTYPE_MAESTRAP:
if (!(readb(&ram[0x3fe]))) { /* card did not interrupt */
if (DebugVar & 1)
- printk(KERN_DEBUG "eicon: IRQ: card tells no interrupt!\n");
+ printk(KERN_DEBUG "eicon: IRQ: card reports no interrupt!\n");
return;
}
break;
@@ -615,7 +726,7 @@
outw(0x3fe, pci_card->PCIreg + M_ADDR);
if (!(inb(pci_card->PCIreg + M_DATA))) { /* card did not interrupt */
if (DebugVar & 1)
- printk(KERN_DEBUG "eicon: IRQ: card tells no interrupt!\n");
+ printk(KERN_DEBUG "eicon: IRQ: card reports no interrupt!\n");
return;
}
break;
@@ -635,16 +746,21 @@
}
} else {
skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);
- ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
- ack->Rc = tmp;
- ack->RcId = ram_inb(ccard, &com->RcId);
- ack->RcCh = ram_inb(ccard, &com->RcCh);
- ack->Reference = ccard->ref_in++;
- if (DebugVar & 64)
- printk(KERN_INFO "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n",
- tmp,ack->RcId,ack->RcCh,ack->Reference);
- skb_queue_tail(&ccard->rackq, skb);
- eicon_schedule_ack(ccard);
+ if (!skb) {
+ if (DebugVar & 1)
+ printk(KERN_ERR "eicon_io: skb_alloc failed in _irq()\n");
+ } else {
+ ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
+ ack->Rc = tmp;
+ ack->RcId = ram_inb(ccard, &com->RcId);
+ ack->RcCh = ram_inb(ccard, &com->RcCh);
+ ack->Reference = ccard->ref_in++;
+ if (DebugVar & 64)
+ printk(KERN_INFO "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n",
+ tmp,ack->RcId,ack->RcCh,ack->Reference);
+ skb_queue_tail(&ccard->rackq, skb);
+ eicon_schedule_ack(ccard);
+ }
ram_outb(ccard, &com->Req, 0);
ram_outb(ccard, &com->Rc, 0);
}
@@ -656,19 +772,24 @@
eicon_IND *ind;
int len = ram_inw(ccard, &com->RBuffer.length);
skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);
- ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
- ind->Ind = tmp;
- ind->IndId = ram_inb(ccard, &com->IndId);
- ind->IndCh = ram_inb(ccard, &com->IndCh);
- ind->MInd = ram_inb(ccard, &com->MInd);
- ind->MLength = ram_inw(ccard, &com->MLength);
- ind->RBuffer.length = len;
- if (DebugVar & 64)
- printk(KERN_INFO "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",
- tmp,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len);
- ram_copyfromcard(ccard, &ind->RBuffer.P, &com->RBuffer.P, len);
- skb_queue_tail(&ccard->rcvq, skb);
- eicon_schedule_rx(ccard);
+ if (!skb) {
+ if (DebugVar & 1)
+ printk(KERN_ERR "eicon_io: skb_alloc failed in _irq()\n");
+ } else {
+ ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
+ ind->Ind = tmp;
+ ind->IndId = ram_inb(ccard, &com->IndId);
+ ind->IndCh = ram_inb(ccard, &com->IndCh);
+ ind->MInd = ram_inb(ccard, &com->MInd);
+ ind->MLength = ram_inw(ccard, &com->MLength);
+ ind->RBuffer.length = len;
+ if (DebugVar & 64)
+ printk(KERN_INFO "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",
+ tmp,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len);
+ ram_copyfromcard(ccard, &ind->RBuffer.P, &com->RBuffer.P, len);
+ skb_queue_tail(&ccard->rcvq, skb);
+ eicon_schedule_rx(ccard);
+ }
ram_outb(ccard, &com->Ind, 0);
}
}
@@ -685,17 +806,22 @@
if((Rc=ram_inb(ccard, &RcIn->Rc))) {
skb = alloc_skb(sizeof(eicon_RC), GFP_ATOMIC);
- ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
- ack->Rc = Rc;
- ack->RcId = ram_inb(ccard, &RcIn->RcId);
- ack->RcCh = ram_inb(ccard, &RcIn->RcCh);
- ack->Reference = ram_inw(ccard, &RcIn->Reference);
- if (DebugVar & 64)
- printk(KERN_INFO "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n",
- Rc,ack->RcId,ack->RcCh,ack->Reference);
- ram_outb(ccard, &RcIn->Rc, 0);
- skb_queue_tail(&ccard->rackq, skb);
- eicon_schedule_ack(ccard);
+ if (!skb) {
+ if (DebugVar & 1)
+ printk(KERN_ERR "eicon_io: skb_alloc failed in _irq()\n");
+ } else {
+ ack = (eicon_RC *)skb_put(skb, sizeof(eicon_RC));
+ ack->Rc = Rc;
+ ack->RcId = ram_inb(ccard, &RcIn->RcId);
+ ack->RcCh = ram_inb(ccard, &RcIn->RcCh);
+ ack->Reference = ram_inw(ccard, &RcIn->Reference);
+ if (DebugVar & 64)
+ printk(KERN_INFO "eicon: IRQ Rc=%d Id=%x Ch=%d Ref=%d\n",
+ Rc,ack->RcId,ack->RcCh,ack->Reference);
+ skb_queue_tail(&ccard->rackq, skb);
+ eicon_schedule_ack(ccard);
+ }
+ ram_outb(ccard, &RcIn->Rc, 0);
}
/* get buffer address of next return code */
RcIn = (eicon_RC *)&prram->B[ram_inw(ccard, &RcIn->next)];
@@ -715,19 +841,24 @@
if(Ind) {
int len = ram_inw(ccard, &IndIn->RBuffer.length);
skb = alloc_skb((sizeof(eicon_IND) + len - 1), GFP_ATOMIC);
- ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
- ind->Ind = Ind;
- ind->IndId = ram_inb(ccard, &IndIn->IndId);
- ind->IndCh = ram_inb(ccard, &IndIn->IndCh);
- ind->MInd = ram_inb(ccard, &IndIn->MInd);
- ind->MLength = ram_inw(ccard, &IndIn->MLength);
- ind->RBuffer.length = len;
- if (DebugVar & 64)
- printk(KERN_INFO "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",
- Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len);
- ram_copyfromcard(ccard, &ind->RBuffer.P, &IndIn->RBuffer.P, len);
- skb_queue_tail(&ccard->rcvq, skb);
- eicon_schedule_rx(ccard);
+ if (!skb) {
+ if (DebugVar & 1)
+ printk(KERN_ERR "eicon_io: skb_alloc failed in _irq()\n");
+ } else {
+ ind = (eicon_IND *)skb_put(skb, (sizeof(eicon_IND) + len - 1));
+ ind->Ind = Ind;
+ ind->IndId = ram_inb(ccard, &IndIn->IndId);
+ ind->IndCh = ram_inb(ccard, &IndIn->IndCh);
+ ind->MInd = ram_inb(ccard, &IndIn->MInd);
+ ind->MLength = ram_inw(ccard, &IndIn->MLength);
+ ind->RBuffer.length = len;
+ if (DebugVar & 64)
+ printk(KERN_INFO "eicon: IRQ Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n",
+ Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,len);
+ ram_copyfromcard(ccard, &ind->RBuffer.P, &IndIn->RBuffer.P, len);
+ skb_queue_tail(&ccard->rcvq, skb);
+ eicon_schedule_rx(ccard);
+ }
ram_outb(ccard, &IndIn->Ind, 0);
}
/* get buffer address of next indication */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)