vserver 1.9.3
[linux-2.6.git] / drivers / isdn / capi / capi.c
index 3429d57..9370808 100644 (file)
@@ -436,51 +436,62 @@ static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
        struct sk_buff *nskb;
        int datalen;
        u16 errcode, datahandle;
-
+       struct tty_ldisc *ld;
+       
        datalen = skb->len - CAPIMSG_LEN(skb->data);
-       if (mp->tty) {
-               if (mp->tty->ldisc.receive_buf == 0) {
-                       printk(KERN_ERR "capi: ldisc has no receive_buf function\n");
-                       return -1;
-               }
-               if (mp->ttyinstop) {
+       if (mp->tty == NULL)
+       {
+#ifdef _DEBUG_DATAFLOW
+               printk(KERN_DEBUG "capi: currently no receiver\n");
+#endif
+               return -1;
+       }
+       
+       ld = tty_ldisc_ref(mp->tty);
+       if (ld == NULL)
+               return -1;
+       if (ld->receive_buf == NULL) {
 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
-                       printk(KERN_DEBUG "capi: recv tty throttled\n");
+               printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n");
 #endif
-                       return -1;
-               }
-               if (mp->tty->ldisc.receive_room &&
-                   mp->tty->ldisc.receive_room(mp->tty) < datalen) {
+               goto bad;
+       }
+       if (mp->ttyinstop) {
 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
-                       printk(KERN_DEBUG "capi: no room in tty\n");
+               printk(KERN_DEBUG "capi: recv tty throttled\n");
 #endif
-                       return -1;
-               }
-               if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) {
-                       printk(KERN_ERR "capi: gen_data_b3_resp failed\n");
-                       return -1;
-               }
-               datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4);
-               errcode = capi20_put_message(mp->ap, nskb);
-               if (errcode != CAPI_NOERROR) {
-                       printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
-                                       errcode);
-                       kfree_skb(nskb);
-                       return -1;
-               }
-               (void)skb_pull(skb, CAPIMSG_LEN(skb->data));
-#ifdef _DEBUG_DATAFLOW
-               printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
-                                       datahandle, skb->len);
+               goto bad;
+       }
+       if (ld->receive_room &&
+           ld->receive_room(mp->tty) < datalen) {
+#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
+               printk(KERN_DEBUG "capi: no room in tty\n");
 #endif
-               mp->tty->ldisc.receive_buf(mp->tty, skb->data, NULL, skb->len);
-               kfree_skb(skb);
-               return 0;
-
+               goto bad;
        }
+       if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) {
+               printk(KERN_ERR "capi: gen_data_b3_resp failed\n");
+               goto bad;
+       }
+       datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4);
+       errcode = capi20_put_message(mp->ap, nskb);
+       if (errcode != CAPI_NOERROR) {
+               printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
+                               errcode);
+               kfree_skb(nskb);
+               goto bad;
+       }
+       (void)skb_pull(skb, CAPIMSG_LEN(skb->data));
 #ifdef _DEBUG_DATAFLOW
-       printk(KERN_DEBUG "capi: currently no receiver\n");
+       printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
+                               datahandle, skb->len);
 #endif
+       ld->receive_buf(mp->tty, skb->data, NULL, skb->len);
+       kfree_skb(skb);
+       tty_ldisc_deref(ld);
+       return 0;
+bad:
+       tty_ldisc_deref(ld);
        return -1;
 }
 
@@ -614,6 +625,7 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
 
 
        if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
+               
                datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2);
 #ifdef _DEBUG_DATAFLOW
                printk(KERN_DEBUG "capi_signal: DATA_B3_IND %u len=%d\n",
@@ -633,10 +645,8 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
 #endif
                kfree_skb(skb);
                (void)capiminor_del_ack(mp, datahandle);
-               if (mp->tty) {
-                       if (mp->tty->ldisc.write_wakeup)
-                               mp->tty->ldisc.write_wakeup(mp->tty);
-               }
+               if (mp->tty)
+                       tty_wakeup(mp->tty);
                (void)handle_minor_send(mp);
 
        } else {