| /* |
| * Android/Easel coprocessor communication. |
| * |
| * Copyright 2016 Google Inc. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| */ |
| |
| #ifndef _UAPI__GOOGLE_EASEL_COMM_H |
| #define _UAPI__GOOGLE_EASEL_COMM_H |
| |
| #include <linux/compiler.h> |
| #include <linux/types.h> |
| |
| /* Maximum message data size 12KB */ |
| #define EASELCOMM_MAX_MESSAGE_SIZE (12 * 1024) |
| |
| /* Maximum service count */ |
| #define EASELCOMM_SERVICE_COUNT 64 |
| |
| /* Easel message identifier. Compatible with libeasel defines. */ |
| typedef __u64 easelcomm_msgid_t; |
| |
| struct easelcomm_wait { |
| __s32 timeout_ms; /* timeout in ms; -1 means indefinite */ |
| }; |
| |
| /* |
| * Userspace/kernel interface message descriptor. libeasel converts |
| * between its representation of messages and these descriptors, plus the |
| * buffer descriptors below, when passing messages between the kernel and |
| * userspace. |
| */ |
| struct easelcomm_kmsg_desc { |
| /* 64-bit IDs go first for 32/64-bit struct packing conformity */ |
| easelcomm_msgid_t message_id; /* message ID */ |
| easelcomm_msgid_t in_reply_to; /* msg ID replied to if non-zero */ |
| __u32 message_size; /* size in bytes of the message data */ |
| __u32 dma_buf_size; /* size of the DMA buffer transfer */ |
| __u32 need_reply; /* non-zero if reply requested */ |
| __u32 replycode; /* replycode if in_reply_to != 0 */ |
| struct easelcomm_wait wait; |
| }; |
| |
| enum easelcomm_dma_buffer_type { |
| EASELCOMM_DMA_BUFFER_UNUSED = 0, |
| EASELCOMM_DMA_BUFFER_USER, |
| EASELCOMM_DMA_BUFFER_DMA_BUF |
| }; |
| |
| /* |
| * Local buffer descriptor argument for ioctls that read and write message |
| * or DMA buffers. The message_id describes an in-progress local outgoing |
| * message for which the message data is being written or the DMA source |
| * buffer is being set, or a remote incoming message for which the message |
| * data is being read or the DMA destination buffer is being set. |
| * The amount and location of the data being transferred is affected by |
| * the following parameters: |
| * offset: Refers to the byte offset where data starts. |
| * size: Refers to the total byte size of actual data. |
| * width: Refers to the a contiguous set of bytes. |
| * In general: 1 <= width <= size |
| * stride: Refers to the byte offset from the beginning of a contiguous set of |
| * data specified by "width" to the next contiguous set of data. |
| * At the moment: stride >= width. |
| * Parameter examples (assume a 10x10 byte buffer): |
| * 1) Transfer a rectangular 3x3 sub-region from a 10x10 buffer, starting at |
| * offset 5: |
| * CFG: offset=5, size=9, width=3, stride=10 |
| * 2) Transfer a full 10x10 buffer (sub-region is same size as buffer): |
| * CFG: offset=0, size=100, width=100, stride=100 |
| * 3) Transfer every even row in a 10x10 buffer: |
| * CFG: offset=0, size=50, width=10, stride=20 |
| * 4) Transfer every even column in a 10x10 buffer: |
| * CFG: offset=0, size=50, width=1, stride=2 |
| * |
| * Note that when using a dma buf: |
| * offset + [ceil(size/width)*stride - (stride-width)] <= buf_size |
| */ |
| struct easelcomm_kbuf_desc { |
| easelcomm_msgid_t message_id; /* ID of message for this transfer */ |
| void __user *buf; /* local buffer source or dest */ |
| int dma_buf_fd; /* fd of local dma_buf */ |
| int buf_type; /* use enum easelcomm_dma_buffer_type */ |
| __u32 buf_size; /* size of the local buffer */ |
| struct easelcomm_wait wait; |
| __u32 dma_buf_off; /* offset into the local dma_buf */ |
| __u32 dma_buf_width; /* width of region */ |
| __u32 dma_buf_stride; /* stride width */ |
| }; |
| |
| /* |
| * Legacy local buffer descriptor for backwards compatibility with clients which |
| * haven't migrated to the new descriptor/ioctls. |
| */ |
| struct easelcomm_kbuf_desc_legacy { |
| easelcomm_msgid_t message_id; /* ID of message for this transfer */ |
| void __user *buf; /* local buffer source or dest */ |
| int dma_buf_fd; /* fd of local dma_buf */ |
| int buf_type; /* use enum easelcomm_dma_buffer_type */ |
| __u32 buf_size; /* size of the local buffer */ |
| struct easelcomm_wait wait; |
| }; |
| |
| /* |
| * Kernel driver ioctls. All ioctls return zero for success or -1 for |
| * error with errno set: EINVAL for invalid parameters (dmesg may contain |
| * further explanation), ENOMEM for out of memory, or other codes as described |
| * below. |
| */ |
| #define EASELCOMM_IOC_MAGIC 0xEA |
| |
| /* |
| * Register the file descriptor for an easelcomm service. The AP client will |
| * flush any local client and remote server messages associated with the |
| * service at this time, assuming any previous traffic is stale. Registration |
| * by the Easel server does not flush state and will commence processing of |
| * any queued incoming messages previously sent to the service by a client. |
| * Only one fd may be registered for a service on each of the AP and Easel |
| * sides. |
| */ |
| #define EASELCOMM_IOC_REGISTER _IOW(EASELCOMM_IOC_MAGIC, 0, int) |
| |
| /* |
| * Start sending an outgoing message. Reads a message descriptor and |
| * returns a modified descriptor with a local message ID assigned. That |
| * ID is then supplied in the buffer descriptors of WRITEBUF and SENDDMA |
| * ioctls as appropriate to supply the message data and local DMA source |
| * information. |
| */ |
| #define EASELCOMM_IOC_SENDMSG _IOWR(EASELCOMM_IOC_MAGIC, 1, \ |
| struct easelcomm_kmsg_desc *) |
| /* |
| * Read the message data for an incoming message received from the |
| * remote. The supplied remote message ID was returned by a previous |
| * WAITMSG or WAITREPLY ioctl. The data is read to the specified buffer |
| * in the calling process. If no DMA transfer is requested by the |
| * associated message then successful completion of this ioctl frees the |
| * local kernel copy of the message. |
| */ |
| #define EASELCOMM_IOC_READDATA _IOW(EASELCOMM_IOC_MAGIC, 10, \ |
| struct easelcomm_kbuf_desc) |
| #define EASELCOMM_IOC_READDATA_LEGACY _IOW(EASELCOMM_IOC_MAGIC, 2, \ |
| struct easelcomm_kbuf_desc_legacy *) |
| /* |
| * Write the message data for an outgoing message being sent to the |
| * remote. The supplied remote message ID was returned by a previous |
| * SENDMSG ioctl. The data is written from the specified buffer in the |
| * calling process. This ioctl sends the message to the remote upon |
| * successful completion; even if the message data length is zero, this |
| * ioctl must still follow a SENDMSG to actually send the message. If no |
| * DMA transfer is requested by the associated message then successful |
| * completion of this ioctl frees the local kernel copy of the message. |
| */ |
| #define EASELCOMM_IOC_WRITEDATA _IOW(EASELCOMM_IOC_MAGIC, 11, \ |
| struct easelcomm_kbuf_desc) |
| #define EASELCOMM_IOC_WRITEDATA_LEGACY _IOW(EASELCOMM_IOC_MAGIC, 3, \ |
| struct easelcomm_kbuf_desc_legacy *) |
| /* |
| * Initiate a DMA write for an outgoing message that includes a DMA |
| * transfer. The supplied local message ID was returned by a previous |
| * SENDMSG ioctl. The DMA data will be read from the specified buffer in the |
| * calling process. The ioctl returns once the DMA transfer is complete (or |
| * skipped due to being discarded by the remote). Successful completion of |
| * this ioctl frees the local kernel copy of the message. |
| */ |
| #define EASELCOMM_IOC_SENDDMA _IOW(EASELCOMM_IOC_MAGIC, 12, \ |
| struct easelcomm_kbuf_desc) |
| #define EASELCOMM_IOC_SENDDMA_LEGACY _IOW(EASELCOMM_IOC_MAGIC, 4, \ |
| struct easelcomm_kbuf_desc_legacy *) |
| /* |
| * Specify the local destination for a DMA transfer requested by an incoming |
| * message. The supplied remote message ID was returned by a previous |
| * WAITMSG or WAITREPLY ioctl. The DMA data will be written to the specified |
| * buffer in the calling process; or if a NULL buffer pointer is supplied then |
| * the DMA transfer is discarded. The ioctl returns once the DMA transfer is |
| * complete (or discarded per the preceding). Successful completion of this |
| * ioctl frees the local kernel copy of the message. |
| */ |
| #define EASELCOMM_IOC_RECVDMA _IOW(EASELCOMM_IOC_MAGIC, 13, \ |
| struct easelcomm_kbuf_desc) |
| #define EASELCOMM_IOC_RECVDMA_LEGACY _IOW(EASELCOMM_IOC_MAGIC, 5, \ |
| struct easelcomm_kbuf_desc_legacy *) |
| /* |
| * Wait for and return a descriptor for a reply from the remote to a |
| * local message that requests a reply. The message ID in the supplied |
| * descriptor was returned by a previous SENDMSG ioctl. This ioctl waits |
| * for the remote's reply message and returns a desciptor for that message. |
| * A READDATA ioctl should then be issued to read the message data, followed |
| * by a RECVDMA if a DMA transfer is requested by the reply. |
| */ |
| #define EASELCOMM_IOC_WAITREPLY _IOWR(EASELCOMM_IOC_MAGIC, 6, \ |
| struct easelcomm_kmsg_desc *) |
| /* |
| * Wait for and return a descriptor for an incoming message from the remote |
| * (that is not a reply to a local message). This ioctl waits for the next |
| * non-reply message from the remote and returns a desciptor for that message. |
| * A READDATA ioctl should then be issued to read the message data, followed |
| * by a RECVDMA if a DMA transfer is requested by the message. |
| * Returns error ESHUTDOWN if a SHUTDOWN ioctl is issued for the file |
| * descriptor or the file descriptor has been closed. |
| */ |
| #define EASELCOMM_IOC_WAITMSG _IOWR(EASELCOMM_IOC_MAGIC, 7, \ |
| struct easelcomm_kmsg_desc *) |
| /* |
| * Shut down the local easelcomm connection for the given file descriptor. |
| * Any other threads blocked on a WAITMSG using the same file descriptor will |
| * return an ESHUTDOWN. Any local in-progress outgoing or incoming messages |
| * for the registered Easel service are discarded. |
| */ |
| #define EASELCOMM_IOC_SHUTDOWN _IO(EASELCOMM_IOC_MAGIC, 8) |
| |
| /* |
| * Any local in-progress outgoing or incoming messages for the registered Easel |
| * service are discarded, and the remote side is sent a command to flush its |
| * local messages for the service. Returns when the remote acknowledges the |
| * flush complete. No userspace handler is required to be registered on the |
| * remote to perform the flush. |
| */ |
| #define EASELCOMM_IOC_FLUSH _IO(EASELCOMM_IOC_MAGIC, 9) |
| |
| /* |
| * The last close() of an fd also flushes any local messages for the |
| * registered service. |
| */ |
| |
| #endif /* _UAPI__GOOGLE_EASEL_COMM_H */ |