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