/*1*2* dvb_ringbuffer.h: ring buffer implementation for the dvb driver3*4* Copyright (C) 2003 Oliver Endriss5* Copyright (C) 2004 Andrew de Quincey6*7* based on code originally found in av7110.c & dvb_ci.c:8* Copyright (C) 1999-2003 Ralph Metzler & Marcus Metzler9* for convergence integrated media GmbH10*11* This program is free software; you can redistribute it and/or12* modify it under the terms of the GNU Lesser General Public License13* as published by the Free Software Foundation; either version 2.114* of the License, or (at your option) any later version.15*16* This program is distributed in the hope that it will be useful,17* but WITHOUT ANY WARRANTY; without even the implied warranty of18* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the19* GNU Lesser General Public License for more details.20*/2122#ifndef _DVB_RINGBUFFER_H_23#define _DVB_RINGBUFFER_H_2425#include <linux/spinlock.h>26#include <linux/wait.h>2728/**29* struct dvb_ringbuffer - Describes a ring buffer used at DVB framework30*31* @data: Area were the ringbuffer data is written32* @size: size of the ringbuffer33* @pread: next position to read34* @pwrite: next position to write35* @error: used by ringbuffer clients to indicate that an error happened.36* @queue: Wait queue used by ringbuffer clients to indicate when buffer37* was filled38* @lock: Spinlock used to protect the ringbuffer39*/40struct dvb_ringbuffer {41u8 *data;42ssize_t size;43ssize_t pread;44ssize_t pwrite;45int error;4647wait_queue_head_t queue;48spinlock_t lock;49};5051#define DVB_RINGBUFFER_PKTHDRSIZE 35253/**54* dvb_ringbuffer_init - initialize ring buffer, lock and queue55*56* @rbuf: pointer to struct dvb_ringbuffer57* @data: pointer to the buffer where the data will be stored58* @len: bytes from ring buffer into @buf59*/60extern void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data,61size_t len);6263/**64* dvb_ringbuffer_empty - test whether buffer is empty65*66* @rbuf: pointer to struct dvb_ringbuffer67*/68extern int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf);6970/**71* dvb_ringbuffer_free - returns the number of free bytes in the buffer72*73* @rbuf: pointer to struct dvb_ringbuffer74*75* Return: number of free bytes in the buffer76*/77extern ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf);7879/**80* dvb_ringbuffer_avail - returns the number of bytes waiting in the buffer81*82* @rbuf: pointer to struct dvb_ringbuffer83*84* Return: number of bytes waiting in the buffer85*/86extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf);8788/**89* dvb_ringbuffer_reset - resets the ringbuffer to initial state90*91* @rbuf: pointer to struct dvb_ringbuffer92*93* Resets the read and write pointers to zero and flush the buffer.94*95* This counts as a read and write operation96*/97extern void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf);9899/*100* read routines & macros101*/102103/**104* dvb_ringbuffer_flush - flush buffer105*106* @rbuf: pointer to struct dvb_ringbuffer107*/108extern void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf);109110/**111* dvb_ringbuffer_flush_spinlock_wakeup- flush buffer protected by spinlock112* and wake-up waiting task(s)113*114* @rbuf: pointer to struct dvb_ringbuffer115*/116extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf);117118/**119* DVB_RINGBUFFER_PEEK - peek at byte @offs in the buffer120*121* @rbuf: pointer to struct dvb_ringbuffer122* @offs: offset inside the ringbuffer123*/124#define DVB_RINGBUFFER_PEEK(rbuf, offs) \125((rbuf)->data[((rbuf)->pread + (offs)) % (rbuf)->size])126127/**128* DVB_RINGBUFFER_SKIP - advance read ptr by @num bytes129*130* @rbuf: pointer to struct dvb_ringbuffer131* @num: number of bytes to advance132*/133#define DVB_RINGBUFFER_SKIP(rbuf, num) {\134(rbuf)->pread = ((rbuf)->pread + (num)) % (rbuf)->size;\135}136137/**138* dvb_ringbuffer_read_user - Reads a buffer into a user pointer139*140* @rbuf: pointer to struct dvb_ringbuffer141* @buf: pointer to the buffer where the data will be stored142* @len: bytes from ring buffer into @buf143*144* This variant assumes that the buffer is a memory at the userspace. So,145* it will internally call copy_to_user().146*147* Return: number of bytes transferred or -EFAULT148*/149extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf,150u8 __user *buf, size_t len);151152/**153* dvb_ringbuffer_read - Reads a buffer into a pointer154*155* @rbuf: pointer to struct dvb_ringbuffer156* @buf: pointer to the buffer where the data will be stored157* @len: bytes from ring buffer into @buf158*159* This variant assumes that the buffer is a memory at the Kernel space160*161* Return: number of bytes transferred or -EFAULT162*/163extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf,164u8 *buf, size_t len);165166/*167* write routines & macros168*/169170/**171* DVB_RINGBUFFER_WRITE_BYTE - write single byte to ring buffer172*173* @rbuf: pointer to struct dvb_ringbuffer174* @byte: byte to write175*/176#define DVB_RINGBUFFER_WRITE_BYTE(rbuf, byte) \177{ (rbuf)->data[(rbuf)->pwrite] = (byte); \178(rbuf)->pwrite = ((rbuf)->pwrite + 1) % (rbuf)->size; }179180/**181* dvb_ringbuffer_write - Writes a buffer into the ringbuffer182*183* @rbuf: pointer to struct dvb_ringbuffer184* @buf: pointer to the buffer where the data will be read185* @len: bytes from ring buffer into @buf186*187* This variant assumes that the buffer is a memory at the Kernel space188*189* return: number of bytes transferred or -EFAULT190*/191extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,192size_t len);193194/**195* dvb_ringbuffer_write_user - Writes a buffer received via a user pointer196*197* @rbuf: pointer to struct dvb_ringbuffer198* @buf: pointer to the buffer where the data will be read199* @len: bytes from ring buffer into @buf200*201* This variant assumes that the buffer is a memory at the userspace. So,202* it will internally call copy_from_user().203*204* Return: number of bytes transferred or -EFAULT205*/206extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,207const u8 __user *buf, size_t len);208209/**210* dvb_ringbuffer_pkt_write - Write a packet into the ringbuffer.211*212* @rbuf: Ringbuffer to write to.213* @buf: Buffer to write.214* @len: Length of buffer (currently limited to 65535 bytes max).215*216* Return: Number of bytes written, or -EFAULT, -ENOMEM, -EINVAL.217*/218extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8 *buf,219size_t len);220221/**222* dvb_ringbuffer_pkt_read_user - Read from a packet in the ringbuffer.223*224* @rbuf: Ringbuffer concerned.225* @idx: Packet index as returned by dvb_ringbuffer_pkt_next().226* @offset: Offset into packet to read from.227* @buf: Destination buffer for data.228* @len: Size of destination buffer.229*230* Return: Number of bytes read, or -EFAULT.231*232* .. note::233*234* unlike dvb_ringbuffer_read(), this does **NOT** update the read pointer235* in the ringbuffer. You must use dvb_ringbuffer_pkt_dispose() to mark a236* packet as no longer required.237*/238extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf,239size_t idx,240int offset, u8 __user *buf,241size_t len);242243/**244* dvb_ringbuffer_pkt_read - Read from a packet in the ringbuffer.245* Note: unlike dvb_ringbuffer_read_user(), this DOES update the read pointer246* in the ringbuffer.247*248* @rbuf: Ringbuffer concerned.249* @idx: Packet index as returned by dvb_ringbuffer_pkt_next().250* @offset: Offset into packet to read from.251* @buf: Destination buffer for data.252* @len: Size of destination buffer.253*254* Return: Number of bytes read, or -EFAULT.255*/256extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,257int offset, u8 *buf, size_t len);258259/**260* dvb_ringbuffer_pkt_dispose - Dispose of a packet in the ring buffer.261*262* @rbuf: Ring buffer concerned.263* @idx: Packet index as returned by dvb_ringbuffer_pkt_next().264*/265extern void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx);266267/**268* dvb_ringbuffer_pkt_next - Get the index of the next packet in a ringbuffer.269*270* @rbuf: Ringbuffer concerned.271* @idx: Previous packet index, or -1 to return the first packet index.272* @pktlen: On success, will be updated to contain the length of the packet273* in bytes.274* returns Packet index (if >=0), or -1 if no packets available.275*/276extern ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf,277size_t idx, size_t *pktlen);278279#endif /* _DVB_RINGBUFFER_H_ */280281282