Loading drivers/platform/msm/mhi/mhi_main.c +9 −7 Original line number Diff line number Diff line /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -546,7 +546,8 @@ void reset_bb_ctxt(struct mhi_device_ctxt *mhi_dev_ctxt, mhi_log(MHI_MSG_VERBOSE, "Exited\n"); } static enum MHI_STATUS mhi_queue_xfer(struct mhi_client_handle *client_handle, static enum MHI_STATUS mhi_queue_dma_xfer( struct mhi_client_handle *client_handle, dma_addr_t buf, size_t buf_len, enum MHI_FLAGS mhi_flags) { union mhi_xfer_pkt *pkt_loc; Loading Loading @@ -609,9 +610,8 @@ error: pm_runtime_put_noidle(&mhi_dev_ctxt->dev_info->plat_dev->dev); return ret_val; } EXPORT_SYMBOL(mhi_queue_xfer); int mhi_queue_virt_xfer(struct mhi_client_handle *client_handle, int mhi_queue_xfer(struct mhi_client_handle *client_handle, void *buf, size_t buf_len, enum MHI_FLAGS mhi_flags) { int r; Loading Loading @@ -640,18 +640,20 @@ int mhi_queue_virt_xfer(struct mhi_client_handle *client_handle, "Queueing to HW: Client Buf 0x%p, size 0x%zx, DMA %llx, chan %d\n", buf, buf_len, (u64)bb->bb_p_addr, client_handle->chan_info.chan_nr); r = mhi_queue_xfer(client_handle, r = mhi_queue_dma_xfer(client_handle, bb->bb_p_addr, bb->buf_len, mhi_flags); /* Assumption: If create_bb did not fail, we do not * expect mhi_queue_xfer to fail, if it does, the bb list will be /* * Assumption: If create_bounce_buffer did not fail, we do not * expect mhi_queue_dma_xfer to fail, if it does, the bb list will be * out of sync with the descriptor list which is problematic. */ BUG_ON(r); return r; } EXPORT_SYMBOL(mhi_queue_xfer); enum MHI_STATUS mhi_send_cmd(struct mhi_device_ctxt *mhi_dev_ctxt, enum MHI_COMMAND cmd, u32 chan) Loading drivers/platform/msm/mhi_uci/mhi_uci.c +23 −67 Original line number Diff line number Diff line /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -24,7 +24,6 @@ #include <linux/tty.h> #include <linux/delay.h> #include <linux/ipc_logging.h> #include <linux/dma-mapping.h> #include <linux/device.h> #define MHI_DEV_NODE_NAME_LEN 13 Loading Loading @@ -115,7 +114,7 @@ struct uci_client { int mhi_status; void *pkt_loc; size_t pkt_size; dma_addr_t *in_buf_list; void **in_buf_list; atomic_t out_pkt_pend_ack; atomic_t mhi_disabled; struct mhi_uci_ctxt_t *uci_ctxt; Loading Loading @@ -256,7 +255,6 @@ static enum MHI_STATUS mhi_init_inbound(struct uci_client *client_handle, { enum MHI_STATUS ret_val = MHI_STATUS_SUCCESS; u32 i = 0; dma_addr_t dma_addr = 0; struct chan_attr *chan_attributes = &uci_ctxt.chan_attrib[chan]; void *data_loc = NULL; Loading @@ -269,7 +267,7 @@ static enum MHI_STATUS mhi_init_inbound(struct uci_client *client_handle, chan_attributes->nr_trbs = mhi_get_free_desc(client_handle->in_handle); client_handle->in_buf_list = kmalloc(sizeof(dma_addr_t) * chan_attributes->nr_trbs, kmalloc(sizeof(void *) * chan_attributes->nr_trbs, GFP_KERNEL); if (!client_handle->in_buf_list) return MHI_STATUS_ERROR; Loading @@ -282,18 +280,10 @@ static enum MHI_STATUS mhi_init_inbound(struct uci_client *client_handle, data_loc, buf_size); if (data_loc == NULL) return -ENOMEM; dma_addr = dma_map_single(NULL, data_loc, buf_size, DMA_FROM_DEVICE); if (dma_mapping_error(NULL, dma_addr)) { uci_log(UCI_DBG_ERROR, "Failed to Map DMA\n"); return -ENOMEM; } client_handle->in_buf_list[i] = dma_addr; client_handle->in_buf_list[i] = data_loc; ret_val = mhi_queue_xfer(client_handle->in_handle, dma_addr, buf_size, MHI_EOT); data_loc, buf_size, MHI_EOT); if (MHI_STATUS_SUCCESS != ret_val) { dma_unmap_single(NULL, dma_addr, buf_size, DMA_FROM_DEVICE); kfree(data_loc); uci_log(UCI_DBG_ERROR, "Failed insertion for chan %d, ret %d\n", Loading @@ -314,7 +304,6 @@ static int mhi_uci_send_packet(struct mhi_client_handle **client_handle, int data_left_to_insert = 0; size_t data_to_insert_now = 0; u32 data_inserted_so_far = 0; dma_addr_t dma_addr = 0; int ret_val = 0; enum MHI_FLAGS flags; struct uci_client *uci_handle; Loading Loading @@ -353,27 +342,19 @@ static int mhi_uci_send_packet(struct mhi_client_handle **client_handle, data_loc = buf; } dma_addr = dma_map_single(NULL, data_loc, data_to_insert_now, DMA_TO_DEVICE); if (dma_mapping_error(NULL, dma_addr)) { uci_log(UCI_DBG_ERROR, "Failed to Map DMA 0x%x\n", size); data_inserted_so_far = -ENOMEM; goto error_memcpy; } flags = MHI_EOT; if (data_left_to_insert - data_to_insert_now > 0) flags |= MHI_CHAIN | MHI_EOB; uci_log(UCI_DBG_VERBOSE, "At trb i = %d/%d, chain = %d, eob = %d, addr 0x%lx chan %d\n", "At trb i = %d/%d, chain = %d, eob = %d, addr 0x%p chan %d\n", i, nr_avail_trbs, flags & MHI_CHAIN, flags & MHI_EOB, (uintptr_t)dma_addr, data_loc, uci_handle->out_chan); ret_val = mhi_queue_xfer(*client_handle, dma_addr, ret_val = mhi_queue_xfer(*client_handle, data_loc, data_to_insert_now, flags); if (0 != ret_val) { goto error_queue; } else { Loading @@ -387,10 +368,6 @@ static int mhi_uci_send_packet(struct mhi_client_handle **client_handle, return data_inserted_so_far; error_queue: dma_unmap_single(NULL, (dma_addr_t)dma_addr, data_to_insert_now, DMA_TO_DEVICE); error_memcpy: kfree(data_loc); return data_inserted_so_far; Loading Loading @@ -676,10 +653,6 @@ static int mhi_uci_client_release(struct inode *mhi_inode, uci_handle->in_chan_state = 0; atomic_set(&uci_handle->out_pkt_pend_ack, 0); for (i = 0; i < nr_in_bufs; ++i) { dma_unmap_single(NULL, uci_handle->in_buf_list[i], buf_size, DMA_FROM_DEVICE); kfree((void *)uci_handle->in_buf_list[i]); } kfree(uci_handle->in_buf_list); Loading @@ -697,7 +670,6 @@ static ssize_t mhi_uci_client_read(struct file *file, char __user *buf, size_t uspace_buf_size, loff_t *bytes_pending) { struct uci_client *uci_handle = NULL; uintptr_t phy_buf = 0; struct mhi_client_handle *client_handle = NULL; int ret_val = 0; size_t buf_size = 0; Loading Loading @@ -728,19 +700,16 @@ static ssize_t mhi_uci_client_read(struct file *file, char __user *buf, "Failed to poll inbound ret %d avail pkt %d\n", ret_val, atomic_read(&uci_handle->avail_pkts)); } phy_buf = result.payload_buf; if (phy_buf != 0) uci_handle->pkt_loc = (void *)phy_buf; if (result.buf_addr) uci_handle->pkt_loc = result.buf_addr; else uci_handle->pkt_loc = 0; uci_handle->pkt_size = result.bytes_xferd; *bytes_pending = uci_handle->pkt_size; uci_log(UCI_DBG_VERBOSE, "Got pkt of size 0x%zx at addr 0x%lx, chan %d\n", uci_handle->pkt_size, (uintptr_t)phy_buf, chan); dma_unmap_single(NULL, (dma_addr_t)phy_buf, buf_size, DMA_FROM_DEVICE); "Got pkt size 0x%zx at addr 0x%lx, chan %d\n", uci_handle->pkt_size, (uintptr_t)result.buf_addr, chan); } if ((*bytes_pending == 0 || uci_handle->pkt_loc == 0) && (atomic_read(&uci_handle->avail_pkts) <= 0)) { Loading Loading @@ -774,9 +743,9 @@ static ssize_t mhi_uci_client_read(struct file *file, char __user *buf, uci_handle->pkt_size != 0 && uci_handle->pkt_loc != 0) { uci_log(UCI_DBG_VERBOSE, "Got packet: avail pkts %d phy_adr 0x%lx, chan %d\n", "Got packet: avail pkts %d phy_adr 0x%p, chan %d\n", atomic_read(&uci_handle->avail_pkts), phy_buf, result.buf_addr, chan); break; /* Loading @@ -785,10 +754,10 @@ static ssize_t mhi_uci_client_read(struct file *file, char __user *buf, */ } else { uci_log(UCI_DBG_CRITICAL, "chan %d err: avail pkts %d phy_adr 0x%lx mhi_stat%d\n", "chan %d err: avail pkts %d phy_adr 0x%p mhi_stat%d\n", chan, atomic_read(&uci_handle->avail_pkts), phy_buf, result.buf_addr, uci_handle->mhi_status); return -EIO; } Loading Loading @@ -830,16 +799,12 @@ static ssize_t mhi_uci_client_read(struct file *file, char __user *buf, uci_log(UCI_DBG_VERBOSE, "Pkt loc %p ,chan %d\n", uci_handle->pkt_loc, chan); memset(uci_handle->pkt_loc, 0, buf_size); phy_buf = dma_map_single(NULL, uci_handle->pkt_loc, buf_size, DMA_FROM_DEVICE); atomic_dec(&uci_handle->avail_pkts); uci_log(UCI_DBG_VERBOSE, "Decremented avail pkts avail 0x%x\n", atomic_read(&uci_handle->avail_pkts)); ret_val = mhi_queue_xfer(client_handle, phy_buf, ret_val = mhi_queue_xfer(client_handle, uci_handle->pkt_loc, buf_size, MHI_EOT); if (MHI_STATUS_SUCCESS != ret_val) { uci_log(UCI_DBG_ERROR, "Failed to recycle element\n"); Loading Loading @@ -987,13 +952,11 @@ static void process_rs232_state(struct mhi_result *result) } if (result->bytes_xferd != sizeof(struct rs232_ctrl_msg)) { uci_log(UCI_DBG_ERROR, "Buffer is of wrong size is: 0x%x: expected 0x%zx\n", "Buffer is of wrong size is: 0x%zx: expected 0x%zx\n", result->bytes_xferd, sizeof(struct rs232_ctrl_msg)); goto error_size; } dma_unmap_single(NULL, result->payload_buf, result->bytes_xferd, DMA_FROM_DEVICE); rs232_pkt = (void *)result->payload_buf; rs232_pkt = result->buf_addr; MHI_GET_CTRL_DEST_ID(CTRL_DEST_ID, rs232_pkt, chan); client = &uci_ctxt.client_handles[chan / 2]; Loading @@ -1014,11 +977,8 @@ static void process_rs232_state(struct mhi_result *result) error_bad_xfer: error_size: memset(rs232_pkt, 0, sizeof(struct rs232_ctrl_msg)); dma_map_single(NULL, rs232_pkt, sizeof(struct rs232_ctrl_msg), DMA_FROM_DEVICE); ret_val = mhi_queue_xfer(client->in_handle, result->payload_buf, result->buf_addr, result->bytes_xferd, result->flags); if (MHI_STATUS_SUCCESS != ret_val) { Loading @@ -1044,11 +1004,7 @@ static void parse_inbound_ack(struct uci_client *uci_handle, static void parse_outbound_ack(struct uci_client *uci_handle, struct mhi_result *result) { dma_unmap_single(NULL, result->payload_buf, result->bytes_xferd, DMA_TO_DEVICE); kfree((void *) result->payload_buf); kfree(result->buf_addr); uci_log(UCI_DBG_VERBOSE, "Received ack on chan %d, pending acks: 0x%x\n", uci_handle->out_chan, Loading include/linux/msm_mhi.h +7 −5 Original line number Diff line number Diff line /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -113,8 +113,8 @@ enum MHI_FLAGS { struct mhi_result { void *user_data; dma_addr_t payload_buf; u32 bytes_xferd; void *buf_addr; size_t bytes_xferd; enum MHI_STATUS transaction_status; enum MHI_FLAGS flags; }; Loading Loading @@ -180,12 +180,14 @@ enum MHI_STATUS mhi_open_channel(struct mhi_client_handle *client_handle); * @chain Specify whether to set the chain bit on this buffer * @eob Specify whether this buffer should trigger EOB interrupt * * NOTE: * Not thread safe, caller must ensure concurrency protection. * User buffer must be physically contiguous. * * @Return MHI_STATUS */ enum MHI_STATUS mhi_queue_xfer(struct mhi_client_handle *client_handle, dma_addr_t buf, size_t buf_len, enum MHI_FLAGS flags); int mhi_queue_xfer(struct mhi_client_handle *client_handle, void *buf, size_t buf_len, enum MHI_FLAGS mhi_flags); /** * mhi_close_channel - Client can request channel to be closed and handle freed Loading Loading
drivers/platform/msm/mhi/mhi_main.c +9 −7 Original line number Diff line number Diff line /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -546,7 +546,8 @@ void reset_bb_ctxt(struct mhi_device_ctxt *mhi_dev_ctxt, mhi_log(MHI_MSG_VERBOSE, "Exited\n"); } static enum MHI_STATUS mhi_queue_xfer(struct mhi_client_handle *client_handle, static enum MHI_STATUS mhi_queue_dma_xfer( struct mhi_client_handle *client_handle, dma_addr_t buf, size_t buf_len, enum MHI_FLAGS mhi_flags) { union mhi_xfer_pkt *pkt_loc; Loading Loading @@ -609,9 +610,8 @@ error: pm_runtime_put_noidle(&mhi_dev_ctxt->dev_info->plat_dev->dev); return ret_val; } EXPORT_SYMBOL(mhi_queue_xfer); int mhi_queue_virt_xfer(struct mhi_client_handle *client_handle, int mhi_queue_xfer(struct mhi_client_handle *client_handle, void *buf, size_t buf_len, enum MHI_FLAGS mhi_flags) { int r; Loading Loading @@ -640,18 +640,20 @@ int mhi_queue_virt_xfer(struct mhi_client_handle *client_handle, "Queueing to HW: Client Buf 0x%p, size 0x%zx, DMA %llx, chan %d\n", buf, buf_len, (u64)bb->bb_p_addr, client_handle->chan_info.chan_nr); r = mhi_queue_xfer(client_handle, r = mhi_queue_dma_xfer(client_handle, bb->bb_p_addr, bb->buf_len, mhi_flags); /* Assumption: If create_bb did not fail, we do not * expect mhi_queue_xfer to fail, if it does, the bb list will be /* * Assumption: If create_bounce_buffer did not fail, we do not * expect mhi_queue_dma_xfer to fail, if it does, the bb list will be * out of sync with the descriptor list which is problematic. */ BUG_ON(r); return r; } EXPORT_SYMBOL(mhi_queue_xfer); enum MHI_STATUS mhi_send_cmd(struct mhi_device_ctxt *mhi_dev_ctxt, enum MHI_COMMAND cmd, u32 chan) Loading
drivers/platform/msm/mhi_uci/mhi_uci.c +23 −67 Original line number Diff line number Diff line /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -24,7 +24,6 @@ #include <linux/tty.h> #include <linux/delay.h> #include <linux/ipc_logging.h> #include <linux/dma-mapping.h> #include <linux/device.h> #define MHI_DEV_NODE_NAME_LEN 13 Loading Loading @@ -115,7 +114,7 @@ struct uci_client { int mhi_status; void *pkt_loc; size_t pkt_size; dma_addr_t *in_buf_list; void **in_buf_list; atomic_t out_pkt_pend_ack; atomic_t mhi_disabled; struct mhi_uci_ctxt_t *uci_ctxt; Loading Loading @@ -256,7 +255,6 @@ static enum MHI_STATUS mhi_init_inbound(struct uci_client *client_handle, { enum MHI_STATUS ret_val = MHI_STATUS_SUCCESS; u32 i = 0; dma_addr_t dma_addr = 0; struct chan_attr *chan_attributes = &uci_ctxt.chan_attrib[chan]; void *data_loc = NULL; Loading @@ -269,7 +267,7 @@ static enum MHI_STATUS mhi_init_inbound(struct uci_client *client_handle, chan_attributes->nr_trbs = mhi_get_free_desc(client_handle->in_handle); client_handle->in_buf_list = kmalloc(sizeof(dma_addr_t) * chan_attributes->nr_trbs, kmalloc(sizeof(void *) * chan_attributes->nr_trbs, GFP_KERNEL); if (!client_handle->in_buf_list) return MHI_STATUS_ERROR; Loading @@ -282,18 +280,10 @@ static enum MHI_STATUS mhi_init_inbound(struct uci_client *client_handle, data_loc, buf_size); if (data_loc == NULL) return -ENOMEM; dma_addr = dma_map_single(NULL, data_loc, buf_size, DMA_FROM_DEVICE); if (dma_mapping_error(NULL, dma_addr)) { uci_log(UCI_DBG_ERROR, "Failed to Map DMA\n"); return -ENOMEM; } client_handle->in_buf_list[i] = dma_addr; client_handle->in_buf_list[i] = data_loc; ret_val = mhi_queue_xfer(client_handle->in_handle, dma_addr, buf_size, MHI_EOT); data_loc, buf_size, MHI_EOT); if (MHI_STATUS_SUCCESS != ret_val) { dma_unmap_single(NULL, dma_addr, buf_size, DMA_FROM_DEVICE); kfree(data_loc); uci_log(UCI_DBG_ERROR, "Failed insertion for chan %d, ret %d\n", Loading @@ -314,7 +304,6 @@ static int mhi_uci_send_packet(struct mhi_client_handle **client_handle, int data_left_to_insert = 0; size_t data_to_insert_now = 0; u32 data_inserted_so_far = 0; dma_addr_t dma_addr = 0; int ret_val = 0; enum MHI_FLAGS flags; struct uci_client *uci_handle; Loading Loading @@ -353,27 +342,19 @@ static int mhi_uci_send_packet(struct mhi_client_handle **client_handle, data_loc = buf; } dma_addr = dma_map_single(NULL, data_loc, data_to_insert_now, DMA_TO_DEVICE); if (dma_mapping_error(NULL, dma_addr)) { uci_log(UCI_DBG_ERROR, "Failed to Map DMA 0x%x\n", size); data_inserted_so_far = -ENOMEM; goto error_memcpy; } flags = MHI_EOT; if (data_left_to_insert - data_to_insert_now > 0) flags |= MHI_CHAIN | MHI_EOB; uci_log(UCI_DBG_VERBOSE, "At trb i = %d/%d, chain = %d, eob = %d, addr 0x%lx chan %d\n", "At trb i = %d/%d, chain = %d, eob = %d, addr 0x%p chan %d\n", i, nr_avail_trbs, flags & MHI_CHAIN, flags & MHI_EOB, (uintptr_t)dma_addr, data_loc, uci_handle->out_chan); ret_val = mhi_queue_xfer(*client_handle, dma_addr, ret_val = mhi_queue_xfer(*client_handle, data_loc, data_to_insert_now, flags); if (0 != ret_val) { goto error_queue; } else { Loading @@ -387,10 +368,6 @@ static int mhi_uci_send_packet(struct mhi_client_handle **client_handle, return data_inserted_so_far; error_queue: dma_unmap_single(NULL, (dma_addr_t)dma_addr, data_to_insert_now, DMA_TO_DEVICE); error_memcpy: kfree(data_loc); return data_inserted_so_far; Loading Loading @@ -676,10 +653,6 @@ static int mhi_uci_client_release(struct inode *mhi_inode, uci_handle->in_chan_state = 0; atomic_set(&uci_handle->out_pkt_pend_ack, 0); for (i = 0; i < nr_in_bufs; ++i) { dma_unmap_single(NULL, uci_handle->in_buf_list[i], buf_size, DMA_FROM_DEVICE); kfree((void *)uci_handle->in_buf_list[i]); } kfree(uci_handle->in_buf_list); Loading @@ -697,7 +670,6 @@ static ssize_t mhi_uci_client_read(struct file *file, char __user *buf, size_t uspace_buf_size, loff_t *bytes_pending) { struct uci_client *uci_handle = NULL; uintptr_t phy_buf = 0; struct mhi_client_handle *client_handle = NULL; int ret_val = 0; size_t buf_size = 0; Loading Loading @@ -728,19 +700,16 @@ static ssize_t mhi_uci_client_read(struct file *file, char __user *buf, "Failed to poll inbound ret %d avail pkt %d\n", ret_val, atomic_read(&uci_handle->avail_pkts)); } phy_buf = result.payload_buf; if (phy_buf != 0) uci_handle->pkt_loc = (void *)phy_buf; if (result.buf_addr) uci_handle->pkt_loc = result.buf_addr; else uci_handle->pkt_loc = 0; uci_handle->pkt_size = result.bytes_xferd; *bytes_pending = uci_handle->pkt_size; uci_log(UCI_DBG_VERBOSE, "Got pkt of size 0x%zx at addr 0x%lx, chan %d\n", uci_handle->pkt_size, (uintptr_t)phy_buf, chan); dma_unmap_single(NULL, (dma_addr_t)phy_buf, buf_size, DMA_FROM_DEVICE); "Got pkt size 0x%zx at addr 0x%lx, chan %d\n", uci_handle->pkt_size, (uintptr_t)result.buf_addr, chan); } if ((*bytes_pending == 0 || uci_handle->pkt_loc == 0) && (atomic_read(&uci_handle->avail_pkts) <= 0)) { Loading Loading @@ -774,9 +743,9 @@ static ssize_t mhi_uci_client_read(struct file *file, char __user *buf, uci_handle->pkt_size != 0 && uci_handle->pkt_loc != 0) { uci_log(UCI_DBG_VERBOSE, "Got packet: avail pkts %d phy_adr 0x%lx, chan %d\n", "Got packet: avail pkts %d phy_adr 0x%p, chan %d\n", atomic_read(&uci_handle->avail_pkts), phy_buf, result.buf_addr, chan); break; /* Loading @@ -785,10 +754,10 @@ static ssize_t mhi_uci_client_read(struct file *file, char __user *buf, */ } else { uci_log(UCI_DBG_CRITICAL, "chan %d err: avail pkts %d phy_adr 0x%lx mhi_stat%d\n", "chan %d err: avail pkts %d phy_adr 0x%p mhi_stat%d\n", chan, atomic_read(&uci_handle->avail_pkts), phy_buf, result.buf_addr, uci_handle->mhi_status); return -EIO; } Loading Loading @@ -830,16 +799,12 @@ static ssize_t mhi_uci_client_read(struct file *file, char __user *buf, uci_log(UCI_DBG_VERBOSE, "Pkt loc %p ,chan %d\n", uci_handle->pkt_loc, chan); memset(uci_handle->pkt_loc, 0, buf_size); phy_buf = dma_map_single(NULL, uci_handle->pkt_loc, buf_size, DMA_FROM_DEVICE); atomic_dec(&uci_handle->avail_pkts); uci_log(UCI_DBG_VERBOSE, "Decremented avail pkts avail 0x%x\n", atomic_read(&uci_handle->avail_pkts)); ret_val = mhi_queue_xfer(client_handle, phy_buf, ret_val = mhi_queue_xfer(client_handle, uci_handle->pkt_loc, buf_size, MHI_EOT); if (MHI_STATUS_SUCCESS != ret_val) { uci_log(UCI_DBG_ERROR, "Failed to recycle element\n"); Loading Loading @@ -987,13 +952,11 @@ static void process_rs232_state(struct mhi_result *result) } if (result->bytes_xferd != sizeof(struct rs232_ctrl_msg)) { uci_log(UCI_DBG_ERROR, "Buffer is of wrong size is: 0x%x: expected 0x%zx\n", "Buffer is of wrong size is: 0x%zx: expected 0x%zx\n", result->bytes_xferd, sizeof(struct rs232_ctrl_msg)); goto error_size; } dma_unmap_single(NULL, result->payload_buf, result->bytes_xferd, DMA_FROM_DEVICE); rs232_pkt = (void *)result->payload_buf; rs232_pkt = result->buf_addr; MHI_GET_CTRL_DEST_ID(CTRL_DEST_ID, rs232_pkt, chan); client = &uci_ctxt.client_handles[chan / 2]; Loading @@ -1014,11 +977,8 @@ static void process_rs232_state(struct mhi_result *result) error_bad_xfer: error_size: memset(rs232_pkt, 0, sizeof(struct rs232_ctrl_msg)); dma_map_single(NULL, rs232_pkt, sizeof(struct rs232_ctrl_msg), DMA_FROM_DEVICE); ret_val = mhi_queue_xfer(client->in_handle, result->payload_buf, result->buf_addr, result->bytes_xferd, result->flags); if (MHI_STATUS_SUCCESS != ret_val) { Loading @@ -1044,11 +1004,7 @@ static void parse_inbound_ack(struct uci_client *uci_handle, static void parse_outbound_ack(struct uci_client *uci_handle, struct mhi_result *result) { dma_unmap_single(NULL, result->payload_buf, result->bytes_xferd, DMA_TO_DEVICE); kfree((void *) result->payload_buf); kfree(result->buf_addr); uci_log(UCI_DBG_VERBOSE, "Received ack on chan %d, pending acks: 0x%x\n", uci_handle->out_chan, Loading
include/linux/msm_mhi.h +7 −5 Original line number Diff line number Diff line /* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -113,8 +113,8 @@ enum MHI_FLAGS { struct mhi_result { void *user_data; dma_addr_t payload_buf; u32 bytes_xferd; void *buf_addr; size_t bytes_xferd; enum MHI_STATUS transaction_status; enum MHI_FLAGS flags; }; Loading Loading @@ -180,12 +180,14 @@ enum MHI_STATUS mhi_open_channel(struct mhi_client_handle *client_handle); * @chain Specify whether to set the chain bit on this buffer * @eob Specify whether this buffer should trigger EOB interrupt * * NOTE: * Not thread safe, caller must ensure concurrency protection. * User buffer must be physically contiguous. * * @Return MHI_STATUS */ enum MHI_STATUS mhi_queue_xfer(struct mhi_client_handle *client_handle, dma_addr_t buf, size_t buf_len, enum MHI_FLAGS flags); int mhi_queue_xfer(struct mhi_client_handle *client_handle, void *buf, size_t buf_len, enum MHI_FLAGS mhi_flags); /** * mhi_close_channel - Client can request channel to be closed and handle freed Loading