patch-pre2.0.6 linux/drivers/isdn/teles/card.c
Next file: linux/drivers/isdn/teles/fsm.c
Previous file: linux/drivers/isdn/teles/callc.c
Back to the patch index
Back to the overall index
- Lines: 439
- Date:
Sun May 19 15:29:30 1996
- Orig file:
pre2.0.5/linux/drivers/isdn/teles/card.c
- Orig date:
Mon Apr 29 18:05:17 1996
diff -u --recursive --new-file pre2.0.5/linux/drivers/isdn/teles/card.c linux/drivers/isdn/teles/card.c
@@ -1,4 +1,4 @@
-/* $Id: card.c,v 1.1 1996/04/13 10:22:42 fritz Exp $
+/* $Id: card.c,v 1.5 1996/05/17 03:45:02 fritz Exp $
*
* card.c low level stuff for the Teles S0 isdn card
*
@@ -7,6 +7,28 @@
* Beat Doebeli log all D channel traffic
*
* $Log: card.c,v $
+ * Revision 1.5 1996/05/17 03:45:02 fritz
+ * Made error messages more clearly.
+ * Bugfix: Only 31 bytes of 32-byte audio frames
+ * have been transfered to upper layers.
+ *
+ * Revision 1.4 1996/05/06 10:17:57 fritz
+ * Added voice-send stuff
+ * (Not reporting EXIR when in voice-mode, since it's normal).
+ *
+ * Revision 1.3 1996/04/30 22:02:40 isdn4dev
+ * Bugfixes for 16.3
+ * -improved IO allocation
+ * -fix second B channel problem
+ * -correct ph_command patch
+ *
+ * Revision 1.2 1996/04/30 10:00:59 fritz
+ * Bugfix: Added ph_command(8) for 16.3.
+ * Bugfix: Ports did not get registered correctly
+ * when using a 16.3.
+ * Started voice support.
+ * Some experimental changes of waitforXFW().
+ *
* Revision 1.1 1996/04/13 10:22:42 fritz
* Initial revision
*
@@ -21,6 +43,7 @@
#include <linux/interrupt.h>
#undef DCHAN_VERBOSE
+#define FRITZ_EXPERIMENTAL
extern void tei_handler(struct PStack *st, byte pr,
struct BufHeader *ibh);
@@ -183,11 +206,16 @@
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--;
}
@@ -198,11 +226,16 @@
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--;
}
@@ -332,15 +365,6 @@
readhscx_s(hsp->iobase, hsp->hscx, 0x3e, ptr, count);
writehscxCMDR_3(hsp->iobase, hsp->hscx, 0x80);
}
-#ifdef BCHAN_VERBOSE
- {
- int i;
- printk(KERN_DEBUG "hscx_empty_fifo");
- for (i = 0; i < count; i++)
- printk(" %2x", ptr[i]);
- printk("\n");
- }
-#endif /* BCHAN_VERBOSE */
}
static void
@@ -361,15 +385,7 @@
if (count <= 0)
return;
-#if 0
- if (!hsp->sendptr) {
- ptr = DATAPTR(ibh);
- printk(KERN_DEBUG "snd bytes %2x %2x %2x %2x %2x\n", ptr[0], ptr[1], ptr[2],
- ptr[3], ptr[4]);
- }
-#endif
-
- more = 0;
+ more = (hsp->mode == 1)?1:0;
if (count > 32) {
more = !0;
count = 32;
@@ -417,7 +433,7 @@
printk(KERN_WARNING
"Teles: HSCX invalid frame\n");
if (r & 0x40)
- printk(KERN_WARNING "Teles: HSCX RDO\n");
+ printk(KERN_WARNING "Teles: HSCX RDO mode=%d\n",hsp->mode);
if (!r & 0x20)
printk(KERN_WARNING "Teles: HSCX CRC error\n");
if (hsp->rcvibh)
@@ -455,7 +471,7 @@
if (BufPoolGet(&hsp->rcvibh, &hsp->rbufpool,
GFP_ATOMIC, (void *) 1, 2)) {
printk(KERN_WARNING
- "HSCX RME out of buffers at %ld\n",
+ "HSCX RPF out of buffers at %ld\n",
jiffies);
WRITEHSCX_CMDR(hsp->membase, hsp->iobase,
hsp->hscx, 0x80);
@@ -464,12 +480,14 @@
hsp->rcvptr = 0;
hscx_empty_fifo(hsp, 32);
-#ifdef VOICE
- hsp->rcvibh->datasize = hsp->rcvptr - 1;
- BufQueueLink(&hsp->rq, hsp->rcvibh);
- hsp->rcvibh = NULL;
- hscx_sched_event(hsp, HSCX_RCVBUFREADY);
-#endif
+ if (hsp->mode == 1) {
+ /* receive audio data */
+ hsp->rcvibh->datasize = hsp->rcvptr;
+ BufQueueLink(&hsp->rq, hsp->rcvibh);
+ hsp->rcvibh = NULL;
+ hscx_sched_event(hsp, HSCX_RCVBUFREADY);
+ }
+
}
afterRPF:
if (val & 0x10) { /* XPR */
@@ -651,8 +669,17 @@
ph_command(sp, 9);
break;
case (12):
+ ph_command(sp, 8);
+ sp->ph_active = 5;
+ isac_sched_event(sp, ISAC_PHCHANGE);
+ if (!sp->xmtibh)
+ if (!BufQueueUnlink(&sp->xmtibh, &sp->sq))
+ sp->sendptr = 0;
+ if (sp->xmtibh)
+ fill_fifo(sp);
+ break;
case (13):
- ph_command(sp, 8);
+ ph_command(sp, 9);
sp->ph_active = 5;
isac_sched_event(sp, ISAC_PHCHANGE);
if (!sp->xmtibh)
@@ -673,7 +700,7 @@
static void
teles_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
- byte val, val2, r;
+ byte val, val2, r, exval;
struct IsdnCardState *sp;
unsigned int count;
struct HscxState *hsp;
@@ -688,10 +715,12 @@
if (val & 0x01) {
hsp = sp->hs + 1;
- printk(KERN_WARNING "HSCX B EXIR %x xmitbh %lx rcvibh %lx\n",
- READHSCX(sp->membase, sp->iobase, 1, HSCX_EXIR),
- (long) hsp->xmtibh,
- (long) hsp->rcvibh);
+ 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 (val & 0xf8) {
if (sp->debug)
@@ -699,8 +728,12 @@
hscx_interrupt(sp, val, 1);
}
if (val & 0x02) {
- printk(KERN_WARNING "HSCX A EXIR %x\n",
- READHSCX(sp->membase, sp->iobase, 0, HSCX_EXIR));
+ 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);
}
/* ??? Why do that vvvvvvvvvvvvvvvvvvvvv different on Teles 16-3 ??? */
@@ -1057,17 +1090,46 @@
case 0x180:
case 0x280:
case 0x380:
- printk(KERN_INFO "teles: port 0x%x specified, assuming 0x%x\n",
- card->iobase, (card->iobase | 0xc00));
card->iobase |= 0xc00;
break;
}
- if (check_region(card->iobase, 8)) {
- printk(KERN_WARNING
- "teles: ports %x-%x already in use\n",
- card->iobase,
- card->iobase + 8 );
- return -1;
+ if (card->membase) { /* 16.0 */
+ if (check_region(card->iobase, 8)) {
+ printk(KERN_WARNING
+ "teles: ports %x-%x already in use\n",
+ card->iobase,
+ card->iobase + 8 );
+ return -1;
+ }
+ } else { /* 16.3 */
+ if (check_region(card->iobase, 16)) {
+ printk(KERN_WARNING
+ "teles: 16.3 ports %x-%x already in use\n",
+ card->iobase,
+ card->iobase + 16 );
+ return -1;
+ }
+ if (check_region((card->iobase - 0xc00) , 32)) {
+ printk(KERN_WARNING
+ "teles: 16.3 ports %x-%x already in use\n",
+ card->iobase - 0xc00,
+ card->iobase - 0xc00 + 32);
+ return -1;
+ }
+ if (check_region((card->iobase - 0x800) , 32)) {
+ printk(KERN_WARNING
+ "teles: 16.3 ports %x-%x already in use\n",
+ card->iobase - 0x800,
+ card->iobase - 0x800 + 32);
+ return -1;
+ }
+ if (check_region((card->iobase - 0x400) , 32)) {
+ printk(KERN_WARNING
+ "teles: 16.3 ports %x-%x already in use\n",
+ card->iobase - 0x400,
+ card->iobase - 0x400 + 32);
+ return -1;
+ }
}
switch (card->interrupt) {
case 2:
@@ -1100,30 +1162,37 @@
}
if (card->membase) {
cfval |= (((unsigned int) card->membase >> 9) & 0xF0);
-
- if (bytein(card->iobase + 0) != 0x51) {
- printk(KERN_INFO "XXX Byte at %x is %x\n",
- card->iobase + 0,
- bytein(card->iobase + 0));
- return -2;
- }
- if (bytein(card->iobase + 1) != 0x93) {
- printk(KERN_INFO "XXX Byte at %x is %x\n",
- card->iobase + 1,
- bytein(card->iobase + 1));
- return -2;
- }
- val = bytein(card->iobase + 2); /* 0x1e=without AB
- * 0x1f=with AB
- */
- if (val != 0x1e && val != 0x1f) {
- printk(KERN_INFO "XXX Byte at %x is %x\n",
- card->iobase + 2,
- bytein(card->iobase + 2));
- return -2;
- }
+ }
+ if (bytein(card->iobase + 0) != 0x51) {
+ printk(KERN_INFO "XXX Byte at %x is %x\n",
+ card->iobase + 0,
+ bytein(card->iobase + 0));
+ return -2;
+ }
+ if (bytein(card->iobase + 1) != 0x93) {
+ printk(KERN_INFO "XXX Byte at %x is %x\n",
+ card->iobase + 1,
+ bytein(card->iobase + 1));
+ return -2;
+ }
+ val = bytein(card->iobase + 2); /* 0x1e=without AB
+ * 0x1f=with AB
+ * 0x1c 16.3 ???
+ */
+ if (val != 0x1c && val != 0x1e && val != 0x1f) {
+ printk(KERN_INFO "XXX Byte at %x is %x\n",
+ card->iobase + 2,
+ bytein(card->iobase + 2));
+ return -2;
+ }
+ if (card->membase) { /* 16.0 */
+ request_region(card->iobase, 8, "teles 16.0");
+ } else {
+ request_region(card->iobase, 16, "teles 16.3");
+ request_region(card->iobase - 0xC00, 32, "teles HSCX0");
+ request_region(card->iobase - 0x800, 32, "teles HSCX1");
+ request_region(card->iobase - 0x400, 32, "teles ISAC");
}
- request_region(card->iobase, 8, "teles");
cli();
timout = jiffies + (HZ / 10) + 1;
byteout(card->iobase + 4, cfval);
@@ -1182,10 +1251,11 @@
printk(KERN_DEBUG "modehscx hscx %d mode %d ichan %d\n",
hscx, mode, ichan);
- if (hscx == 0)
- ichan = 1 - ichan; /* raar maar waar... */
-
+ hs->mode = mode;
if (sp->membase) {
+ /* What's that ??? KKeil */
+ if (hscx == 0)
+ ichan = 1 - ichan; /* raar maar waar... */
writehscx_0(sp->membase, hscx, HSCX_CCR1, 0x85);
writehscx_0(sp->membase, hscx, HSCX_XAD1, 0xFF);
writehscx_0(sp->membase, hscx, HSCX_XAD2, 0xFF);
@@ -1547,7 +1617,7 @@
static void
release_irq(int cardnr)
{
- struct IsdnCard *card = cards + cardnr;
+ struct IsdnCard *card = cards + cardnr;
irq2dev_map[card->interrupt] = NULL;
free_irq(card->interrupt, NULL);
@@ -1584,7 +1654,14 @@
close_hscxstate(sp->hs);
if (cards[cardnr].iobase)
- release_region(cards[cardnr].iobase, 8);
+ if (cards[cardnr].membase) { /* 16.0 */
+ release_region(cards[cardnr].iobase, 8);
+ } else {
+ release_region(cards[cardnr].iobase, 16);
+ release_region(cards[cardnr].iobase - 0xC00, 32);
+ release_region(cards[cardnr].iobase - 0x800, 32);
+ release_region(cards[cardnr].iobase - 0x400, 32);
+ }
Sfree((void *) sp);
}
@@ -1652,35 +1729,35 @@
struct HscxState *hsp = sp->hs + st->l1.hscx;
switch (pr) {
- case (PH_DATA):
- if (hsp->xmtibh)
- BufQueueLink(&hsp->sq, ibh);
- else {
- hsp->xmtibh = ibh;
- hsp->sendptr = 0;
- hsp->releasebuf = !0;
- hscx_fill_fifo(hsp);
- }
- break;
- case (PH_DATA_PULLED):
- if (hsp->xmtibh) {
- printk(KERN_DEBUG "hscx_l2l1: this shouldn't happen\n");
- break;
- }
- hsp->xmtibh = ibh;
- hsp->sendptr = 0;
- hsp->releasebuf = 0;
- hscx_fill_fifo(hsp);
- break;
- case (PH_REQUEST_PULL):
- if (!hsp->xmtibh) {
- st->l1.requestpull = 0;
- st->l1.l1l2(st, PH_PULL_ACK, NULL);
- } else
- st->l1.requestpull = !0;
- break;
+ case (PH_DATA):
+ if (hsp->xmtibh)
+ BufQueueLink(&hsp->sq, ibh);
+ else {
+ hsp->xmtibh = ibh;
+ hsp->sendptr = 0;
+ hsp->releasebuf = !0;
+ hscx_fill_fifo(hsp);
+ }
+ break;
+ case (PH_DATA_PULLED):
+ if (hsp->xmtibh) {
+ printk(KERN_DEBUG "hscx_l2l1: this shouldn't happen\n");
+ break;
+ }
+ hsp->xmtibh = ibh;
+ hsp->sendptr = 0;
+ hsp->releasebuf = 0;
+ hscx_fill_fifo(hsp);
+ break;
+ case (PH_REQUEST_PULL):
+ if (!hsp->xmtibh) {
+ st->l1.requestpull = 0;
+ st->l1.l1l2(st, PH_PULL_ACK, NULL);
+ } else
+ st->l1.requestpull = !0;
+ break;
}
-
+
}
extern struct IsdnBuffers *tracebuf;
@@ -1778,7 +1855,5 @@
void
teles_reportcard(int cardnr)
{
-
printk(KERN_DEBUG "teles_reportcard\n");
-
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this