Exemple #1
0
static long capi_read(struct inode *inode, struct file *file,
		      char *buf, unsigned long count)
#endif
{
	unsigned int minor = MINOR(inode->i_rdev);
	struct capidev *cdev;
	struct sk_buff *skb;
	int retval;
	size_t copied;

	if (!minor || minor > CAPI_MAXMINOR || !capidevs[minor].is_registered)
		return -ENODEV;

	cdev = &capidevs[minor];

	if ((skb = skb_dequeue(&cdev->recv_queue)) == 0) {

		if (file->f_flags & O_NONBLOCK)
			return -EAGAIN;

		for (;;) {
			interruptible_sleep_on(&cdev->recv_wait);
			if ((skb = skb_dequeue(&cdev->recv_queue)) != 0)
				break;
			if (current->signal & ~current->blocked)
				break;
		}
		if (skb == 0)
			return -ERESTARTNOHAND;
	}
	if (skb->len > count) {
		skb_queue_head(&cdev->recv_queue, skb);
		return -EMSGSIZE;
	}
	if (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3
	    && CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND)
		CAPIMSG_SETDATA(skb->data, buf + CAPIMSG_LEN(skb->data));
	retval = copy_to_user(buf, skb->data, skb->len);
	if (retval) {
		skb_queue_head(&cdev->recv_queue, skb);
		return retval;
	}
	copied = skb->len;


	kfree_skb(skb, FREE_READ);

	return copied;
}
Exemple #2
0
void B1_handle_interrupt(avmb1_card * card)
{
	unsigned char b1cmd;
	struct sk_buff *skb;

	unsigned ApplId;
	unsigned MsgLen;
	unsigned DataB3Len;
	unsigned NCCI;
	unsigned WindowSize;

	if (!B1_rx_full(card->port))
		return;

	b1cmd = B1_get_byte(card->port);

	switch (b1cmd) {

	case RECEIVE_DATA_B3_IND:

		ApplId = (unsigned) B1_get_word(card->port);
		MsgLen = B1_get_slice(card->port, card->msgbuf);
		DataB3Len = B1_get_slice(card->port, card->databuf);

		if (showcapimsgs > 2) {
			__u8 cmd = CAPIMSG_COMMAND(card->msgbuf);
			__u8 subcmd = CAPIMSG_SUBCOMMAND(card->msgbuf);
			__u32 contr = CAPIMSG_CONTROL(card->msgbuf);
			CAPIMSG_SETDATA(card->msgbuf, card->databuf);
			if (showcapimsgs & 1) {
				printk(KERN_DEBUG "b1lli: Got [0x%lx] id#%d %s len=%u/%u\n",
				       (unsigned long) contr,
				       CAPIMSG_APPID(card->msgbuf),
				       capi_cmd2str(cmd, subcmd),
				       MsgLen, DataB3Len);
			} else {
				printk(KERN_DEBUG "b1lli: Got [0x%lx] %s\n", (unsigned long)contr, capi_message2str(card->msgbuf));
			}
		}
		if (!(skb = dev_alloc_skb(DataB3Len + MsgLen))) {
			printk(KERN_ERR "b1lli: incoming packet dropped\n");
		} else {
			SET_SKB_FREE(skb);
			memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
			memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);
			CAPIMSG_SETDATA(skb->data, skb->data + MsgLen);
			avmb1_handle_capimsg(card, ApplId, skb);
		}
		break;

	case RECEIVE_MESSAGE:

		ApplId = (unsigned) B1_get_word(card->port);
		MsgLen = B1_get_slice(card->port, card->msgbuf);
		if (showcapimsgs) {
			__u8 cmd = CAPIMSG_COMMAND(card->msgbuf);
			__u8 subcmd = CAPIMSG_SUBCOMMAND(card->msgbuf);
			__u32 contr = CAPIMSG_CONTROL(card->msgbuf);
			if (showcapimsgs & 1) {
				printk(KERN_DEBUG "b1lli: Got [0x%lx] id#%d %s len=%u\n",
				       (unsigned long) contr,
				       CAPIMSG_APPID(card->msgbuf),
				       capi_cmd2str(cmd, subcmd),
				       MsgLen);
			} else {
				printk(KERN_DEBUG "b1lli: Got [0x%lx] %s\n",
						(unsigned long) contr,
						capi_message2str(card->msgbuf));
			}

		}
		if (!(skb = dev_alloc_skb(MsgLen))) {
			printk(KERN_ERR "b1lli: incoming packet dropped\n");
		} else {
			SET_SKB_FREE(skb);
			memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
			avmb1_handle_capimsg(card, ApplId, skb);
		}
		break;

	case RECEIVE_NEW_NCCI:

		ApplId = B1_get_word(card->port);
		NCCI = B1_get_word(card->port);
		WindowSize = B1_get_word(card->port);

		if (showcapimsgs)
			printk(KERN_DEBUG "b1lli: NEW_NCCI app %u ncci 0x%x\n", ApplId, NCCI);

		avmb1_handle_new_ncci(card, ApplId, NCCI, WindowSize);

		break;

	case RECEIVE_FREE_NCCI:

		ApplId = B1_get_word(card->port);
		NCCI = B1_get_word(card->port);

		if (showcapimsgs)
			printk(KERN_DEBUG "b1lli: FREE_NCCI app %u ncci 0x%x\n", ApplId, NCCI);

		avmb1_handle_free_ncci(card, ApplId, NCCI);
		break;

	case RECEIVE_START:
		if (card->blocked)
			printk(KERN_DEBUG "b1lli: RESTART\n");
		card->blocked = 0;
		break;

	case RECEIVE_STOP:
		printk(KERN_DEBUG "b1lli: STOP\n");
		card->blocked = 1;
		break;

	case RECEIVE_INIT:

		card->versionlen = B1_get_slice(card->port, card->versionbuf);
		card->cardstate = CARD_ACTIVE;
		parse_version(card);
		printk(KERN_INFO "b1lli: %s-card (%s) with %s now active\n",
		       card->version[VER_CARDTYPE],
		       card->version[VER_DRIVER],
		       card->version[VER_PROTO]);
		avmb1_card_ready(card);
		break;
	default:
		printk(KERN_ERR "b1lli: B1_handle_interrupt: 0x%x ???\n", b1cmd);
		break;
	}
}