00001
00023 #ifndef __ANALOGY_BUFFER_H__
00024 #define __ANALOGY_BUFFER_H__
00025
00026 #ifndef DOXYGEN_CPP
00027
00028 #ifdef __KERNEL__
00029
00030 #include <linux/version.h>
00031 #include <linux/mm.h>
00032
00033 #include <rtdm/rtdm_driver.h>
00034
00035 #include <analogy/os_facilities.h>
00036 #include <analogy/context.h>
00037
00038
00039
00040 #define A4L_BUF_EOBUF_NR 0
00041 #define A4L_BUF_EOBUF (1 << A4L_BUF_EOBUF_NR)
00042
00043 #define A4L_BUF_ERROR_NR 1
00044 #define A4L_BUF_ERROR (1 << A4L_BUF_ERROR_NR)
00045
00046 #define A4L_BUF_EOA_NR 2
00047 #define A4L_BUF_EOA (1 << A4L_BUF_EOA_NR)
00048
00049
00050
00051 #define A4L_BUF_BULK_NR 8
00052 #define A4L_BUF_BULK (1 << A4L_BUF_BULK_NR)
00053
00054 #define A4L_BUF_MAP_NR 9
00055 #define A4L_BUF_MAP (1 << A4L_BUF_MAP_NR)
00056
00057 struct a4l_subdevice;
00058
00059
00060 struct a4l_buffer {
00061
00062
00063 struct a4l_subdevice *subd;
00064
00065
00066 void *buf;
00067
00068
00069 unsigned long size;
00070
00071 unsigned long *pg_list;
00072
00073
00074 a4l_sync_t sync;
00075
00076
00077 unsigned long end_count;
00078 unsigned long prd_count;
00079 unsigned long cns_count;
00080 unsigned long tmp_count;
00081
00082
00083 unsigned long flags;
00084
00085
00086 a4l_cmd_t *cur_cmd;
00087
00088
00089 unsigned long mng_count;
00090
00091
00092
00093 unsigned long wake_count;
00094 };
00095 typedef struct a4l_buffer a4l_buf_t;
00096
00097
00098
00099
00100
00101
00102
00103 static inline int __produce(a4l_cxt_t *cxt,
00104 a4l_buf_t *buf, void *pin, unsigned long count)
00105 {
00106 unsigned long start_ptr = (buf->prd_count % buf->size);
00107 unsigned long tmp_cnt = count;
00108 int ret = 0;
00109
00110 while (ret == 0 && tmp_cnt != 0) {
00111
00112 unsigned long blk_size = (start_ptr + tmp_cnt > buf->size) ?
00113 buf->size - start_ptr : tmp_cnt;
00114
00115
00116 if (cxt == NULL)
00117 memcpy(buf->buf + start_ptr, pin, blk_size);
00118 else
00119 ret = rtdm_safe_copy_from_user(cxt->user_info,
00120 buf->buf + start_ptr,
00121 pin, blk_size);
00122
00123
00124 pin += blk_size;
00125 tmp_cnt -= blk_size;
00126 start_ptr = 0;
00127 }
00128
00129 return ret;
00130 }
00131
00132
00133
00134
00135 static inline int __consume(a4l_cxt_t *cxt,
00136 a4l_buf_t *buf, void *pout, unsigned long count)
00137 {
00138 unsigned long start_ptr = (buf->cns_count % buf->size);
00139 unsigned long tmp_cnt = count;
00140 int ret = 0;
00141
00142 while (ret == 0 && tmp_cnt != 0) {
00143
00144 unsigned long blk_size = (start_ptr + tmp_cnt > buf->size) ?
00145 buf->size - start_ptr : tmp_cnt;
00146
00147
00148 if (cxt == NULL)
00149 memcpy(pout, buf->buf + start_ptr, blk_size);
00150 else
00151 ret = rtdm_safe_copy_to_user(cxt->user_info,
00152 pout,
00153 buf->buf + start_ptr,
00154 blk_size);
00155
00156
00157 pout += blk_size;
00158 tmp_cnt -= blk_size;
00159 start_ptr = 0;
00160 }
00161
00162 return ret;
00163 }
00164
00165
00166
00167
00168 static inline void __munge(struct a4l_subdevice * subd,
00169 void (*munge) (struct a4l_subdevice *,
00170 void *, unsigned long),
00171 a4l_buf_t * buf, unsigned long count)
00172 {
00173 unsigned long start_ptr = (buf->mng_count % buf->size);
00174 unsigned long tmp_cnt = count;
00175
00176 while (tmp_cnt != 0) {
00177
00178 unsigned long blk_size = (start_ptr + tmp_cnt > buf->size) ?
00179 buf->size - start_ptr : tmp_cnt;
00180
00181
00182 munge(subd, buf->buf + start_ptr, blk_size);
00183
00184
00185 tmp_cnt -= blk_size;
00186 start_ptr = 0;
00187 }
00188 }
00189
00190
00191
00192
00193 static inline int __handle_event(a4l_buf_t * buf)
00194 {
00195 int ret = 0;
00196
00197
00198
00199 if (test_bit(A4L_BUF_EOA_NR, &buf->flags)) {
00200 ret = -ENOENT;
00201 }
00202
00203 if (test_bit(A4L_BUF_ERROR_NR, &buf->flags)) {
00204 ret = -EPIPE;
00205 }
00206
00207 return ret;
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 static inline int __pre_abs_put(a4l_buf_t * buf, unsigned long count)
00244 {
00245 if (count - buf->tmp_count > buf->size) {
00246 set_bit(A4L_BUF_ERROR_NR, &buf->flags);
00247 return -EPIPE;
00248 }
00249
00250 buf->tmp_count = buf->cns_count;
00251
00252 return 0;
00253 }
00254
00255 static inline int __pre_put(a4l_buf_t * buf, unsigned long count)
00256 {
00257 return __pre_abs_put(buf, buf->tmp_count + count);
00258 }
00259
00260 static inline int __pre_abs_get(a4l_buf_t * buf, unsigned long count)
00261 {
00262
00263
00264
00265 if (buf->tmp_count == 0 || buf->cns_count == 0)
00266 goto out;
00267
00268
00269
00270
00271
00272
00273 if (buf->end_count != 0 && (long)(count - buf->end_count) > 0)
00274 goto out;
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 if ((long)(count - buf->tmp_count) > 0) {
00286 set_bit(A4L_BUF_ERROR_NR, &buf->flags);
00287 return -EPIPE;
00288 }
00289
00290 out:
00291 buf->tmp_count = buf->prd_count;
00292
00293 return 0;
00294 }
00295
00296 static inline int __pre_get(a4l_buf_t * buf, unsigned long count)
00297 {
00298 return __pre_abs_get(buf, buf->tmp_count + count);
00299 }
00300
00301 static inline int __abs_put(a4l_buf_t * buf, unsigned long count)
00302 {
00303 unsigned long old = buf->prd_count;
00304
00305 if ((long)(buf->prd_count - count) >= 0)
00306 return -EINVAL;
00307
00308 buf->prd_count = count;
00309
00310 if ((old / buf->size) != (count / buf->size))
00311 set_bit(A4L_BUF_EOBUF_NR, &buf->flags);
00312
00313 if (buf->end_count != 0 && (long)(count - buf->end_count) >= 0)
00314 set_bit(A4L_BUF_EOA_NR, &buf->flags);
00315
00316 return 0;
00317 }
00318
00319 static inline int __put(a4l_buf_t * buf, unsigned long count)
00320 {
00321 return __abs_put(buf, buf->prd_count + count);
00322 }
00323
00324 static inline int __abs_get(a4l_buf_t * buf, unsigned long count)
00325 {
00326 unsigned long old = buf->cns_count;
00327
00328 if ((long)(buf->cns_count - count) >= 0)
00329 return -EINVAL;
00330
00331 buf->cns_count = count;
00332
00333 if ((old / buf->size) != count / buf->size)
00334 set_bit(A4L_BUF_EOBUF_NR, &buf->flags);
00335
00336 if (buf->end_count != 0 && (long)(count - buf->end_count) >= 0)
00337 set_bit(A4L_BUF_EOA_NR, &buf->flags);
00338
00339 return 0;
00340 }
00341
00342 static inline int __get(a4l_buf_t * buf, unsigned long count)
00343 {
00344 return __abs_get(buf, buf->cns_count + count);
00345 }
00346
00347 static inline unsigned long __count_to_put(a4l_buf_t * buf)
00348 {
00349 unsigned long ret;
00350
00351 if ((long) (buf->size + buf->cns_count - buf->prd_count) > 0)
00352 ret = buf->size + buf->cns_count - buf->prd_count;
00353 else
00354 ret = 0;
00355
00356 return ret;
00357 }
00358
00359 static inline unsigned long __count_to_get(a4l_buf_t * buf)
00360 {
00361 unsigned long ret;
00362
00363
00364
00365 if (buf->end_count == 0 || (long)(buf->end_count - buf->prd_count) > 0)
00366 ret = buf->prd_count;
00367 else
00368 ret = buf->end_count;
00369
00370 if ((long)(ret - buf->cns_count) > 0)
00371 ret -= buf->cns_count;
00372 else
00373 ret = 0;
00374
00375 return ret;
00376 }
00377
00378 static inline unsigned long __count_to_end(a4l_buf_t * buf)
00379 {
00380 unsigned long ret = buf->end_count - buf->cns_count;
00381
00382 if (buf->end_count == 0)
00383 return ULONG_MAX;
00384
00385 return ((long)ret) < 0 ? 0 : ret;
00386 }
00387
00388
00389
00390 int a4l_alloc_buffer(a4l_buf_t *buf_desc, int buf_size);
00391
00392 void a4l_free_buffer(a4l_buf_t *buf_desc);
00393
00394 void a4l_init_buffer(a4l_buf_t * buf_desc);
00395
00396 void a4l_cleanup_buffer(a4l_buf_t * buf_desc);
00397
00398 int a4l_setup_buffer(a4l_cxt_t *cxt, a4l_cmd_t *cmd);
00399
00400 int a4l_cancel_buffer(a4l_cxt_t *cxt);
00401
00402 int a4l_buf_prepare_absput(struct a4l_subdevice *subd,
00403 unsigned long count);
00404
00405 int a4l_buf_commit_absput(struct a4l_subdevice *subd,
00406 unsigned long count);
00407
00408 int a4l_buf_prepare_put(struct a4l_subdevice *subd,
00409 unsigned long count);
00410
00411 int a4l_buf_commit_put(struct a4l_subdevice *subd,
00412 unsigned long count);
00413
00414 int a4l_buf_put(struct a4l_subdevice *subd,
00415 void *bufdata, unsigned long count);
00416
00417 int a4l_buf_prepare_absget(struct a4l_subdevice *subd,
00418 unsigned long count);
00419
00420 int a4l_buf_commit_absget(struct a4l_subdevice *subd,
00421 unsigned long count);
00422
00423 int a4l_buf_prepare_get(struct a4l_subdevice *subd,
00424 unsigned long count);
00425
00426 int a4l_buf_commit_get(struct a4l_subdevice *subd,
00427 unsigned long count);
00428
00429 int a4l_buf_get(struct a4l_subdevice *subd,
00430 void *bufdata, unsigned long count);
00431
00432 int a4l_buf_evt(struct a4l_subdevice *subd, unsigned long evts);
00433
00434 unsigned long a4l_buf_count(struct a4l_subdevice *subd);
00435
00436
00437
00438 static inline a4l_cmd_t *a4l_get_cmd(a4l_subd_t *subd)
00439 {
00440 return (subd->buf) ? subd->buf->cur_cmd : NULL;
00441 }
00442
00443
00444
00445 int a4l_get_chan(struct a4l_subdevice *subd);
00446
00447
00448
00449 int a4l_ioctl_mmap(a4l_cxt_t * cxt, void *arg);
00450 int a4l_ioctl_bufcfg(a4l_cxt_t * cxt, void *arg);
00451 int a4l_ioctl_bufcfg2(a4l_cxt_t * cxt, void *arg);
00452 int a4l_ioctl_bufinfo(a4l_cxt_t * cxt, void *arg);
00453 int a4l_ioctl_bufinfo2(a4l_cxt_t * cxt, void *arg);
00454 int a4l_ioctl_poll(a4l_cxt_t * cxt, void *arg);
00455 ssize_t a4l_read_buffer(a4l_cxt_t * cxt, void *bufdata, size_t nbytes);
00456 ssize_t a4l_write_buffer(a4l_cxt_t * cxt, const void *bufdata, size_t nbytes);
00457 int a4l_select(a4l_cxt_t *cxt,
00458 rtdm_selector_t *selector,
00459 enum rtdm_selecttype type, unsigned fd_index);
00460
00461 #endif
00462
00463
00464 struct a4l_mmap_arg {
00465 unsigned int idx_subd;
00466 unsigned long size;
00467 void *ptr;
00468 };
00469 typedef struct a4l_mmap_arg a4l_mmap_t;
00470
00471
00472
00473 #define A4L_BUF_MAXSIZE 0x1000000
00474 #define A4L_BUF_DEFSIZE 0x10000
00475 #define A4L_BUF_DEFMAGIC 0xffaaff55
00476
00477
00478 struct a4l_buffer_config {
00479
00480
00481
00482
00483
00484
00485
00486 unsigned int idx_subd;
00487 unsigned long buf_size;
00488 };
00489 typedef struct a4l_buffer_config a4l_bufcfg_t;
00490
00491
00492 struct a4l_buffer_info {
00493 unsigned int idx_subd;
00494 unsigned long buf_size;
00495 unsigned long rw_count;
00496 };
00497 typedef struct a4l_buffer_info a4l_bufinfo_t;
00498
00499
00500 struct a4l_buffer_config2 {
00501 unsigned long wake_count;
00502 unsigned long reserved[3];
00503 };
00504 typedef struct a4l_buffer_config2 a4l_bufcfg2_t;
00505
00506
00507 struct a4l_poll {
00508 unsigned int idx_subd;
00509 unsigned long arg;
00510 };
00511 typedef struct a4l_poll a4l_poll_t;
00512
00513 #endif
00514
00515 #endif