1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * 3*4882a593Smuzhiyun * dvb_ringbuffer.h: ring buffer implementation for the dvb driver 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (C) 2003 Oliver Endriss 6*4882a593Smuzhiyun * Copyright (C) 2004 Andrew de Quincey 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * based on code originally found in av7110.c & dvb_ci.c: 9*4882a593Smuzhiyun * Copyright (C) 1999-2003 Ralph Metzler & Marcus Metzler 10*4882a593Smuzhiyun * for convergence integrated media GmbH 11*4882a593Smuzhiyun * 12*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or 13*4882a593Smuzhiyun * modify it under the terms of the GNU Lesser General Public License 14*4882a593Smuzhiyun * as published by the Free Software Foundation; either version 2.1 15*4882a593Smuzhiyun * of the License, or (at your option) any later version. 16*4882a593Smuzhiyun * 17*4882a593Smuzhiyun * This program is distributed in the hope that it will be useful, 18*4882a593Smuzhiyun * but WITHOUT ANY WARRANTY; without even the implied warranty of 19*4882a593Smuzhiyun * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20*4882a593Smuzhiyun * GNU Lesser General Public License for more details. 21*4882a593Smuzhiyun */ 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun #ifndef _DVB_RINGBUFFER_H_ 24*4882a593Smuzhiyun #define _DVB_RINGBUFFER_H_ 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun #include <linux/spinlock.h> 27*4882a593Smuzhiyun #include <linux/wait.h> 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun /** 30*4882a593Smuzhiyun * struct dvb_ringbuffer - Describes a ring buffer used at DVB framework 31*4882a593Smuzhiyun * 32*4882a593Smuzhiyun * @data: Area were the ringbuffer data is written 33*4882a593Smuzhiyun * @size: size of the ringbuffer 34*4882a593Smuzhiyun * @pread: next position to read 35*4882a593Smuzhiyun * @pwrite: next position to write 36*4882a593Smuzhiyun * @error: used by ringbuffer clients to indicate that an error happened. 37*4882a593Smuzhiyun * @queue: Wait queue used by ringbuffer clients to indicate when buffer 38*4882a593Smuzhiyun * was filled 39*4882a593Smuzhiyun * @lock: Spinlock used to protect the ringbuffer 40*4882a593Smuzhiyun */ 41*4882a593Smuzhiyun struct dvb_ringbuffer { 42*4882a593Smuzhiyun u8 *data; 43*4882a593Smuzhiyun ssize_t size; 44*4882a593Smuzhiyun ssize_t pread; 45*4882a593Smuzhiyun ssize_t pwrite; 46*4882a593Smuzhiyun int error; 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun wait_queue_head_t queue; 49*4882a593Smuzhiyun spinlock_t lock; 50*4882a593Smuzhiyun }; 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun #define DVB_RINGBUFFER_PKTHDRSIZE 3 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun /** 55*4882a593Smuzhiyun * dvb_ringbuffer_init - initialize ring buffer, lock and queue 56*4882a593Smuzhiyun * 57*4882a593Smuzhiyun * @rbuf: pointer to struct dvb_ringbuffer 58*4882a593Smuzhiyun * @data: pointer to the buffer where the data will be stored 59*4882a593Smuzhiyun * @len: bytes from ring buffer into @buf 60*4882a593Smuzhiyun */ 61*4882a593Smuzhiyun extern void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, 62*4882a593Smuzhiyun size_t len); 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun /** 65*4882a593Smuzhiyun * dvb_ringbuffer_empty - test whether buffer is empty 66*4882a593Smuzhiyun * 67*4882a593Smuzhiyun * @rbuf: pointer to struct dvb_ringbuffer 68*4882a593Smuzhiyun */ 69*4882a593Smuzhiyun extern int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf); 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun /** 72*4882a593Smuzhiyun * dvb_ringbuffer_free - returns the number of free bytes in the buffer 73*4882a593Smuzhiyun * 74*4882a593Smuzhiyun * @rbuf: pointer to struct dvb_ringbuffer 75*4882a593Smuzhiyun * 76*4882a593Smuzhiyun * Return: number of free bytes in the buffer 77*4882a593Smuzhiyun */ 78*4882a593Smuzhiyun extern ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf); 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun /** 81*4882a593Smuzhiyun * dvb_ringbuffer_avail - returns the number of bytes waiting in the buffer 82*4882a593Smuzhiyun * 83*4882a593Smuzhiyun * @rbuf: pointer to struct dvb_ringbuffer 84*4882a593Smuzhiyun * 85*4882a593Smuzhiyun * Return: number of bytes waiting in the buffer 86*4882a593Smuzhiyun */ 87*4882a593Smuzhiyun extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf); 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun /** 90*4882a593Smuzhiyun * dvb_ringbuffer_reset - resets the ringbuffer to initial state 91*4882a593Smuzhiyun * 92*4882a593Smuzhiyun * @rbuf: pointer to struct dvb_ringbuffer 93*4882a593Smuzhiyun * 94*4882a593Smuzhiyun * Resets the read and write pointers to zero and flush the buffer. 95*4882a593Smuzhiyun * 96*4882a593Smuzhiyun * This counts as a read and write operation 97*4882a593Smuzhiyun */ 98*4882a593Smuzhiyun extern void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf); 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun /* 101*4882a593Smuzhiyun * read routines & macros 102*4882a593Smuzhiyun */ 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun /** 105*4882a593Smuzhiyun * dvb_ringbuffer_flush - flush buffer 106*4882a593Smuzhiyun * 107*4882a593Smuzhiyun * @rbuf: pointer to struct dvb_ringbuffer 108*4882a593Smuzhiyun */ 109*4882a593Smuzhiyun extern void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf); 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun /** 112*4882a593Smuzhiyun * dvb_ringbuffer_flush_spinlock_wakeup- flush buffer protected by spinlock 113*4882a593Smuzhiyun * and wake-up waiting task(s) 114*4882a593Smuzhiyun * 115*4882a593Smuzhiyun * @rbuf: pointer to struct dvb_ringbuffer 116*4882a593Smuzhiyun */ 117*4882a593Smuzhiyun extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf); 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun /** 120*4882a593Smuzhiyun * DVB_RINGBUFFER_PEEK - peek at byte @offs in the buffer 121*4882a593Smuzhiyun * 122*4882a593Smuzhiyun * @rbuf: pointer to struct dvb_ringbuffer 123*4882a593Smuzhiyun * @offs: offset inside the ringbuffer 124*4882a593Smuzhiyun */ 125*4882a593Smuzhiyun #define DVB_RINGBUFFER_PEEK(rbuf, offs) \ 126*4882a593Smuzhiyun ((rbuf)->data[((rbuf)->pread + (offs)) % (rbuf)->size]) 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun /** 129*4882a593Smuzhiyun * DVB_RINGBUFFER_SKIP - advance read ptr by @num bytes 130*4882a593Smuzhiyun * 131*4882a593Smuzhiyun * @rbuf: pointer to struct dvb_ringbuffer 132*4882a593Smuzhiyun * @num: number of bytes to advance 133*4882a593Smuzhiyun */ 134*4882a593Smuzhiyun #define DVB_RINGBUFFER_SKIP(rbuf, num) {\ 135*4882a593Smuzhiyun (rbuf)->pread = ((rbuf)->pread + (num)) % (rbuf)->size;\ 136*4882a593Smuzhiyun } 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun /** 139*4882a593Smuzhiyun * dvb_ringbuffer_read_user - Reads a buffer into a user pointer 140*4882a593Smuzhiyun * 141*4882a593Smuzhiyun * @rbuf: pointer to struct dvb_ringbuffer 142*4882a593Smuzhiyun * @buf: pointer to the buffer where the data will be stored 143*4882a593Smuzhiyun * @len: bytes from ring buffer into @buf 144*4882a593Smuzhiyun * 145*4882a593Smuzhiyun * This variant assumes that the buffer is a memory at the userspace. So, 146*4882a593Smuzhiyun * it will internally call copy_to_user(). 147*4882a593Smuzhiyun * 148*4882a593Smuzhiyun * Return: number of bytes transferred or -EFAULT 149*4882a593Smuzhiyun */ 150*4882a593Smuzhiyun extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, 151*4882a593Smuzhiyun u8 __user *buf, size_t len); 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun /** 154*4882a593Smuzhiyun * dvb_ringbuffer_read - Reads a buffer into a pointer 155*4882a593Smuzhiyun * 156*4882a593Smuzhiyun * @rbuf: pointer to struct dvb_ringbuffer 157*4882a593Smuzhiyun * @buf: pointer to the buffer where the data will be stored 158*4882a593Smuzhiyun * @len: bytes from ring buffer into @buf 159*4882a593Smuzhiyun * 160*4882a593Smuzhiyun * This variant assumes that the buffer is a memory at the Kernel space 161*4882a593Smuzhiyun * 162*4882a593Smuzhiyun * Return: number of bytes transferred or -EFAULT 163*4882a593Smuzhiyun */ 164*4882a593Smuzhiyun extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, 165*4882a593Smuzhiyun u8 *buf, size_t len); 166*4882a593Smuzhiyun 167*4882a593Smuzhiyun /* 168*4882a593Smuzhiyun * write routines & macros 169*4882a593Smuzhiyun */ 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun /** 172*4882a593Smuzhiyun * DVB_RINGBUFFER_WRITE_BYTE - write single byte to ring buffer 173*4882a593Smuzhiyun * 174*4882a593Smuzhiyun * @rbuf: pointer to struct dvb_ringbuffer 175*4882a593Smuzhiyun * @byte: byte to write 176*4882a593Smuzhiyun */ 177*4882a593Smuzhiyun #define DVB_RINGBUFFER_WRITE_BYTE(rbuf, byte) \ 178*4882a593Smuzhiyun { (rbuf)->data[(rbuf)->pwrite] = (byte); \ 179*4882a593Smuzhiyun (rbuf)->pwrite = ((rbuf)->pwrite + 1) % (rbuf)->size; } 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun /** 182*4882a593Smuzhiyun * dvb_ringbuffer_write - Writes a buffer into the ringbuffer 183*4882a593Smuzhiyun * 184*4882a593Smuzhiyun * @rbuf: pointer to struct dvb_ringbuffer 185*4882a593Smuzhiyun * @buf: pointer to the buffer where the data will be read 186*4882a593Smuzhiyun * @len: bytes from ring buffer into @buf 187*4882a593Smuzhiyun * 188*4882a593Smuzhiyun * This variant assumes that the buffer is a memory at the Kernel space 189*4882a593Smuzhiyun * 190*4882a593Smuzhiyun * return: number of bytes transferred or -EFAULT 191*4882a593Smuzhiyun */ 192*4882a593Smuzhiyun extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, 193*4882a593Smuzhiyun size_t len); 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun /** 196*4882a593Smuzhiyun * dvb_ringbuffer_write_user - Writes a buffer received via a user pointer 197*4882a593Smuzhiyun * 198*4882a593Smuzhiyun * @rbuf: pointer to struct dvb_ringbuffer 199*4882a593Smuzhiyun * @buf: pointer to the buffer where the data will be read 200*4882a593Smuzhiyun * @len: bytes from ring buffer into @buf 201*4882a593Smuzhiyun * 202*4882a593Smuzhiyun * This variant assumes that the buffer is a memory at the userspace. So, 203*4882a593Smuzhiyun * it will internally call copy_from_user(). 204*4882a593Smuzhiyun * 205*4882a593Smuzhiyun * Return: number of bytes transferred or -EFAULT 206*4882a593Smuzhiyun */ 207*4882a593Smuzhiyun extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf, 208*4882a593Smuzhiyun const u8 __user *buf, size_t len); 209*4882a593Smuzhiyun 210*4882a593Smuzhiyun /** 211*4882a593Smuzhiyun * dvb_ringbuffer_pkt_write - Write a packet into the ringbuffer. 212*4882a593Smuzhiyun * 213*4882a593Smuzhiyun * @rbuf: Ringbuffer to write to. 214*4882a593Smuzhiyun * @buf: Buffer to write. 215*4882a593Smuzhiyun * @len: Length of buffer (currently limited to 65535 bytes max). 216*4882a593Smuzhiyun * 217*4882a593Smuzhiyun * Return: Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL. 218*4882a593Smuzhiyun */ 219*4882a593Smuzhiyun extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8 *buf, 220*4882a593Smuzhiyun size_t len); 221*4882a593Smuzhiyun 222*4882a593Smuzhiyun /** 223*4882a593Smuzhiyun * dvb_ringbuffer_pkt_read_user - Read from a packet in the ringbuffer. 224*4882a593Smuzhiyun * 225*4882a593Smuzhiyun * @rbuf: Ringbuffer concerned. 226*4882a593Smuzhiyun * @idx: Packet index as returned by dvb_ringbuffer_pkt_next(). 227*4882a593Smuzhiyun * @offset: Offset into packet to read from. 228*4882a593Smuzhiyun * @buf: Destination buffer for data. 229*4882a593Smuzhiyun * @len: Size of destination buffer. 230*4882a593Smuzhiyun * 231*4882a593Smuzhiyun * Return: Number of bytes read, or -EFAULT. 232*4882a593Smuzhiyun * 233*4882a593Smuzhiyun * .. note:: 234*4882a593Smuzhiyun * 235*4882a593Smuzhiyun * unlike dvb_ringbuffer_read(), this does **NOT** update the read pointer 236*4882a593Smuzhiyun * in the ringbuffer. You must use dvb_ringbuffer_pkt_dispose() to mark a 237*4882a593Smuzhiyun * packet as no longer required. 238*4882a593Smuzhiyun */ 239*4882a593Smuzhiyun extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, 240*4882a593Smuzhiyun size_t idx, 241*4882a593Smuzhiyun int offset, u8 __user *buf, 242*4882a593Smuzhiyun size_t len); 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun /** 245*4882a593Smuzhiyun * dvb_ringbuffer_pkt_read - Read from a packet in the ringbuffer. 246*4882a593Smuzhiyun * Note: unlike dvb_ringbuffer_read_user(), this DOES update the read pointer 247*4882a593Smuzhiyun * in the ringbuffer. 248*4882a593Smuzhiyun * 249*4882a593Smuzhiyun * @rbuf: Ringbuffer concerned. 250*4882a593Smuzhiyun * @idx: Packet index as returned by dvb_ringbuffer_pkt_next(). 251*4882a593Smuzhiyun * @offset: Offset into packet to read from. 252*4882a593Smuzhiyun * @buf: Destination buffer for data. 253*4882a593Smuzhiyun * @len: Size of destination buffer. 254*4882a593Smuzhiyun * 255*4882a593Smuzhiyun * Return: Number of bytes read, or -EFAULT. 256*4882a593Smuzhiyun */ 257*4882a593Smuzhiyun extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, 258*4882a593Smuzhiyun int offset, u8 *buf, size_t len); 259*4882a593Smuzhiyun 260*4882a593Smuzhiyun /** 261*4882a593Smuzhiyun * dvb_ringbuffer_pkt_dispose - Dispose of a packet in the ring buffer. 262*4882a593Smuzhiyun * 263*4882a593Smuzhiyun * @rbuf: Ring buffer concerned. 264*4882a593Smuzhiyun * @idx: Packet index as returned by dvb_ringbuffer_pkt_next(). 265*4882a593Smuzhiyun */ 266*4882a593Smuzhiyun extern void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx); 267*4882a593Smuzhiyun 268*4882a593Smuzhiyun /** 269*4882a593Smuzhiyun * dvb_ringbuffer_pkt_next - Get the index of the next packet in a ringbuffer. 270*4882a593Smuzhiyun * 271*4882a593Smuzhiyun * @rbuf: Ringbuffer concerned. 272*4882a593Smuzhiyun * @idx: Previous packet index, or -1 to return the first packet index. 273*4882a593Smuzhiyun * @pktlen: On success, will be updated to contain the length of the packet 274*4882a593Smuzhiyun * in bytes. 275*4882a593Smuzhiyun * returns Packet index (if >=0), or -1 if no packets available. 276*4882a593Smuzhiyun */ 277*4882a593Smuzhiyun extern ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, 278*4882a593Smuzhiyun size_t idx, size_t *pktlen); 279*4882a593Smuzhiyun 280*4882a593Smuzhiyun #endif /* _DVB_RINGBUFFER_H_ */ 281