Loading drivers/char/msm_smd_pkt.c +38 −4 Original line number Diff line number Diff line Loading @@ -390,7 +390,7 @@ static long smd_pkt_ioctl(struct file *file, unsigned int cmd, } ssize_t smd_pkt_read(struct file *file, char __user *buf, char __user *_buf, size_t count, loff_t *ppos) { Loading @@ -399,6 +399,7 @@ ssize_t smd_pkt_read(struct file *file, int pkt_size; struct smd_pkt_dev *smd_pkt_devp; unsigned long flags; void *buf; smd_pkt_devp = file->private_data; Loading @@ -421,6 +422,10 @@ ssize_t smd_pkt_read(struct file *file, D_READ("Begin %s on smd_pkt_dev id:%d buffer_size %zu\n", __func__, smd_pkt_devp->i, count); buf = kmalloc(count, GFP_KERNEL); if (!buf) return -ENOMEM; wait_for_packet: r = wait_event_interruptible(smd_pkt_devp->ch_read_wait_queue, !smd_pkt_devp->ch || Loading @@ -432,6 +437,7 @@ wait_for_packet: if (smd_pkt_devp->has_reset) { mutex_unlock(&smd_pkt_devp->rx_lock); E_SMD_PKT_SSR(smd_pkt_devp); kfree(buf); return notify_reset(smd_pkt_devp); } Loading @@ -439,6 +445,7 @@ wait_for_packet: mutex_unlock(&smd_pkt_devp->rx_lock); pr_err_ratelimited("%s on a closed smd_pkt_dev id:%d\n", __func__, smd_pkt_devp->i); kfree(buf); return -EINVAL; } Loading @@ -450,6 +457,7 @@ wait_for_packet: pr_err_ratelimited("%s: wait_event_interruptible on smd_pkt_dev id:%d ret %i\n", __func__, smd_pkt_devp->i, r); } kfree(buf); return r; } Loading @@ -466,6 +474,7 @@ wait_for_packet: if (pkt_size < 0) { pr_err_ratelimited("%s: Error %d obtaining packet size for Channel %s", __func__, pkt_size, smd_pkt_devp->ch_name); kfree(buf); return pkt_size; } Loading @@ -474,12 +483,13 @@ wait_for_packet: __func__, smd_pkt_devp->i, pkt_size, count); mutex_unlock(&smd_pkt_devp->rx_lock); kfree(buf); return -ETOOSMALL; } bytes_read = 0; do { r = smd_read_user_buffer(smd_pkt_devp->ch, r = smd_read(smd_pkt_devp->ch, (buf + bytes_read), (pkt_size - bytes_read)); if (r < 0) { Loading @@ -490,6 +500,7 @@ wait_for_packet: } pr_err_ratelimited("%s Error while reading %d\n", __func__, r); kfree(buf); return r; } bytes_read += r; Loading @@ -500,6 +511,7 @@ wait_for_packet: if (smd_pkt_devp->has_reset) { mutex_unlock(&smd_pkt_devp->rx_lock); E_SMD_PKT_SSR(smd_pkt_devp); kfree(buf); return notify_reset(smd_pkt_devp); } } while (pkt_size != bytes_read); Loading @@ -518,8 +530,14 @@ wait_for_packet: spin_unlock_irqrestore(&smd_pkt_devp->pa_spinlock, flags); mutex_unlock(&smd_pkt_devp->ch_lock); r = copy_to_user(_buf, buf, bytes_read); if (r) { kfree(buf); return -EFAULT; } D_READ("Finished %s on smd_pkt_dev id:%d %d bytes\n", __func__, smd_pkt_devp->i, bytes_read); kfree(buf); /* check and wakeup read threads waiting on this device */ check_and_wakeup_reader(smd_pkt_devp); Loading @@ -528,13 +546,14 @@ wait_for_packet: } ssize_t smd_pkt_write(struct file *file, const char __user *buf, const char __user *_buf, size_t count, loff_t *ppos) { int r = 0, bytes_written; struct smd_pkt_dev *smd_pkt_devp; DEFINE_WAIT(write_wait); void *buf; smd_pkt_devp = file->private_data; Loading @@ -557,12 +576,23 @@ ssize_t smd_pkt_write(struct file *file, D_WRITE("Begin %s on smd_pkt_dev id:%d data_size %zu\n", __func__, smd_pkt_devp->i, count); buf = kmalloc(count, GFP_KERNEL); if (!buf) return -ENOMEM; r = copy_from_user(buf, _buf, count); if (r) { kfree(buf); return -EFAULT; } mutex_lock(&smd_pkt_devp->tx_lock); if (!smd_pkt_devp->blocking_write) { if (smd_write_avail(smd_pkt_devp->ch) < count) { pr_err_ratelimited("%s: Not enough space in smd_pkt_dev id:%d\n", __func__, smd_pkt_devp->i); mutex_unlock(&smd_pkt_devp->tx_lock); kfree(buf); return -ENOMEM; } } Loading @@ -572,6 +602,7 @@ ssize_t smd_pkt_write(struct file *file, mutex_unlock(&smd_pkt_devp->tx_lock); pr_err_ratelimited("%s: Error:%d in smd_pkt_dev id:%d @ smd_write_start\n", __func__, r, smd_pkt_devp->i); kfree(buf); return r; } Loading @@ -590,11 +621,12 @@ ssize_t smd_pkt_write(struct file *file, if (smd_pkt_devp->has_reset) { mutex_unlock(&smd_pkt_devp->tx_lock); E_SMD_PKT_SSR(smd_pkt_devp); kfree(buf); return notify_reset(smd_pkt_devp); } else { r = smd_write_segment(smd_pkt_devp->ch, (void *)(buf + bytes_written), (count - bytes_written), 1); (count - bytes_written)); if (r < 0) { mutex_unlock(&smd_pkt_devp->tx_lock); if (smd_pkt_devp->has_reset) { Loading @@ -603,6 +635,7 @@ ssize_t smd_pkt_write(struct file *file, } pr_err_ratelimited("%s on smd_pkt_dev id:%d failed r:%d\n", __func__, smd_pkt_devp->i, r); kfree(buf); return r; } bytes_written += r; Loading @@ -613,6 +646,7 @@ ssize_t smd_pkt_write(struct file *file, D_WRITE("Finished %s on smd_pkt_dev id:%d %zu bytes\n", __func__, smd_pkt_devp->i, count); kfree(buf); return count; } Loading drivers/soc/qcom/ipc_router_smd_xprt.c +1 −1 Original line number Diff line number Diff line Loading @@ -233,7 +233,7 @@ static int msm_ipc_router_smd_remote_write(void *data, sz_written = smd_write_segment(smd_xprtp->channel, ipc_rtr_pkt->data + offset, (ipc_rtr_pkt->len - offset), 0); (ipc_rtr_pkt->len - offset)); offset += sz_written; sz_written = 0; } Loading drivers/soc/qcom/smd.c +31 −113 Original line number Diff line number Diff line Loading @@ -226,30 +226,21 @@ static inline void smd_write_intr(unsigned int val, void __iomem *addr) * @dest: Destination address * @src: Source address * @num_bytes: Number of bytes to copy * @from_user: true if data being copied is from userspace, false otherwise * * @return: Address of destination * * This function copies num_bytes from src to dest. This is used as the memcpy * function to copy data to SMD FIFO in case the SMD FIFO is naturally aligned. */ static void *smd_memcpy_to_fifo(void *dest, const void *src, size_t num_bytes, bool from_user) static void *smd_memcpy_to_fifo(void *dest, const void *src, size_t num_bytes) { union fifo_mem *temp_dst = (union fifo_mem *)dest; union fifo_mem *temp_src = (union fifo_mem *)src; uintptr_t mask = sizeof(union fifo_mem) - 1; int ret; /* Do byte copies until we hit 8-byte (double word) alignment */ while ((uintptr_t)temp_dst & mask && num_bytes) { if (from_user) { ret = copy_from_user(temp_dst, temp_src, 1); BUG_ON(ret != 0); } else { __raw_writeb_no_log(temp_src->u8, temp_dst); } temp_src = (union fifo_mem *)((uintptr_t)temp_src + 1); temp_dst = (union fifo_mem *)((uintptr_t)temp_dst + 1); num_bytes--; Loading @@ -257,14 +248,7 @@ static void *smd_memcpy_to_fifo(void *dest, const void *src, size_t num_bytes, /* Do double word copies */ while (num_bytes >= sizeof(union fifo_mem)) { if (from_user) { ret = copy_from_user(temp_dst, temp_src, sizeof(union fifo_mem)); BUG_ON(ret != 0); } else { __raw_writeq_no_log(temp_src->u64, temp_dst); } temp_dst++; temp_src++; num_bytes -= sizeof(union fifo_mem); Loading @@ -272,13 +256,7 @@ static void *smd_memcpy_to_fifo(void *dest, const void *src, size_t num_bytes, /* Copy remaining bytes */ while (num_bytes--) { if (from_user) { ret = copy_from_user(temp_dst, temp_src, 1); BUG_ON(ret != 0); } else { __raw_writeb_no_log(temp_src->u8, temp_dst); } temp_src = (union fifo_mem *)((uintptr_t)temp_src + 1); temp_dst = (union fifo_mem *)((uintptr_t)temp_dst + 1); } Loading @@ -291,7 +269,6 @@ static void *smd_memcpy_to_fifo(void *dest, const void *src, size_t num_bytes, * @dest: Destination address * @src: Source address * @num_bytes: Number of bytes to copy * @to_user: true if data being copied is from userspace, false otherwise * * @return: Address of destination * Loading @@ -299,23 +276,15 @@ static void *smd_memcpy_to_fifo(void *dest, const void *src, size_t num_bytes, * function to copy data from SMD FIFO in case the SMD FIFO is naturally * aligned. */ static void *smd_memcpy_from_fifo(void *dest, const void *src, size_t num_bytes, bool to_user) static void *smd_memcpy_from_fifo(void *dest, const void *src, size_t num_bytes) { union fifo_mem *temp_dst = (union fifo_mem *)dest; union fifo_mem *temp_src = (union fifo_mem *)src; uintptr_t mask = sizeof(union fifo_mem) - 1; int ret; /* Do byte copies until we hit 8-byte (double word) alignment */ while ((uintptr_t)temp_src & mask && num_bytes) { if (to_user) { ret = copy_to_user(temp_dst, temp_src, 1); BUG_ON(ret != 0); } else { temp_dst->u8 = __raw_readb_no_log(temp_src); } temp_src = (union fifo_mem *)((uintptr_t)temp_src + 1); temp_dst = (union fifo_mem *)((uintptr_t)temp_dst + 1); num_bytes--; Loading @@ -323,14 +292,7 @@ static void *smd_memcpy_from_fifo(void *dest, const void *src, size_t num_bytes, /* Do double word copies */ while (num_bytes >= sizeof(union fifo_mem)) { if (to_user) { ret = copy_to_user(temp_dst, temp_src, sizeof(union fifo_mem)); BUG_ON(ret != 0); } else { temp_dst->u64 = __raw_readq_no_log(temp_src); } temp_dst++; temp_src++; num_bytes -= sizeof(union fifo_mem); Loading @@ -338,13 +300,7 @@ static void *smd_memcpy_from_fifo(void *dest, const void *src, size_t num_bytes, /* Copy remaining bytes */ while (num_bytes--) { if (to_user) { ret = copy_to_user(temp_dst, temp_src, 1); BUG_ON(ret != 0); } else { temp_dst->u8 = __raw_readb_no_log(temp_src); } temp_src = (union fifo_mem *)((uintptr_t)temp_src + 1); temp_dst = (union fifo_mem *)((uintptr_t)temp_dst + 1); } Loading @@ -358,7 +314,6 @@ static void *smd_memcpy_from_fifo(void *dest, const void *src, size_t num_bytes, * @dest: Destination address * @src: Source address * @num_bytes: Number of bytes to copy * @from_user: always false * * @return: On Success, address of destination * Loading @@ -366,17 +321,11 @@ static void *smd_memcpy_from_fifo(void *dest, const void *src, size_t num_bytes, * memcpy function to copy data to SMD FIFO in case the SMD FIFO is 4 byte * aligned. */ static void *smd_memcpy32_to_fifo(void *dest, const void *src, size_t num_bytes, bool from_user) static void *smd_memcpy32_to_fifo(void *dest, const void *src, size_t num_bytes) { uint32_t *dest_local = (uint32_t *)dest; uint32_t *src_local = (uint32_t *)src; if (from_user) { panic("%s: Word Based Access not supported", __func__); } BUG_ON(num_bytes & SMD_FIFO_ADDR_ALIGN_BYTES); BUG_ON(!dest_local || ((uintptr_t)dest_local & SMD_FIFO_ADDR_ALIGN_BYTES)); Loading @@ -395,7 +344,6 @@ static void *smd_memcpy32_to_fifo(void *dest, const void *src, size_t num_bytes, * @dest: Destination address * @src: Source address * @num_bytes: Number of bytes to copy * @to_user: true if data being copied is from userspace, false otherwise * * @return: On Success, destination address * Loading @@ -404,17 +352,12 @@ static void *smd_memcpy32_to_fifo(void *dest, const void *src, size_t num_bytes, * aligned. */ static void *smd_memcpy32_from_fifo(void *dest, const void *src, size_t num_bytes, bool to_user) size_t num_bytes) { uint32_t *dest_local = (uint32_t *)dest; uint32_t *src_local = (uint32_t *)src; if (to_user) { panic("%s: Word Based Access not supported", __func__); } BUG_ON(num_bytes & SMD_FIFO_ADDR_ALIGN_BYTES); BUG_ON(!dest_local || ((uintptr_t)dest_local & SMD_FIFO_ADDR_ALIGN_BYTES)); Loading Loading @@ -1234,7 +1177,7 @@ static void ch_read_done(struct smd_channel *ch, unsigned count) * by smd_*_read() and update_packet_state() * will read-and-discard if the _data pointer is null */ static int ch_read(struct smd_channel *ch, void *_data, int len, int user_buf) static int ch_read(struct smd_channel *ch, void *_data, int len) { void *ptr; unsigned n; Loading @@ -1249,7 +1192,7 @@ static int ch_read(struct smd_channel *ch, void *_data, int len, int user_buf) if (n > len) n = len; if (_data) ch->read_from_fifo(data, ptr, n, user_buf); ch->read_from_fifo(data, ptr, n); data += n; len -= n; Loading Loading @@ -1278,7 +1221,7 @@ static void update_packet_state(struct smd_channel *ch) if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE) return; r = ch_read(ch, hdr, SMD_HEADER_SIZE, 0); r = ch_read(ch, hdr, SMD_HEADER_SIZE); BUG_ON(r != SMD_HEADER_SIZE); ch->current_packet = hdr[0]; Loading Loading @@ -1610,7 +1553,7 @@ static int smd_is_packet(struct smd_alloc_elm *alloc_elm) } static int smd_stream_write(smd_channel_t *ch, const void *_data, int len, int user_buf, bool intr_ntfy) bool intr_ntfy) { void *ptr; const unsigned char *buf = _data; Loading @@ -1631,7 +1574,7 @@ static int smd_stream_write(smd_channel_t *ch, const void *_data, int len, if (xfer > len) xfer = len; ch->write_to_fifo(ptr, buf, xfer, user_buf); ch->write_to_fifo(ptr, buf, xfer); ch_write_done(ch, xfer); len -= xfer; buf += xfer; Loading @@ -1646,7 +1589,7 @@ static int smd_stream_write(smd_channel_t *ch, const void *_data, int len, } static int smd_packet_write(smd_channel_t *ch, const void *_data, int len, int user_buf, bool intr_ntfy) bool intr_ntfy) { int ret; unsigned hdr[5]; Loading @@ -1664,7 +1607,7 @@ static int smd_packet_write(smd_channel_t *ch, const void *_data, int len, hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0; ret = smd_stream_write(ch, hdr, sizeof(hdr), 0, false); ret = smd_stream_write(ch, hdr, sizeof(hdr), false); if (ret < 0 || ret != sizeof(hdr)) { SMD_DBG("%s failed to write pkt header: %d returned\n", __func__, ret); Loading @@ -1672,7 +1615,7 @@ static int smd_packet_write(smd_channel_t *ch, const void *_data, int len, } ret = smd_stream_write(ch, _data, len, user_buf, true); ret = smd_stream_write(ch, _data, len, true); if (ret < 0 || ret != len) { SMD_DBG("%s failed to write pkt data: %d returned\n", __func__, ret); Loading @@ -1682,14 +1625,14 @@ static int smd_packet_write(smd_channel_t *ch, const void *_data, int len, return len; } static int smd_stream_read(smd_channel_t *ch, void *data, int len, int user_buf) static int smd_stream_read(smd_channel_t *ch, void *data, int len) { int r; if (len < 0) return -EINVAL; r = ch_read(ch, data, len, user_buf); r = ch_read(ch, data, len); if (r > 0) if (!read_intr_blocked(ch)) ch->notify_other_cpu(ch); Loading @@ -1697,7 +1640,7 @@ static int smd_stream_read(smd_channel_t *ch, void *data, int len, int user_buf) return r; } static int smd_packet_read(smd_channel_t *ch, void *data, int len, int user_buf) static int smd_packet_read(smd_channel_t *ch, void *data, int len) { unsigned long flags; int r; Loading @@ -1714,7 +1657,7 @@ static int smd_packet_read(smd_channel_t *ch, void *data, int len, int user_buf) if (len > ch->current_packet) len = ch->current_packet; r = ch_read(ch, data, len, user_buf); r = ch_read(ch, data, len); if (r > 0) if (!read_intr_blocked(ch)) ch->notify_other_cpu(ch); Loading @@ -1727,8 +1670,7 @@ static int smd_packet_read(smd_channel_t *ch, void *data, int len, int user_buf) return r; } static int smd_packet_read_from_cb(smd_channel_t *ch, void *data, int len, int user_buf) static int smd_packet_read_from_cb(smd_channel_t *ch, void *data, int len) { int r; Loading @@ -1744,7 +1686,7 @@ static int smd_packet_read_from_cb(smd_channel_t *ch, void *data, int len, if (len > ch->current_packet) len = ch->current_packet; r = ch_read(ch, data, len, user_buf); r = ch_read(ch, data, len); if (r > 0) if (!read_intr_blocked(ch)) ch->notify_other_cpu(ch); Loading Loading @@ -1899,8 +1841,7 @@ static int smd_alloc_channel(struct smd_alloc_elm *alloc_elm, int table_id, ch->write_to_fifo = smd_memcpy_to_fifo; } smd_memcpy_from_fifo(ch->name, alloc_elm->name, SMD_MAX_CH_NAME_LEN, false); smd_memcpy_from_fifo(ch->name, alloc_elm->name, SMD_MAX_CH_NAME_LEN); ch->name[SMD_MAX_CH_NAME_LEN-1] = 0; ch->pdev.name = ch->name; Loading Loading @@ -2118,7 +2059,7 @@ int smd_write_start(smd_channel_t *ch, int len) hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0; ret = smd_stream_write(ch, hdr, sizeof(hdr), 0, true); ret = smd_stream_write(ch, hdr, sizeof(hdr), true); if (ret < 0 || ret != sizeof(hdr)) { ch->pending_pkt_sz = 0; pr_err("%s: packet header failed to write\n", __func__); Loading @@ -2128,8 +2069,7 @@ int smd_write_start(smd_channel_t *ch, int len) } EXPORT_SYMBOL(smd_write_start); int smd_write_segment(smd_channel_t *ch, const void *data, int len, int user_buf) int smd_write_segment(smd_channel_t *ch, const void *data, int len) { int bytes_written; Loading @@ -2152,7 +2092,7 @@ int smd_write_segment(smd_channel_t *ch, const void *data, int len, return -EINVAL; } bytes_written = smd_stream_write(ch, data, len, user_buf, true); bytes_written = smd_stream_write(ch, data, len, true); ch->pending_pkt_sz -= bytes_written; Loading Loading @@ -2206,21 +2146,10 @@ int smd_read(smd_channel_t *ch, void *data, int len) return -ENODEV; } return ch->read(ch, data, len, 0); return ch->read(ch, data, len); } EXPORT_SYMBOL(smd_read); int smd_read_user_buffer(smd_channel_t *ch, void *data, int len) { if (!ch) { pr_err("%s: Invalid channel specified\n", __func__); return -ENODEV; } return ch->read(ch, data, len, 1); } EXPORT_SYMBOL(smd_read_user_buffer); int smd_read_from_cb(smd_channel_t *ch, void *data, int len) { if (!ch) { Loading @@ -2228,7 +2157,7 @@ int smd_read_from_cb(smd_channel_t *ch, void *data, int len) return -ENODEV; } return ch->read_from_cb(ch, data, len, 0); return ch->read_from_cb(ch, data, len); } EXPORT_SYMBOL(smd_read_from_cb); Loading @@ -2239,21 +2168,10 @@ int smd_write(smd_channel_t *ch, const void *data, int len) return -ENODEV; } return ch->pending_pkt_sz ? -EBUSY : ch->write(ch, data, len, 0, true); return ch->pending_pkt_sz ? -EBUSY : ch->write(ch, data, len, true); } EXPORT_SYMBOL(smd_write); int smd_write_user_buffer(smd_channel_t *ch, const void *data, int len) { if (!ch) { pr_err("%s: Invalid channel specified\n", __func__); return -ENODEV; } return ch->pending_pkt_sz ? -EBUSY : ch->write(ch, data, len, 1, true); } EXPORT_SYMBOL(smd_write_user_buffer); int smd_read_avail(smd_channel_t *ch) { if (!ch) { Loading drivers/soc/qcom/smd_private.h +5 −8 Original line number Diff line number Diff line Loading @@ -141,21 +141,18 @@ struct smd_channel { void *priv; void (*notify)(void *priv, unsigned flags); int (*read)(smd_channel_t *ch, void *data, int len, int user_buf); int (*read)(smd_channel_t *ch, void *data, int len); int (*write)(smd_channel_t *ch, const void *data, int len, int user_buf, bool int_ntfy); bool int_ntfy); int (*read_avail)(smd_channel_t *ch); int (*write_avail)(smd_channel_t *ch); int (*read_from_cb)(smd_channel_t *ch, void *data, int len, int user_buf); int (*read_from_cb)(smd_channel_t *ch, void *data, int len); void (*update_state)(smd_channel_t *ch); unsigned last_state; void (*notify_other_cpu)(smd_channel_t *ch); void *(*read_from_fifo)(void *dest, const void *src, size_t num_bytes, bool to_user); void *(*write_to_fifo)(void *dest, const void *src, size_t num_bytes, bool from_user); void * (*read_from_fifo)(void *dest, const void *src, size_t num_bytes); void * (*write_to_fifo)(void *dest, const void *src, size_t num_bytes); char name[20]; struct platform_device pdev; Loading include/soc/qcom/smd.h +2 −23 Original line number Diff line number Diff line Loading @@ -84,10 +84,6 @@ int smd_close(smd_channel_t *ch); /* passing a null pointer for data reads and discards */ int smd_read(smd_channel_t *ch, void *data, int len); int smd_read_from_cb(smd_channel_t *ch, void *data, int len); /* Same as smd_read() but takes a data buffer from userspace * The function might sleep. Only safe to call from user context */ int smd_read_user_buffer(smd_channel_t *ch, void *data, int len); /* Write to stream channels may do a partial write and return ** the length actually written. Loading @@ -95,10 +91,6 @@ int smd_read_user_buffer(smd_channel_t *ch, void *data, int len); ** it will return the requested length written or an error. */ int smd_write(smd_channel_t *ch, const void *data, int len); /* Same as smd_write() but takes a data buffer from userspace * The function might sleep. Only safe to call from user context */ int smd_write_user_buffer(smd_channel_t *ch, const void *data, int len); int smd_write_avail(smd_channel_t *ch); int smd_read_avail(smd_channel_t *ch); Loading Loading @@ -172,7 +164,6 @@ int smd_write_start(smd_channel_t *ch, int len); * @ch: channel to write packet to * @data: buffer of data to write * @len: length of data buffer * @user_buf: (0) - buffer from kernelspace (1) - buffer from userspace * * Returns: * number of bytes written Loading @@ -180,8 +171,7 @@ int smd_write_start(smd_channel_t *ch, int len); * -EINVAL - invalid length * -ENOEXEC - transaction not started */ int smd_write_segment(smd_channel_t *ch, const void *data, int len, int user_buf); int smd_write_segment(smd_channel_t *ch, const void *data, int len); /* Completes a packet transaction. Do not call from interrupt context. * Loading Loading @@ -278,22 +268,11 @@ static inline int smd_read_from_cb(smd_channel_t *ch, void *data, int len) return -ENODEV; } static inline int smd_read_user_buffer(smd_channel_t *ch, void *data, int len) { return -ENODEV; } static inline int smd_write(smd_channel_t *ch, const void *data, int len) { return -ENODEV; } static inline int smd_write_user_buffer(smd_channel_t *ch, const void *data, int len) { return -ENODEV; } static inline int smd_write_avail(smd_channel_t *ch) { return -ENODEV; Loading Loading @@ -353,7 +332,7 @@ static inline int smd_write_start(smd_channel_t *ch, int len) } static inline int smd_write_segment(smd_channel_t *ch, const void *data, int len, int user_buf) smd_write_segment(smd_channel_t *ch, const void *data, int len) { return -ENODEV; } Loading Loading
drivers/char/msm_smd_pkt.c +38 −4 Original line number Diff line number Diff line Loading @@ -390,7 +390,7 @@ static long smd_pkt_ioctl(struct file *file, unsigned int cmd, } ssize_t smd_pkt_read(struct file *file, char __user *buf, char __user *_buf, size_t count, loff_t *ppos) { Loading @@ -399,6 +399,7 @@ ssize_t smd_pkt_read(struct file *file, int pkt_size; struct smd_pkt_dev *smd_pkt_devp; unsigned long flags; void *buf; smd_pkt_devp = file->private_data; Loading @@ -421,6 +422,10 @@ ssize_t smd_pkt_read(struct file *file, D_READ("Begin %s on smd_pkt_dev id:%d buffer_size %zu\n", __func__, smd_pkt_devp->i, count); buf = kmalloc(count, GFP_KERNEL); if (!buf) return -ENOMEM; wait_for_packet: r = wait_event_interruptible(smd_pkt_devp->ch_read_wait_queue, !smd_pkt_devp->ch || Loading @@ -432,6 +437,7 @@ wait_for_packet: if (smd_pkt_devp->has_reset) { mutex_unlock(&smd_pkt_devp->rx_lock); E_SMD_PKT_SSR(smd_pkt_devp); kfree(buf); return notify_reset(smd_pkt_devp); } Loading @@ -439,6 +445,7 @@ wait_for_packet: mutex_unlock(&smd_pkt_devp->rx_lock); pr_err_ratelimited("%s on a closed smd_pkt_dev id:%d\n", __func__, smd_pkt_devp->i); kfree(buf); return -EINVAL; } Loading @@ -450,6 +457,7 @@ wait_for_packet: pr_err_ratelimited("%s: wait_event_interruptible on smd_pkt_dev id:%d ret %i\n", __func__, smd_pkt_devp->i, r); } kfree(buf); return r; } Loading @@ -466,6 +474,7 @@ wait_for_packet: if (pkt_size < 0) { pr_err_ratelimited("%s: Error %d obtaining packet size for Channel %s", __func__, pkt_size, smd_pkt_devp->ch_name); kfree(buf); return pkt_size; } Loading @@ -474,12 +483,13 @@ wait_for_packet: __func__, smd_pkt_devp->i, pkt_size, count); mutex_unlock(&smd_pkt_devp->rx_lock); kfree(buf); return -ETOOSMALL; } bytes_read = 0; do { r = smd_read_user_buffer(smd_pkt_devp->ch, r = smd_read(smd_pkt_devp->ch, (buf + bytes_read), (pkt_size - bytes_read)); if (r < 0) { Loading @@ -490,6 +500,7 @@ wait_for_packet: } pr_err_ratelimited("%s Error while reading %d\n", __func__, r); kfree(buf); return r; } bytes_read += r; Loading @@ -500,6 +511,7 @@ wait_for_packet: if (smd_pkt_devp->has_reset) { mutex_unlock(&smd_pkt_devp->rx_lock); E_SMD_PKT_SSR(smd_pkt_devp); kfree(buf); return notify_reset(smd_pkt_devp); } } while (pkt_size != bytes_read); Loading @@ -518,8 +530,14 @@ wait_for_packet: spin_unlock_irqrestore(&smd_pkt_devp->pa_spinlock, flags); mutex_unlock(&smd_pkt_devp->ch_lock); r = copy_to_user(_buf, buf, bytes_read); if (r) { kfree(buf); return -EFAULT; } D_READ("Finished %s on smd_pkt_dev id:%d %d bytes\n", __func__, smd_pkt_devp->i, bytes_read); kfree(buf); /* check and wakeup read threads waiting on this device */ check_and_wakeup_reader(smd_pkt_devp); Loading @@ -528,13 +546,14 @@ wait_for_packet: } ssize_t smd_pkt_write(struct file *file, const char __user *buf, const char __user *_buf, size_t count, loff_t *ppos) { int r = 0, bytes_written; struct smd_pkt_dev *smd_pkt_devp; DEFINE_WAIT(write_wait); void *buf; smd_pkt_devp = file->private_data; Loading @@ -557,12 +576,23 @@ ssize_t smd_pkt_write(struct file *file, D_WRITE("Begin %s on smd_pkt_dev id:%d data_size %zu\n", __func__, smd_pkt_devp->i, count); buf = kmalloc(count, GFP_KERNEL); if (!buf) return -ENOMEM; r = copy_from_user(buf, _buf, count); if (r) { kfree(buf); return -EFAULT; } mutex_lock(&smd_pkt_devp->tx_lock); if (!smd_pkt_devp->blocking_write) { if (smd_write_avail(smd_pkt_devp->ch) < count) { pr_err_ratelimited("%s: Not enough space in smd_pkt_dev id:%d\n", __func__, smd_pkt_devp->i); mutex_unlock(&smd_pkt_devp->tx_lock); kfree(buf); return -ENOMEM; } } Loading @@ -572,6 +602,7 @@ ssize_t smd_pkt_write(struct file *file, mutex_unlock(&smd_pkt_devp->tx_lock); pr_err_ratelimited("%s: Error:%d in smd_pkt_dev id:%d @ smd_write_start\n", __func__, r, smd_pkt_devp->i); kfree(buf); return r; } Loading @@ -590,11 +621,12 @@ ssize_t smd_pkt_write(struct file *file, if (smd_pkt_devp->has_reset) { mutex_unlock(&smd_pkt_devp->tx_lock); E_SMD_PKT_SSR(smd_pkt_devp); kfree(buf); return notify_reset(smd_pkt_devp); } else { r = smd_write_segment(smd_pkt_devp->ch, (void *)(buf + bytes_written), (count - bytes_written), 1); (count - bytes_written)); if (r < 0) { mutex_unlock(&smd_pkt_devp->tx_lock); if (smd_pkt_devp->has_reset) { Loading @@ -603,6 +635,7 @@ ssize_t smd_pkt_write(struct file *file, } pr_err_ratelimited("%s on smd_pkt_dev id:%d failed r:%d\n", __func__, smd_pkt_devp->i, r); kfree(buf); return r; } bytes_written += r; Loading @@ -613,6 +646,7 @@ ssize_t smd_pkt_write(struct file *file, D_WRITE("Finished %s on smd_pkt_dev id:%d %zu bytes\n", __func__, smd_pkt_devp->i, count); kfree(buf); return count; } Loading
drivers/soc/qcom/ipc_router_smd_xprt.c +1 −1 Original line number Diff line number Diff line Loading @@ -233,7 +233,7 @@ static int msm_ipc_router_smd_remote_write(void *data, sz_written = smd_write_segment(smd_xprtp->channel, ipc_rtr_pkt->data + offset, (ipc_rtr_pkt->len - offset), 0); (ipc_rtr_pkt->len - offset)); offset += sz_written; sz_written = 0; } Loading
drivers/soc/qcom/smd.c +31 −113 Original line number Diff line number Diff line Loading @@ -226,30 +226,21 @@ static inline void smd_write_intr(unsigned int val, void __iomem *addr) * @dest: Destination address * @src: Source address * @num_bytes: Number of bytes to copy * @from_user: true if data being copied is from userspace, false otherwise * * @return: Address of destination * * This function copies num_bytes from src to dest. This is used as the memcpy * function to copy data to SMD FIFO in case the SMD FIFO is naturally aligned. */ static void *smd_memcpy_to_fifo(void *dest, const void *src, size_t num_bytes, bool from_user) static void *smd_memcpy_to_fifo(void *dest, const void *src, size_t num_bytes) { union fifo_mem *temp_dst = (union fifo_mem *)dest; union fifo_mem *temp_src = (union fifo_mem *)src; uintptr_t mask = sizeof(union fifo_mem) - 1; int ret; /* Do byte copies until we hit 8-byte (double word) alignment */ while ((uintptr_t)temp_dst & mask && num_bytes) { if (from_user) { ret = copy_from_user(temp_dst, temp_src, 1); BUG_ON(ret != 0); } else { __raw_writeb_no_log(temp_src->u8, temp_dst); } temp_src = (union fifo_mem *)((uintptr_t)temp_src + 1); temp_dst = (union fifo_mem *)((uintptr_t)temp_dst + 1); num_bytes--; Loading @@ -257,14 +248,7 @@ static void *smd_memcpy_to_fifo(void *dest, const void *src, size_t num_bytes, /* Do double word copies */ while (num_bytes >= sizeof(union fifo_mem)) { if (from_user) { ret = copy_from_user(temp_dst, temp_src, sizeof(union fifo_mem)); BUG_ON(ret != 0); } else { __raw_writeq_no_log(temp_src->u64, temp_dst); } temp_dst++; temp_src++; num_bytes -= sizeof(union fifo_mem); Loading @@ -272,13 +256,7 @@ static void *smd_memcpy_to_fifo(void *dest, const void *src, size_t num_bytes, /* Copy remaining bytes */ while (num_bytes--) { if (from_user) { ret = copy_from_user(temp_dst, temp_src, 1); BUG_ON(ret != 0); } else { __raw_writeb_no_log(temp_src->u8, temp_dst); } temp_src = (union fifo_mem *)((uintptr_t)temp_src + 1); temp_dst = (union fifo_mem *)((uintptr_t)temp_dst + 1); } Loading @@ -291,7 +269,6 @@ static void *smd_memcpy_to_fifo(void *dest, const void *src, size_t num_bytes, * @dest: Destination address * @src: Source address * @num_bytes: Number of bytes to copy * @to_user: true if data being copied is from userspace, false otherwise * * @return: Address of destination * Loading @@ -299,23 +276,15 @@ static void *smd_memcpy_to_fifo(void *dest, const void *src, size_t num_bytes, * function to copy data from SMD FIFO in case the SMD FIFO is naturally * aligned. */ static void *smd_memcpy_from_fifo(void *dest, const void *src, size_t num_bytes, bool to_user) static void *smd_memcpy_from_fifo(void *dest, const void *src, size_t num_bytes) { union fifo_mem *temp_dst = (union fifo_mem *)dest; union fifo_mem *temp_src = (union fifo_mem *)src; uintptr_t mask = sizeof(union fifo_mem) - 1; int ret; /* Do byte copies until we hit 8-byte (double word) alignment */ while ((uintptr_t)temp_src & mask && num_bytes) { if (to_user) { ret = copy_to_user(temp_dst, temp_src, 1); BUG_ON(ret != 0); } else { temp_dst->u8 = __raw_readb_no_log(temp_src); } temp_src = (union fifo_mem *)((uintptr_t)temp_src + 1); temp_dst = (union fifo_mem *)((uintptr_t)temp_dst + 1); num_bytes--; Loading @@ -323,14 +292,7 @@ static void *smd_memcpy_from_fifo(void *dest, const void *src, size_t num_bytes, /* Do double word copies */ while (num_bytes >= sizeof(union fifo_mem)) { if (to_user) { ret = copy_to_user(temp_dst, temp_src, sizeof(union fifo_mem)); BUG_ON(ret != 0); } else { temp_dst->u64 = __raw_readq_no_log(temp_src); } temp_dst++; temp_src++; num_bytes -= sizeof(union fifo_mem); Loading @@ -338,13 +300,7 @@ static void *smd_memcpy_from_fifo(void *dest, const void *src, size_t num_bytes, /* Copy remaining bytes */ while (num_bytes--) { if (to_user) { ret = copy_to_user(temp_dst, temp_src, 1); BUG_ON(ret != 0); } else { temp_dst->u8 = __raw_readb_no_log(temp_src); } temp_src = (union fifo_mem *)((uintptr_t)temp_src + 1); temp_dst = (union fifo_mem *)((uintptr_t)temp_dst + 1); } Loading @@ -358,7 +314,6 @@ static void *smd_memcpy_from_fifo(void *dest, const void *src, size_t num_bytes, * @dest: Destination address * @src: Source address * @num_bytes: Number of bytes to copy * @from_user: always false * * @return: On Success, address of destination * Loading @@ -366,17 +321,11 @@ static void *smd_memcpy_from_fifo(void *dest, const void *src, size_t num_bytes, * memcpy function to copy data to SMD FIFO in case the SMD FIFO is 4 byte * aligned. */ static void *smd_memcpy32_to_fifo(void *dest, const void *src, size_t num_bytes, bool from_user) static void *smd_memcpy32_to_fifo(void *dest, const void *src, size_t num_bytes) { uint32_t *dest_local = (uint32_t *)dest; uint32_t *src_local = (uint32_t *)src; if (from_user) { panic("%s: Word Based Access not supported", __func__); } BUG_ON(num_bytes & SMD_FIFO_ADDR_ALIGN_BYTES); BUG_ON(!dest_local || ((uintptr_t)dest_local & SMD_FIFO_ADDR_ALIGN_BYTES)); Loading @@ -395,7 +344,6 @@ static void *smd_memcpy32_to_fifo(void *dest, const void *src, size_t num_bytes, * @dest: Destination address * @src: Source address * @num_bytes: Number of bytes to copy * @to_user: true if data being copied is from userspace, false otherwise * * @return: On Success, destination address * Loading @@ -404,17 +352,12 @@ static void *smd_memcpy32_to_fifo(void *dest, const void *src, size_t num_bytes, * aligned. */ static void *smd_memcpy32_from_fifo(void *dest, const void *src, size_t num_bytes, bool to_user) size_t num_bytes) { uint32_t *dest_local = (uint32_t *)dest; uint32_t *src_local = (uint32_t *)src; if (to_user) { panic("%s: Word Based Access not supported", __func__); } BUG_ON(num_bytes & SMD_FIFO_ADDR_ALIGN_BYTES); BUG_ON(!dest_local || ((uintptr_t)dest_local & SMD_FIFO_ADDR_ALIGN_BYTES)); Loading Loading @@ -1234,7 +1177,7 @@ static void ch_read_done(struct smd_channel *ch, unsigned count) * by smd_*_read() and update_packet_state() * will read-and-discard if the _data pointer is null */ static int ch_read(struct smd_channel *ch, void *_data, int len, int user_buf) static int ch_read(struct smd_channel *ch, void *_data, int len) { void *ptr; unsigned n; Loading @@ -1249,7 +1192,7 @@ static int ch_read(struct smd_channel *ch, void *_data, int len, int user_buf) if (n > len) n = len; if (_data) ch->read_from_fifo(data, ptr, n, user_buf); ch->read_from_fifo(data, ptr, n); data += n; len -= n; Loading Loading @@ -1278,7 +1221,7 @@ static void update_packet_state(struct smd_channel *ch) if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE) return; r = ch_read(ch, hdr, SMD_HEADER_SIZE, 0); r = ch_read(ch, hdr, SMD_HEADER_SIZE); BUG_ON(r != SMD_HEADER_SIZE); ch->current_packet = hdr[0]; Loading Loading @@ -1610,7 +1553,7 @@ static int smd_is_packet(struct smd_alloc_elm *alloc_elm) } static int smd_stream_write(smd_channel_t *ch, const void *_data, int len, int user_buf, bool intr_ntfy) bool intr_ntfy) { void *ptr; const unsigned char *buf = _data; Loading @@ -1631,7 +1574,7 @@ static int smd_stream_write(smd_channel_t *ch, const void *_data, int len, if (xfer > len) xfer = len; ch->write_to_fifo(ptr, buf, xfer, user_buf); ch->write_to_fifo(ptr, buf, xfer); ch_write_done(ch, xfer); len -= xfer; buf += xfer; Loading @@ -1646,7 +1589,7 @@ static int smd_stream_write(smd_channel_t *ch, const void *_data, int len, } static int smd_packet_write(smd_channel_t *ch, const void *_data, int len, int user_buf, bool intr_ntfy) bool intr_ntfy) { int ret; unsigned hdr[5]; Loading @@ -1664,7 +1607,7 @@ static int smd_packet_write(smd_channel_t *ch, const void *_data, int len, hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0; ret = smd_stream_write(ch, hdr, sizeof(hdr), 0, false); ret = smd_stream_write(ch, hdr, sizeof(hdr), false); if (ret < 0 || ret != sizeof(hdr)) { SMD_DBG("%s failed to write pkt header: %d returned\n", __func__, ret); Loading @@ -1672,7 +1615,7 @@ static int smd_packet_write(smd_channel_t *ch, const void *_data, int len, } ret = smd_stream_write(ch, _data, len, user_buf, true); ret = smd_stream_write(ch, _data, len, true); if (ret < 0 || ret != len) { SMD_DBG("%s failed to write pkt data: %d returned\n", __func__, ret); Loading @@ -1682,14 +1625,14 @@ static int smd_packet_write(smd_channel_t *ch, const void *_data, int len, return len; } static int smd_stream_read(smd_channel_t *ch, void *data, int len, int user_buf) static int smd_stream_read(smd_channel_t *ch, void *data, int len) { int r; if (len < 0) return -EINVAL; r = ch_read(ch, data, len, user_buf); r = ch_read(ch, data, len); if (r > 0) if (!read_intr_blocked(ch)) ch->notify_other_cpu(ch); Loading @@ -1697,7 +1640,7 @@ static int smd_stream_read(smd_channel_t *ch, void *data, int len, int user_buf) return r; } static int smd_packet_read(smd_channel_t *ch, void *data, int len, int user_buf) static int smd_packet_read(smd_channel_t *ch, void *data, int len) { unsigned long flags; int r; Loading @@ -1714,7 +1657,7 @@ static int smd_packet_read(smd_channel_t *ch, void *data, int len, int user_buf) if (len > ch->current_packet) len = ch->current_packet; r = ch_read(ch, data, len, user_buf); r = ch_read(ch, data, len); if (r > 0) if (!read_intr_blocked(ch)) ch->notify_other_cpu(ch); Loading @@ -1727,8 +1670,7 @@ static int smd_packet_read(smd_channel_t *ch, void *data, int len, int user_buf) return r; } static int smd_packet_read_from_cb(smd_channel_t *ch, void *data, int len, int user_buf) static int smd_packet_read_from_cb(smd_channel_t *ch, void *data, int len) { int r; Loading @@ -1744,7 +1686,7 @@ static int smd_packet_read_from_cb(smd_channel_t *ch, void *data, int len, if (len > ch->current_packet) len = ch->current_packet; r = ch_read(ch, data, len, user_buf); r = ch_read(ch, data, len); if (r > 0) if (!read_intr_blocked(ch)) ch->notify_other_cpu(ch); Loading Loading @@ -1899,8 +1841,7 @@ static int smd_alloc_channel(struct smd_alloc_elm *alloc_elm, int table_id, ch->write_to_fifo = smd_memcpy_to_fifo; } smd_memcpy_from_fifo(ch->name, alloc_elm->name, SMD_MAX_CH_NAME_LEN, false); smd_memcpy_from_fifo(ch->name, alloc_elm->name, SMD_MAX_CH_NAME_LEN); ch->name[SMD_MAX_CH_NAME_LEN-1] = 0; ch->pdev.name = ch->name; Loading Loading @@ -2118,7 +2059,7 @@ int smd_write_start(smd_channel_t *ch, int len) hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0; ret = smd_stream_write(ch, hdr, sizeof(hdr), 0, true); ret = smd_stream_write(ch, hdr, sizeof(hdr), true); if (ret < 0 || ret != sizeof(hdr)) { ch->pending_pkt_sz = 0; pr_err("%s: packet header failed to write\n", __func__); Loading @@ -2128,8 +2069,7 @@ int smd_write_start(smd_channel_t *ch, int len) } EXPORT_SYMBOL(smd_write_start); int smd_write_segment(smd_channel_t *ch, const void *data, int len, int user_buf) int smd_write_segment(smd_channel_t *ch, const void *data, int len) { int bytes_written; Loading @@ -2152,7 +2092,7 @@ int smd_write_segment(smd_channel_t *ch, const void *data, int len, return -EINVAL; } bytes_written = smd_stream_write(ch, data, len, user_buf, true); bytes_written = smd_stream_write(ch, data, len, true); ch->pending_pkt_sz -= bytes_written; Loading Loading @@ -2206,21 +2146,10 @@ int smd_read(smd_channel_t *ch, void *data, int len) return -ENODEV; } return ch->read(ch, data, len, 0); return ch->read(ch, data, len); } EXPORT_SYMBOL(smd_read); int smd_read_user_buffer(smd_channel_t *ch, void *data, int len) { if (!ch) { pr_err("%s: Invalid channel specified\n", __func__); return -ENODEV; } return ch->read(ch, data, len, 1); } EXPORT_SYMBOL(smd_read_user_buffer); int smd_read_from_cb(smd_channel_t *ch, void *data, int len) { if (!ch) { Loading @@ -2228,7 +2157,7 @@ int smd_read_from_cb(smd_channel_t *ch, void *data, int len) return -ENODEV; } return ch->read_from_cb(ch, data, len, 0); return ch->read_from_cb(ch, data, len); } EXPORT_SYMBOL(smd_read_from_cb); Loading @@ -2239,21 +2168,10 @@ int smd_write(smd_channel_t *ch, const void *data, int len) return -ENODEV; } return ch->pending_pkt_sz ? -EBUSY : ch->write(ch, data, len, 0, true); return ch->pending_pkt_sz ? -EBUSY : ch->write(ch, data, len, true); } EXPORT_SYMBOL(smd_write); int smd_write_user_buffer(smd_channel_t *ch, const void *data, int len) { if (!ch) { pr_err("%s: Invalid channel specified\n", __func__); return -ENODEV; } return ch->pending_pkt_sz ? -EBUSY : ch->write(ch, data, len, 1, true); } EXPORT_SYMBOL(smd_write_user_buffer); int smd_read_avail(smd_channel_t *ch) { if (!ch) { Loading
drivers/soc/qcom/smd_private.h +5 −8 Original line number Diff line number Diff line Loading @@ -141,21 +141,18 @@ struct smd_channel { void *priv; void (*notify)(void *priv, unsigned flags); int (*read)(smd_channel_t *ch, void *data, int len, int user_buf); int (*read)(smd_channel_t *ch, void *data, int len); int (*write)(smd_channel_t *ch, const void *data, int len, int user_buf, bool int_ntfy); bool int_ntfy); int (*read_avail)(smd_channel_t *ch); int (*write_avail)(smd_channel_t *ch); int (*read_from_cb)(smd_channel_t *ch, void *data, int len, int user_buf); int (*read_from_cb)(smd_channel_t *ch, void *data, int len); void (*update_state)(smd_channel_t *ch); unsigned last_state; void (*notify_other_cpu)(smd_channel_t *ch); void *(*read_from_fifo)(void *dest, const void *src, size_t num_bytes, bool to_user); void *(*write_to_fifo)(void *dest, const void *src, size_t num_bytes, bool from_user); void * (*read_from_fifo)(void *dest, const void *src, size_t num_bytes); void * (*write_to_fifo)(void *dest, const void *src, size_t num_bytes); char name[20]; struct platform_device pdev; Loading
include/soc/qcom/smd.h +2 −23 Original line number Diff line number Diff line Loading @@ -84,10 +84,6 @@ int smd_close(smd_channel_t *ch); /* passing a null pointer for data reads and discards */ int smd_read(smd_channel_t *ch, void *data, int len); int smd_read_from_cb(smd_channel_t *ch, void *data, int len); /* Same as smd_read() but takes a data buffer from userspace * The function might sleep. Only safe to call from user context */ int smd_read_user_buffer(smd_channel_t *ch, void *data, int len); /* Write to stream channels may do a partial write and return ** the length actually written. Loading @@ -95,10 +91,6 @@ int smd_read_user_buffer(smd_channel_t *ch, void *data, int len); ** it will return the requested length written or an error. */ int smd_write(smd_channel_t *ch, const void *data, int len); /* Same as smd_write() but takes a data buffer from userspace * The function might sleep. Only safe to call from user context */ int smd_write_user_buffer(smd_channel_t *ch, const void *data, int len); int smd_write_avail(smd_channel_t *ch); int smd_read_avail(smd_channel_t *ch); Loading Loading @@ -172,7 +164,6 @@ int smd_write_start(smd_channel_t *ch, int len); * @ch: channel to write packet to * @data: buffer of data to write * @len: length of data buffer * @user_buf: (0) - buffer from kernelspace (1) - buffer from userspace * * Returns: * number of bytes written Loading @@ -180,8 +171,7 @@ int smd_write_start(smd_channel_t *ch, int len); * -EINVAL - invalid length * -ENOEXEC - transaction not started */ int smd_write_segment(smd_channel_t *ch, const void *data, int len, int user_buf); int smd_write_segment(smd_channel_t *ch, const void *data, int len); /* Completes a packet transaction. Do not call from interrupt context. * Loading Loading @@ -278,22 +268,11 @@ static inline int smd_read_from_cb(smd_channel_t *ch, void *data, int len) return -ENODEV; } static inline int smd_read_user_buffer(smd_channel_t *ch, void *data, int len) { return -ENODEV; } static inline int smd_write(smd_channel_t *ch, const void *data, int len) { return -ENODEV; } static inline int smd_write_user_buffer(smd_channel_t *ch, const void *data, int len) { return -ENODEV; } static inline int smd_write_avail(smd_channel_t *ch) { return -ENODEV; Loading Loading @@ -353,7 +332,7 @@ static inline int smd_write_start(smd_channel_t *ch, int len) } static inline int smd_write_segment(smd_channel_t *ch, const void *data, int len, int user_buf) smd_write_segment(smd_channel_t *ch, const void *data, int len) { return -ENODEV; } Loading