xref: /OK3568_Linux_fs/kernel/include/media/dvb_ringbuffer.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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