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