| /* |
| * Copyright (C) 2012-2017 Samsung Electronics, Inc. |
| * |
| * This software is licensed under the terms of the GNU General Public |
| * License version 2, as published by the Free Software Foundation, and |
| * may be copied, distributed, and modified under those terms. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| */ |
| |
| #ifndef __LIB_CIRC_BUF_H__ |
| #define __LIB_CIRC_BUF_H__ |
| |
| #include <linux/types.h> |
| |
| /* One more byte is used for differentiating between empty and full buffer */ |
| #define CIRC_BUF_EMPTY_FLAG_SIZE 1 |
| #define CIRC_BUF_META_SIZE (sizeof(struct circ_buf) + CIRC_BUF_EMPTY_FLAG_SIZE) |
| |
| struct circ_buf { |
| u32 write_count; |
| u32 read_count; |
| char buffer[]; |
| } __packed; |
| |
| struct circ_buf_desc { |
| struct circ_buf *circ_buf; |
| unsigned int size; |
| |
| /* These are local copies of circ_buf counters |
| * for tracking actual state (circ_buf counters are shared |
| * between reader and writer and thus should only be updated |
| * when new state is ok for the reader to see). */ |
| unsigned int write_count; |
| unsigned int read_count; |
| }; |
| |
| enum circ_buf_user_mode { |
| CIRC_BUF_MODE_KERNEL, |
| CIRC_BUF_MODE_USER, |
| CIRC_BUF_MODE_DROP |
| }; |
| |
| /** |
| * Function creates circ_buf_desc structure with circ_buf of specified size. |
| * @param[in] size size of circ_buf |
| * @return descriptor of allocated circ_buf, or NULL if allocation failed |
| */ |
| struct circ_buf_desc *circ_buf_create(unsigned long size); |
| |
| /** |
| * Function destroys circ_buf_desc structure along with its circ_buf. |
| * @param[in] circ_buf_desc descriptor of buffer to destroy |
| */ |
| void circ_buf_destroy(struct circ_buf_desc *circ_buf_desc); |
| |
| /** |
| * Function allocates circ_buf_desc structure and initializes its fields. |
| * @return allocated circ_buf descriptor, or NULL if allocation failed |
| */ |
| struct circ_buf_desc *circ_buf_desc_alloc(void); |
| |
| /** |
| * Function sets circ_buf_desc structure pointing to previously allocated buffer |
| * and initializes its fields. |
| * @return allocated circ_buf descriptor, or NULL if allocation failed |
| */ |
| struct circ_buf *circ_buf_set(void *buf); |
| |
| /** |
| * Function frees circ_buf descriptor. |
| * @param[in] circ_buf_desc circ_buf descriptor to free |
| */ |
| void circ_buf_desc_free(struct circ_buf_desc *circ_buf_desc); |
| |
| /** |
| * Function allocates circ_buf of specified size. |
| * @param[in] size size of circ_buf |
| * @return pointer to allocated circ_buf, or NULL of allocation failed |
| */ |
| struct circ_buf *circ_buf_alloc(unsigned long size); |
| |
| /** |
| * Function frees circ_buf. |
| * @param[in] circ_buf circ_buf to free |
| */ |
| void circ_buf_free(struct circ_buf *circ_buf); |
| |
| /** |
| * Function initialized circ_buf to be empty. |
| * @param[in] circ_buf circ_buf to initialize |
| */ |
| void circ_buf_init(struct circ_buf *circ_buf); |
| |
| /** |
| * Function connects circ_buf of specified size to the circ_buf desc. |
| * @param[in] circ_buf_desc descriptor to connect circ_buf to |
| * @param[in] circ_buf circ_buf to connect |
| * @param[in] size size of circ_buf |
| * @return error code |
| */ |
| void circ_buf_connect(struct circ_buf_desc *circ_buf_desc, |
| struct circ_buf *circ_buf, unsigned long size); |
| |
| /** |
| * Function writes specified buf to circ_buf and updates |
| * circ_buf write counter. |
| * @param[in] circ_buf_desc descriptor of circ_buf to write buf to |
| * @param[in] buf input buf to write to circ_buf |
| * @param[in] length amount of bytes to write |
| * @param[in] mode enum indicating whether passed buf |
| * belongs to userspace or kernel memory |
| * @return number on bytes written on success or error code |
| */ |
| ssize_t circ_buf_write(struct circ_buf_desc *circ_buf_desc, const char *buf, |
| size_t length, enum circ_buf_user_mode mode); |
| |
| /** |
| * Function writes specified buf to circ_buf without updating circ_buf write counter. |
| * @param[in] circ_buf_desc descriptor of circ_buf to write buf to |
| * @param[in] buf input buf to write to circ_buf |
| * @param[in] length amount of bytes to write |
| * @param[in] mode enum indicating whether passed buf |
| * belongs to userspace or kernel memory |
| * @return number of bytes written on success or error code |
| */ |
| ssize_t circ_buf_write_local(struct circ_buf_desc *circ_buf_desc, const char *buf, |
| size_t length, enum circ_buf_user_mode mode); |
| |
| /** |
| * Function reads contents of circ_buf to output buf and updates |
| * circ_buf read counter. |
| * @param[in] circ_buf_desc descriptor of circ_buf to read from |
| * @param[in] buf output buf to read from circ_buf |
| * @param[in] length amount of bytes to read |
| * @param[in] mode enum indicating whether passed buf |
| * belongs to userspace or kernel memory, |
| * or contents of circ_buf must be simply dropped. |
| * @return number of bytes read on success or error code |
| */ |
| ssize_t circ_buf_read(struct circ_buf_desc *circ_buf_desc, char *buf, |
| size_t length, enum circ_buf_user_mode mode); |
| |
| /** |
| * Function reads contents of circ_buf to output buf without updating circ_buf read counter. |
| * @param[in] circ_buf_desc descriptor of circ_buf to read from |
| * @param[in] buf output buf to read from circ_buf |
| * @param[in] length amount of bytes to read |
| * @param[in] mode enum indicating whether passed buf |
| * belongs to userspace or kernel memory, |
| * or contents of circ_buf must be simply dropped. |
| * @return number of bytes read on success or error code |
| */ |
| ssize_t circ_buf_read_local(struct circ_buf_desc *circ_buf_desc, char *buf, |
| size_t length, enum circ_buf_user_mode mode); |
| |
| /** |
| * Function reads contents of circ_buf by specified offset from read_count, |
| * not updating circ_buf read counter. Not intended to be used by clients, |
| * required for API extensions. |
| * @param[in] circ_buf_desc descriptor of circ_buf to read from |
| * @param[in] buf output buf to read from circ_buf |
| * @param[in] length amount of bytes to read |
| * @param[in] offset offset from read_count to start reading from |
| * @param[in] mode enum indicating whether passed buf |
| * belongs to userspace or kernel memory, |
| * or contents of circ_buf must be simply dropped. |
| * @return number of bytes read on success or error code |
| */ |
| ssize_t __circ_buf_read_local(struct circ_buf_desc *circ_buf_desc, char *buf, |
| size_t length, size_t offset, enum circ_buf_user_mode mode); |
| |
| /** |
| * Function updates circ_buf write counter, so reader can see new value. |
| * @param[in] circ_buf_desc descriptor of circ_buf to update counter in |
| */ |
| void circ_buf_flush_write(struct circ_buf_desc *circ_buf_desc); |
| |
| /** |
| * Function updates circ_buf read counter, so writer can see new value. |
| * @param[in] circ_buf_desc descriptor of circ_buf to update counter in |
| */ |
| void circ_buf_flush_read(struct circ_buf_desc *circ_buf_desc); |
| |
| /** |
| * Function restores circ_buf_desc write counter to the value its circ_buf has. |
| * @param[in] circ_buf_desc descriptor of circ_buf to update counter in |
| */ |
| void circ_buf_rollback_write(struct circ_buf_desc *circ_buf_desc); |
| |
| /** |
| * Function restores circ_buf_desc read counter to the value its circ_buf has. |
| * @param[in] circ_buf_desc descriptor of circ_buf to update counter in |
| */ |
| void circ_buf_rollback_read(struct circ_buf_desc *circ_buf_desc); |
| |
| /** |
| * Function checks if circ_buf is empty. |
| * Should be used with care, because result is not guaranteed to be valid |
| * after the access, unless there is external locking mechanism. |
| * @param[in] circ_buf_desc descriptor of circ_buf to check |
| * @return non-0 is circ_buf is empty and 0 otherwise |
| */ |
| unsigned int circ_buf_is_empty(struct circ_buf_desc *circ_buf_desc); |
| |
| /** |
| * Function checks if circ_buf is full. |
| * Should be used with care, because result is not guaranteed to be valid |
| * after the access, unless there is external locking mechanism. |
| * @param[in] circ_buf_desc descriptor of circ_buf to check |
| * @return non-0 is circ_bufis full and 0 otherwise |
| */ |
| unsigned int circ_buf_is_full(struct circ_buf_desc *circ_buf_desc); |
| |
| /** |
| * Function calculates amount of bytes in buffer currently available to write. |
| * Should be used with care, because result is not guaranteed to be valid |
| * after the access, unless there is external locking mechanism. |
| * @param[in] circ_buf_desc descriptor of circ_buf to check |
| * @return number of free bytes |
| */ |
| size_t circ_buf_bytes_free(struct circ_buf_desc *circ_buf_desc); |
| |
| /** |
| * Function calculates amount of bytes written in buffer and not read yet. |
| * Should be used with care, because result is not guaranteed to be valid |
| * after the access, unless there is external locking mechanism. |
| * @param[in] circ_buf_desc descriptor of circ_buf to check |
| * @return number of used bytes |
| */ |
| size_t circ_buf_bytes_used(struct circ_buf_desc *circ_buf_desc); |
| |
| #endif /* __LIB_CIRC_BUF_H__ */ |