[Xenomai-git] Alexis Berlemont : analogy: improve robustness of the detach procedure
Module: xenomai-abe Branch: analogy Commit: 7682ee62bf180ccdf95fc300c7e40595a68e909a URL: http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=7682ee62bf180ccdf95fc300c7e40595a68e909a Author: Alexis Berlemont alexis.berlem...@gmail.com Date: Tue Feb 9 00:40:51 2010 +0100 analogy: improve robustness of the detach procedure If a subdevice was busy because of an acquisition, the detach procedure failed and left the device in an incoherent state which needed reboot. This bug was fixed by adding a pre-cleanup function which tests subdevices' status. --- include/analogy/transfer.h |2 + ksrc/drivers/analogy/device.c | 13 ++--- ksrc/drivers/analogy/transfer.c | 53 ++ 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/include/analogy/transfer.h b/include/analogy/transfer.h index e50d574..3d44ac6 100644 --- a/include/analogy/transfer.h +++ b/include/analogy/transfer.h @@ -33,6 +33,7 @@ #define A4L_TSF_BUSY 0 #define A4L_TSF_BULK 1 #define A4L_TSF_MMAP 2 +#define A4L_TSF_CLEAN 3 /* Fields init values */ #define A4L_IRQ_UNUSED (unsigned int)((unsigned short)(~0)) @@ -81,6 +82,7 @@ int a4l_rdproc_transfer(char *page, void a4l_presetup_transfer(a4l_cxt_t * cxt); int a4l_setup_transfer(a4l_cxt_t * cxt); +int a4l_precleanup_transfer(a4l_cxt_t * cxt); int a4l_cleanup_transfer(a4l_cxt_t * cxt); int a4l_reserve_transfer(a4l_cxt_t * cxt, int idx_subd); int a4l_init_transfer(a4l_cxt_t * cxt, a4l_cmd_t * cmd); diff --git a/ksrc/drivers/analogy/device.c b/ksrc/drivers/analogy/device.c index 1b7a012..cd586f7 100644 --- a/ksrc/drivers/analogy/device.c +++ b/ksrc/drivers/analogy/device.c @@ -432,18 +432,21 @@ int a4l_ioctl_devcfg(a4l_cxt_t * cxt, void *arg) if (arg == NULL) { /* Basic checking */ - if (!test_bit - (A4L_DEV_ATTACHED, (a4l_get_dev(cxt)-flags))) { + if (!test_bit(A4L_DEV_ATTACHED, (a4l_get_dev(cxt)-flags))) { __a4l_err(a4l_ioctl_devcfg: free device, no driver to detach\n); return -EINVAL; } - /* Removes the related proc file */ + /* Pre-cleanup of the transfer structure, we ensure + that nothing is busy */ + if ((ret = a4l_precleanup_transfer(cxt)) != 0) + return ret; + /* Remove the related proc file */ a4l_proc_detach(cxt); - /* Frees the transfer structure and its related data */ + /* Free the transfer structure and its related data */ if ((ret = a4l_cleanup_transfer(cxt)) != 0) return ret; - /* Frees the device and the driver from each other */ + /* Free the device and the driver from each other */ if ((ret = a4l_device_detach(cxt)) == 0) clear_bit(A4L_DEV_ATTACHED, (a4l_get_dev(cxt)-flags)); diff --git a/ksrc/drivers/analogy/transfer.c b/ksrc/drivers/analogy/transfer.c index b2c91bd..5239d08 100644 --- a/ksrc/drivers/analogy/transfer.c +++ b/ksrc/drivers/analogy/transfer.c @@ -33,39 +33,70 @@ /* --- Initialization / cleanup / cancel functions --- */ -int a4l_cleanup_transfer(a4l_cxt_t * cxt) +int a4l_precleanup_transfer(a4l_cxt_t * cxt) { a4l_dev_t *dev; a4l_trf_t *tsf; - int i; + int i, err = 0; __a4l_dbg(1, core_dbg, - a4l_cleanup_transfer: minor=%d\n, + a4l_precleanup_transfer: minor=%d\n, a4l_get_minor(cxt)); dev = a4l_get_dev(cxt); tsf = dev-transfer; if (tsf == NULL) { - __a4l_err(a4l_cleanup_transfer: + __a4l_err(a4l_precleanup_transfer: incoherent status, transfer block not reachable\n); return -ENODEV; } for (i = 0; i tsf-nb_subd; i++) { - if (test_bit(A4L_TSF_BUSY, (tsf-status[i]))) { - __a4l_err(a4l_cleanup_transfer: - device busy, acquisition occuring\n); - return -EBUSY; - } if (test_bit(A4L_TSF_MMAP, (tsf-status[i]))) { - __a4l_err(a4l_cleanup_transfer: + __a4l_err(a4l_precleanup_transfer: device busy, buffer must be unmapped\n); - return -EPERM; + err = -EPERM; + goto out_error; } + + if (test_and_set_bit(A4L_TSF_BUSY, (tsf-status[i]))) { + __a4l_err(a4l_precleanup_transfer: + device busy, acquisition occuring\n); + err = -EBUSY; + goto out_error; +
[Xenomai-git] Stefan Schaal : analogy: add a4l_config_subd() declaration in analogy.h
Module: xenomai-abe Branch: analogy Commit: 18f01559067cf9130524eced060255509c00c1c1 URL: http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=18f01559067cf9130524eced060255509c00c1c1 Author: Stefan Schaal ssch...@usc.edu Date: Tue Feb 9 00:41:55 2010 +0100 analogy: add a4l_config_subd() declaration in analogy.h --- include/analogy/analogy.h |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/include/analogy/analogy.h b/include/analogy/analogy.h index ca05d60..faff80f 100644 --- a/include/analogy/analogy.h +++ b/include/analogy/analogy.h @@ -130,6 +130,9 @@ int a4l_sync_read(a4l_desc_t * dsc, unsigned int chan_desc, unsigned int delay, void *buf, size_t nbyte); +int a4l_config_subd(a4l_desc_t * dsc, + unsigned int idx_subd, unsigned int type, ...); + int a4l_sync_dio(a4l_desc_t *dsc, unsigned int idx_subd, void *mask, void *buf); ___ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git
[Xenomai-git] Alexis Berlemont : analogy: in insn_write, no more real-time mode and automatic subd selection
Module: xenomai-abe Branch: analogy Commit: 796598357a152087c026df1c87159936f1312da7 URL: http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=796598357a152087c026df1c87159936f1312da7 Author: Alexis Berlemont alexis.berlem...@gmail.com Date: Tue Feb 9 00:40:18 2010 +0100 analogy: in insn_write, no more real-time mode and automatic subd selection --- src/utils/analogy/insn_write.c | 138 --- 1 files changed, 57 insertions(+), 81 deletions(-) diff --git a/src/utils/analogy/insn_write.c b/src/utils/analogy/insn_write.c index 9d61dc8..829b7d7 100644 --- a/src/utils/analogy/insn_write.c +++ b/src/utils/analogy/insn_write.c @@ -26,14 +26,8 @@ #include errno.h #include getopt.h -#include native/task.h - #include analogy/analogy.h -/* For write operation, we consider - the default subdevice index is 1 */ -#define ID_SUBD 1 - /* Ten triggered scans by default */ #define SCAN_CNT 10 @@ -45,16 +39,12 @@ static int value = 0; static double dvalue = 0; static char *filename = FILENAME; static int verbose; -static int real_time; -static int idx_subd = ID_SUBD; +static int idx_subd = -1; static int idx_chan; static int idx_rng = -1; -static RT_TASK rt_task_desc; - struct option insn_write_opts[] = { {verbose, no_argument, NULL, 'v'}, - {real-time, no_argument, NULL, 'r'}, {device, required_argument, NULL, 'd'}, {subdevice, required_argument, NULL, 's'}, {scan-count, required_argument, NULL, 'S'}, @@ -69,9 +59,8 @@ void do_print_usage(void) fprintf(stdout, usage:\tinsn_write [OPTS]\n); fprintf(stdout, \tOPTS:\t -v, --verbose: verbose output\n); fprintf(stdout, - \t\t -r, --real-time: enable real-time acquisition mode\n); - fprintf(stdout, - \t\t -d, --device: device filename (analogy0, analogy1, ...)\n); + \t\t -d, --device: + device filename (analogy0, analogy1, ...)\n); fprintf(stdout, \t\t -s, --subdevice: subdevice index\n); fprintf(stdout, \t\t -c, --channel: channel to use\n); fprintf(stdout, \t\t -R, --range: range to use\n); @@ -81,24 +70,22 @@ void do_print_usage(void) int main(int argc, char *argv[]) { - int ret = 0; + int i = 0, err = 0; a4l_desc_t dsc = { .sbdata = NULL }; + a4l_sbinfo_t *sbinfo; a4l_chinfo_t *chinfo; a4l_rnginfo_t *rnginfo; unsigned int scan_size; /* Compute arguments */ - while ((ret = getopt_long(argc, + while ((err = getopt_long(argc, argv, vrd:s:c:R:V:h, insn_write_opts, NULL)) = 0) { - switch (ret) { + switch (err) { case 'v': verbose = 1; break; - case 'r': - real_time = 1; - break; case 'd': filename = optarg; break; @@ -125,11 +112,11 @@ int main(int argc, char *argv[]) /* Restart the argument scanning */ optind = 1; - while ((ret = getopt_long(argc, + while ((err = getopt_long(argc, argv, vrd:s:c:R:V:h, insn_write_opts, NULL)) = 0) { - switch (ret) { + switch (err) { case 'V': if (idx_rng 0) value = (int)strtoul(optarg, NULL, 0); @@ -138,43 +125,18 @@ int main(int argc, char *argv[]) } } - if (real_time != 0) { - - if (verbose != 0) - printf(insn_write: switching to real-time mode\n); - - /* Prevent any memory-swapping for this program */ - ret = mlockall(MCL_CURRENT | MCL_FUTURE); - if (ret 0) { - ret = errno; - fprintf(stderr, insn_write: mlockall failed (ret=%d)\n, - ret); - goto out_insn_write; - } - - /* Turn the current process into an RT task */ - ret = rt_task_shadow(rt_task_desc, NULL, 1, 0); - if (ret 0) { - fprintf(stderr, - insn_write: rt_task_shadow failed (ret=%d)\n, - ret); - goto out_insn_write; - } - - } - /* Open the device */ - ret = a4l_open(dsc, filename); - if (ret 0) { + err = a4l_open(dsc, filename); + if (err 0) { fprintf(stderr, - insn_write: a4l_open %s failed (ret=%d)\n, - filename, ret); - return ret; +
[Xenomai-git] Alexis Berlemont : analogy: minor changes in comments
Module: xenomai-abe Branch: analogy Commit: c9fb5b9dac6883a90dfca42e4a4c71082a979f0b URL: http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=c9fb5b9dac6883a90dfca42e4a4c71082a979f0b Author: Alexis Berlemont alexis.berlem...@gmail.com Date: Tue Feb 9 00:41:23 2010 +0100 analogy: minor changes in comments --- ksrc/drivers/analogy/device.c | 22 +++--- 1 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ksrc/drivers/analogy/device.c b/ksrc/drivers/analogy/device.c index cd586f7..082053f 100644 --- a/ksrc/drivers/analogy/device.c +++ b/ksrc/drivers/analogy/device.c @@ -95,7 +95,7 @@ int a4l_rdproc_devs(char *page, p += sprintf(p, | %02d | %s | %s\n, i, status, name); } - /* Handles any proc-file reading way */ + /* Handle any proc-file reading way */ len = p - page - off; /* If the requested size is greater than we provide, the read operation is over */ @@ -122,18 +122,18 @@ int a4l_proc_attach(a4l_cxt_t * cxt) struct proc_dir_entry *entry; char *entry_name, *p; - /* Allocates the buffer for the file name */ + /* Allocate the buffer for the file name */ entry_name = rtdm_malloc(A4L_NAMELEN + 4); if ((p = entry_name) == NULL) { __a4l_err(a4l_proc_attach: failed to allocate buffer\n); return -ENOMEM; } - /* Creates the proc file name */ + /* Create the proc file name */ p += sprintf(p, %02d-, a4l_get_minor(cxt)); strncpy(p, dev-driver-board_name, A4L_NAMELEN); - /* Creates the proc entry */ + /* Create the proc entry */ entry = create_proc_entry(entry_name, 0444, a4l_proc_root); if (entry == NULL) { __a4l_err(a4l_proc_attach: @@ -150,7 +150,7 @@ int a4l_proc_attach(a4l_cxt_t * cxt) wrap_proc_dir_entry_owner(entry); out_setup_proc_transfer: - /* Frees the file name buffer */ + /* Free the file name buffer */ rtdm_free(entry_name); return ret; @@ -161,7 +161,7 @@ void a4l_proc_detach(a4l_cxt_t * cxt) char *entry_name, *p; a4l_dev_t *dev = a4l_get_dev(cxt); - /* Allocates the buffer for the file name */ + /* Allocate the buffer for the file name */ entry_name = rtdm_malloc(A4L_NAMELEN + 4); if ((p = entry_name) == NULL) { __a4l_err(a4l_proc_detach: @@ -169,14 +169,14 @@ void a4l_proc_detach(a4l_cxt_t * cxt) return; } - /* Builds the name */ + /* Build the name */ p += sprintf(p, %02d-, a4l_get_minor(cxt)); strncpy(p, dev-driver-board_name, A4L_NAMELEN); - /* Removes the proc file */ + /* Remove the proc file */ remove_proc_entry(entry_name, a4l_proc_root); - /* Frees the temporary buffer */ + /* Free the temporary buffer */ rtdm_free(entry_name); } @@ -460,10 +460,10 @@ int a4l_ioctl_devcfg(a4l_cxt_t * cxt, void *arg) } /* Pre-initialization of the transfer structure */ a4l_presetup_transfer(cxt); - /* Links the device with the driver */ + /* Link the device with the driver */ if ((ret = a4l_device_attach(cxt, arg)) != 0) return ret; - /* Creates the transfer structure and + /* Create the transfer structure and the related proc file */ if ((ret = a4l_setup_transfer(cxt)) != 0 || (ret = a4l_proc_attach(cxt)) != 0) ___ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git
[Xenomai-git] Alexis Berlemont : analogy: fix a potential missing initialization of the subd descriptor
Module: xenomai-abe Branch: analogy Commit: 6469e07b0a6069ccb91de0fa79b28e8f094ab1c6 URL: http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=6469e07b0a6069ccb91de0fa79b28e8f094ab1c6 Author: Alexis Berlemont alexis.berlem...@gmail.com Date: Thu Feb 11 01:02:08 2010 +0100 analogy: fix a potential missing initialization of the subd descriptor --- src/utils/analogy/insn_bits.c | 20 +++ src/utils/analogy/insn_read.c | 50 -- src/utils/analogy/insn_write.c | 52 --- 3 files changed, 73 insertions(+), 49 deletions(-) diff --git a/src/utils/analogy/insn_bits.c b/src/utils/analogy/insn_bits.c index d7a8e1b..9e672c4 100644 --- a/src/utils/analogy/insn_bits.c +++ b/src/utils/analogy/insn_bits.c @@ -152,6 +152,26 @@ int main(int argc, char *argv[]) if (verbose != 0) printf(insn_bits: selected subdevice index = %d\n, idx_subd); + /* We must check that the subdevice is really a digital one + (in case, the subdevice index was set with the option -s) */ + err = a4l_get_subdinfo(dsc, idx_subd, sbinfo); + if (err 0) { + fprintf(stderr, + insn_bits: get_sbinfo(%d) failed (err = %d)\n, + idx_subd, err); + err = -EINVAL; + goto out_insn_bits; + } + + if ((sbinfo-flags A4L_SUBD_TYPES) != A4L_SUBD_DIO + (sbinfo-flags A4L_SUBD_TYPES) != A4L_SUBD_DI + (sbinfo-flags A4L_SUBD_TYPES) != A4L_SUBD_DO) { + fprintf(stderr, + insn_bits: selected subdevice is not digital\n); + err = -EINVAL; + goto out_insn_bits; + } + /* Set the data size to read / write */ scan_size = a4l_sizeof_subd(sbinfo); diff --git a/src/utils/analogy/insn_read.c b/src/utils/analogy/insn_read.c index 47be76d..b3501ac 100644 --- a/src/utils/analogy/insn_read.c +++ b/src/utils/analogy/insn_read.c @@ -185,7 +185,7 @@ out: int main(int argc, char *argv[]) { - int i = 0, err = 0; + int err = 0; unsigned int cnt = 0; a4l_desc_t dsc = { .sbdata = NULL }; a4l_sbinfo_t *sbinfo; @@ -244,13 +244,6 @@ int main(int argc, char *argv[]) return err; } - /* Check there is an input subdevice */ - if (dsc.idx_read_subd 0) { - err = -ENOENT; - fprintf(stderr, insn_read: no input subdevice available\n); - goto out_insn_read; - } - if (verbose != 0) { printf(insn_read: device %s opened (fd=%d)\n, filename, dsc.fd); @@ -280,22 +273,9 @@ int main(int argc, char *argv[]) printf(insn_read: complex descriptor retrieved\n); /* If no subdevice index was set, look for an analog input - subdevice (the first found will be selected) */ - while (idx_subd == -1 i dsc.nb_subd) { - - err = a4l_get_subdinfo(dsc, i, sbinfo); - if (err 0) { - fprintf(stderr, - insn_read: get_sbinfo(%d) failed (err = %d)\n, - i, err); - goto out_insn_read; - } - - if ((sbinfo-flags A4L_SUBD_TYPES) == A4L_SUBD_AI) - idx_subd = i; - - i++; - } + subdevice */ + if (idx_subd == -1) + idx_subd = dsc.idx_read_subd; if (idx_subd == -1) { fprintf(stderr, @@ -304,6 +284,28 @@ int main(int argc, char *argv[]) goto out_insn_read; } + if (verbose != 0) + printf(insn_read: selected subdevice index = %d\n, idx_subd); + + /* We must check that the subdevice is really an AI one + (in case, the subdevice index was set with the option -s) */ + err = a4l_get_subdinfo(dsc, idx_subd, sbinfo); + if (err 0) { + fprintf(stderr, + insn_read: get_sbinfo(%d) failed (err = %d)\n, + idx_subd, err); + err = -EINVAL; + goto out_insn_read; + } + + if ((sbinfo-flags A4L_SUBD_TYPES) != A4L_SUBD_AI) { + fprintf(stderr, + insn_read: wrong subdevice selected + (not an analog input)\n); + err = -EINVAL; + goto out_insn_read; + } + if (idx_rng = 0) { err = a4l_get_rnginfo(dsc, diff --git a/src/utils/analogy/insn_write.c b/src/utils/analogy/insn_write.c index 829b7d7..4039b90 100644 --- a/src/utils/analogy/insn_write.c +++ b/src/utils/analogy/insn_write.c @@ -70,7 +70,7 @@ void do_print_usage(void) int main(int argc, char *argv[]) { - int i = 0, err = 0; +
[Xenomai-git] Alexis Berlemont : analogy: make a4l_config_subd support open drain configuration
Module: xenomai-abe Branch: analogy Commit: 4d8bc9f203b926fb316b9695660ca187e13881da URL: http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=4d8bc9f203b926fb316b9695660ca187e13881da Author: Alexis Berlemont alexis.berlem...@gmail.com Date: Sat Feb 20 17:34:14 2010 +0100 analogy: make a4l_config_subd support open drain configuration --- src/drvlib/analogy/sync.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/src/drvlib/analogy/sync.c b/src/drvlib/analogy/sync.c index 73f1dd6..4bcde62 100644 --- a/src/drvlib/analogy/sync.c +++ b/src/drvlib/analogy/sync.c @@ -315,7 +315,7 @@ int a4l_sync_dio(a4l_desc_t *dsc, return -EINVAL; } - /* Send the config instruction */ + /* Send the insn_bits instruction */ ret = a4l_snd_insn(dsc, insn); /* Update the buffer if need be */ @@ -375,6 +375,7 @@ int a4l_config_subd(a4l_desc_t * dsc, switch (type) { case A4L_INSN_CONFIG_DIO_OUTPUT: case A4L_INSN_CONFIG_DIO_INPUT: + case A4L_INSN_CONFIG_DIO_OPENDRAIN: { unsigned int idx_chan = va_arg(args, unsigned int); insn.chan_desc = CHAN(idx_chan); ___ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git
[Xenomai-git] Alexis Berlemont : analogy: fix a bug in cmd_read with real-time mode enabled
Module: xenomai-abe Branch: analogy Commit: 0584265f069be4447cdb853062b095b0c3889627 URL: http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=0584265f069be4447cdb853062b095b0c3889627 Author: Alexis Berlemont alexis.berlem...@gmail.com Date: Sun Mar 14 01:25:51 2010 +0100 analogy: fix a bug in cmd_read with real-time mode enabled The count of read bytes was overwritten by the results of the call to rt_task_set_mode(). --- src/utils/analogy/cmd_read.c | 15 +-- 1 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/utils/analogy/cmd_read.c b/src/utils/analogy/cmd_read.c index 1562a21..32d3db0 100644 --- a/src/utils/analogy/cmd_read.c +++ b/src/utils/analogy/cmd_read.c @@ -410,14 +410,16 @@ int main(int argc, char *argv[]) cnt += ret; if (real_time != 0) { - ret = rt_task_set_mode(0, T_PRIMARY, NULL); - if (ret 0) { + int err = rt_task_set_mode(0, T_PRIMARY, NULL); + if (err 0) { fprintf(stderr, cmd_read: rt_task_set_mode failed (ret=%d)\n, - ret); + err); + ret = err; goto out_main; } } + } while (ret 0); } else { @@ -465,11 +467,12 @@ int main(int argc, char *argv[]) } if (real_time != 0) { - ret = rt_task_set_mode(0, T_PRIMARY, NULL); - if (ret 0) { + int err = rt_task_set_mode(0, T_PRIMARY, NULL); + if (err 0) { fprintf(stderr, cmd_read: rt_task_set_mode failed (ret=%d)\n, - ret); + err); + ret = err; goto out_main; } } ___ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git
[Xenomai-git] Alexis Berlemont : analogy: make __pre_abs_get more robust at ends of acquisitions
Module: xenomai-abe Branch: analogy Commit: fe740c3a21a886e58b52f51c9874a1b1a445aa99 URL: http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=fe740c3a21a886e58b52f51c9874a1b1a445aa99 Author: Alexis Berlemont alexis.berlem...@gmail.com Date: Mon Mar 1 01:09:44 2010 +0100 analogy: make __pre_abs_get more robust at ends of acquisitions --- include/analogy/buffer.h | 28 ++-- 1 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/analogy/buffer.h b/include/analogy/buffer.h index 7b210b8..0e8f279 100644 --- a/include/analogy/buffer.h +++ b/include/analogy/buffer.h @@ -201,12 +201,36 @@ static inline int __pre_put(a4l_buf_t * buf, unsigned long count) static inline int __pre_abs_get(a4l_buf_t * buf, unsigned long count) { - if (!(buf-tmp_count == 0 buf-cns_count == 0) - (long)(count - buf-tmp_count) 0) { + + /* The first time, we expect the buffer to be properly filled + before the trigger occurence; by the way, we need tmp_count to + have been initialized and tmp_count is updated right here */ + if (buf-tmp_count == 0 || buf-cns_count == 0) + goto out; + + /* At the end of the acquisition, the user application has + written the defined amount of data into the buffer; so the + last time, the DMA channel can easily overtake the tmp + frontier because no more data were sent from user space; + therefore no useless alarm should be sent */ + if ((long)(count - buf-end_count) 0) + goto out; + + /* Once the exception are passed, we check that the DMA + transfer has not overtaken the last record of the production + count (tmp_count was updated with prd_count the last time + __pre_abs_get was called). We must understand that we cannot + compare the current DMA count with the current production + count because even if, right now, the production count is + higher than the DMA count, it does not mean that the DMA count + was not greater a few cycles before; in such case, the DMA + channel would have retrieved the wrong data */ + if ((long)(count - buf-tmp_count) 0) { set_bit(A4L_BUF_ERROR_NR, buf-evt_flags); return -EPIPE; } +out: buf-tmp_count = buf-prd_count; return 0; ___ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git
[Xenomai-git] Alexis Berlemont : analogy: [pcimio] fix many race conditions in DMA output transfers
Module: xenomai-abe Branch: analogy Commit: 07bae25974ad76d29a427b195c6b7de1c0d30c63 URL: http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=07bae25974ad76d29a427b195c6b7de1c0d30c63 Author: Alexis Berlemont alexis.berlem...@gmail.com Date: Mon Mar 1 01:08:28 2010 +0100 analogy: [pcimio] fix many race conditions in DMA output transfers WARNING: Some parts of the driver mio_common cannot be tolerated in a real-time system. For example, the function ni_ao_wait_for_dma_load must be reviewed; it contains two busy waiting loops which can last up to 1 micro-seconds. --- .../analogy/national_instruments/mio_common.c | 98 +++ ksrc/drivers/analogy/national_instruments/mite.c | 17 +++- 2 files changed, 72 insertions(+), 43 deletions(-) diff --git a/ksrc/drivers/analogy/national_instruments/mio_common.c b/ksrc/drivers/analogy/national_instruments/mio_common.c index db9762a..1a39206 100644 --- a/ksrc/drivers/analogy/national_instruments/mio_common.c +++ b/ksrc/drivers/analogy/national_instruments/mio_common.c @@ -506,17 +506,28 @@ void mite_handle_b_linkc(a4l_subd_t *subd) a4l_unlock_irqrestore(devpriv-mite_channel_lock, flags); } -static int ni_ao_wait_for_dma_load(a4l_dev_t *dev) +static int ni_ao_wait_for_dma_load(a4l_subd_t *subd) { static const int timeout = 1; + + a4l_dev_t *dev = subd-dev; + a4l_buf_t *buf = dev-transfer.bufs[subd-idx]; + int i; for (i = 0; i timeout; i++) { + + int buffer_filled; unsigned short b_status; b_status = devpriv-stc_readw(dev, AO_Status_1_Register); - if (b_status AO_FIFO_Half_Full_St) + + buffer_filled = test_bit(A4L_BUF_EOA_NR, buf-evt_flags); + buffer_filled |= (b_status AO_FIFO_Half_Full_St); + + if (buffer_filled) break; + /* If we poll too often, the pci bus activity seems to slow the dma transfer down */ a4l_udelay(10); @@ -569,7 +580,7 @@ static inline int ni_request_cdo_mite_channel(a4l_dev_t *dev) #define ni_sync_ai_dma(x) do { } while (0) #define mite_handle_b_linkc(x) do { } while (0) -static inline int ni_ao_wait_for_dma_load(a4l_dev_t *dev) +static inline int ni_ao_wait_for_dma_load(a4l_subd_t *subd) { return -ENOTSUPP; } @@ -714,14 +725,12 @@ static void ni_handle_eos(a4l_subd_t *subd) } static void ni_event(a4l_subd_t * subd) -{ - +{ /* Temporary hack */ a4l_dev_t *dev = subd-dev; a4l_buf_t *buf = dev-transfer.bufs[subd-idx]; - if(test_bit(A4L_BUF_ERROR, buf-evt_flags)) { - + if(test_bit(A4L_BUF_ERROR_NR, buf-evt_flags)) { if (subd-cancel != NULL) subd-cancel(subd); } @@ -939,28 +948,15 @@ static void handle_b_interrupt(a4l_dev_t * dev, a4l_subd_t *subd = a4l_get_subd(dev, NI_AO_SUBDEV); - a4l_info(dev, ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n, -b_status, ao_mite_status); - ni_mio_print_status_b(b_status); - -#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \ - defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE)) - /* Currently, mite.c requires us to handle LINKC */ - if (ao_mite_status CHSR_LINKC) { - mite_handle_b_linkc(subd); - } + a4l_dbg(1, drv_dbg, dev, + ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n, + b_status, ao_mite_status); - if (ao_mite_status ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY | - CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR | - CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) { - a4l_info(dev, unknown mite interrupt, ack! (ao_mite_status=%08x)\n, -ao_mite_status); - a4l_buf_evt(subd, A4L_BUF_ERROR); - } -#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */ + ni_mio_print_status_b(b_status); if (b_status == 0x) return; + if (b_status AO_Overrun_St) { a4l_err(dev, ni_mio_common: interrupt: @@ -971,15 +967,38 @@ static void handle_b_interrupt(a4l_dev_t * dev, } if (b_status AO_BC_TC_St) { - a4l_info(dev, -ni_mio_common: interrupt: -AO BC_TC status=0x%04x status2=0x%04x\n, -b_status, devpriv-stc_readw(dev, AO_Status_2_Register)); + a4l_dbg(1, drv_dbg, dev, + ni_mio_common: interrupt: + AO BC_TC status=0x%04x status2=0x%04x\n, + b_status, devpriv-stc_readw(dev, AO_Status_2_Register)); a4l_buf_evt(subd, A4L_BUF_EOA); } +#if
[Xenomai-git] Alexis Berlemont : analogy: remove rt_task_set_mode from test programs
Module: xenomai-abe Branch: analogy Commit: 4be0333bef1a7dd41ef79b4d31209642b05e5593 URL: http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=4be0333bef1a7dd41ef79b4d31209642b05e5593 Author: Alexis Berlemont alexis.berlem...@gmail.com Date: Tue Mar 16 01:11:55 2010 +0100 analogy: remove rt_task_set_mode from test programs --- src/utils/analogy/cmd_read.c | 33 - src/utils/analogy/cmd_write.c | 11 --- 2 files changed, 0 insertions(+), 44 deletions(-) diff --git a/src/utils/analogy/cmd_read.c b/src/utils/analogy/cmd_read.c index 32d3db0..1345f5b 100644 --- a/src/utils/analogy/cmd_read.c +++ b/src/utils/analogy/cmd_read.c @@ -375,17 +375,6 @@ int main(int argc, char *argv[]) if (verbose != 0) printf(cmd_read: command successfully sent\n); - if (real_time != 0) { - - ret = rt_task_set_mode(0, T_PRIMARY, NULL); - if (ret 0) { - fprintf(stderr, - cmd_read: rt_task_set_mode failed (ret=%d)\n, - ret); - goto out_main; - } - } - if (use_mmap == 0) { /* Fetch data */ @@ -409,17 +398,6 @@ int main(int argc, char *argv[]) /* Update the counter */ cnt += ret; - if (real_time != 0) { - int err = rt_task_set_mode(0, T_PRIMARY, NULL); - if (err 0) { - fprintf(stderr, - cmd_read: rt_task_set_mode failed (ret=%d)\n, - err); - ret = err; - goto out_main; - } - } - } while (ret 0); } else { @@ -466,17 +444,6 @@ int main(int argc, char *argv[]) goto out_main; } - if (real_time != 0) { - int err = rt_task_set_mode(0, T_PRIMARY, NULL); - if (err 0) { - fprintf(stderr, - cmd_read: rt_task_set_mode failed (ret=%d)\n, - err); - ret = err; - goto out_main; - } - } - /* Update the counter */ cnt += front; diff --git a/src/utils/analogy/cmd_write.c b/src/utils/analogy/cmd_write.c index 2e152ed..c76fa81 100644 --- a/src/utils/analogy/cmd_write.c +++ b/src/utils/analogy/cmd_write.c @@ -300,17 +300,6 @@ int main(int argc, char *argv[]) for (i = 0; i BUF_SIZE; i++) buf[i] = i; - if (real_time != 0) { - - ret = rt_task_set_mode(0, T_PRIMARY, NULL); - if (ret 0) { - fprintf(stderr, - cmd_read: rt_task_set_mode failed (ret=%d)\n, - ret); - goto out_main; - } - } - if (use_mmap == 0) { /* Send data */ ___ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git
[Xenomai-git] Alexis Berlemont : analogy: in cmd_{read, write}, replace a4l_sys_* by a4l_async_*
Module: xenomai-abe Branch: analogy Commit: e5d83a81b5ff7e77e67c229e66c6057126702c01 URL: http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=e5d83a81b5ff7e77e67c229e66c6057126702c01 Author: Alexis Berlemont alexis.berlem...@gmail.com Date: Thu Mar 18 23:36:48 2010 +0100 analogy: in cmd_{read, write}, replace a4l_sys_* by a4l_async_* The function a4l_sys_read and a4l_sys_write are not the default functions to use in common applications; a4l_async_read and a4l_async_write were provided on that purpose. --- src/utils/analogy/cmd_read.c |3 +-- src/utils/analogy/cmd_write.c |2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/utils/analogy/cmd_read.c b/src/utils/analogy/cmd_read.c index 1345f5b..ee65dc9 100644 --- a/src/utils/analogy/cmd_read.c +++ b/src/utils/analogy/cmd_read.c @@ -379,9 +379,8 @@ int main(int argc, char *argv[]) /* Fetch data */ do { - /* Perform the read operation */ - ret = a4l_sys_read(dsc.fd, buf, BUF_SIZE); + ret = a4l_async_read(dsc, buf, BUF_SIZE, A4L_INFINITE); if (ret 0) { fprintf(stderr, cmd_read: a4l_read failed (ret=%d)\n, diff --git a/src/utils/analogy/cmd_write.c b/src/utils/analogy/cmd_write.c index c76fa81..5ce9218 100644 --- a/src/utils/analogy/cmd_write.c +++ b/src/utils/analogy/cmd_write.c @@ -308,7 +308,7 @@ int main(int argc, char *argv[]) (scan_size * cmd.stop_arg - cnt) BUF_SIZE ? BUF_SIZE : (scan_size * cmd.stop_arg - cnt); - ret = a4l_sys_write(dsc.fd, buf, tmp); + ret = a4l_async_write(dsc, buf, tmp, A4L_INFINITE); if (ret 0) { fprintf(stderr, cmd_write: a4l_write failed (ret=%d)\n, ___ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git
[Xenomai-git] Alexis Berlemont : analogy: declare a4l_async_read and a4l_async_write in analogy.h
Module: xenomai-abe Branch: analogy Commit: dda990d9e6ed9299039614c6799c91a43c158243 URL: http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=dda990d9e6ed9299039614c6799c91a43c158243 Author: Alexis Berlemont alexis.berlem...@gmail.com Date: Thu Mar 18 23:37:50 2010 +0100 analogy: declare a4l_async_read and a4l_async_write in analogy.h --- include/analogy/analogy.h |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/include/analogy/analogy.h b/include/analogy/analogy.h index faff80f..c40f2e7 100644 --- a/include/analogy/analogy.h +++ b/include/analogy/analogy.h @@ -114,6 +114,12 @@ int a4l_poll(a4l_desc_t * dsc, int a4l_mmap(a4l_desc_t * dsc, unsigned int idx_subd, unsigned long size, void **ptr); +int a4l_async_read(a4l_desc_t * dsc, + void *buf, size_t nbyte, unsigned long ms_timeout); + +int a4l_async_write(a4l_desc_t * dsc, + void *buf, size_t nbyte, unsigned long ms_timeout); + int a4l_snd_insnlist(a4l_desc_t * dsc, a4l_insnlst_t * arg); int a4l_snd_insn(a4l_desc_t * dsc, a4l_insn_t *arg); ___ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git
[Xenomai-git] Daniele Nicolodi : analogy: [pcimio] enable subdevice buffer mmapping
Module: xenomai-abe Branch: analogy Commit: efe65c75f8d38ac02459fab902150dde9ba39521 URL: http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=efe65c75f8d38ac02459fab902150dde9ba39521 Author: Daniele Nicolodi nicol...@science.unitn.it Date: Fri Mar 19 00:11:31 2010 +0100 analogy: [pcimio] enable subdevice buffer mmapping --- .../analogy/national_instruments/mio_common.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ksrc/drivers/analogy/national_instruments/mio_common.c b/ksrc/drivers/analogy/national_instruments/mio_common.c index 1a39206..a51a3cd 100644 --- a/ksrc/drivers/analogy/national_instruments/mio_common.c +++ b/ksrc/drivers/analogy/national_instruments/mio_common.c @@ -4913,7 +4913,7 @@ int ni_E_init(a4l_dev_t *dev) a4l_dbg(1, drv_dbg, dev, mio_common: AI: %d channels\n, boardtype.n_adchan); - subd-flags = A4L_SUBD_AI | A4L_SUBD_CMD; + subd-flags = A4L_SUBD_AI | A4L_SUBD_CMD | A4L_SUBD_MMAP; subd-rng_desc = ni_range_lkup[boardtype.gainlkup]; subd-chan_desc = kmalloc(sizeof(a4l_chdesc_t) + @@ -4981,7 +4981,7 @@ int ni_E_init(a4l_dev_t *dev) if (boardtype.ao_fifo_depth) { - subd-flags |= A4L_SUBD_CMD; + subd-flags |= A4L_SUBD_CMD | A4L_SUBD_MMAP; subd-do_cmd = ni_ao_cmd; subd-cmd_mask = mio_ao_cmd_mask; subd-do_cmdtest = ni_ao_cmdtest; ___ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git
[Xenomai-git] Daniele Nicolodi : analogy: fix a bug in a4l_ioctl_bufinfo when idle
Module: xenomai-abe Branch: analogy Commit: 2b1efb3818166b57bfa87286309243a1aa20914c URL: http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=2b1efb3818166b57bfa87286309243a1aa20914c Author: Daniele Nicolodi nicol...@science.unitn.it Date: Fri Mar 19 00:17:23 2010 +0100 analogy: fix a bug in a4l_ioctl_bufinfo when idle --- ksrc/drivers/analogy/buffer.c | 10 ++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/ksrc/drivers/analogy/buffer.c b/ksrc/drivers/analogy/buffer.c index aa6acac..bbd79ec 100644 --- a/ksrc/drivers/analogy/buffer.c +++ b/ksrc/drivers/analogy/buffer.c @@ -557,6 +557,14 @@ int a4l_ioctl_bufinfo(a4l_cxt_t * cxt, void *arg) buf = dev-transfer.bufs[info.idx_subd]; + /* If a transfer is not occuring, simply return buffer + informations, otherwise make the transfer progress */ + if (!test_bit(A4L_TSF_BUSY, + (dev-transfer.status[info.idx_subd]))) { + info.rw_count = 0; + goto a4l_ioctl_bufinfo_out; + } + ret = __handle_event(buf); if (info.idx_subd == dev-transfer.idx_read_subd) { @@ -618,6 +626,8 @@ int a4l_ioctl_bufinfo(a4l_cxt_t * cxt, void *arg) buf-mng_count += tmp_cnt; } +a4l_ioctl_bufinfo_out: + /* Sets the buffer size */ info.buf_size = buf-size; ___ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git
[Xenomai-git] Alexis Berlemont : analogy: at close time, cancel any busy subdevice
Module: xenomai-abe Branch: analogy Commit: c8f0dc05f19e15ea22852b1a2df28ccab3cc9c5c URL: http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=c8f0dc05f19e15ea22852b1a2df28ccab3cc9c5c Author: Alexis Berlemont alexis.berlem...@gmail.com Date: Fri Mar 19 01:03:09 2010 +0100 analogy: at close time, cancel any busy subdevice --- include/analogy/transfer.h|1 + ksrc/drivers/analogy/rtdm_interface.c |5 +++-- ksrc/drivers/analogy/transfer.c | 16 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/include/analogy/transfer.h b/include/analogy/transfer.h index 3d44ac6..e6bdc3c 100644 --- a/include/analogy/transfer.h +++ b/include/analogy/transfer.h @@ -87,6 +87,7 @@ int a4l_cleanup_transfer(a4l_cxt_t * cxt); int a4l_reserve_transfer(a4l_cxt_t * cxt, int idx_subd); int a4l_init_transfer(a4l_cxt_t * cxt, a4l_cmd_t * cmd); int a4l_cancel_transfer(a4l_cxt_t * cxt, int idx_subd); +int a4l_cancel_transfers(a4l_cxt_t * cxt); ssize_t a4l_put(a4l_cxt_t * cxt, void *buf, size_t nbytes); ssize_t a4l_get(a4l_cxt_t * cxt, void *buf, size_t nbytes); diff --git a/ksrc/drivers/analogy/rtdm_interface.c b/ksrc/drivers/analogy/rtdm_interface.c index 86d3f9d..f769e4a 100644 --- a/ksrc/drivers/analogy/rtdm_interface.c +++ b/ksrc/drivers/analogy/rtdm_interface.c @@ -33,6 +33,7 @@ #include analogy/context.h #include analogy/ioctl.h #include analogy/device.h +#include analogy/transfer.h int (*a4l_ioctl_functions[NB_IOCTL_FUNCTIONS]) (a4l_cxt_t *, void *) = { a4l_ioctl_devcfg, @@ -141,9 +142,9 @@ int a4l_rt_close(struct rtdm_dev_context *context, a4l_init_cxt(context, user_info, cxt); a4l_set_dev(cxt); __a4l_dbg(1, core_dbg, - a4l_rt_close: minor=%d\n, a4l_get_minor(cxt)); + a4l_rt_close: minor=%d\n, a4l_get_minor(cxt)); - return 0; + return a4l_cancel_transfers(cxt);; } ssize_t a4l_rt_read(struct rtdm_dev_context * context, diff --git a/ksrc/drivers/analogy/transfer.c b/ksrc/drivers/analogy/transfer.c index 5239d08..f25f912 100644 --- a/ksrc/drivers/analogy/transfer.c +++ b/ksrc/drivers/analogy/transfer.c @@ -337,6 +337,22 @@ int a4l_cancel_transfer(a4l_cxt_t * cxt, int idx_subd) return ret; } +int a4l_cancel_transfers(a4l_cxt_t * cxt) +{ + a4l_dev_t *dev = a4l_get_dev(cxt); + int i, ret = 0; + + /* The caller of a4l_cancel_transfers is bound not to have + checked whether the subdevice was attached; so we do it here */ + if (!test_bit(A4L_DEV_ATTACHED, dev-flags)) + return 0; + + for (i = 0; i dev-transfer.nb_subd ret == 0; i++) + ret = a4l_cancel_transfer(cxt, i); + + return ret; +} + /* --- IRQ handling section --- */ int a4l_request_irq(a4l_dev_t * dev, ___ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git