mISDN: Cleanup debug messages
[safe/jmp/linux-2.6] / drivers / isdn / mISDN / tei.c
index 6fbae42..bfcdd97 100644 (file)
@@ -122,8 +122,11 @@ da_deactivate(struct FsmInst *fi, int event, void *arg)
        }
        read_unlock_irqrestore(&mgr->lock, flags);
        /* All TEI are inactiv */
-       mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, NULL, 1);
-       mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING);
+       if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
+               mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
+                       NULL, 1);
+               mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING);
+       }
 }
 
 static void
@@ -132,9 +135,11 @@ da_ui(struct FsmInst *fi, int event, void *arg)
        struct manager  *mgr = fi->userdata;
 
        /* restart da timer */
-       mISDN_FsmDelTimer(&mgr->datimer, 2);
-       mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, NULL, 2);
-
+       if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
+               mISDN_FsmDelTimer(&mgr->datimer, 2);
+               mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
+                       NULL, 2);
+       }
 }
 
 static void
@@ -222,7 +227,7 @@ tei_debug(struct FsmInst *fi, char *fmt, ...)
        if (!(*debug & DEBUG_L2_TEIFSM))
                return;
        va_start(va, fmt);
-       printk(KERN_DEBUG "tei(%d): ", tm->l2->tei);
+       printk(KERN_DEBUG "sapi(%d) tei(%d): ", tm->l2->sapi, tm->l2->tei);
        vprintk(fmt, va);
        printk("\n");
        va_end(va);
@@ -393,7 +398,7 @@ dl_unit_data(struct manager *mgr, struct sk_buff *skb)
        return 0;
 }
 
-unsigned int
+static unsigned int
 random_ri(void)
 {
        u16 x;
@@ -421,7 +426,7 @@ done:
 }
 
 static void
-put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, u_char tei)
+put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, int tei)
 {
        struct sk_buff *skb;
        u_char bp[8];
@@ -435,9 +440,8 @@ put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, u_char tei)
        bp[4] = ri >> 8;
        bp[5] = ri & 0xff;
        bp[6] = m_id;
-       bp[7] = (tei << 1) | 1;
-       skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr),
-           8, bp, GFP_ATOMIC);
+       bp[7] = ((tei << 1) & 0xff) | 1;
+       skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr), 8, bp, GFP_ATOMIC);
        if (!skb) {
                printk(KERN_WARNING "%s: no skb for tei msg\n", __func__);
                return;
@@ -772,7 +776,7 @@ tei_ph_data_ind(struct teimgr *tm, u_int mt, u_char *dp, int len)
 }
 
 static struct layer2 *
-create_new_tei(struct manager *mgr, int tei)
+create_new_tei(struct manager *mgr, int tei, int sapi)
 {
        u_long          opt = 0;
        u_long          flags;
@@ -781,12 +785,12 @@ create_new_tei(struct manager *mgr, int tei)
 
        if (!mgr->up)
                return NULL;
-       if (tei < 64)
+       if ((tei >= 0) && (tei < 64))
                test_and_set_bit(OPTION_L2_FIXEDTEI, &opt);
        if (mgr->ch.st->dev->Dprotocols
          & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1)))
                test_and_set_bit(OPTION_L2_PMX, &opt);
-       l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, (u_int)opt, (u_long)tei);
+       l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, opt, tei, sapi);
        if (!l2) {
                printk(KERN_WARNING "%s:no memory for layer2\n", __func__);
                return NULL;
@@ -834,12 +838,17 @@ new_tei_req(struct manager *mgr, u_char *dp)
        ri += dp[1];
        if (!mgr->up)
                goto denied;
-       tei = get_free_tei(mgr);
+       if (!(dp[3] & 1)) /* Extension bit != 1 */
+               goto denied;
+       if (dp[3] != 0xff)
+               tei = dp[3] >> 1; /* 3GPP TS 08.56 6.1.11.2 */
+       else
+               tei = get_free_tei(mgr);
        if (tei < 0) {
                printk(KERN_WARNING "%s:No free tei\n", __func__);
                goto denied;
        }
-       l2 = create_new_tei(mgr, tei);
+       l2 = create_new_tei(mgr, tei, CTRL_SAPI);
        if (!l2)
                goto denied;
        else
@@ -863,7 +872,6 @@ ph_data_ind(struct manager *mgr, struct sk_buff *skb)
                            __func__, skb->len);
                goto done;
        }
-       if (*debug  & DEBUG_L2_TEI)
 
        if ((skb->data[0] >> 2) != TEI_SAPI) /* not for us */
                goto done;
@@ -968,11 +976,9 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
 
        if (*debug & DEBUG_L2_TEI)
                printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
-                       __func__, mgr->ch.st->dev->name, crq->protocol,
-                       crq->adr.dev, crq->adr.channel, crq->adr.sapi,
-                       crq->adr.tei);
-       if (crq->adr.sapi != 0) /* not supported yet */
-               return -EINVAL;
+                       __func__, dev_name(&mgr->ch.st->dev->dev),
+                       crq->protocol, crq->adr.dev, crq->adr.channel,
+                       crq->adr.sapi, crq->adr.tei);
        if (crq->adr.tei > GROUP_TEI)
                return -EINVAL;
        if (crq->adr.tei < 64)
@@ -1019,8 +1025,8 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
                }
                return 0;
        }
-       l2 = create_l2(crq->ch, crq->protocol, (u_int)opt,
-               (u_long)crq->adr.tei);
+       l2 = create_l2(crq->ch, crq->protocol, opt,
+               crq->adr.tei, crq->adr.sapi);
        if (!l2)
                return -ENOMEM;
        l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL);
@@ -1103,6 +1109,7 @@ free_teimanager(struct manager *mgr)
 {
        struct layer2   *l2, *nl2;
 
+       test_and_clear_bit(OPTION_L1_HOLD, &mgr->options);
        if (test_bit(MGR_OPT_NETWORK, &mgr->options)) {
                /* not locked lock is taken in release tei */
                mgr->up = NULL;
@@ -1133,13 +1140,26 @@ static int
 ctrl_teimanager(struct manager *mgr, void *arg)
 {
        /* currently we only have one option */
-       int     clean = *((int *)arg);
-
-       if (clean)
-               test_and_set_bit(OPTION_L2_CLEANUP, &mgr->options);
-       else
-               test_and_clear_bit(OPTION_L2_CLEANUP, &mgr->options);
-       return 0;
+       int     *val = (int *)arg;
+       int     ret = 0;
+
+       switch (val[0]) {
+       case IMCLEAR_L2:
+               if (val[1])
+                       test_and_set_bit(OPTION_L2_CLEANUP, &mgr->options);
+               else
+                       test_and_clear_bit(OPTION_L2_CLEANUP, &mgr->options);
+               break;
+       case IMHOLD_L1:
+               if (val[1])
+                       test_and_set_bit(OPTION_L1_HOLD, &mgr->options);
+               else
+                       test_and_clear_bit(OPTION_L1_HOLD, &mgr->options);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+       return ret;
 }
 
 /* This function does create a L2 for fixed TEI in NT Mode */
@@ -1147,7 +1167,7 @@ static int
 check_data(struct manager *mgr, struct sk_buff *skb)
 {
        struct mISDNhead        *hh =  mISDN_HEAD_P(skb);
-       int                     ret, tei;
+       int                     ret, tei, sapi;
        struct layer2           *l2;
 
        if (*debug & DEBUG_L2_CTRL)
@@ -1159,20 +1179,27 @@ check_data(struct manager *mgr, struct sk_buff *skb)
                return -ENOTCONN;
        if (skb->len != 3)
                return -ENOTCONN;
-       if (skb->data[0] != 0)
-               /* only SAPI 0 command */
-               return -ENOTCONN;
+       if (skb->data[0] & 3) /* EA0 and CR must be  0 */
+               return -EINVAL;
+       sapi = skb->data[0] >> 2;
        if (!(skb->data[1] & 1)) /* invalid EA1 */
                return -EINVAL;
-       tei = skb->data[1] >> 0;
+       tei = skb->data[1] >> 1;
        if (tei > 63) /* not a fixed tei */
                return -ENOTCONN;
        if ((skb->data[2] & ~0x10) != SABME)
                return -ENOTCONN;
        /* We got a SABME for a fixed TEI */
-       l2 = create_new_tei(mgr, tei);
-       if (!l2)
+       if (*debug & DEBUG_L2_CTRL)
+               printk(KERN_DEBUG "%s: SABME sapi(%d) tei(%d)\n",
+                   __func__, sapi, tei);
+       l2 = create_new_tei(mgr, tei, sapi);
+       if (!l2) {
+               if (*debug & DEBUG_L2_CTRL)
+                       printk(KERN_DEBUG "%s: failed to create new tei\n",
+                           __func__);
                return -ENOMEM;
+       }
        ret = l2->ch.send(&l2->ch, skb);
        return ret;
 }
@@ -1287,7 +1314,7 @@ create_teimanager(struct mISDNdevice *dev)
        if (!mgr)
                return -ENOMEM;
        INIT_LIST_HEAD(&mgr->layer2);
-       mgr->lock = __RW_LOCK_UNLOCKED(mgr->lock);
+       rwlock_init(&mgr->lock);
        skb_queue_head_init(&mgr->sendq);
        mgr->nextid = 1;
        mgr->lastid = MISDN_ID_NONE;