patch-2.1.92 linux/drivers/isdn/hisax/isdnl1.c
Next file: linux/drivers/isdn/hisax/isdnl1.h
Previous file: linux/drivers/isdn/hisax/isac.h
Back to the patch index
Back to the overall index
- Lines: 1984
- Date:
Wed Apr 1 16:20:58 1998
- Orig file:
v2.1.91/linux/drivers/isdn/hisax/isdnl1.c
- Orig date:
Thu Feb 12 20:56:06 1998
diff -u --recursive --new-file v2.1.91/linux/drivers/isdn/hisax/isdnl1.c linux/drivers/isdn/hisax/isdnl1.c
@@ -1,4 +1,4 @@
-/* $Id: isdnl1.c,v 1.15 1997/05/27 15:17:55 fritz Exp $
+/* $Id: isdnl1.c,v 2.18 1998/02/12 23:07:42 keil Exp $
* isdnl1.c common low level stuff for Siemens Chipsetbased isdn cards
* based on the teles driver from Jan den Ouden
@@ -11,131 +11,239 @@
*
*
* $Log: isdnl1.c,v $
- * Revision 1.15 1997/05/27 15:17:55 fritz
- * Added changes for recent 2.1.x kernels:
- * changed return type of isdn_close
- * queue_task_* -> queue_task
- * clear/set_bit -> test_and_... where apropriate.
- * changed type of hard_header_cache parameter.
+ * Revision 2.18 1998/02/12 23:07:42 keil
+ * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
+ *
+ * Revision 2.17 1998/02/11 17:28:07 keil
+ * Niccy PnP/PCI support
+ *
+ * Revision 2.16 1998/02/09 18:46:08 keil
+ * Support for Sedlbauer PCMCIA (Marcus Niemann)
*
- * Revision 1.14 1997/04/07 23:00:08 keil
- * GFP_KERNEL ---> GFP_ATOMIC
+ * Revision 2.15 1998/02/09 10:54:51 keil
+ * fixes for leased mode
*
- * Revision 1.13 1997/04/06 22:55:50 keil
- * Using SKB's
+ * Revision 2.14 1998/02/03 23:31:31 keil
+ * add AMD7930 support
*
- * Revision 1.12 1997/03/26 13:43:57 keil
- * small cosmetics
+ * Revision 2.13 1998/02/02 13:33:02 keil
+ * New card support
*
- * Revision 1.11 1997/03/25 23:11:23 keil
- * US NI-1 protocol
+ * Revision 2.12 1998/01/31 21:41:48 keil
+ * changes for newer 2.1 kernels
*
- * Revision 1.10 1997/03/13 14:45:05 keil
- * using IRQ proof queue_task
+ * Revision 2.11 1997/11/12 15:01:23 keil
+ * COMPAQ_ISA changes
*
- * Revision 1.9 1997/03/12 21:44:21 keil
- * change Interrupt routine from atomic quick to normal
+ * Revision 2.10 1997/11/08 21:35:48 keil
+ * new l1 init
*
- * Revision 1.8 1997/02/09 00:24:31 keil
- * new interface handling, one interface per card
+ * Revision 2.9 1997/11/06 17:09:18 keil
+ * New 2.1 init code
*
- * Revision 1.7 1997/01/27 15:56:03 keil
- * PCMCIA Teles card and ITK ix1 micro added
+ * Revision 2.8 1997/10/29 19:00:05 keil
+ * new layer1,changes for 2.1
*
- * Revision 1.6 1997/01/21 22:20:00 keil
- * changes for D-channel log; Elsa Quickstep support
+ * Revision 2.7 1997/10/10 20:56:50 fritz
+ * New HL interface.
*
- * Revision 1.5 1997/01/10 12:51:19 keil
- * cleanup; set newversion
+ * Revision 2.6 1997/09/12 10:05:16 keil
+ * ISDN_CTRL_DEBUG define
*
- * Revision 1.4 1996/12/08 19:44:53 keil
- * L2FRAME_DEBUG and other changes from Pekka Sarnila
+ * Revision 2.5 1997/09/11 17:24:45 keil
+ * Add new cards
*
- * Revision 1.3 1996/11/18 15:34:47 keil
- * fix HSCX version code
+ * Revision 2.4 1997/08/15 17:47:09 keil
+ * avoid oops because a uninitialised timer
*
- * Revision 1.2 1996/10/27 22:16:54 keil
- * ISAC/HSCX version lookup
+ * Revision 2.3 1997/08/01 11:16:40 keil
+ * cosmetics
*
- * Revision 1.1 1996/10/13 20:04:53 keil
- * Initial revision
+ * Revision 2.2 1997/07/30 17:11:08 keil
+ * L1deactivated exported
*
+ * Revision 2.1 1997/07/27 21:35:38 keil
+ * new layer1 interface
+ *
+ * Revision 2.0 1997/06/26 11:02:53 keil
+ * New Layer and card interface
+ *
+ * Revision 1.15 1997/05/27 15:17:55 fritz
+ * Added changes for recent 2.1.x kernels:
+ * changed return type of isdn_close
+ * queue_task_* -> queue_task
+ * clear/set_bit -> test_and_... where apropriate.
+ * changed type of hard_header_cache parameter.
*
+ * old changes removed KKe
*
*/
-const char *l1_revision = "$Revision: 1.15 $";
+const char *l1_revision = "$Revision: 2.18 $";
#define __NO_VERSION__
#include <linux/config.h>
#include "hisax.h"
#include "isdnl1.h"
+#include <linux/kernel_stat.h>
+#if (LINUX_VERSION_CODE < 0x020150) /* 2.1.80 */
+#define kstat_irqs( PAR ) kstat.interrupts( (PAR) )
+#endif
+
+
#if CARD_TELES0
-#include "teles0.h"
+extern int setup_teles0(struct IsdnCard *card);
#endif
#if CARD_TELES3
-#include "teles3.h"
+extern int setup_teles3(struct IsdnCard *card);
#endif
#if CARD_AVM_A1
-#include "avm_a1.h"
+extern int setup_avm_a1(struct IsdnCard *card);
#endif
#if CARD_ELSA
-#include "elsa.h"
+extern int setup_elsa(struct IsdnCard *card);
#endif
#if CARD_IX1MICROR2
-#include "ix1_micro.h"
+extern int setup_ix1micro(struct IsdnCard *card);
#endif
-/* #define I4L_IRQ_FLAG SA_INTERRUPT */
-#define I4L_IRQ_FLAG 0
+#if CARD_DIEHLDIVA
+extern int setup_diva(struct IsdnCard *card);
+#endif
-#define HISAX_STATUS_BUFSIZE 4096
+#if CARD_ASUSCOM
+extern int setup_asuscom(struct IsdnCard *card);
+#endif
-#define INCLUDE_INLINE_FUNCS
-#include <linux/tqueue.h>
-#include <linux/interrupt.h>
+#if CARD_TELEINT
+extern int setup_TeleInt(struct IsdnCard *card);
+#endif
-const char *CardType[] =
-{"No Card", "Teles 16.0", "Teles 8.0", "Teles 16.3",
- "Creatix/Teles PnP", "AVM A1", "Elsa ML",
-#ifdef CONFIG_HISAX_ELSA_PCMCIA
- "Elsa PCMCIA",
-#else
- "Elsa Quickstep",
+#if CARD_SEDLBAUER
+extern int setup_sedlbauer(struct IsdnCard *card);
#endif
- "Teles PCMCIA", "ITK ix1-micro Rev.2"};
-static char *HSCXVer[] =
-{"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
- "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
+#if CARD_SPORTSTER
+extern int setup_sportster(struct IsdnCard *card);
+#endif
-static char *ISACVer[] =
-{"2086/2186 V1.1", "2085 B1", "2085 B2",
- "2085 V2.3"};
+#if CARD_MIC
+extern int setup_mic(struct IsdnCard *card);
+#endif
+
+#if CARD_NETJET
+extern int setup_netjet(struct IsdnCard *card);
+#endif
+
+#if CARD_TELES3C
+extern int setup_t163c(struct IsdnCard *card);
+#endif
+
+#if CARD_AMD7930
+extern int setup_amd7930(struct IsdnCard *card);
+#endif
+
+#if CARD_NICCY
+extern int setup_niccy(struct IsdnCard *card);
+#endif
+
+#define HISAX_STATUS_BUFSIZE 4096
+#define ISDN_CTRL_DEBUG 1
+#define INCLUDE_INLINE_FUNCS
+#include <linux/tqueue.h>
+#include <linux/interrupt.h>
+const char *CardType[] =
+{"No Card", "Teles 16.0", "Teles 8.0", "Teles 16.3", "Creatix/Teles PnP",
+ "AVM A1", "Elsa ML", "Elsa Quickstep", "Teles PCMCIA", "ITK ix1-micro Rev.2",
+ "Elsa PCMCIA", "Eicon.Diehl Diva", "ISDNLink", "TeleInt", "Teles 16.3c",
+ "Sedlbauer Speed Card", "USR Sportster", "ith mic Linux", "Elsa PCI",
+ "Compaq ISA", "NETjet", "Teles PCI", "Sedlbauer Speed Star (PCMCIA)",
+ "AMD 7930", "NICCY"
+};
extern struct IsdnCard cards[];
extern int nrcards;
extern char *HiSax_id;
+extern struct IsdnBuffers *tracebuf;
+
+#define TIMER3_VALUE 7
+
+static
+struct Fsm l1fsm =
+{NULL, 0, 0, NULL, NULL};
+
+enum {
+ ST_L1_F2,
+ ST_L1_F3,
+ ST_L1_F4,
+ ST_L1_F5,
+ ST_L1_F6,
+ ST_L1_F7,
+ ST_L1_F8,
+};
+
+#define L1_STATE_COUNT (ST_L1_F8+1)
+
+static char *strL1State[] =
+{
+ "ST_L1_F2",
+ "ST_L1_F3",
+ "ST_L1_F4",
+ "ST_L1_F5",
+ "ST_L1_F6",
+ "ST_L1_F7",
+ "ST_L1_F8",
+};
+
+enum {
+ EV_PH_ACTIVATE,
+ EV_RESET_IND,
+ EV_DEACT_CNF,
+ EV_DEACT_IND,
+ EV_POWER_UP,
+ EV_RSYNC_IND,
+ EV_INFO2_IND,
+ EV_INFO4_IND,
+ EV_TIMER_DEACT,
+ EV_TIMER_ACT,
+ EV_TIMER3,
+};
+
+#define L1_EVENT_COUNT (EV_TIMER3 + 1)
+
+static char *strL1Event[] =
+{
+ "EV_PH_ACTIVATE",
+ "EV_RESET_IND",
+ "EV_DEACT_CNF",
+ "EV_DEACT_IND",
+ "EV_POWER_UP",
+ "EV_RSYNC_IND",
+ "EV_INFO2_IND",
+ "EV_INFO4_IND",
+ "EV_TIMER_DEACT",
+ "EV_TIMER_ACT",
+ "EV_TIMER3",
+};
/*
* Find card with given driverId
*/
static inline struct IsdnCardState
-*
-hisax_findcard(int driverid)
+*hisax_findcard(int driverid)
{
int i;
for (i = 0; i < nrcards; i++)
- if (cards[i].sp)
- if (cards[i].sp->myid == driverid)
- return (cards[i].sp);
- return (struct IsdnCardState *) 0;
+ if (cards[i].cs)
+ if (cards[i].cs->myid == driverid)
+ return (cards[i].cs);
+ return (NULL);
}
int
@@ -162,6 +270,7 @@
}
}
+#if ISDN_CTRL_DEBUG
void
HiSax_putstatus(struct IsdnCardState *csta, char *buf)
{
@@ -194,6 +303,23 @@
csta->iif.statcallb(&ic);
}
}
+#else
+#define KDEBUG_DEF
+#include "../kdebug.h"
+
+static int DbgLineNr=0,DbgSequenzNr=1;
+
+void
+HiSax_putstatus(struct IsdnCardState *csta, char *buf)
+{
+ char tmp[512];
+
+ if (DbgLineNr==23)
+ DbgLineNr=0;
+ sprintf(tmp, "%5d %s",DbgSequenzNr++,buf);
+ gput_str(tmp,0,DbgLineNr++);
+}
+#endif
int
ll_run(struct IsdnCardState *csta)
@@ -238,228 +364,119 @@
}
void
-debugl1(struct IsdnCardState *sp, char *msg)
+debugl1(struct IsdnCardState *cs, char *msg)
{
char tmp[256], tm[32];
jiftime(tm, jiffies);
- sprintf(tmp, "%s Card %d %s\n", tm, sp->cardnr + 1, msg);
- HiSax_putstatus(sp, tmp);
-}
-
-/*
- * HSCX stuff goes here
- */
-
-
-char *
-HscxVersion(u_char v)
-{
- return (HSCXVer[v & 0xf]);
-}
-
-void
-hscx_sched_event(struct HscxState *hsp, int event)
-{
- hsp->event |= 1 << event;
- queue_task(&hsp->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+ sprintf(tmp, "%s Card %d %s\n", tm, cs->cardnr + 1, msg);
+ HiSax_putstatus(cs, tmp);
}
-/*
- * ISAC stuff goes here
- */
-
-char *
-ISACVersion(u_char v)
+static void
+l1m_debug(struct FsmInst *fi, char *s)
{
- return (ISACVer[(v >> 5) & 3]);
+ struct PStack *st = fi->userdata;
+
+ debugl1(st->l1.hardware, s);
}
void
-isac_sched_event(struct IsdnCardState *sp, int event)
-{
- sp->event |= 1 << event;
- queue_task(&sp->tqueue, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
-}
-
-int
-act_wanted(struct IsdnCardState *sp)
+L1activated(struct IsdnCardState *cs)
{
struct PStack *st;
- st = sp->stlist;
- while (st)
- if (st->l1.act_state)
- return (!0);
+ st = cs->stlist;
+ while (st) {
+ if (test_and_clear_bit(FLG_L1_ACTIVATING, &st->l1.Flags))
+ st->l1.l1man(st, PH_ACTIVATE_CNF, NULL);
else
- st = st->next;
- return (0);
-}
-
-void
-isac_new_ph(struct IsdnCardState *sp)
-{
- int enq;
-
- enq = act_wanted(sp);
-
- switch (sp->ph_state) {
- case (6):
- sp->ph_active = 0;
- sp->ph_command(sp, 15);
- break;
- case (15):
- sp->ph_active = 0;
- if (enq)
- sp->ph_command(sp, 0);
- break;
- case (0):
- sp->ph_active = 0;
- if (enq)
- sp->ph_command(sp, 0);
-#if 0
- else
- sp->ph_command(sp, 15);
-#endif
- break;
- case (7):
- sp->ph_active = 0;
- if (enq)
- sp->ph_command(sp, 9);
- break;
- case (12):
- sp->ph_command(sp, 8);
- sp->ph_active = 5;
- isac_sched_event(sp, ISAC_PHCHANGE);
- if (!sp->tx_skb)
- sp->tx_skb = skb_dequeue(&sp->sq);
- if (sp->tx_skb) {
- sp->tx_cnt = 0;
- sp->isac_fill_fifo(sp);
- }
- break;
- case (13):
- sp->ph_command(sp, 9);
- sp->ph_active = 5;
- isac_sched_event(sp, ISAC_PHCHANGE);
- if (!sp->tx_skb)
- sp->tx_skb = skb_dequeue(&sp->sq);
- if (sp->tx_skb) {
- sp->tx_cnt = 0;
- sp->isac_fill_fifo(sp);
- }
- break;
- case (4):
- case (8):
- sp->ph_active = 0;
- break;
- default:
- sp->ph_active = 0;
- break;
- }
-}
-
-static void
-restart_ph(struct IsdnCardState *sp)
-{
- if (!sp->ph_active) {
- if ((sp->ph_state == 6) || (sp->ph_state == 0)) {
- sp->ph_command(sp, 0);
- sp->ph_active = 2;
- } else {
- sp->ph_command(sp, 1);
- sp->ph_active = 1;
- }
- } else if (sp->ph_active == 2) {
- sp->ph_command(sp, 1);
- sp->ph_active = 1;
+ st->l1.l1man(st, PH_ACTIVATE_IND, NULL);
+ st = st->next;
}
}
-
-static void
-act_ivated(struct IsdnCardState *sp)
+void
+L1deactivated(struct IsdnCardState *cs)
{
struct PStack *st;
- st = sp->stlist;
+ st = cs->stlist;
while (st) {
- if (st->l1.act_state == 1) {
- st->l1.act_state = 2;
- st->l1.l1man(st, PH_ACTIVATE, NULL);
- }
+ if (test_bit(FLG_L1_DBUSY, &cs->HW_Flags))
+ st->l1.l1l2(st, PH_PAUSE_CNF, NULL);
+ st->l1.l1man(st, PH_DEACTIVATE_IND, NULL);
st = st->next;
}
+ test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags);
}
-static void
-process_new_ph(struct IsdnCardState *sp)
-{
- if (sp->ph_active == 5)
- act_ivated(sp);
-}
-
-static void
-process_xmt(struct IsdnCardState *sp)
+void
+DChannel_proc_xmt(struct IsdnCardState *cs)
{
struct PStack *stptr;
- if (sp->tx_skb)
+ if (cs->tx_skb)
return;
- stptr = sp->stlist;
+ stptr = cs->stlist;
while (stptr != NULL)
- if (stptr->l1.requestpull) {
- stptr->l1.requestpull = 0;
- stptr->l1.l1l2(stptr, PH_PULL_ACK, NULL);
+ if (test_and_clear_bit(FLG_L1_PULL_REQ, &stptr->l1.Flags)) {
+ stptr->l1.l1l2(stptr, PH_PULL_CNF, NULL);
break;
} else
stptr = stptr->next;
}
-static void
-process_rcv(struct IsdnCardState *sp)
+void
+DChannel_proc_rcv(struct IsdnCardState *cs)
{
struct sk_buff *skb, *nskb;
- struct PStack *stptr;
- int found, broadc;
+ struct PStack *stptr = cs->stlist;
+ int found, tei, sapi;
char tmp[64];
- while ((skb = skb_dequeue(&sp->rq))) {
+ if (stptr)
+ if (test_bit(FLG_L1_ACTTIMER, &stptr->l1.Flags))
+ FsmEvent(&stptr->l1.l1m, EV_TIMER_ACT, NULL);
+ while ((skb = skb_dequeue(&cs->rq))) {
#ifdef L2FRAME_DEBUG /* psa */
- if (sp->debug & L1_DEB_LAPD)
- Logl2Frame(sp, skb, "PH_DATA", 1);
+ if (cs->debug & L1_DEB_LAPD)
+ Logl2Frame(cs, skb, "PH_DATA", 1);
#endif
- stptr = sp->stlist;
- broadc = (skb->data[1] >> 1) == 127;
-
- if (broadc) {
- if (!(skb->data[0] >> 2)) { /* sapi 0 */
- sp->CallFlags = 3;
- if (sp->dlogflag) {
- LogFrame(sp, skb->data, skb->len);
- dlogframe(sp, skb->data + 3, skb->len - 3,
+ stptr = cs->stlist;
+ sapi = skb->data[0] >> 2;
+ tei = skb->data[1] >> 1;
+
+ if (tei == GROUP_TEI) {
+ if (sapi == CTRL_SAPI) { /* sapi 0 */
+ if (cs->dlogflag) {
+ LogFrame(cs, skb->data, skb->len);
+ dlogframe(cs, skb->data + 3, skb->len - 3,
"Q.931 frame network->user broadcast");
}
- }
- while (stptr != NULL) {
- if ((skb->data[0] >> 2) == stptr->l2.sap)
+ while (stptr != NULL) {
if ((nskb = skb_clone(skb, GFP_ATOMIC)))
- stptr->l1.l1l2(stptr, PH_DATA, nskb);
+ stptr->l1.l1l2(stptr, PH_DATA_IND, nskb);
else
printk(KERN_WARNING "HiSax: isdn broadcast buffer shortage\n");
- stptr = stptr->next;
+ stptr = stptr->next;
+ }
+ } else if (sapi == TEI_SAPI) {
+ while (stptr != NULL) {
+ if ((nskb = skb_clone(skb, GFP_ATOMIC)))
+ stptr->l1.l1tei(stptr, PH_DATA_IND, nskb);
+ else
+ printk(KERN_WARNING "HiSax: tei broadcast buffer shortage\n");
+ stptr = stptr->next;
+ }
}
- SET_SKB_FREE(skb);
dev_kfree_skb(skb);
- } else {
+ } else if (sapi == CTRL_SAPI) {
found = 0;
while (stptr != NULL)
- if (((skb->data[0] >> 2) == stptr->l2.sap) &&
- ((skb->data[1] >> 1) == stptr->l2.tei)) {
- stptr->l1.l1l2(stptr, PH_DATA, skb);
+ if (tei == stptr->l2.tei) {
+ stptr->l1.l1l2(stptr, PH_DATA_IND, skb);
found = !0;
break;
} else
@@ -474,167 +491,70 @@
sprintf(tmp,
"Q.931 frame network->user with tei %d (not for us)",
skb->data[1] >> 1);
- LogFrame(sp, skb->data, skb->len);
- dlogframe(sp, skb->data + 4, skb->len - 4, tmp);
+ LogFrame(cs, skb->data, skb->len);
+ dlogframe(cs, skb->data + 4, skb->len - 4, tmp);
}
- SET_SKB_FREE(skb);
dev_kfree_skb(skb);
}
}
-
}
-
-}
-
-static void
-isac_bh(struct IsdnCardState *sp)
-{
- if (!sp)
- return;
-
- if (test_and_clear_bit(ISAC_PHCHANGE, &sp->event))
- process_new_ph(sp);
- if (test_and_clear_bit(ISAC_RCVBUFREADY, &sp->event))
- process_rcv(sp);
- if (test_and_clear_bit(ISAC_XMTBUFREADY, &sp->event))
- process_xmt(sp);
}
static void
-l2l1(struct PStack *st, int pr, void *arg)
+BChannel_proc_xmt(struct BCState *bcs)
{
- struct IsdnCardState *sp = (struct IsdnCardState *) st->l1.hardware;
- struct sk_buff *skb = arg;
- char str[64];
-
- switch (pr) {
- case (PH_DATA):
- if (sp->tx_skb) {
- skb_queue_tail(&sp->sq, skb);
-#ifdef L2FRAME_DEBUG /* psa */
- if (sp->debug & L1_DEB_LAPD)
- Logl2Frame(sp, skb, "PH_DATA Queued", 0);
-#endif
- } else {
- if ((sp->dlogflag) && (!(skb->data[2] & 1))) { /* I-FRAME */
- LogFrame(sp, skb->data, skb->len);
- sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei);
- dlogframe(sp, skb->data + st->l2.ihsize, skb->len - st->l2.ihsize,
- str);
- }
- sp->tx_skb = skb;
- sp->tx_cnt = 0;
-#ifdef L2FRAME_DEBUG /* psa */
- if (sp->debug & L1_DEB_LAPD)
- Logl2Frame(sp, skb, "PH_DATA", 0);
-#endif
- sp->isac_fill_fifo(sp);
- }
- break;
- case (PH_DATA_PULLED):
- if (sp->tx_skb) {
- if (sp->debug & L1_DEB_WARN)
- debugl1(sp, " l2l1 tx_skb exist this shouldn't happen");
- break;
- }
- if ((sp->dlogflag) && (!(skb->data[2] & 1))) { /* I-FRAME */
- LogFrame(sp, skb->data, skb->len);
- sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei);
- dlogframe(sp, skb->data + st->l2.ihsize, skb->len - st->l2.ihsize,
- str);
- }
- sp->tx_skb = skb;
- sp->tx_cnt = 0;
-#ifdef L2FRAME_DEBUG /* psa */
- if (sp->debug & L1_DEB_LAPD)
- Logl2Frame(sp, skb, "PH_DATA_PULLED", 0);
-#endif
- sp->isac_fill_fifo(sp);
- break;
- case (PH_REQUEST_PULL):
-#ifdef L2FRAME_DEBUG /* psa */
- if (sp->debug & L1_DEB_LAPD)
- debugl1(sp, "-> PH_REQUEST_PULL");
-#endif
- if (!sp->tx_skb) {
- st->l1.requestpull = 0;
- st->l1.l1l2(st, PH_PULL_ACK, NULL);
- } else
- st->l1.requestpull = !0;
- break;
- }
-}
-
+ struct PStack *st = bcs->st;
-static void
-hscx_process_xmt(struct HscxState *hsp)
-{
- struct PStack *st = hsp->st;
-
- if (hsp->tx_skb)
+ if (test_bit(BC_FLG_BUSY, &bcs->Flag))
return;
- if (st->l1.requestpull) {
- st->l1.requestpull = 0;
- st->l1.l1l2(st, PH_PULL_ACK, NULL);
- }
- if (!hsp->active)
- if ((!hsp->tx_skb) && (!skb_queue_len(&hsp->squeue)))
- hsp->sp->modehscx(hsp, 0, 0);
+ if (test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags))
+ st->l1.l1l2(st, PH_PULL_CNF, NULL);
+ if (!test_bit(BC_FLG_ACTIV, &bcs->Flag))
+ if (!test_bit(BC_FLG_BUSY, &bcs->Flag) && (!skb_queue_len(&bcs->squeue)))
+ st->ma.manl1(st, PH_DEACTIVATE_CNF, 0);
}
static void
-hscx_process_rcv(struct HscxState *hsp)
+BChannel_proc_rcv(struct BCState *bcs)
{
struct sk_buff *skb;
-#ifdef DEBUG_MAGIC
- if (hsp->magic != 301270) {
- printk(KERN_DEBUG "hscx_process_rcv magic not 301270\n");
- return;
- }
-#endif
- while ((skb = skb_dequeue(&hsp->rqueue))) {
- hsp->st->l1.l1l2(hsp->st, PH_DATA, skb);
+ while ((skb = skb_dequeue(&bcs->rqueue))) {
+ bcs->st->l1.l1l2(bcs->st, PH_DATA_IND, skb);
}
}
static void
-hscx_bh(struct HscxState *hsp)
+BChannel_bh(struct BCState *bcs)
{
-
- if (!hsp)
+ if (!bcs)
return;
-
- if (test_and_clear_bit(HSCX_RCVBUFREADY, &hsp->event))
- hscx_process_rcv(hsp);
- if (test_and_clear_bit(HSCX_XMTBUFREADY, &hsp->event))
- hscx_process_xmt(hsp);
-
+ if (test_and_clear_bit(B_RCVBUFREADY, &bcs->event))
+ BChannel_proc_rcv(bcs);
+ if (test_and_clear_bit(B_XMTBUFREADY, &bcs->event))
+ BChannel_proc_xmt(bcs);
}
-/*
- * interrupt stuff ends here
- */
-
void
-HiSax_addlist(struct IsdnCardState *sp,
+HiSax_addlist(struct IsdnCardState *cs,
struct PStack *st)
{
- st->next = sp->stlist;
- sp->stlist = st;
+ st->next = cs->stlist;
+ cs->stlist = st;
}
void
-HiSax_rmlist(struct IsdnCardState *sp,
+HiSax_rmlist(struct IsdnCardState *cs,
struct PStack *st)
{
struct PStack *p;
- if (sp->stlist == st)
- sp->stlist = st->next;
+ FsmDelTimer(&st->l1.timer, 0);
+ if (cs->stlist == st)
+ cs->stlist = st->next;
else {
- p = sp->stlist;
+ p = cs->stlist;
while (p)
if (p->next == st) {
p->next = st->next;
@@ -644,248 +564,117 @@
}
}
-static void
-check_ph_act(struct IsdnCardState *sp)
-{
- struct PStack *st = sp->stlist;
-
- while (st) {
- if (st->l1.act_state)
- return;
- st = st->next;
- }
- if (sp->ph_active == 5)
- sp->ph_active = 4;
-}
-
-static void
-HiSax_manl1(struct PStack *st, int pr,
- void *arg)
-{
- struct IsdnCardState *sp = (struct IsdnCardState *)
- st->l1.hardware;
- long flags;
- char tmp[32];
-
- switch (pr) {
- case (PH_ACTIVATE):
- if (sp->debug) {
- sprintf(tmp, "PH_ACT ph_active %d", sp->ph_active);
- debugl1(sp, tmp);
- }
- save_flags(flags);
- cli();
- if (sp->ph_active & 4) {
- sp->ph_active = 5;
- st->l1.act_state = 2;
- restore_flags(flags);
- st->l1.l1man(st, PH_ACTIVATE, NULL);
- } else {
- st->l1.act_state = 1;
- if (sp->ph_active == 0)
- restart_ph(sp);
- restore_flags(flags);
- }
- break;
- case (PH_DEACTIVATE):
- st->l1.act_state = 0;
- if (sp->debug) {
- sprintf(tmp, "PH_DEACT ph_active %d", sp->ph_active);
- debugl1(sp, tmp);
- }
- check_ph_act(sp);
- break;
- }
-}
-
-static void
-HiSax_l2l1discardq(struct PStack *st, int pr,
- void *heldby, int releasetoo)
-{
- struct IsdnCardState *sp = (struct IsdnCardState *) st->l1.hardware;
- struct sk_buff *skb;
-
-#ifdef DEBUG_MAGIC
- if (sp->magic != 301271) {
- printk(KERN_DEBUG "isac_discardq magic not 301271\n");
- return;
- }
-#endif
-
- while ((skb = skb_dequeue(&sp->sq))) {
- SET_SKB_FREE(skb);
- dev_kfree_skb(skb);
- }
-}
-
-void
-setstack_HiSax(struct PStack *st, struct IsdnCardState *sp)
-{
- st->l1.hardware = sp;
- st->protocol = sp->protocol;
-
- setstack_tei(st);
-
- st->l1.stlistp = &(sp->stlist);
- st->l1.act_state = 0;
- st->l2.l2l1 = l2l1;
- st->l2.l2l1discardq = HiSax_l2l1discardq;
- st->ma.manl1 = HiSax_manl1;
- st->l1.requestpull = 0;
-}
-
void
-init_hscxstate(struct IsdnCardState *sp,
- int hscx)
+init_bcstate(struct IsdnCardState *cs,
+ int bc)
{
- struct HscxState *hsp = sp->hs + hscx;
+ struct BCState *bcs = cs->bcs + bc;
- hsp->sp = sp;
- hsp->hscx = hscx;
-
- hsp->tqueue.next = 0;
- hsp->tqueue.sync = 0;
- hsp->tqueue.routine = (void *) (void *) hscx_bh;
- hsp->tqueue.data = hsp;
-
- hsp->inuse = 0;
- hsp->init = 0;
- hsp->active = 0;
-
-#ifdef DEBUG_MAGIC
- hsp->magic = 301270;
-#endif
-}
-
-int
-get_irq(int cardnr, void *routine)
-{
- struct IsdnCard *card = cards + cardnr;
- long flags;
-
- save_flags(flags);
- cli();
- if (request_irq(card->sp->irq, routine,
- I4L_IRQ_FLAG, "HiSax", card->sp)) {
- printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n",
- card->sp->irq);
- restore_flags(flags);
- return (0);
- }
- restore_flags(flags);
- return (1);
-}
-
-static void
-release_irq(int cardnr)
-{
- struct IsdnCard *card = cards + cardnr;
-
- free_irq(card->sp->irq, card->sp);
-}
-
-void
-close_hscxstate(struct HscxState *hs)
-{
- struct sk_buff *skb;
-
- hs->sp->modehscx(hs, 0, 0);
- hs->inuse = 0;
- if (hs->init) {
- if (hs->rcvbuf) {
- kfree(hs->rcvbuf);
- hs->rcvbuf = NULL;
- }
- while ((skb = skb_dequeue(&hs->rqueue))) {
- SET_SKB_FREE(skb);
- dev_kfree_skb(skb);
- }
- while ((skb = skb_dequeue(&hs->squeue))) {
- SET_SKB_FREE(skb);
- dev_kfree_skb(skb);
- }
- if (hs->tx_skb) {
- SET_SKB_FREE(hs->tx_skb);
- dev_kfree_skb(hs->tx_skb);
- hs->tx_skb = NULL;
- }
- }
- hs->init = 0;
+ bcs->cs = cs;
+ bcs->channel = bc;
+ bcs->tqueue.next = 0;
+ bcs->tqueue.sync = 0;
+ bcs->tqueue.routine = (void *) (void *) BChannel_bh;
+ bcs->tqueue.data = bcs;
+ bcs->BC_SetStack = NULL;
+ bcs->BC_Close = NULL;
+ bcs->Flag = 0;
}
static void
closecard(int cardnr)
{
- struct IsdnCardState *csta = cards[cardnr].sp;
+ struct IsdnCardState *csta = cards[cardnr].cs;
struct sk_buff *skb;
-
- close_hscxstate(csta->hs + 1);
- close_hscxstate(csta->hs);
+
+ if (csta->bcs->BC_Close != NULL) {
+ csta->bcs->BC_Close(csta->bcs + 1);
+ csta->bcs->BC_Close(csta->bcs);
+ }
if (csta->rcvbuf) {
kfree(csta->rcvbuf);
csta->rcvbuf = NULL;
}
while ((skb = skb_dequeue(&csta->rq))) {
- SET_SKB_FREE(skb);
dev_kfree_skb(skb);
}
while ((skb = skb_dequeue(&csta->sq))) {
- SET_SKB_FREE(skb);
dev_kfree_skb(skb);
}
if (csta->tx_skb) {
- SET_SKB_FREE(csta->tx_skb);
dev_kfree_skb(csta->tx_skb);
csta->tx_skb = NULL;
}
- switch (csta->typ) {
-#if CARD_TELES0
- case ISDN_CTYPE_16_0:
- case ISDN_CTYPE_8_0:
- release_io_teles0(cards + cardnr);
- break;
-#endif
-#if CARD_TELES3
- case ISDN_CTYPE_PNP:
- case ISDN_CTYPE_16_3:
- case ISDN_CTYPE_TELESPCMCIA:
- release_io_teles3(cards + cardnr);
- break;
-#endif
-#if CARD_AVM_A1
- case ISDN_CTYPE_A1:
- release_io_avm_a1(cards + cardnr);
- break;
-#endif
-#if CARD_ELSA
- case ISDN_CTYPE_ELSA:
- case ISDN_CTYPE_ELSA_QS1000:
- release_io_elsa(cards + cardnr);
- break;
-#endif
-#if CARD_IX1MICROR2
- case ISDN_CTYPE_IX1MICROR2:
- release_io_ix1micro(cards + cardnr);
- break;
-#endif
- default:
- break;
+ if (csta->mon_rx) {
+ kfree(csta->mon_rx);
+ csta->mon_rx = NULL;
+ }
+ if (csta->mon_tx) {
+ kfree(csta->mon_tx);
+ csta->mon_tx = NULL;
}
+ csta->cardmsg(csta, CARD_RELEASE, NULL);
+ del_timer(&csta->dbusytimer);
ll_unload(csta);
}
-static int
-checkcard(int cardnr, char *id)
+HISAX_INITFUNC(static int init_card(struct IsdnCardState *cs))
+{
+ int irq_cnt, cnt = 3;
+ long flags;
+
+ save_flags(flags);
+ cli();
+ irq_cnt = kstat_irqs(cs->irq);
+ printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ], cs->irq,
+ irq_cnt);
+ if (cs->cardmsg(cs, CARD_SETIRQ, NULL)) {
+ printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n",
+ cs->irq);
+ return(1);
+ }
+ while (cnt) {
+ cs->cardmsg(cs, CARD_INIT, NULL);
+ sti();
+ current->state = TASK_INTERRUPTIBLE;
+ /* Timeout 10ms */
+ current->timeout = jiffies + (10 * HZ) / 1000;
+ schedule();
+ restore_flags(flags);
+ printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ],
+ cs->irq, kstat_irqs(cs->irq));
+ if (kstat_irqs(cs->irq) == irq_cnt) {
+ printk(KERN_WARNING
+ "%s: IRQ(%d) getting no interrupts during init %d\n",
+ CardType[cs->typ], cs->irq, 4 - cnt);
+ if (cnt == 1) {
+ free_irq(cs->irq, cs);
+ return (2);
+ } else {
+ cs->cardmsg(cs, CARD_RESET, NULL);
+ cnt--;
+ }
+ } else {
+ cs->cardmsg(cs, CARD_TEST, NULL);
+ return(0);
+ }
+ }
+ restore_flags(flags);
+ return(3);
+}
+
+HISAX_INITFUNC(static int
+checkcard(int cardnr, char *id, int *busy_flag))
{
long flags;
int ret = 0;
struct IsdnCard *card = cards + cardnr;
- struct IsdnCardState *sp;
+ struct IsdnCardState *cs;
save_flags(flags);
cli();
- if (!(sp = (struct IsdnCardState *)
+ if (!(cs = (struct IsdnCardState *)
kmalloc(sizeof(struct IsdnCardState), GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax: No memory for IsdnCardState(card %d)\n",
@@ -893,10 +682,16 @@
restore_flags(flags);
return (0);
}
- card->sp = sp;
- sp->cardnr = cardnr;
- sp->cfg_reg = 0;
- sp->protocol = card->protocol;
+ card->cs = cs;
+ cs->cardnr = cardnr;
+ cs->debug = L1_DEB_WARN;
+ cs->HW_Flags = 0;
+ cs->busy_flag = busy_flag;
+#if TEI_PER_CARD
+#else
+ test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags);
+#endif
+ cs->protocol = card->protocol;
if ((card->typ > 0) && (card->typ < 31)) {
if (!((1 << card->typ) & SUPORTED_CARDS)) {
@@ -913,31 +708,34 @@
restore_flags(flags);
return (0);
}
- if (!(sp->dlogspace = kmalloc(4096, GFP_ATOMIC))) {
+ if (!(cs->dlogspace = kmalloc(4096, GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax: No memory for dlogspace(card %d)\n",
cardnr + 1);
restore_flags(flags);
return (0);
}
- if (!(sp->status_buf = kmalloc(HISAX_STATUS_BUFSIZE, GFP_ATOMIC))) {
+ if (!(cs->status_buf = kmalloc(HISAX_STATUS_BUFSIZE, GFP_ATOMIC))) {
printk(KERN_WARNING
"HiSax: No memory for status_buf(card %d)\n",
cardnr + 1);
- kfree(sp->dlogspace);
+ kfree(cs->dlogspace);
restore_flags(flags);
return (0);
}
- sp->status_read = sp->status_buf;
- sp->status_write = sp->status_buf;
- sp->status_end = sp->status_buf + HISAX_STATUS_BUFSIZE - 1;
- sp->typ = card->typ;
- sp->CallFlags = 0;
- strcpy(sp->iif.id, id);
- sp->iif.channels = 2;
- sp->iif.maxbufsize = MAX_DATA_SIZE;
- sp->iif.hl_hdrlen = MAX_HEADER_LEN;
- sp->iif.features =
+ cs->stlist = NULL;
+ cs->dlogflag = 0;
+ cs->mon_tx = NULL;
+ cs->mon_rx = NULL;
+ cs->status_read = cs->status_buf;
+ cs->status_write = cs->status_buf;
+ cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1;
+ cs->typ = card->typ;
+ strcpy(cs->iif.id, id);
+ cs->iif.channels = 2;
+ cs->iif.maxbufsize = MAX_DATA_SIZE;
+ cs->iif.hl_hdrlen = MAX_HEADER_LEN;
+ cs->iif.features =
ISDN_FEATURE_L2_X75I |
ISDN_FEATURE_L2_HDLC |
ISDN_FEATURE_L2_TRANS |
@@ -953,21 +751,19 @@
#endif
0;
- sp->iif.command = HiSax_command;
- sp->iif.writebuf = NULL;
- sp->iif.writecmd = NULL;
- sp->iif.writebuf_skb = HiSax_writebuf_skb;
- sp->iif.readstat = HiSax_readstatus;
- register_isdn(&sp->iif);
- sp->myid = sp->iif.channels;
- restore_flags(flags);
- printk(KERN_NOTICE
+ cs->iif.command = HiSax_command;
+ cs->iif.writecmd = NULL;
+ cs->iif.writebuf_skb = HiSax_writebuf_skb;
+ cs->iif.readstat = HiSax_readstatus;
+ register_isdn(&cs->iif);
+ cs->myid = cs->iif.channels;
+ printk(KERN_INFO
"HiSax: Card %d Protocol %s Id=%s (%d)\n", cardnr + 1,
(card->protocol == ISDN_PTYPE_1TR6) ? "1TR6" :
(card->protocol == ISDN_PTYPE_EURO) ? "EDSS1" :
(card->protocol == ISDN_PTYPE_LEASED) ? "LEASED" :
(card->protocol == ISDN_PTYPE_NI1) ? "NI1" :
- "NONE", sp->iif.id, sp->myid);
+ "NONE", cs->iif.id, cs->myid);
switch (card->typ) {
#if CARD_TELES0
case ISDN_CTYPE_16_0:
@@ -979,6 +775,7 @@
case ISDN_CTYPE_16_3:
case ISDN_CTYPE_PNP:
case ISDN_CTYPE_TELESPCMCIA:
+ case ISDN_CTYPE_COMPAQ_ISA:
ret = setup_teles3(card);
break;
#endif
@@ -989,7 +786,9 @@
#endif
#if CARD_ELSA
case ISDN_CTYPE_ELSA:
- case ISDN_CTYPE_ELSA_QS1000:
+ case ISDN_CTYPE_ELSA_PNP:
+ case ISDN_CTYPE_ELSA_PCMCIA:
+ case ISDN_CTYPE_ELSA_PCI:
ret = setup_elsa(card);
break;
#endif
@@ -998,90 +797,103 @@
ret = setup_ix1micro(card);
break;
#endif
- default:
- printk(KERN_WARNING "HiSax: Unknown Card Typ %d\n",
- card->typ);
- ll_unload(sp);
- return (0);
- }
- if (!ret) {
- ll_unload(sp);
- return (0);
- }
- if (!(sp->rcvbuf = kmalloc(MAX_DFRAME_LEN, GFP_ATOMIC))) {
- printk(KERN_WARNING
- "HiSax: No memory for isac rcvbuf\n");
- return (1);
- }
- sp->rcvidx = 0;
- sp->tx_skb = NULL;
- sp->tx_cnt = 0;
- sp->event = 0;
- sp->tqueue.next = 0;
- sp->tqueue.sync = 0;
- sp->tqueue.routine = (void *) (void *) isac_bh;
- sp->tqueue.data = sp;
-
- skb_queue_head_init(&sp->rq);
- skb_queue_head_init(&sp->sq);
-
- sp->stlist = NULL;
- sp->ph_active = 0;
- sp->dlogflag = 0;
- sp->debug = L1_DEB_WARN;
-#ifdef DEBUG_MAGIC
- sp->magic = 301271;
+#if CARD_DIEHLDIVA
+ case ISDN_CTYPE_DIEHLDIVA:
+ ret = setup_diva(card);
+ break;
#endif
-
- init_hscxstate(sp, 0);
- init_hscxstate(sp, 1);
-
- switch (card->typ) {
-#if CARD_TELES0
- case ISDN_CTYPE_16_0:
- case ISDN_CTYPE_8_0:
- ret = initteles0(sp);
+#if CARD_ASUSCOM
+ case ISDN_CTYPE_ASUSCOM:
+ ret = setup_asuscom(card);
break;
#endif
-#if CARD_TELES3
- case ISDN_CTYPE_16_3:
- case ISDN_CTYPE_PNP:
- case ISDN_CTYPE_TELESPCMCIA:
- ret = initteles3(sp);
+#if CARD_TELEINT
+ case ISDN_CTYPE_TELEINT:
+ ret = setup_TeleInt(card);
break;
#endif
-#if CARD_AVM_A1
- case ISDN_CTYPE_A1:
- ret = initavm_a1(sp);
+#if CARD_SEDLBAUER
+ case ISDN_CTYPE_SEDLBAUER:
+ case ISDN_CTYPE_SEDLBAUER_PCMCIA:
+ ret = setup_sedlbauer(card);
break;
#endif
-#if CARD_ELSA
- case ISDN_CTYPE_ELSA:
- case ISDN_CTYPE_ELSA_QS1000:
- ret = initelsa(sp);
+#if CARD_SPORTSTER
+ case ISDN_CTYPE_SPORTSTER:
+ ret = setup_sportster(card);
break;
#endif
-#if CARD_IX1MICROR2
- case ISDN_CTYPE_IX1MICROR2:
- ret = initix1micro(sp);
+#if CARD_MIC
+ case ISDN_CTYPE_MIC:
+ ret = setup_mic(card);
break;
#endif
- default:
- ret = 0;
+#if CARD_NETJET
+ case ISDN_CTYPE_NETJET:
+ ret = setup_netjet(card);
+ break;
+#endif
+#if CARD_TELES3C
+ case ISDN_CTYPE_TELES3C:
+ ret = setup_t163c(card);
+ break;
+#endif
+#if CARD_NICCY
+ case ISDN_CTYPE_NICCY:
+ ret = setup_niccy(card);
+ break;
+#endif
+#if CARD_AMD7930
+ case ISDN_CTYPE_AMD7930:
+ ret = setup_amd7930(card);
break;
+#endif
+ default:
+ printk(KERN_WARNING "HiSax: Unknown Card Typ %d\n",
+ card->typ);
+ ll_unload(cs);
+ restore_flags(flags);
+ return (0);
}
if (!ret) {
+ ll_unload(cs);
+ restore_flags(flags);
+ return (0);
+ }
+ if (!(cs->rcvbuf = kmalloc(MAX_DFRAME_LEN, GFP_ATOMIC))) {
+ printk(KERN_WARNING
+ "HiSax: No memory for isac rcvbuf\n");
+ return (1);
+ }
+ cs->rcvidx = 0;
+ cs->tx_skb = NULL;
+ cs->tx_cnt = 0;
+ cs->event = 0;
+ cs->tqueue.next = 0;
+ cs->tqueue.sync = 0;
+ cs->tqueue.data = cs;
+
+ skb_queue_head_init(&cs->rq);
+ skb_queue_head_init(&cs->sq);
+
+ init_bcstate(cs, 0);
+ init_bcstate(cs, 1);
+ ret = init_card(cs);
+ if (ret) {
closecard(cardnr);
+ restore_flags(flags);
return (0);
}
- init_tei(sp, sp->protocol);
- CallcNewChan(sp);
- ll_run(sp);
+ init_tei(cs, cs->protocol);
+ CallcNewChan(cs);
+ ll_run(cs);
+ cs->l1cmd(cs, PH_RESET_REQ, NULL);
+ restore_flags(flags);
return (1);
}
-void
-HiSax_shiftcards(int idx)
+HISAX_INITFUNC(void
+HiSax_shiftcards(int idx))
{
int i;
@@ -1089,8 +901,8 @@
memcpy(&cards[i], &cards[i + 1], sizeof(cards[i]));
}
-int
-HiSax_inithardware(void)
+HISAX_INITFUNC(int
+HiSax_inithardware(int *busy_flag))
{
int foundcards = 0;
int i = 0;
@@ -1120,15 +932,15 @@
else
sprintf(ids, "%s%d", id, i);
}
- if (checkcard(i, ids)) {
+ if (checkcard(i, ids, busy_flag)) {
foundcards++;
i++;
} else {
printk(KERN_WARNING "HiSax: Card %s not installed !\n",
CardType[cards[i].typ]);
- if (cards[i].sp)
- kfree((void *) cards[i].sp);
- cards[i].sp = NULL;
+ if (cards[i].cs)
+ kfree((void *) cards[i].cs);
+ cards[i].cs = NULL;
HiSax_shiftcards(i);
}
}
@@ -1144,159 +956,66 @@
save_flags(flags);
cli();
for (i = 0; i < nrcards; i++)
- if (cards[i].sp) {
- ll_stop(cards[i].sp);
- CallcFreeChan(cards[i].sp);
- release_tei(cards[i].sp);
- release_irq(i);
+ if (cards[i].cs) {
+ ll_stop(cards[i].cs);
+ release_tei(cards[i].cs);
closecard(i);
- kfree((void *) cards[i].sp);
- cards[i].sp = NULL;
+ free_irq(cards[i].cs->irq, cards[i].cs);
+ kfree((void *) cards[i].cs);
+ cards[i].cs = NULL;
}
+ Isdnl1Free();
+ TeiFree();
Isdnl2Free();
CallcFree();
restore_flags(flags);
}
-static void
-hscx_l2l1(struct PStack *st, int pr, void *arg)
-{
- struct sk_buff *skb = arg;
- struct IsdnCardState *sp = (struct IsdnCardState *) st->l1.hardware;
- struct HscxState *hsp = sp->hs + st->l1.hscx;
- long flags;
-
- switch (pr) {
- case (PH_DATA):
- save_flags(flags);
- cli();
- if (hsp->tx_skb) {
- skb_queue_tail(&hsp->squeue, skb);
- restore_flags(flags);
- } else {
- restore_flags(flags);
- hsp->tx_skb = skb;
- hsp->count = 0;
- sp->hscx_fill_fifo(hsp);
- }
- break;
- case (PH_DATA_PULLED):
- if (hsp->tx_skb) {
- printk(KERN_WARNING "hscx_l2l1: this shouldn't happen\n");
- break;
- }
- hsp->tx_skb = skb;
- hsp->count = 0;
- sp->hscx_fill_fifo(hsp);
- break;
- case (PH_REQUEST_PULL):
- if (!hsp->tx_skb) {
- st->l1.requestpull = 0;
- st->l1.l1l2(st, PH_PULL_ACK, NULL);
- } else
- st->l1.requestpull = !0;
- break;
- }
-
-}
-extern struct IsdnBuffers *tracebuf;
-
-static void
-hscx_l2l1discardq(struct PStack *st, int pr, void *heldby,
- int releasetoo)
-{
- struct IsdnCardState *sp = (struct IsdnCardState *)
- st->l1.hardware;
- struct HscxState *hsp = sp->hs + st->l1.hscx;
- struct sk_buff *skb;
-
-#ifdef DEBUG_MAGIC
- if (hsp->magic != 301270) {
- printk(KERN_DEBUG "hscx_discardq magic not 301270\n");
- return;
- }
-#endif
-
- while ((skb = skb_dequeue(&hsp->squeue))) {
- SET_SKB_FREE(skb);
- dev_kfree_skb(skb);
- }
-}
-
-static int
-open_hscxstate(struct IsdnCardState *sp,
- int hscx)
-{
- struct HscxState *hsp = sp->hs + hscx;
-
- if (!hsp->init) {
- if (!(hsp->rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
- printk(KERN_WARNING
- "HiSax: No memory for hscx_rcvbuf\n");
- return (1);
- }
- skb_queue_head_init(&hsp->rqueue);
- skb_queue_head_init(&hsp->squeue);
- }
- hsp->init = !0;
-
- hsp->tx_skb = NULL;
- hsp->event = 0;
- hsp->rcvidx = 0;
- hsp->tx_cnt = 0;
- return (0);
-}
-
-static void
-hscx_manl1(struct PStack *st, int pr,
- void *arg)
-{
- struct IsdnCardState *sp = (struct IsdnCardState *) st->l1.hardware;
- struct HscxState *hsp = sp->hs + st->l1.hscx;
-
- switch (pr) {
- case (PH_ACTIVATE):
- hsp->active = !0;
- sp->modehscx(hsp, st->l1.hscxmode, st->l1.hscxchannel);
- st->l1.l1man(st, PH_ACTIVATE, NULL);
- break;
- case (PH_DEACTIVATE):
- if (!hsp->tx_skb)
- sp->modehscx(hsp, 0, 0);
-
- hsp->active = 0;
- break;
- }
-}
-
-int
-setstack_hscx(struct PStack *st, struct HscxState *hs)
-{
- if (open_hscxstate(st->l1.hardware, hs->hscx))
- return (-1);
-
- st->l1.hscx = hs->hscx;
- st->l2.l2l1 = hscx_l2l1;
- st->ma.manl1 = hscx_manl1;
- st->l2.l2l1discardq = hscx_l2l1discardq;
-
- st->l1.act_state = 0;
- st->l1.requestpull = 0;
-
- hs->st = st;
- return (0);
-}
-
void
HiSax_reportcard(int cardnr)
{
- struct IsdnCardState *sp = cards[cardnr].sp;
+ struct IsdnCardState *cs = cards[cardnr].cs;
+ struct PStack *stptr;
+ struct l3_process *pc;
+ int j, i = 1;
printk(KERN_DEBUG "HiSax: reportcard No %d\n", cardnr + 1);
- printk(KERN_DEBUG "HiSax: Type %s\n", CardType[sp->typ]);
- printk(KERN_DEBUG "HiSax: debuglevel %x\n", sp->debug);
+ printk(KERN_DEBUG "HiSax: Type %s\n", CardType[cs->typ]);
+ printk(KERN_DEBUG "HiSax: debuglevel %x\n", cs->debug);
printk(KERN_DEBUG "HiSax: HiSax_reportcard address 0x%lX\n",
(ulong) & HiSax_reportcard);
+ printk(KERN_DEBUG "HiSax: cs 0x%lX\n", (ulong) cs);
+ printk(KERN_DEBUG "HiSax: cs stl 0x%lX\n", (ulong) & (cs->stlist));
+ stptr = cs->stlist;
+ while (stptr != NULL) {
+ printk(KERN_DEBUG "HiSax: dst%d 0x%lX\n", i, (ulong) stptr);
+ printk(KERN_DEBUG "HiSax: dst%d stp 0x%lX\n", i, (ulong) stptr->l1.stlistp);
+ printk(KERN_DEBUG "HiSax: tei %d sapi %d\n",
+ stptr->l2.tei, stptr->l2.sap);
+ printk(KERN_DEBUG "HiSax: man 0x%lX\n", (ulong) stptr->ma.layer);
+ pc = stptr->l3.proc;
+ while (pc) {
+ printk(KERN_DEBUG "HiSax: l3proc %x 0x%lX\n", pc->callref,
+ (ulong) pc);
+ printk(KERN_DEBUG "HiSax: state %d st 0x%lX chan 0x%lX\n",
+ pc->state, (ulong) pc->st, (ulong) pc->chan);
+ pc = pc->next;
+ }
+ stptr = stptr->next;
+ i++;
+ }
+ for (j = 0; j < 2; j++) {
+ printk(KERN_DEBUG "HiSax: ch%d 0x%lX\n", j,
+ (ulong) & cs->channel[j]);
+ stptr = cs->channel[j].b_st;
+ i = 1;
+ while (stptr != NULL) {
+ printk(KERN_DEBUG "HiSax: b_st%d 0x%lX\n", i, (ulong) stptr);
+ printk(KERN_DEBUG "HiSax: man 0x%lX\n", (ulong) stptr->ma.layer);
+ stptr = stptr->next;
+ i++;
+ }
+ }
}
#ifdef L2FRAME_DEBUG /* psa */
@@ -1366,7 +1085,7 @@
}
void
-Logl2Frame(struct IsdnCardState *sp, struct sk_buff *skb, char *buf, int dir)
+Logl2Frame(struct IsdnCardState *cs, struct sk_buff *skb, char *buf, int dir)
{
char tmp[132];
u_char *ptr;
@@ -1374,13 +1093,293 @@
ptr = skb->data;
if (ptr[0] & 1 || !(ptr[1] & 1))
- debugl1(sp, "Addres not LAPD");
+ debugl1(cs, "Addres not LAPD");
else {
sprintf(tmp, "%s %s: %s%c (sapi %d, tei %d)",
(dir ? "<-" : "->"), buf, l2frames(ptr),
((ptr[0] & 2) >> 1) == dir ? 'C' : 'R', ptr[0] >> 2, ptr[1] >> 1);
- debugl1(sp, tmp);
+ debugl1(cs, tmp);
}
}
-
#endif
+
+static void
+l1_reset(struct FsmInst *fi, int event, void *arg)
+{
+ FsmChangeState(fi, ST_L1_F3);
+}
+
+static void
+l1_deact_cnf(struct FsmInst *fi, int event, void *arg)
+{
+ struct PStack *st = fi->userdata;
+ struct IsdnCardState *cs = st->l1.hardware;
+
+ FsmChangeState(fi, ST_L1_F3);
+ if (test_bit(FLG_L1_ACTIVATING, &st->l1.Flags))
+ cs->l1cmd(cs, PH_ENABLE_REQ, NULL);
+}
+
+static void
+l1_deact_req(struct FsmInst *fi, int event, void *arg)
+{
+ struct PStack *st = fi->userdata;
+
+ FsmChangeState(fi, ST_L1_F3);
+ if (!test_bit(FLG_L1_T3RUN, &st->l1.Flags)) {
+ FsmDelTimer(&st->l1.timer, 1);
+ FsmAddTimer(&st->l1.timer, 550, EV_TIMER_DEACT, NULL, 2);
+ test_and_set_bit(FLG_L1_DEACTTIMER, &st->l1.Flags);
+ }
+}
+
+static void
+l1_power_up(struct FsmInst *fi, int event, void *arg)
+{
+ struct PStack *st = fi->userdata;
+ struct IsdnCardState *cs = st->l1.hardware;
+
+ if (test_bit(FLG_L1_ACTIVATING, &st->l1.Flags)) {
+ FsmChangeState(fi, ST_L1_F4);
+ cs->l1cmd(cs, PH_INFO3_REQ, NULL);
+ FsmDelTimer(&st->l1.timer, 1);
+ FsmAddTimer(&st->l1.timer, TIMER3_VALUE * HZ, EV_TIMER3, NULL, 2);
+ test_and_set_bit(FLG_L1_T3RUN, &st->l1.Flags);
+ } else
+ FsmChangeState(fi, ST_L1_F3);
+}
+
+static void
+l1_go_F5(struct FsmInst *fi, int event, void *arg)
+{
+ FsmChangeState(fi, ST_L1_F5);
+}
+
+static void
+l1_go_F8(struct FsmInst *fi, int event, void *arg)
+{
+ FsmChangeState(fi, ST_L1_F8);
+}
+
+static void
+l1_info2_ind(struct FsmInst *fi, int event, void *arg)
+{
+ struct PStack *st = fi->userdata;
+ struct IsdnCardState *cs = st->l1.hardware;
+
+ FsmChangeState(fi, ST_L1_F6);
+ cs->l1cmd(cs, PH_INFO3_REQ, NULL);
+}
+
+static void
+l1_info4_ind(struct FsmInst *fi, int event, void *arg)
+{
+ struct PStack *st = fi->userdata;
+ struct IsdnCardState *cs = st->l1.hardware;
+
+ FsmChangeState(fi, ST_L1_F7);
+ cs->l1cmd(cs, PH_INFO3_REQ, NULL);
+ if (test_and_clear_bit(FLG_L1_DEACTTIMER, &st->l1.Flags))
+ FsmDelTimer(&st->l1.timer, 4);
+ if (!test_bit(FLG_L1_ACTIVATED, &st->l1.Flags)) {
+ if (test_and_clear_bit(FLG_L1_T3RUN, &st->l1.Flags))
+ FsmDelTimer(&st->l1.timer, 3);
+ FsmAddTimer(&st->l1.timer, 110, EV_TIMER_ACT, NULL, 2);
+ test_and_set_bit(FLG_L1_ACTTIMER, &st->l1.Flags);
+ }
+}
+
+static void
+l1_timer3(struct FsmInst *fi, int event, void *arg)
+{
+ struct PStack *st = fi->userdata;
+ struct IsdnCardState *cs = st->l1.hardware;
+
+ test_and_clear_bit(FLG_L1_T3RUN, &st->l1.Flags);
+ if (test_and_clear_bit(FLG_L1_ACTIVATING, &st->l1.Flags))
+ L1deactivated(cs);
+ if (st->l1.l1m.state != ST_L1_F6)
+ FsmChangeState(fi, ST_L1_F3);
+}
+
+static void
+l1_timer_act(struct FsmInst *fi, int event, void *arg)
+{
+ struct PStack *st = fi->userdata;
+ struct IsdnCardState *cs = st->l1.hardware;
+
+ test_and_clear_bit(FLG_L1_ACTTIMER, &st->l1.Flags);
+ test_and_set_bit(FLG_L1_ACTIVATED, &st->l1.Flags);
+ L1activated(cs);
+}
+
+static void
+l1_timer_deact(struct FsmInst *fi, int event, void *arg)
+{
+ struct PStack *st = fi->userdata;
+ struct IsdnCardState *cs = st->l1.hardware;
+
+ test_and_clear_bit(FLG_L1_DEACTTIMER, &st->l1.Flags);
+ test_and_clear_bit(FLG_L1_ACTIVATED, &st->l1.Flags);
+ L1deactivated(cs);
+ cs->l1cmd(cs, PH_DEACT_ACK, NULL);
+}
+
+static void
+l1_activate(struct FsmInst *fi, int event, void *arg)
+{
+ struct PStack *st = fi->userdata;
+ struct IsdnCardState *cs = st->l1.hardware;
+
+ cs->l1cmd(cs, PH_RESET_REQ, NULL);
+}
+
+static struct FsmNode L1FnList[] HISAX_INITDATA =
+{
+ {ST_L1_F3, EV_PH_ACTIVATE, l1_activate},
+ {ST_L1_F3, EV_RESET_IND, l1_reset},
+ {ST_L1_F4, EV_RESET_IND, l1_reset},
+ {ST_L1_F5, EV_RESET_IND, l1_reset},
+ {ST_L1_F6, EV_RESET_IND, l1_reset},
+ {ST_L1_F7, EV_RESET_IND, l1_reset},
+ {ST_L1_F8, EV_RESET_IND, l1_reset},
+ {ST_L1_F3, EV_DEACT_CNF, l1_deact_cnf},
+ {ST_L1_F4, EV_DEACT_CNF, l1_deact_cnf},
+ {ST_L1_F5, EV_DEACT_CNF, l1_deact_cnf},
+ {ST_L1_F6, EV_DEACT_CNF, l1_deact_cnf},
+ {ST_L1_F7, EV_DEACT_CNF, l1_deact_cnf},
+ {ST_L1_F8, EV_DEACT_CNF, l1_deact_cnf},
+ {ST_L1_F6, EV_DEACT_IND, l1_deact_req},
+ {ST_L1_F7, EV_DEACT_IND, l1_deact_req},
+ {ST_L1_F8, EV_DEACT_IND, l1_deact_req},
+ {ST_L1_F3, EV_POWER_UP, l1_power_up},
+ {ST_L1_F4, EV_RSYNC_IND, l1_go_F5},
+ {ST_L1_F6, EV_RSYNC_IND, l1_go_F8},
+ {ST_L1_F7, EV_RSYNC_IND, l1_go_F8},
+ {ST_L1_F3, EV_INFO2_IND, l1_info2_ind},
+ {ST_L1_F4, EV_INFO2_IND, l1_info2_ind},
+ {ST_L1_F5, EV_INFO2_IND, l1_info2_ind},
+ {ST_L1_F7, EV_INFO2_IND, l1_info2_ind},
+ {ST_L1_F8, EV_INFO2_IND, l1_info2_ind},
+ {ST_L1_F3, EV_INFO4_IND, l1_info4_ind},
+ {ST_L1_F4, EV_INFO4_IND, l1_info4_ind},
+ {ST_L1_F5, EV_INFO4_IND, l1_info4_ind},
+ {ST_L1_F6, EV_INFO4_IND, l1_info4_ind},
+ {ST_L1_F8, EV_INFO4_IND, l1_info4_ind},
+ {ST_L1_F3, EV_TIMER3, l1_timer3},
+ {ST_L1_F4, EV_TIMER3, l1_timer3},
+ {ST_L1_F5, EV_TIMER3, l1_timer3},
+ {ST_L1_F6, EV_TIMER3, l1_timer3},
+ {ST_L1_F8, EV_TIMER3, l1_timer3},
+ {ST_L1_F7, EV_TIMER_ACT, l1_timer_act},
+ {ST_L1_F3, EV_TIMER_DEACT, l1_timer_deact},
+ {ST_L1_F4, EV_TIMER_DEACT, l1_timer_deact},
+ {ST_L1_F5, EV_TIMER_DEACT, l1_timer_deact},
+ {ST_L1_F6, EV_TIMER_DEACT, l1_timer_deact},
+ {ST_L1_F7, EV_TIMER_DEACT, l1_timer_deact},
+ {ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact},
+};
+
+#define L1_FN_COUNT (sizeof(L1FnList)/sizeof(struct FsmNode))
+
+HISAX_INITFUNC(void Isdnl1New(void))
+{
+ l1fsm.state_count = L1_STATE_COUNT;
+ l1fsm.event_count = L1_EVENT_COUNT;
+ l1fsm.strEvent = strL1Event;
+ l1fsm.strState = strL1State;
+ FsmNew(&l1fsm, L1FnList, L1_FN_COUNT);
+}
+
+void Isdnl1Free(void)
+{
+ FsmFree(&l1fsm);
+}
+
+static void
+dch_manl1(struct PStack *st, int pr,
+ void *arg)
+{
+ struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
+ char tmp[32];
+
+ switch (pr) {
+ case PH_ACTIVATE_REQ:
+ if (cs->debug) {
+ sprintf(tmp, "PH_ACTIVATE_REQ %s",
+ strL1State[st->l1.l1m.state]);
+ debugl1(cs, tmp);
+ }
+ if (test_bit(FLG_L1_ACTIVATED, &st->l1.Flags))
+ st->l1.l1man(st, PH_ACTIVATE_CNF, NULL);
+ else {
+ test_and_set_bit(FLG_L1_ACTIVATING, &st->l1.Flags);
+ FsmEvent(&st->l1.l1m, EV_PH_ACTIVATE, arg);
+ }
+ break;
+ case PH_DEACTIVATE_REQ:
+ if (cs->debug) {
+ sprintf(tmp, "PH_DEACTIVATE_REQ %s",
+ strL1State[st->l1.l1m.state]);
+ debugl1(cs, tmp);
+ }
+ break;
+ case PH_TESTLOOP_REQ:
+ if (1 & (int) arg)
+ debugl1(cs, "PH_TEST_LOOP B1");
+ if (2 & (int) arg)
+ debugl1(cs, "PH_TEST_LOOP B2");
+ if (!(3 & (int) arg))
+ debugl1(cs, "PH_TEST_LOOP DISABLED");
+ cs->l1cmd(cs, PH_TESTLOOP_REQ, arg);
+ break;
+ case PH_RESET_IND:
+ FsmEvent(&st->l1.l1m, EV_RESET_IND, arg);
+ break;
+ case PH_DEACT_CNF:
+ FsmEvent(&st->l1.l1m, EV_DEACT_CNF, arg);
+ break;
+ case PH_DEACT_IND:
+ FsmEvent(&st->l1.l1m, EV_DEACT_IND, arg);
+ break;
+ case PH_POWERUP_CNF:
+ FsmEvent(&st->l1.l1m, EV_POWER_UP, arg);
+ break;
+ case PH_RSYNC_IND:
+ FsmEvent(&st->l1.l1m, EV_RSYNC_IND, arg);
+ break;
+ case PH_INFO2_IND:
+ FsmEvent(&st->l1.l1m, EV_INFO2_IND, arg);
+ break;
+ case PH_I4_P8_IND:
+ case PH_I4_P10_IND:
+ FsmEvent(&st->l1.l1m, EV_INFO4_IND, arg);
+ break;
+ default:
+ if (cs->debug) {
+ sprintf(tmp, "dch_manl1 msg %04X unhandled", pr);
+ debugl1(cs, tmp);
+ }
+ break;
+ }
+}
+
+void
+setstack_HiSax(struct PStack *st, struct IsdnCardState *cs)
+{
+ st->l1.hardware = cs;
+ st->protocol = cs->protocol;
+ st->l1.l1m.fsm = &l1fsm;
+ st->l1.l1m.state = ST_L1_F3;
+ st->l1.l1m.debug = cs->debug;
+ st->l1.l1m.userdata = st;
+ st->l1.l1m.userint = 0;
+ st->l1.l1m.printdebug = l1m_debug;
+ FsmInitTimer(&st->l1.l1m, &st->l1.timer);
+ setstack_tei(st);
+ setstack_manager(st);
+ st->l1.stlistp = &(cs->stlist);
+ st->ma.manl1 = dch_manl1;
+ st->l1.Flags = 0;
+ cs->setstack_d(st, cs);
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov