in capi/capi.c [490:567]
static void handle_minor_send(struct capiminor *mp)
{
struct tty_struct *tty;
struct sk_buff *skb;
u16 len;
u16 errcode;
u16 datahandle;
tty = tty_port_tty_get(&mp->port);
if (!tty)
return;
if (mp->ttyoutstop) {
pr_debug("capi: send: tty stopped\n");
tty_kref_put(tty);
return;
}
while (1) {
spin_lock_bh(&mp->outlock);
skb = __skb_dequeue(&mp->outqueue);
if (!skb) {
spin_unlock_bh(&mp->outlock);
break;
}
len = (u16)skb->len;
mp->outbytes -= len;
spin_unlock_bh(&mp->outlock);
datahandle = atomic_inc_return(&mp->datahandle);
skb_push(skb, CAPI_DATA_B3_REQ_LEN);
memset(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
capimsg_setu16(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
capimsg_setu16(skb->data, 2, mp->ap->applid);
capimsg_setu8 (skb->data, 4, CAPI_DATA_B3);
capimsg_setu8 (skb->data, 5, CAPI_REQ);
capimsg_setu16(skb->data, 6, atomic_inc_return(&mp->msgid));
capimsg_setu32(skb->data, 8, mp->ncci); /* NCCI */
capimsg_setu32(skb->data, 12, (u32)(long)skb->data);/* Data32 */
capimsg_setu16(skb->data, 16, len); /* Data length */
capimsg_setu16(skb->data, 18, datahandle);
capimsg_setu16(skb->data, 20, 0); /* Flags */
if (capiminor_add_ack(mp, datahandle) < 0) {
skb_pull(skb, CAPI_DATA_B3_REQ_LEN);
spin_lock_bh(&mp->outlock);
__skb_queue_head(&mp->outqueue, skb);
mp->outbytes += len;
spin_unlock_bh(&mp->outlock);
break;
}
errcode = capi20_put_message(mp->ap, skb);
if (errcode == CAPI_NOERROR) {
pr_debug("capi: DATA_B3_REQ %u len=%u\n",
datahandle, len);
continue;
}
capiminor_del_ack(mp, datahandle);
if (errcode == CAPI_SENDQUEUEFULL) {
skb_pull(skb, CAPI_DATA_B3_REQ_LEN);
spin_lock_bh(&mp->outlock);
__skb_queue_head(&mp->outqueue, skb);
mp->outbytes += len;
spin_unlock_bh(&mp->outlock);
break;
}
/* ups, drop packet */
printk(KERN_ERR "capi: put_message = %x\n", errcode);
kfree_skb(skb);
}
tty_kref_put(tty);
}