X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fisdn%2Fcapi%2Fcapi.c;h=9370808bb328057f5379cbb99715bdf5fa52b4f5;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=3429d57e297eef21284108506a0584d91e5ea339;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 3429d57e2..9370808bb 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -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 {