Loading drivers/platform/msm/mhi_dev/mhi_uci.c +63 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ #include <linux/cdev.h> #include <linux/wait.h> #include <linux/uaccess.h> #include <linux/uio.h> #include <linux/slab.h> #include <linux/poll.h> #include <linux/sched.h> Loading Loading @@ -424,6 +425,8 @@ static ssize_t mhi_uci_ctrl_client_read(struct file *file, char __user *buf, size_t count, loff_t *offp); static ssize_t mhi_uci_client_write(struct file *file, const char __user *buf, size_t count, loff_t *offp); static ssize_t mhi_uci_client_write_iter(struct kiocb *iocb, struct iov_iter *buf); static int mhi_uci_client_open(struct inode *mhi_inode, struct file*); static int mhi_uci_ctrl_open(struct inode *mhi_inode, struct file*); static int mhi_uci_client_release(struct inode *mhi_inode, Loading Loading @@ -1480,6 +1483,65 @@ static ssize_t mhi_uci_client_write(struct file *file, } static ssize_t mhi_uci_client_write_iter(struct kiocb *iocb, struct iov_iter *buf) { struct uci_client *uci_handle = NULL; void *data_loc; unsigned long memcpy_result; int rc; struct file *file = iocb->ki_filp; ssize_t count = iov_iter_count(buf); if (!file || !buf || !count || !file->private_data) { uci_log(UCI_DBG_DBG, "Invalid access to write-iter\n"); return -EINVAL; } uci_handle = file->private_data; if (!uci_handle->send || !uci_handle->out_handle) { uci_log(UCI_DBG_DBG, "Invalid handle or send\n"); return -EINVAL; } if (atomic_read(&uci_ctxt.mhi_disabled)) { uci_log(UCI_DBG_ERROR, "Client %d attempted to write while MHI is disabled\n", uci_handle->out_chan); return -EIO; } if (!mhi_uci_are_channels_connected(uci_handle)) { uci_log(UCI_DBG_ERROR, "%s:Channels are not connected\n", __func__); return -ENODEV; } if (count > TRB_MAX_DATA_SIZE) { uci_log(UCI_DBG_ERROR, "Too big write size: %lu, max supported size is %d\n", count, TRB_MAX_DATA_SIZE); return -EFBIG; } data_loc = kmalloc(count, GFP_KERNEL); if (!data_loc) return -ENOMEM; memcpy_result = copy_from_iter_full(data_loc, count, buf); if (!memcpy_result) { rc = -EFAULT; goto error_memcpy; } rc = mhi_uci_send_packet(uci_handle, data_loc, count); if (rc == count) return rc; error_memcpy: kfree(data_loc); return rc; } void mhi_uci_chan_state_notify_all(struct mhi_dev *mhi, enum mhi_ctrl_info ch_state) { Loading Loading @@ -1877,6 +1939,7 @@ static const struct file_operations mhi_uci_ctrl_client_fops = { static const struct file_operations mhi_uci_client_fops = { .read = mhi_uci_client_read, .write = mhi_uci_client_write, .write_iter = mhi_uci_client_write_iter, .open = mhi_uci_client_open, .release = mhi_uci_client_release, .poll = mhi_uci_client_poll, Loading Loading
drivers/platform/msm/mhi_dev/mhi_uci.c +63 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ #include <linux/cdev.h> #include <linux/wait.h> #include <linux/uaccess.h> #include <linux/uio.h> #include <linux/slab.h> #include <linux/poll.h> #include <linux/sched.h> Loading Loading @@ -424,6 +425,8 @@ static ssize_t mhi_uci_ctrl_client_read(struct file *file, char __user *buf, size_t count, loff_t *offp); static ssize_t mhi_uci_client_write(struct file *file, const char __user *buf, size_t count, loff_t *offp); static ssize_t mhi_uci_client_write_iter(struct kiocb *iocb, struct iov_iter *buf); static int mhi_uci_client_open(struct inode *mhi_inode, struct file*); static int mhi_uci_ctrl_open(struct inode *mhi_inode, struct file*); static int mhi_uci_client_release(struct inode *mhi_inode, Loading Loading @@ -1480,6 +1483,65 @@ static ssize_t mhi_uci_client_write(struct file *file, } static ssize_t mhi_uci_client_write_iter(struct kiocb *iocb, struct iov_iter *buf) { struct uci_client *uci_handle = NULL; void *data_loc; unsigned long memcpy_result; int rc; struct file *file = iocb->ki_filp; ssize_t count = iov_iter_count(buf); if (!file || !buf || !count || !file->private_data) { uci_log(UCI_DBG_DBG, "Invalid access to write-iter\n"); return -EINVAL; } uci_handle = file->private_data; if (!uci_handle->send || !uci_handle->out_handle) { uci_log(UCI_DBG_DBG, "Invalid handle or send\n"); return -EINVAL; } if (atomic_read(&uci_ctxt.mhi_disabled)) { uci_log(UCI_DBG_ERROR, "Client %d attempted to write while MHI is disabled\n", uci_handle->out_chan); return -EIO; } if (!mhi_uci_are_channels_connected(uci_handle)) { uci_log(UCI_DBG_ERROR, "%s:Channels are not connected\n", __func__); return -ENODEV; } if (count > TRB_MAX_DATA_SIZE) { uci_log(UCI_DBG_ERROR, "Too big write size: %lu, max supported size is %d\n", count, TRB_MAX_DATA_SIZE); return -EFBIG; } data_loc = kmalloc(count, GFP_KERNEL); if (!data_loc) return -ENOMEM; memcpy_result = copy_from_iter_full(data_loc, count, buf); if (!memcpy_result) { rc = -EFAULT; goto error_memcpy; } rc = mhi_uci_send_packet(uci_handle, data_loc, count); if (rc == count) return rc; error_memcpy: kfree(data_loc); return rc; } void mhi_uci_chan_state_notify_all(struct mhi_dev *mhi, enum mhi_ctrl_info ch_state) { Loading Loading @@ -1877,6 +1939,7 @@ static const struct file_operations mhi_uci_ctrl_client_fops = { static const struct file_operations mhi_uci_client_fops = { .read = mhi_uci_client_read, .write = mhi_uci_client_write, .write_iter = mhi_uci_client_write_iter, .open = mhi_uci_client_open, .release = mhi_uci_client_release, .poll = mhi_uci_client_poll, Loading