mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 21:22:09 -04:00
msm: mhi-dev: Add support for AIO write API
Diag client uses asynchronous writes for data transfer. Adding write_iter API in mhi to support the same. Change-Id: If14ebdd4aa848046abd15ea93d939691c6962fcd Signed-off-by: Gauri Joshi <gaurjosh@codeaurora.org>
This commit is contained in:
parent
c728c09e3a
commit
8838ca5600
1 changed files with 63 additions and 0 deletions
|
|
@ -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>
|
||||
|
|
@ -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,
|
||||
|
|
@ -1480,6 +1483,65 @@ error_memcpy:
|
|||
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -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…
Reference in a new issue