Commit | Line | Data |
---|---|---|
2235acb2 JC |
1 | /* The industrial I/O simple minimally locked ring buffer. |
2 | * | |
3 | * Copyright (c) 2008 Jonathan Cameron | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify it | |
6 | * under the terms of the GNU General Public License version 2 as published by | |
7 | * the Free Software Foundation. | |
8 | * | |
9 | * This code is deliberately kept separate from the main industrialio I/O core | |
10 | * as it is intended that in the future a number of different software ring | |
11 | * buffer implementations will exist with different characteristics to suit | |
12 | * different applications. | |
13 | * | |
14 | * This particular one was designed for a data capture application where it was | |
15 | * particularly important that no userspace reads would interrupt the capture | |
16 | * process. To this end the ring is not locked during a read. | |
17 | * | |
18 | * Comments on this buffer design welcomed. It's far from efficient and some of | |
19 | * my understanding of the effects of scheduling on this are somewhat limited. | |
20 | * Frankly, to my mind, this is the current weak point in the industrial I/O | |
21 | * patch set. | |
22 | */ | |
23 | ||
24 | #ifndef _IIO_RING_SW_H_ | |
25 | #define _IIO_RING_SW_H_ | |
26 | /* NEEDS COMMENTS */ | |
27 | /* The intention is that this should be a separate module from the iio core. | |
28 | * This is a bit like supporting algorithms dependent on what the device | |
29 | * driver requests - some may support multiple options */ | |
30 | ||
31 | ||
2235acb2 JC |
32 | #include "iio.h" |
33 | #include "ring_generic.h" | |
34 | ||
35 | #if defined CONFIG_IIO_SW_RING || defined CONFIG_IIO_SW_RING_MODULE | |
36 | ||
37 | /** | |
4c572605 | 38 | * iio_create_sw_rb() - software ring buffer allocation |
2235acb2 JC |
39 | * @r: pointer to ring buffer pointer |
40 | **/ | |
41 | int iio_create_sw_rb(struct iio_ring_buffer **r); | |
42 | ||
43 | /** | |
4c572605 | 44 | * iio_init_sw_rb() - initialize the software ring buffer |
2235acb2 | 45 | * @r: pointer to a software ring buffer created by an |
4c572605 RD |
46 | * iio_create_sw_rb call |
47 | * @indio_dev: industrial I/O device structure | |
2235acb2 JC |
48 | **/ |
49 | int iio_init_sw_rb(struct iio_ring_buffer *r, struct iio_dev *indio_dev); | |
4c572605 | 50 | |
2235acb2 | 51 | /** |
4c572605 RD |
52 | * iio_exit_sw_rb() - reverse what was done in iio_init_sw_rb |
53 | * @r: pointer to a software ring buffer created by an | |
54 | * iio_create_sw_rb call | |
2235acb2 JC |
55 | **/ |
56 | void iio_exit_sw_rb(struct iio_ring_buffer *r); | |
57 | ||
58 | /** | |
4c572605 RD |
59 | * iio_free_sw_rb() - free memory occupied by the core ring buffer struct |
60 | * @r: pointer to a software ring buffer created by an | |
61 | * iio_create_sw_rb call | |
2235acb2 JC |
62 | **/ |
63 | void iio_free_sw_rb(struct iio_ring_buffer *r); | |
64 | ||
65 | /** | |
4c572605 RD |
66 | * iio_mark_sw_rb_in_use() - reference counting to prevent incorrect chances |
67 | * @r: pointer to a software ring buffer created by an | |
68 | * iio_create_sw_rb call | |
2235acb2 JC |
69 | **/ |
70 | void iio_mark_sw_rb_in_use(struct iio_ring_buffer *r); | |
71 | ||
72 | /** | |
4c572605 RD |
73 | * iio_unmark_sw_rb_in_use() - notify the ring buffer that we don't care anymore |
74 | * @r: pointer to a software ring buffer created by an | |
75 | * iio_create_sw_rb call | |
2235acb2 JC |
76 | **/ |
77 | void iio_unmark_sw_rb_in_use(struct iio_ring_buffer *r); | |
78 | ||
79 | /** | |
4c572605 RD |
80 | * iio_read_last_from_sw_rb() - attempt to read the last stored datum from the rb |
81 | * @r: pointer to a software ring buffer created by an | |
82 | * iio_create_sw_rb call | |
83 | * @data: where to store the last datum | |
2235acb2 JC |
84 | **/ |
85 | int iio_read_last_from_sw_rb(struct iio_ring_buffer *r, u8 *data); | |
86 | ||
87 | /** | |
4c572605 RD |
88 | * iio_store_to_sw_rb() - store a new datum to the ring buffer |
89 | * @r: pointer to ring buffer instance | |
90 | * @data: the datum to be stored including timestamp if relevant | |
91 | * @timestamp: timestamp which will be attached to buffer events if relevant | |
2235acb2 JC |
92 | **/ |
93 | int iio_store_to_sw_rb(struct iio_ring_buffer *r, u8 *data, s64 timestamp); | |
94 | ||
95 | /** | |
4c572605 | 96 | * iio_rip_sw_rb() - attempt to read data from the ring buffer |
2235acb2 JC |
97 | * @r: ring buffer instance |
98 | * @count: number of datum's to try and read | |
99 | * @data: where the data will be stored. | |
100 | * @dead_offset: how much of the stored data was possibly invalidated by | |
101 | * the end of the copy. | |
102 | **/ | |
103 | int iio_rip_sw_rb(struct iio_ring_buffer *r, | |
104 | size_t count, | |
105 | u8 **data, | |
106 | int *dead_offset); | |
107 | ||
108 | /** | |
4c572605 RD |
109 | * iio_request_update_sw_rb() - update params if update needed |
110 | * @r: pointer to a software ring buffer created by an | |
111 | * iio_create_sw_rb call | |
2235acb2 JC |
112 | **/ |
113 | int iio_request_update_sw_rb(struct iio_ring_buffer *r); | |
114 | ||
115 | /** | |
4c572605 RD |
116 | * iio_mark_update_needed_sw_rb() - tell the ring buffer it needs a param update |
117 | * @r: pointer to a software ring buffer created by an | |
118 | * iio_create_sw_rb call | |
2235acb2 JC |
119 | **/ |
120 | int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r); | |
121 | ||
122 | ||
123 | /** | |
4c572605 RD |
124 | * iio_get_bpd_sw_rb() - get the datum size in bytes |
125 | * @r: pointer to a software ring buffer created by an | |
126 | * iio_create_sw_rb call | |
2235acb2 JC |
127 | **/ |
128 | int iio_get_bpd_sw_rb(struct iio_ring_buffer *r); | |
129 | ||
130 | /** | |
4c572605 RD |
131 | * iio_set_bpd_sw_rb() - set the datum size in bytes |
132 | * @r: pointer to a software ring buffer created by an | |
133 | * iio_create_sw_rb call | |
134 | * @bpd: bytes per datum value | |
2235acb2 JC |
135 | **/ |
136 | int iio_set_bpd_sw_rb(struct iio_ring_buffer *r, size_t bpd); | |
137 | ||
138 | /** | |
4c572605 RD |
139 | * iio_get_length_sw_rb() - get how many datums the rb may contain |
140 | * @r: pointer to a software ring buffer created by an | |
141 | * iio_create_sw_rb call | |
2235acb2 JC |
142 | **/ |
143 | int iio_get_length_sw_rb(struct iio_ring_buffer *r); | |
144 | ||
145 | /** | |
4c572605 RD |
146 | * iio_set_length_sw_rb() - set how many datums the rb may contain |
147 | * @r: pointer to a software ring buffer created by an | |
148 | * iio_create_sw_rb call | |
149 | * @length: max number of data items for the ring buffer | |
2235acb2 JC |
150 | **/ |
151 | int iio_set_length_sw_rb(struct iio_ring_buffer *r, int length); | |
152 | ||
153 | /** | |
4c572605 RD |
154 | * iio_ring_sw_register_funcs() - helper function to set up rb access |
155 | * @ra: pointer to @iio_ring_access_funcs | |
2235acb2 JC |
156 | **/ |
157 | static inline void iio_ring_sw_register_funcs(struct iio_ring_access_funcs *ra) | |
158 | { | |
159 | ra->mark_in_use = &iio_mark_sw_rb_in_use; | |
160 | ra->unmark_in_use = &iio_unmark_sw_rb_in_use; | |
161 | ||
162 | ra->store_to = &iio_store_to_sw_rb; | |
163 | ra->read_last = &iio_read_last_from_sw_rb; | |
164 | ra->rip_lots = &iio_rip_sw_rb; | |
165 | ||
166 | ra->mark_param_change = &iio_mark_update_needed_sw_rb; | |
167 | ra->request_update = &iio_request_update_sw_rb; | |
168 | ||
169 | ra->get_bpd = &iio_get_bpd_sw_rb; | |
170 | ra->set_bpd = &iio_set_bpd_sw_rb; | |
171 | ||
172 | ra->get_length = &iio_get_length_sw_rb; | |
173 | ra->set_length = &iio_set_length_sw_rb; | |
174 | }; | |
175 | ||
176 | /** | |
177 | * struct iio_sw_ring_buffer - software ring buffer | |
178 | * @buf: generic ring buffer elements | |
179 | * @data: the ring buffer memory | |
180 | * @read_p: read pointer (oldest available) | |
181 | * @write_p: write pointer | |
182 | * @last_written_p: read pointer (newest available) | |
183 | * @half_p: half buffer length behind write_p (event generation) | |
184 | * @use_count: reference count to prevent resizing when in use | |
185 | * @update_needed: flag to indicated change in size requested | |
186 | * @use_lock: lock to prevent change in size when in use | |
187 | * | |
188 | * Note that the first element of all ring buffers must be a | |
189 | * struct iio_ring_buffer. | |
190 | **/ | |
191 | ||
192 | struct iio_sw_ring_buffer { | |
193 | struct iio_ring_buffer buf; | |
194 | unsigned char *data; | |
195 | unsigned char *read_p; | |
196 | unsigned char *write_p; | |
197 | unsigned char *last_written_p; | |
198 | /* used to act as a point at which to signal an event */ | |
199 | unsigned char *half_p; | |
200 | int use_count; | |
201 | int update_needed; | |
202 | spinlock_t use_lock; | |
203 | }; | |
204 | ||
205 | #define iio_to_sw_ring(r) container_of(r, struct iio_sw_ring_buffer, buf) | |
206 | ||
207 | struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev); | |
208 | void iio_sw_rb_free(struct iio_ring_buffer *ring); | |
209 | ||
210 | ||
211 | ||
212 | #else /* CONFIG_IIO_RING_BUFFER*/ | |
213 | static inline void iio_ring_sw_register_funcs(struct iio_ring_access_funcs *ra) | |
214 | {}; | |
215 | #endif /* !CONFIG_IIO_RING_BUFFER */ | |
216 | #endif /* _IIO_RING_SW_H_ */ |