Module: xenomai-3 Branch: master Commit: 1c00aab42aec168634b0380cfc1735296e164db0 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=1c00aab42aec168634b0380cfc1735296e164db0
Author: Jorge Ramirez-Ortiz <j...@xenomai.org> Date: Tue Aug 26 13:50:41 2014 -0400 drivers/analogy: modify the cmd test behaviour --- kernel/drivers/analogy/command.c | 66 +++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/kernel/drivers/analogy/command.c b/kernel/drivers/analogy/command.c index 213591d..7420bc5 100644 --- a/kernel/drivers/analogy/command.c +++ b/kernel/drivers/analogy/command.c @@ -26,16 +26,18 @@ #include <rtdm/analogy/device.h> /* --- Command descriptor management functions --- */ -int a4l_fill_cmddesc(struct a4l_device_context * cxt, struct a4l_cmd_desc * desc, void *arg) +int a4l_fill_cmddesc(struct a4l_device_context *cxt, struct a4l_cmd_desc *desc, + unsigned int **chan_descs, void *arg) { - int ret = 0; unsigned int *tmpchans = NULL; + int ret = 0; ret = rtdm_safe_copy_from_user(rtdm_private_to_fd(cxt), desc, arg, sizeof(struct a4l_cmd_desc)); if (ret != 0) goto out_cmddesc; + if (desc->nb_chan == 0) { ret = -EINVAL; goto out_cmddesc; @@ -50,13 +52,16 @@ int a4l_fill_cmddesc(struct a4l_device_context * cxt, struct a4l_cmd_desc * desc ret = rtdm_safe_copy_from_user(rtdm_private_to_fd(cxt), tmpchans, desc->chan_descs, - desc->nb_chan * sizeof(unsigned long)); - if (ret != 0) + desc->nb_chan * sizeof(unsigned int)); + if (ret != 0) { + __a4l_err("%s invalid arguments \n", __FUNCTION__); goto out_cmddesc; + } + *chan_descs = desc->chan_descs; desc->chan_descs = tmpchans; - __a4l_dbg(1, core_dbg, "desc dump\n"); + __a4l_dbg(1, core_dbg, "desc dump: \n"); __a4l_dbg(1, core_dbg, "\t->idx_subd=%u\n", desc->idx_subd); __a4l_dbg(1, core_dbg, "\t->flags=%lu\n", desc->flags); __a4l_dbg(1, core_dbg, "\t->nb_chan=%u\n", desc->nb_chan); @@ -64,9 +69,10 @@ int a4l_fill_cmddesc(struct a4l_device_context * cxt, struct a4l_cmd_desc * desc __a4l_dbg(1, core_dbg, "\t->data_len=%u\n", desc->data_len); __a4l_dbg(1, core_dbg, "\t->pdata=0x%p\n", desc->data); - out_cmddesc: + out_cmddesc: if (ret != 0) { + __a4l_err("a4l_fill_cmddesc: %d \n", ret); if (tmpchans != NULL) rtdm_free(tmpchans); desc->chan_descs = NULL; @@ -113,7 +119,7 @@ int a4l_check_cmddesc(struct a4l_device_context * cxt, struct a4l_cmd_desc * des } return a4l_check_chanlist(dev->transfer.subds[desc->idx_subd], - desc->nb_chan, desc->chan_descs); + desc->nb_chan, desc->chan_descs); } /* --- Command checking functions --- */ @@ -124,7 +130,7 @@ int a4l_check_generic_cmdcnt(struct a4l_cmd_desc * desc) /* Makes sure trigger sources are trivially valid */ tmp1 = - desc->start_src & ~(TRIG_NOW | TRIG_INT | TRIG_EXT | TRIG_FOLLOW); + desc->start_src & ~(TRIG_NOW | TRIG_INT | TRIG_EXT | TRIG_FOLLOW); tmp2 = desc->start_src & (TRIG_NOW | TRIG_INT | TRIG_EXT | TRIG_FOLLOW); if (tmp1 != 0 || tmp2 == 0) { __a4l_err("a4l_check_cmddesc: start_src, weird trigger\n"); @@ -288,6 +294,7 @@ int a4l_ioctl_cmd(struct a4l_device_context * ctx, void *arg) int ret = 0, simul_flag = 0; struct a4l_cmd_desc *cmd_desc = NULL; struct a4l_device *dev = a4l_get_dev(ctx); + unsigned int *chan_descs, *tmp; struct a4l_subdevice *subd; /* The command launching cannot be done in real-time because @@ -309,7 +316,7 @@ int a4l_ioctl_cmd(struct a4l_device_context * ctx, void *arg) memset(cmd_desc, 0, sizeof(struct a4l_cmd_desc)); /* Gets the command */ - ret = a4l_fill_cmddesc(ctx, cmd_desc, arg); + ret = a4l_fill_cmddesc(ctx, cmd_desc, &chan_descs, arg); if (ret != 0) goto out_ioctl_cmd; @@ -327,24 +334,28 @@ int a4l_ioctl_cmd(struct a4l_device_context * ctx, void *arg) goto out_ioctl_cmd; __a4l_dbg(1, core_dbg,"1st cmd checks passed\n"); - subd = dev->transfer.subds[cmd_desc->idx_subd]; /* Tests the command with the cmdtest function */ - if (subd->do_cmdtest != NULL) - ret = subd->do_cmdtest(subd, cmd_desc); - if (ret != 0) { - __a4l_err("a4l_ioctl_cmd: driver's cmd_test failed\n"); - goto out_ioctl_cmd; - } - - __a4l_dbg(1, core_dbg, "driver's cmd checks passed\n"); - if (cmd_desc->flags & A4L_CMD_SIMUL) { simul_flag = 1; + + if (!subd->do_cmdtest) { + __a4l_err("a4l_ioctl_cmd: driver's cmd_test NULL\n"); + ret = -EINVAL; + goto out_ioctl_cmd; + } + + ret = subd->do_cmdtest(subd, cmd_desc); + if (ret != 0) { + __a4l_err("a4l_ioctl_cmd: driver's cmd_test failed\n"); + goto out_ioctl_cmd; + } + __a4l_dbg(1, core_dbg, "driver's cmd checks passed\n"); goto out_ioctl_cmd; } + /* Gets the transfer system ready */ ret = a4l_setup_buffer(ctx, cmd_desc); if (ret < 0) @@ -358,10 +369,21 @@ int a4l_ioctl_cmd(struct a4l_device_context * ctx, void *arg) goto out_ioctl_cmd; } -out_ioctl_cmd: - if (ret != 0 || simul_flag == 1) { + out_ioctl_cmd: + + if (simul_flag) { + /* copy the kernel based descriptor */ + tmp = cmd_desc->chan_descs; + /* return the user based descriptor */ + cmd_desc->chan_descs = chan_descs; rtdm_safe_copy_to_user(rtdm_private_to_fd(ctx), arg, cmd_desc, - sizeof(struct a4l_cmd_desc)); + sizeof(struct a4l_cmd_desc)); + /* make sure we release the memory associated to the kernel */ + cmd_desc->chan_descs = tmp; + + } + + if (ret != 0 || simul_flag == 1) { a4l_free_cmddesc(cmd_desc); rtdm_free(cmd_desc); } _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git