00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00029 #ifdef HAVE_CONFIG_H
00030 #include "config/config.h"
00031 #endif
00032 #ifndef USP_TEST
00033 # include <asm/uaccess.h>
00034 # include <linux/module.h>
00035 # include <linux/wait.h>
00036 # include <linux/vmalloc.h>
00037 # include "most-constants.h"
00038 # include "rt-nrt.h"
00039 #else
00040 # include "usp-test.h"
00041 #endif
00042
00043 #include "most-rxbuf.h"
00044
00048 #define PR "rxbuf: "
00049
00050
00051
00052
00053
00054 struct rx_buffer *rxbuf_alloc(unsigned int reader_count,
00055 unsigned int frame_count,
00056 unsigned int bytes_per_frame)
00057 {
00058 unsigned int i;
00059 struct rx_buffer *ret;
00060
00061
00062 frame_count++;
00063
00064
00065 ret = ker_malloc(sizeof(struct rx_buffer));
00066 if (unlikely(!ret)) {
00067 rtnrt_err(PR "Allocating struct rx_buffer failed\n");
00068 return NULL;
00069 }
00070 memset(ret, 0, sizeof(struct rx_buffer));
00071
00072
00073 ret->reader_count = reader_count;
00074 ret->frame_count = frame_count;
00075 ret->bytes_per_frame = bytes_per_frame;
00076
00077
00078 ret->buffer = vmalloc(bytes_per_frame * frame_count);
00079 pr_rxbuf_debug(PR "Allocating %d bytes ringbuffer (0x%p)\n",
00080 bytes_per_frame * frame_count, ret->buffer);
00081 if (unlikely(!ret->buffer)) {
00082 rtnrt_err(PR "Allocating ring buffer failed\n");
00083 goto err_buf;
00084 }
00085 #ifdef DEBUG
00086 memset(ret->buffer, 0, bytes_per_frame * frame_count);
00087 #endif
00088
00089
00090 for (i = 0; i < ret->reader_count; i++) {
00091 ret->readptr[i] = ret->buffer;
00092 }
00093 ret->writeptr = ret->buffer;
00094
00095 return ret;
00096
00097 err_buf:
00098 kfree(ret);
00099 return NULL;
00100 }
00101
00102
00103
00104
00105 void rxbuf_free(struct rx_buffer *ring)
00106 {
00107 if (ring) {
00108 if (ring->buffer) {
00109 vfree(ring->buffer);
00110 }
00111 kfree(ring);
00112 }
00113 }
00114
00115
00116
00117
00118 ssize_t rxbuf_get(struct rx_buffer *ring,
00119 unsigned int reader_index,
00120 struct frame_part frame_part,
00121 unsigned char *buffer,
00122 size_t bytes,
00123 struct rtnrt_memcopy_desc *copy)
00124 {
00125 int frames_to_copy, still_to_copy;
00126 int bytes_full;
00127 unsigned char *readp = ring->readptr[reader_index];
00128 unsigned int ring_size = ring->bytes_per_frame * ring->frame_count;
00129 unsigned char *ring_end = ring->buffer + ring_size;
00130 int err;
00131
00132
00133 bytes -= bytes % frame_part.count;
00134
00135
00136 if (bytes > ring_size) {
00137 rtnrt_err(PR "bytes (%d) must be smaller than ring_size (%d)\n",
00138 (int)bytes, ring_size);
00139 return -EINVAL;
00140 }
00141
00142
00143 bytes_full = ring->writeptr - readp;
00144 if (bytes_full < 0) {
00145 bytes_full = ring_size + bytes_full;
00146 }
00147 frames_to_copy = min((size_t)bytes_full / ring->bytes_per_frame, bytes /
00148 frame_part.count);
00149
00150 pr_rxbuf_debug(PR "bytes full: %d, frames to copy: %d\n",
00151 bytes_full, frames_to_copy);
00152
00153
00154 if (frames_to_copy == 0) {
00155 return 0;
00156 }
00157
00158
00159 still_to_copy = frames_to_copy;
00160 while (still_to_copy > 0) {
00161
00162
00163 err = rtnrt_copy(copy, buffer, readp + frame_part.offset, frame_part.count);
00164
00165 if (err != 0) {
00166 rtnrt_warn(PR "Error %d in copy, copied %d bytes\n",
00167 err, frames_to_copy - still_to_copy);
00168 return (frames_to_copy - still_to_copy) * frame_part.count;
00169 }
00170
00171 readp += ring->bytes_per_frame;
00172
00173 if (readp >= ring_end) {
00174 readp = ring->buffer;
00175 }
00176 buffer += frame_part.count;
00177 still_to_copy--;
00178 }
00179
00180 ring->readptr[reader_index] = readp;
00181
00182 return frames_to_copy * frame_part.count;
00183
00184 }
00185
00186
00187
00188
00189 bool rxbuf_is_empty(struct rx_buffer *ring, int reader_index)
00190 {
00191 return ring->writeptr == ring->readptr[reader_index];
00192 }
00193
00194
00195
00196
00197 ssize_t rxbuf_put(struct rx_buffer *ring,
00198 unsigned char *buffer,
00199 size_t bytes)
00200 {
00201 int to_copy;
00202 int ring_size = ring->bytes_per_frame * ring->frame_count;
00203
00204 return_value_if_fails_dbg(ring != NULL, -EINVAL);
00205 return_value_if_fails_dbg(buffer != NULL, -EINVAL);
00206 pr_rxbuf_debug(PR "rxbuf_put=%d\n", bytes);
00207
00208
00209 if ((bytes % ring->bytes_per_frame != 0)) {
00210 rtnrt_err(PR "bytes (%d) must be dividable by %d or is too large\n",
00211 (int)bytes, ring->bytes_per_frame);
00212 return -EINVAL;
00213 }
00214
00215
00216 to_copy = min((int)bytes,
00217 (int)(ring_size - (unsigned long)(ring->writeptr - ring->buffer)));
00218
00219 if (to_copy == 0) {
00220 return 0;
00221 }
00222
00223
00224 memcpy(ring->writeptr, buffer, to_copy);
00225
00226
00227 if ((unsigned int)to_copy == bytes) {
00228
00229 ring->writeptr += to_copy;
00230 if (ring->writeptr >= (ring->buffer + ring_size)) {
00231 ring->writeptr = ring->buffer;
00232 }
00233 } else {
00234
00235 buffer += to_copy;
00236 to_copy = bytes - to_copy;
00237
00238 memcpy(ring->buffer, buffer, to_copy);
00239
00240
00241 ring->writeptr = ring->buffer + to_copy;
00242 }
00243
00244 return bytes;
00245 }
00246
00247 #ifdef DEBUG
00248 static spinlock_t print_lock = RTNRT_LSPINLOCK_UNLOCKED(print_lock);
00249
00250
00251
00252
00253 void rxbuf_print_debug(struct rx_buffer *ring, bool data)
00254 {
00255 unsigned int i;
00256
00257 spin_lock(&print_lock);
00258
00259 rtnrt_debug("Frames in ring : %d\n", ring->frame_count);
00260 rtnrt_debug("Bytes per frame : %d\n", ring->bytes_per_frame);
00261 rtnrt_debug("Write offset : %d\n", ring->writeptr - ring->buffer);
00262
00263
00264 for (i = 0; i < ring->reader_count; i++) {
00265 rtnrt_debug("Read offset [%2d] : %d\n", i,
00266 ring->readptr[i] - ring->buffer);
00267 }
00268
00269 if (data) {
00270 for (i = 0; i < (ring->frame_count * ring->bytes_per_frame); i++)
00271 {
00272 rtnrt_printk("%-2.2X ", ring->buffer[i]);
00273 }
00274 }
00275
00276 rtnrt_printk("\n");
00277
00278 spin_unlock(&print_lock);
00279 }
00280 #endif
00281
00282 #ifdef USP_TEST
00283
00284
00285 int main(int argc, char *argv[])
00286 {
00287 int i;
00288 unsigned char user_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
00289 11, 12, 13, 14, 15, 16 };
00290 struct frame_part part;
00291 unsigned char data[1024];
00292 struct rx_buffer *buffer;
00293 int err;
00294
00295 pr_debugm("BEGIN\n");
00296
00297 buffer = rxbuf_alloc(2, 5, 6);
00298 if (!buffer) {
00299 pr_debugm("Error in tvbuf_alloc\n\n\n");
00300 return -1;
00301 }
00302
00303 printf("== Empty? %d, %d\n", rxbuf_is_empty(buffer, 0), rxbuf_is_empty(buffer, 1));
00304
00305 err = rxbuf_put(buffer, user_data, 6);
00306 pr_debugm("Ret=%d\n", err);
00307 printf("== Empty? %d, %d\n", rxbuf_is_empty(buffer, 0), rxbuf_is_empty(buffer, 1));
00308
00309 err = rxbuf_put(buffer, user_data + 6, 6);
00310 pr_debugm("Ret=%d\n", err);
00311 printf("== Empty? %d, %d\n", rxbuf_is_empty(buffer, 0), rxbuf_is_empty(buffer, 1));
00312
00313 rxbuf_print_debug(buffer, true);
00314 part.count = 4;
00315 part.offset = 0;
00316 err = rxbuf_get(buffer, 0, part, data, 12);
00317 pr_debugm("*Ret=%d\n", err);
00318 printf("== Empty? %d, %d\n", rxbuf_is_empty(buffer, 0), rxbuf_is_empty(buffer, 1));
00319
00320 for (i = 0; i < min(err, 12); i++) {
00321 most_printk("%-2.2X ", data[i]);
00322 }
00323 printf("\n");
00324
00325 part.count = 4;
00326 part.offset = 0;
00327 err = rxbuf_get(buffer, 0, part, data, 4);
00328 pr_debugm("Ret=%d\n", err);
00329
00330 for (i = 0; i < min(err, 4); i++) {
00331 printf("%-2.2X ", data[i]);
00332 }
00333 printf("\n");
00334
00335 rxbuf_print_debug(buffer, true);
00336
00337 err = rxbuf_put(buffer, user_data, 12);
00338 pr_debugm("Ret=%d\n", err);
00339 rxbuf_print_debug(buffer, true);
00340
00341 part.count = 4;
00342 part.offset = 0;
00343 err = rxbuf_get(buffer, 0, part, data, 12);
00344 pr_debugm("Ret=%d\n", err);
00345
00346 for (i = 0; i < min(err, 12); i++) {
00347 printf("%-2.2X ", data[i]);
00348 }
00349 printf("\n");
00350
00351 rxbuf_free(buffer);
00352
00353 return 0;
00354 }
00355
00356 #endif
00357
00358