patch-2.0.1 linux/drivers/isdn/teles/card.c
Next file: linux/drivers/net/de4x5.c
Previous file: linux/drivers/isdn/teles/callc.c
Back to the patch index
Back to the overall index
- Lines: 208
- Date:
Sat Jun 29 20:36:23 1996
- Orig file:
v2.0.0/linux/drivers/isdn/teles/card.c
- Orig date:
Sun Jun 9 13:28:43 1996
diff -u --recursive --new-file v2.0.0/linux/drivers/isdn/teles/card.c linux/drivers/isdn/teles/card.c
@@ -1,4 +1,4 @@
-/* $Id: card.c,v 1.9 1996/06/06 14:42:09 fritz Exp $
+/* $Id: card.c,v 1.12 1996/06/24 17:16:52 fritz Exp $
*
* card.c low level stuff for the Teles S0 isdn card
*
@@ -7,6 +7,16 @@
* Beat Doebeli log all D channel traffic
*
* $Log: card.c,v $
+ * Revision 1.12 1996/06/24 17:16:52 fritz
+ * Added check for misconfigured membase.
+ *
+ * Revision 1.11 1996/06/14 03:30:37 fritz
+ * Added recovery from EXIR 40 interrupt.
+ * Some cleanup.
+ *
+ * Revision 1.10 1996/06/11 14:57:20 hipp
+ * minor changes to ensure, that SKBs are sent in the right order
+ *
* Revision 1.9 1996/06/06 14:42:09 fritz
* Bugfix: forgot hsp-> in last change.
*
@@ -52,7 +62,6 @@
#include <linux/interrupt.h>
#undef DCHAN_VERBOSE
-#define FRITZ_EXPERIMENTAL
extern void tei_handler(struct PStack *st, byte pr,
struct BufHeader *ibh);
@@ -215,16 +224,9 @@
static inline void
waitforXFW_0(byte * base, byte hscx)
{
-#ifdef FRITZ_EXPERIMENTAL
long to = 20;
while ((!(readhscx_0(base, hscx, HSCX_STAR) & 0x44)==0x40) && to) {
-#else
- long to = 10;
-
- waitforCEC_0(base, hscx);
- while ((!(readhscx_0(base, hscx, HSCX_STAR) & 0x40)) && to) {
-#endif
udelay(5);
to--;
}
@@ -235,16 +237,9 @@
static inline void
waitforXFW_3(int iobase, byte hscx)
{
-#ifdef FRITZ_EXPERIMENTAL
long to = 20;
while ((!(readhscx_3(iobase, hscx, HSCX_STAR) & 0x44)==0x40) && to) {
-#else
- long to = 10;
-
- waitforCEC_3(iobase, hscx);
- while ((!(readhscx_3(iobase, hscx, HSCX_STAR) & 0x40)) && to) {
-#endif
udelay(5);
to--;
}
@@ -507,10 +502,10 @@
} else {
if (hsp->releasebuf)
BufPoolRelease(hsp->xmtibh);
- hsp->xmtibh = NULL;
hsp->sendptr = 0;
if (hsp->st->l4.l1writewakeup)
hsp->st->l4.l1writewakeup(hsp->st);
+ hsp->xmtibh = NULL;
}
if (!BufQueueUnlink(&hsp->xmtibh, &hsp->sq)) {
hsp->releasebuf = !0;
@@ -709,7 +704,7 @@
static void
teles_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
- byte val, val2, r, exval;
+ byte val, r, exval;
struct IsdnCardState *sp;
unsigned int count;
struct HscxState *hsp;
@@ -725,11 +720,20 @@
if (val & 0x01) {
hsp = sp->hs + 1;
exval = READHSCX(sp->membase, sp->iobase, 1, HSCX_EXIR);
- if ((hsp->mode == 1) || (exval == 0x40))
- hscx_fill_fifo(hsp);
- else
- printk(KERN_WARNING "HSCX B EXIR %x xmitbh %lx rcvibh %lx\n",
- exval, (long) hsp->xmtibh, (long) hsp->rcvibh);
+ if (exval == 0x40) {
+ if (hsp->mode == 1)
+ hscx_fill_fifo(hsp);
+ else {
+ /* Here we lost an TX interrupt, so
+ * restart transmitting the whole frame.
+ */
+ hsp->sendptr = 0;
+ WRITEHSCX_CMDR(hsp->membase, hsp->iobase,
+ hsp->hscx, 0x01);
+ printk(KERN_DEBUG "HSCX B EXIR %x\n", exval);
+ }
+ } else
+ printk(KERN_WARNING "HSCX B EXIR %x\n", exval);
}
if (val & 0xf8) {
if (sp->debug)
@@ -739,33 +743,28 @@
if (val & 0x02) {
hsp = sp->hs;
exval = READHSCX(sp->membase, sp->iobase, 0, HSCX_EXIR);
- if ((hsp->mode == 1) && (exval == 0x40))
- hscx_fill_fifo(hsp);
- else
- printk(KERN_WARNING "HSCX A EXIR %x\n",exval);
+ if (exval == 0x40) {
+ if (hsp->mode == 1)
+ hscx_fill_fifo(hsp);
+ else {
+ /* Here we lost an TX interrupt, so
+ * restart transmitting the whole frame.
+ */
+ hsp->sendptr = 0;
+ WRITEHSCX_CMDR(hsp->membase, hsp->iobase,
+ hsp->hscx, 0x01);
+ printk(KERN_DEBUG "HSCX A EXIR %x\n", exval);
+ }
+ } else
+ printk(KERN_WARNING "HSCX A EXIR %x\n", exval);
}
-
-/* ??? Why do that vvvvvvvvvvvvvvvvvvvvv different on Teles 16-3 ??? */
- if (sp->membase) {
- if (val & 0x04) {
- val = readhscx_0(sp->membase, 0, HSCX_ISTA);
- if (sp->debug)
- printk(KERN_DEBUG "HSCX A interrupt %x\n",
- val);
- hscx_interrupt(sp, val, 0);
- }
- } else {
- val2 = readhscx_3(sp->iobase, 0, HSCX_ISTA);
+ if (val & 0x04) {
+ val = READHSCX(sp->membase, sp->iobase, 0, HSCX_ISTA);
if (sp->debug)
- printk(KERN_DEBUG "HSCX A ISTA %x\n", val2);
- if (val & 0x04) {
- if (sp->debug)
- printk(KERN_DEBUG "HSCX A interrupt %x\n",
- val2);
- hscx_interrupt(sp, val2, 0);
- }
+ printk(KERN_DEBUG "HSCX A interrupt %x\n",
+ val);
+ hscx_interrupt(sp, val, 0);
}
-/* ??? Why do that ^^^^^^^^^^^^^^^^^^^^^ different on Teles 16-3 ??? */
val = READISAC(sp->membase, sp->iobase, ISAC_ISTA);
@@ -1083,6 +1082,13 @@
byte cfval, val;
struct IsdnCard *card = cards + cardnr;
+ if (card->membase)
+ if ((unsigned long)card->membase < 0x10000) {
+ (unsigned long)card->membase <<= 4;
+ printk(KERN_INFO
+ "Teles membase configured DOSish, assuming 0x%lx\n",
+ (unsigned long)card->membase);
+ }
if (!card->iobase) {
if (card->membase) {
printk(KERN_NOTICE
@@ -1090,7 +1096,7 @@
(long) card->membase, card->interrupt,
(card->protocol == ISDN_PTYPE_1TR6) ?
"1TR6" : "EDSS1");
- printk(KERN_INFO "HSCX version A: %x B:%x\n",
+ printk(KERN_INFO "HSCX version A:%x B:%x\n",
readhscx_0(card->membase, 0, HSCX_VSTR) & 0xf,
readhscx_0(card->membase, 1, HSCX_VSTR) & 0xf);
}
@@ -1736,12 +1742,18 @@
struct IsdnCardState *sp = (struct IsdnCardState *)
st->l1.hardware;
struct HscxState *hsp = sp->hs + st->l1.hscx;
+ long flags;
switch (pr) {
case (PH_DATA):
- if (hsp->xmtibh)
+ save_flags(flags);
+ cli();
+ if (hsp->xmtibh) {
BufQueueLink(&hsp->sq, ibh);
+ restore_flags(flags);
+ }
else {
+ restore_flags(flags);
hsp->xmtibh = ibh;
hsp->sendptr = 0;
hsp->releasebuf = !0;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov