Esempio n. 1
0
static ssize_t
capi_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
	struct capidev *cdev = (struct capidev *)file->private_data;
	struct sk_buff *skb;
	int retval;
	__u16 mlen;

        if (ppos != &file->f_pos)
		return -ESPIPE;

	if (!cdev->applid)
		return -ENODEV;

	skb = alloc_skb(count, GFP_USER);
	if (!skb)
		return -ENOMEM;

	if ((retval = copy_from_user(skb_put(skb, count), buf, count))) {
		kfree_skb(skb);
		return -EFAULT;
	}
	mlen = CAPIMSG_LEN(skb->data);
	if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
		if (mlen + CAPIMSG_DATALEN(skb->data) != count) {
			kfree_skb(skb);
			return -EINVAL;
		}
	} else {
		if (mlen != count) {
			kfree_skb(skb);
			return -EINVAL;
		}
	}
	CAPIMSG_SETAPPID(skb->data, cdev->applid);

	cdev->errcode = (*capifuncs->capi_put_message) (cdev->applid, skb);

	if (cdev->errcode) {
		kfree_skb(skb);
		return -EIO;
	}
	if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
		cdev->nsentdatapkt++;
	} else {
		cdev->nsentctlpkt++;
	}
	return count;
}
Esempio n. 2
0
static long capi_write(struct inode *inode, struct file *file,
		       const char *buf, unsigned long count)
#endif
{
	unsigned int minor = MINOR(inode->i_rdev);
	struct capidev *cdev;
	struct sk_buff *skb;
	int retval;
	__u8 cmd;
	__u8 subcmd;
	__u16 mlen;

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

	cdev = &capidevs[minor];

	skb = alloc_skb(count, GFP_USER);

	if ((retval = copy_from_user(skb_put(skb, count), buf, count))) {
		dev_kfree_skb(skb, FREE_WRITE);
		return retval;
	}
	cmd = CAPIMSG_COMMAND(skb->data);
	subcmd = CAPIMSG_SUBCOMMAND(skb->data);
	mlen = CAPIMSG_LEN(skb->data);
	if (cmd == CAPI_DATA_B3 && subcmd == CAPI_REQ) {
		__u16 dlen = CAPIMSG_DATALEN(skb->data);
		if (mlen + dlen != count) {
			dev_kfree_skb(skb, FREE_WRITE);
			return -EINVAL;
		}
	} else if (mlen != count) {
		dev_kfree_skb(skb, FREE_WRITE);
		return -EINVAL;
	}
	CAPIMSG_SETAPPID(skb->data, cdev->applid);

	cdev->errcode = (*capifuncs->capi_put_message) (cdev->applid, skb);

	if (cdev->errcode) {
		dev_kfree_skb(skb, FREE_WRITE);
		return -EIO;
	}
	return count;
}