On 13/10/10 08:31, Alexis Berlemont wrote:
1. Buffer management is badly broken. It is not possible to run any
acquisition command that wraps around in the ring buffer. That can be
simply reproduced with:
cmd_read -v d analogy0 -s 0 -S 0
after a while it will fail with: cmd_read: a4l_read failed (ret=-32).
In dmesg the driver reports: Analogy: MITE: DME overwrite of free area.
OK. Maybe, it is not Analogy's buffer management; it may be specific
to the NI driver. Did you try to reproduce the bug with another driver
(analogy_fake for example)? It may be due to some fix I made this
summer (which is surprising, I thought I tested the change quite
exhaustively... Sorry for that).
The problem is probably in the NI driver. I'm unable to reproduce the
bug with the analogy_fake driver. See attached test script.
2. Buffer is kept memory mapped after the mapping process dies. If a
process mapping a device buffer dies before un-mapping the buffer, it is
not possible to reconfigure the bnuffer. a4l_set_bufsize fails with
error code 32 and dmesg read Analogy: a4l_ioctl_bufcfg: please unmap
before configuring buffer. Sinche the mapping process died I do not
know how to do this.
With a 2.4.x release, did you manage to reproduce the bug?
I'm unable to reproduce the bug with xenomai 2.5.3. See attached test.
It depends on a patch to make the --read-buffer-size and
--write-buffer-size options to analogy_config to effectively work. Also
attached. I do not have a 2.5.4 version handy.
Cheers,
--
Daniele
test_buffer_bug.sh
Description: Bourne shell script
test_mmap_bug.sh
Description: Bourne shell script
/**
* analogy for linux - input command test program
*/
#include stdio.h
#include stdlib.h
#include unistd.h
#include sys/mman.h
#include errno.h
#include getopt.h
#include string.h
#include analogy/analogy.h
/* default device name */
#define DEVICE analogy0
#define DEBUG(frmt, args...) fprintf(stderr, frmt\n, ##args)
#define ERROR(frmt, args...) fprintf(stderr, frmt\n, ##args)
int main(int argc, char **argv)
{
int rv = 0;
unsigned long bufsize;
void *map = NULL;
a4l_desc_t dsc;
char *filename = argv[1];
/* open the device */
rv = a4l_open(dsc, filename);
if (rv 0) {
ERROR(analogy open);
return rv;
}
/* cancel any command which might be in progress */
a4l_snd_cancel(dsc, dsc.idx_read_subd);
/* get buffer size to map */
rv = a4l_get_bufsize(dsc, dsc.idx_read_subd, bufsize);
if (rv 0) {
ERROR(analogy get bufsize);
return rv;
}
/* map read subdevice buffer */
rv = a4l_mmap(dsc, dsc.idx_read_subd, bufsize, map);
if (rv 0) {
ERROR(analogy mmap);
return rv;
}
if (argc 2) {
DEBUG(BUG!);
} else {
/* unmap subdevice buffer */
munmap(map, bufsize);
}
/* close file descriptor */
a4l_close(dsc);
exit(0);
}
commit e7ac38f3f45e439a8d383f3b4adafbb97bf543fe
Author: Daniele Nicolodi nicol...@science.unitn.it
Date: Wed Oct 13 16:03:30 2010 +0200
Make the --read-buffer-size and --write-buffer-size otpions effective.
diff --git a/src/utils/analogy/analogy_config.c b/src/utils/analogy/analogy_config.c
index 1482322..2ce3ddd 100644
--- a/src/utils/analogy/analogy_config.c
+++ b/src/utils/analogy/analogy_config.c
@@ -31,28 +31,25 @@
#include analogy/analogy.h
-/* Declare precompilation constants */
-#define __NBMIN_ARG 2
-#define __NBMAX_ARG 3
-#define __OPTS_DELIMITER ,
+enum action {
+ ATTACH_DRIVER,
+ DETACH_DRIVER,
+ CONFIGURE_BUFFER_SIZE,
+};
-/* Declare prog variables */
-int vlevel = 1;
-int unatt_act = 0;
-struct option a4l_conf_opts[] = {
- {help, no_argument, NULL, 'h'},
- {verbose, no_argument, NULL, 'v'},
- {quiet, no_argument, NULL, 'q'},
- {version, no_argument, NULL, 'V'},
- {remove, no_argument, NULL, 'r'},
- {read-buffer-size, required_argument, NULL, 'R'},
- {write-buffer-size, required_argument, NULL, 'W'},
- {0},
+enum subdevice {
+ READ_SUBDEVICE,
+ WRITE_SUBDEVICE,
};
+/* Verbosity level */
+int vlevel = 1;
+
+/* Driver specific Options delimiter */
+#define DELIMITER ,
+
int compute_opts(char *opts, unsigned int *nb, unsigned long *res)
{
-
int ret = 0, len, ofs;
/* Check arg and inits it */
@@ -67,7 +64,7 @@ int compute_opts(char *opts, unsigned int *nb, unsigned long *res)
do {
(*nb)++;
len = strlen(opts);
- ofs = strcspn(opts, __OPTS_DELIMITER);
+ ofs = strcspn(opts, DELIMITER);
if (res != NULL) {
res[(*nb) - 1] = strtoul(opts, NULL, 0);
if (errno != 0) {
@@ -104,79 +101,57 @@ void do_print_usage(void)
\t\t -W, --write-buffer-size: write buffer size in kB\n);
}
-int main(int argc, char *argv[])
+int detach_driver(const char *devfile)
{
- int c;
- char *devfile;
- a4l_lnkdesc_t lnkdsc;
- int chk_nb, ret = 0, fd = -1;
-
- /* Init the descriptor structure */
-