static void handle_minor_send()

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);
}