Loading drivers/platform/msm/mhi_dev/mhi.c +16 −13 Original line number Diff line number Diff line Loading @@ -2278,6 +2278,12 @@ static int mhi_dev_process_tre_ring(struct mhi_dev *mhi, ch = &mhi->ch[ring->id - mhi->ch_ring_start]; reason.ch_id = ch->ch_id; reason.reason = MHI_DEV_TRE_AVAILABLE; /* * Save lowest value of tre_len to split packets in UCI layer * for write request of size more than tre_len. */ if (!ch->tre_size || ch->tre_size > el->tre.len) ch->tre_size = el->tre.len; /* Invoke a callback to let the client know its data is ready. * Copy this event to the clients context so that it can be Loading Loading @@ -3466,7 +3472,7 @@ int mhi_dev_read_channel(struct mhi_req *mreq) uint64_t read_from_loc; ssize_t bytes_read = 0; size_t write_to_loc = 0; uint32_t usr_buf_remaining; uint32_t usr_buf_remaining, tre_size; int td_done = 0, rc = 0; struct mhi_dev_client *handle_client; Loading Loading @@ -3509,10 +3515,9 @@ int mhi_dev_read_channel(struct mhi_req *mreq) } el = &ring->ring_cache[ring->rd_offset]; mhi_log(MHI_MSG_VERBOSE, "evtptr : 0x%llx\n", el->tre.data_buf_ptr); mhi_log(MHI_MSG_VERBOSE, "evntlen : 0x%x, offset:%lu\n", el->tre.len, ring->rd_offset); mhi_log(MHI_MSG_VERBOSE, "TRE.PTR: 0x%llx, TRE.LEN: 0x%x, rd offset: %lu\n", el->tre.data_buf_ptr, el->tre.len, ring->rd_offset); if (ch->tre_loc) { bytes_to_read = min(usr_buf_remaining, Loading @@ -3531,17 +3536,15 @@ int mhi_dev_read_channel(struct mhi_req *mreq) ch->tre_loc = el->tre.data_buf_ptr; ch->tre_size = el->tre.len; ch->tre_bytes_left = ch->tre_size; mhi_log(MHI_MSG_VERBOSE, "user_buf_remaining %d, ch->tre_size %d\n", usr_buf_remaining, ch->tre_size); bytes_to_read = min(usr_buf_remaining, ch->tre_size); tre_size = el->tre.len; ch->tre_bytes_left = el->tre.len; mhi_log(MHI_MSG_VERBOSE, "user_buf_remaining %d, tre_size %d\n", usr_buf_remaining, el->tre.len); bytes_to_read = min(usr_buf_remaining, tre_size); } bytes_read += bytes_to_read; addr_offset = ch->tre_size - ch->tre_bytes_left; addr_offset = el->tre.len - ch->tre_bytes_left; read_from_loc = ch->tre_loc + addr_offset; write_to_loc = (size_t) mreq->buf + (mreq->len - usr_buf_remaining); Loading drivers/platform/msm/mhi_dev/mhi_uci.c +82 −18 Original line number Diff line number Diff line Loading @@ -391,6 +391,7 @@ struct uci_client { int (*read)(struct uci_client *h, int *bytes); unsigned int tiocm; unsigned int at_ctrl_mask; int tre_len; }; struct mhi_uci_ctxt_t { Loading Loading @@ -1466,8 +1467,9 @@ static ssize_t mhi_uci_client_write(struct file *file, { struct uci_client *uci_handle = NULL; void *data_loc; const char __user *cur_buf; unsigned long memcpy_result; int rc; int rc = 0, tre_len, cur_rc = 0, count_left, cur_txfr_len; if (!file || !buf || !count || !file->private_data) { uci_log(UCI_DBG_DBG, "Invalid access to write\n"); Loading @@ -1475,6 +1477,8 @@ static ssize_t mhi_uci_client_write(struct file *file, } uci_handle = file->private_data; tre_len = uci_handle->tre_len; if (!uci_handle->send || !uci_handle->out_handle) { uci_log(UCI_DBG_DBG, "Invalid handle or send\n"); return -EINVAL; Loading @@ -1497,17 +1501,47 @@ static ssize_t mhi_uci_client_write(struct file *file, count, uci_handle->out_chan_attr->max_packet_size); } data_loc = kmalloc(count, GFP_KERNEL); if (!data_loc) cur_txfr_len = count; if (!tre_len) uci_log(UCI_DBG_ERROR, "tre_len is 0, not updated yet\n"); else if (count > tre_len) { uci_log(UCI_DBG_DBG, "Write req size (%d) > tre_len (%d)\n", count, tre_len); cur_txfr_len = tre_len; } count_left = count; cur_buf = buf; do { data_loc = kmalloc(cur_txfr_len, GFP_KERNEL); if (!data_loc) { uci_log(UCI_DBG_ERROR, "Memory allocation failed\n"); return -ENOMEM; } memcpy_result = copy_from_user(data_loc, buf, count); memcpy_result = copy_from_user(data_loc, cur_buf, cur_txfr_len); if (memcpy_result) { uci_log(UCI_DBG_ERROR, "Mem copy failed\n"); rc = -EFAULT; goto error_memcpy; } rc = mhi_uci_send_packet(uci_handle, data_loc, count); cur_rc = mhi_uci_send_packet(uci_handle, data_loc, cur_txfr_len); if (cur_rc != cur_txfr_len) { uci_log(UCI_DBG_ERROR, "Send failed with error %d, after sending %d data\n", cur_rc, rc); rc = cur_rc; goto error_memcpy; } rc += cur_rc; cur_buf += cur_txfr_len; count_left -= cur_txfr_len; if (count_left < tre_len) cur_txfr_len = count_left; } while (count_left); if (rc == count) return rc; Loading @@ -1523,7 +1557,7 @@ static ssize_t mhi_uci_client_write_iter(struct kiocb *iocb, struct uci_client *uci_handle = NULL; void *data_loc; unsigned long memcpy_result; int rc; int rc = 0, tre_len, cur_rc = 0, count_left, cur_txfr_len; struct file *file = iocb->ki_filp; ssize_t count = iov_iter_count(buf); Loading @@ -1533,6 +1567,8 @@ static ssize_t mhi_uci_client_write_iter(struct kiocb *iocb, } uci_handle = file->private_data; tre_len = uci_handle->tre_len; if (!uci_handle->send || !uci_handle->out_handle) { uci_log(UCI_DBG_DBG, "Invalid handle or send\n"); return -EINVAL; Loading @@ -1555,17 +1591,44 @@ static ssize_t mhi_uci_client_write_iter(struct kiocb *iocb, count, uci_handle->out_chan_attr->max_packet_size); } data_loc = kmalloc(count, GFP_KERNEL); if (!data_loc) cur_txfr_len = count; if (!tre_len) uci_log(UCI_DBG_ERROR, "tre_len is 0, not updated yet\n"); else if (count > tre_len) { uci_log(UCI_DBG_DBG, "Write req size (%d) > tre_len (%d)\n", count, tre_len); cur_txfr_len = tre_len; } count_left = count; do { data_loc = kmalloc(cur_txfr_len, GFP_KERNEL); if (!data_loc) { uci_log(UCI_DBG_ERROR, "Memory allocation failed\n"); return -ENOMEM; } memcpy_result = copy_from_iter_full(data_loc, count, buf); memcpy_result = copy_from_iter_full(data_loc, cur_txfr_len, buf); if (!memcpy_result) { uci_log(UCI_DBG_ERROR, "Mem copy failed\n"); rc = -EFAULT; goto error_memcpy; } cur_rc = mhi_uci_send_packet(uci_handle, data_loc, cur_txfr_len); if (cur_rc != cur_txfr_len) { uci_log(UCI_DBG_ERROR, "Send failed with error %d, after sending %d data\n", cur_rc, rc); rc = cur_rc; goto error_memcpy; } rc += cur_rc; count_left -= cur_txfr_len; if (count_left < tre_len) cur_txfr_len = count_left; } while (count_left); rc = mhi_uci_send_packet(uci_handle, data_loc, count); if (rc == count) return rc; Loading Loading @@ -1683,6 +1746,7 @@ static void uci_event_notifier(struct mhi_dev_client_cb_reason *reason) uci_handle->in_chan); if (reason->ch_id % 2) { atomic_set(&uci_handle->write_data_ready, 1); uci_handle->tre_len = uci_handle->out_handle->channel->tre_size; wake_up(&uci_handle->write_wq); } else { atomic_set(&uci_handle->read_data_ready, 1); Loading Loading
drivers/platform/msm/mhi_dev/mhi.c +16 −13 Original line number Diff line number Diff line Loading @@ -2278,6 +2278,12 @@ static int mhi_dev_process_tre_ring(struct mhi_dev *mhi, ch = &mhi->ch[ring->id - mhi->ch_ring_start]; reason.ch_id = ch->ch_id; reason.reason = MHI_DEV_TRE_AVAILABLE; /* * Save lowest value of tre_len to split packets in UCI layer * for write request of size more than tre_len. */ if (!ch->tre_size || ch->tre_size > el->tre.len) ch->tre_size = el->tre.len; /* Invoke a callback to let the client know its data is ready. * Copy this event to the clients context so that it can be Loading Loading @@ -3466,7 +3472,7 @@ int mhi_dev_read_channel(struct mhi_req *mreq) uint64_t read_from_loc; ssize_t bytes_read = 0; size_t write_to_loc = 0; uint32_t usr_buf_remaining; uint32_t usr_buf_remaining, tre_size; int td_done = 0, rc = 0; struct mhi_dev_client *handle_client; Loading Loading @@ -3509,10 +3515,9 @@ int mhi_dev_read_channel(struct mhi_req *mreq) } el = &ring->ring_cache[ring->rd_offset]; mhi_log(MHI_MSG_VERBOSE, "evtptr : 0x%llx\n", el->tre.data_buf_ptr); mhi_log(MHI_MSG_VERBOSE, "evntlen : 0x%x, offset:%lu\n", el->tre.len, ring->rd_offset); mhi_log(MHI_MSG_VERBOSE, "TRE.PTR: 0x%llx, TRE.LEN: 0x%x, rd offset: %lu\n", el->tre.data_buf_ptr, el->tre.len, ring->rd_offset); if (ch->tre_loc) { bytes_to_read = min(usr_buf_remaining, Loading @@ -3531,17 +3536,15 @@ int mhi_dev_read_channel(struct mhi_req *mreq) ch->tre_loc = el->tre.data_buf_ptr; ch->tre_size = el->tre.len; ch->tre_bytes_left = ch->tre_size; mhi_log(MHI_MSG_VERBOSE, "user_buf_remaining %d, ch->tre_size %d\n", usr_buf_remaining, ch->tre_size); bytes_to_read = min(usr_buf_remaining, ch->tre_size); tre_size = el->tre.len; ch->tre_bytes_left = el->tre.len; mhi_log(MHI_MSG_VERBOSE, "user_buf_remaining %d, tre_size %d\n", usr_buf_remaining, el->tre.len); bytes_to_read = min(usr_buf_remaining, tre_size); } bytes_read += bytes_to_read; addr_offset = ch->tre_size - ch->tre_bytes_left; addr_offset = el->tre.len - ch->tre_bytes_left; read_from_loc = ch->tre_loc + addr_offset; write_to_loc = (size_t) mreq->buf + (mreq->len - usr_buf_remaining); Loading
drivers/platform/msm/mhi_dev/mhi_uci.c +82 −18 Original line number Diff line number Diff line Loading @@ -391,6 +391,7 @@ struct uci_client { int (*read)(struct uci_client *h, int *bytes); unsigned int tiocm; unsigned int at_ctrl_mask; int tre_len; }; struct mhi_uci_ctxt_t { Loading Loading @@ -1466,8 +1467,9 @@ static ssize_t mhi_uci_client_write(struct file *file, { struct uci_client *uci_handle = NULL; void *data_loc; const char __user *cur_buf; unsigned long memcpy_result; int rc; int rc = 0, tre_len, cur_rc = 0, count_left, cur_txfr_len; if (!file || !buf || !count || !file->private_data) { uci_log(UCI_DBG_DBG, "Invalid access to write\n"); Loading @@ -1475,6 +1477,8 @@ static ssize_t mhi_uci_client_write(struct file *file, } uci_handle = file->private_data; tre_len = uci_handle->tre_len; if (!uci_handle->send || !uci_handle->out_handle) { uci_log(UCI_DBG_DBG, "Invalid handle or send\n"); return -EINVAL; Loading @@ -1497,17 +1501,47 @@ static ssize_t mhi_uci_client_write(struct file *file, count, uci_handle->out_chan_attr->max_packet_size); } data_loc = kmalloc(count, GFP_KERNEL); if (!data_loc) cur_txfr_len = count; if (!tre_len) uci_log(UCI_DBG_ERROR, "tre_len is 0, not updated yet\n"); else if (count > tre_len) { uci_log(UCI_DBG_DBG, "Write req size (%d) > tre_len (%d)\n", count, tre_len); cur_txfr_len = tre_len; } count_left = count; cur_buf = buf; do { data_loc = kmalloc(cur_txfr_len, GFP_KERNEL); if (!data_loc) { uci_log(UCI_DBG_ERROR, "Memory allocation failed\n"); return -ENOMEM; } memcpy_result = copy_from_user(data_loc, buf, count); memcpy_result = copy_from_user(data_loc, cur_buf, cur_txfr_len); if (memcpy_result) { uci_log(UCI_DBG_ERROR, "Mem copy failed\n"); rc = -EFAULT; goto error_memcpy; } rc = mhi_uci_send_packet(uci_handle, data_loc, count); cur_rc = mhi_uci_send_packet(uci_handle, data_loc, cur_txfr_len); if (cur_rc != cur_txfr_len) { uci_log(UCI_DBG_ERROR, "Send failed with error %d, after sending %d data\n", cur_rc, rc); rc = cur_rc; goto error_memcpy; } rc += cur_rc; cur_buf += cur_txfr_len; count_left -= cur_txfr_len; if (count_left < tre_len) cur_txfr_len = count_left; } while (count_left); if (rc == count) return rc; Loading @@ -1523,7 +1557,7 @@ static ssize_t mhi_uci_client_write_iter(struct kiocb *iocb, struct uci_client *uci_handle = NULL; void *data_loc; unsigned long memcpy_result; int rc; int rc = 0, tre_len, cur_rc = 0, count_left, cur_txfr_len; struct file *file = iocb->ki_filp; ssize_t count = iov_iter_count(buf); Loading @@ -1533,6 +1567,8 @@ static ssize_t mhi_uci_client_write_iter(struct kiocb *iocb, } uci_handle = file->private_data; tre_len = uci_handle->tre_len; if (!uci_handle->send || !uci_handle->out_handle) { uci_log(UCI_DBG_DBG, "Invalid handle or send\n"); return -EINVAL; Loading @@ -1555,17 +1591,44 @@ static ssize_t mhi_uci_client_write_iter(struct kiocb *iocb, count, uci_handle->out_chan_attr->max_packet_size); } data_loc = kmalloc(count, GFP_KERNEL); if (!data_loc) cur_txfr_len = count; if (!tre_len) uci_log(UCI_DBG_ERROR, "tre_len is 0, not updated yet\n"); else if (count > tre_len) { uci_log(UCI_DBG_DBG, "Write req size (%d) > tre_len (%d)\n", count, tre_len); cur_txfr_len = tre_len; } count_left = count; do { data_loc = kmalloc(cur_txfr_len, GFP_KERNEL); if (!data_loc) { uci_log(UCI_DBG_ERROR, "Memory allocation failed\n"); return -ENOMEM; } memcpy_result = copy_from_iter_full(data_loc, count, buf); memcpy_result = copy_from_iter_full(data_loc, cur_txfr_len, buf); if (!memcpy_result) { uci_log(UCI_DBG_ERROR, "Mem copy failed\n"); rc = -EFAULT; goto error_memcpy; } cur_rc = mhi_uci_send_packet(uci_handle, data_loc, cur_txfr_len); if (cur_rc != cur_txfr_len) { uci_log(UCI_DBG_ERROR, "Send failed with error %d, after sending %d data\n", cur_rc, rc); rc = cur_rc; goto error_memcpy; } rc += cur_rc; count_left -= cur_txfr_len; if (count_left < tre_len) cur_txfr_len = count_left; } while (count_left); rc = mhi_uci_send_packet(uci_handle, data_loc, count); if (rc == count) return rc; Loading Loading @@ -1683,6 +1746,7 @@ static void uci_event_notifier(struct mhi_dev_client_cb_reason *reason) uci_handle->in_chan); if (reason->ch_id % 2) { atomic_set(&uci_handle->write_data_ready, 1); uci_handle->tre_len = uci_handle->out_handle->channel->tre_size; wake_up(&uci_handle->write_wq); } else { atomic_set(&uci_handle->read_data_ready, 1); Loading