[PATCH 34/53] staging: comedi: usbdux: tidy up usbdux_ai_cmd()
Ian Abbott
abbotti at mev.co.uk
Thu Jul 25 15:04:21 UTC 2013
On 2013-07-24 22:19, H Hartley Sweeten wrote:
> Rename the local variable used for the private data pointer to the
> comedi "norm".
>
> Remove the unnecessary sanity check of the private data pointer. This
> function can only be called is the private data was allocated during
> the attach.
>
> Tidy up the exit path using goto to ensure that the semaphore is
> released.
>
> Set the ai_cmd_running flag after submitting the urbs to remove the
> need to clear the flag if the submit fails.
As for ai_inttrig, this could cause the URb completion routine to
execute before the ai_cmd_running flag has been set.
>
> Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>
> Cc: Ian Abbott <abbotti at mev.co.uk>
> Cc: Greg Kroah-Hartman <gregkh at linuxfondation.org>
> ---
> drivers/staging/comedi/drivers/usbdux.c | 92 ++++++++++++++++-----------------
> 1 file changed, 44 insertions(+), 48 deletions(-)
>
> diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
> index 204867b..1982e23 100644
> --- a/drivers/staging/comedi/drivers/usbdux.c
> +++ b/drivers/staging/comedi/drivers/usbdux.c
> @@ -881,86 +881,79 @@ ai_trig_exit:
>
> static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
> {
> + struct usbdux_private *devpriv = dev->private;
> struct comedi_cmd *cmd = &s->async->cmd;
> - unsigned int chan, range;
> - int i, ret;
> - struct usbdux_private *this_usbduxsub = dev->private;
> - int result;
> -
> - if (!this_usbduxsub)
> - return -EFAULT;
> + int len = cmd->chanlist_len;
> + int ret = -EBUSY;
> + int i;
>
> /* block other CPUs from starting an ai_cmd */
> - down(&this_usbduxsub->sem);
> - if (this_usbduxsub->ai_cmd_running) {
> - up(&this_usbduxsub->sem);
> - return -EBUSY;
> - }
> + down(&devpriv->sem);
> +
> + if (devpriv->ai_cmd_running)
> + goto ai_cmd_exit;
> +
> /* set current channel of the running acquisition to zero */
> s->async->cur_chan = 0;
>
> - this_usbduxsub->dux_commands[1] = cmd->chanlist_len;
> - for (i = 0; i < cmd->chanlist_len; ++i) {
> - chan = CR_CHAN(cmd->chanlist[i]);
> - range = CR_RANGE(cmd->chanlist[i]);
> + devpriv->dux_commands[1] = len;
> + for (i = 0; i < len; ++i) {
> + unsigned int chan = CR_CHAN(cmd->chanlist[i]);
> + unsigned int range = CR_RANGE(cmd->chanlist[i]);
> +
> if (i >= NUMCHANNELS)
> break;
> - this_usbduxsub->dux_commands[i + 2] =
> - create_adc_command(chan, range);
> - }
>
> - result = send_dux_commands(dev, SENDADCOMMANDS);
> - if (result < 0) {
> - up(&this_usbduxsub->sem);
> - return result;
> + devpriv->dux_commands[i + 2] = create_adc_command(chan, range);
> }
>
> - if (this_usbduxsub->high_speed) {
> + ret = send_dux_commands(dev, SENDADCOMMANDS);
> + if (ret < 0)
> + goto ai_cmd_exit;
> +
> + if (devpriv->high_speed) {
> /*
> * every channel gets a time window of 125us. Thus, if we
> * sample all 8 channels we need 1ms. If we sample only one
> * channel we need only 125us
> */
> - this_usbduxsub->ai_interval = 1;
> + devpriv->ai_interval = 1;
> /* find a power of 2 for the interval */
> - while ((this_usbduxsub->ai_interval) < (cmd->chanlist_len)) {
> - this_usbduxsub->ai_interval =
> - (this_usbduxsub->ai_interval) * 2;
> - }
> - this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 *
> - (this_usbduxsub->
> - ai_interval));
> + while (devpriv->ai_interval < len)
> + devpriv->ai_interval *= 2;
> +
> + devpriv->ai_timer = cmd->scan_begin_arg /
> + (125000 * devpriv->ai_interval);
> } else {
> /* interval always 1ms */
> - this_usbduxsub->ai_interval = 1;
> - this_usbduxsub->ai_timer = cmd->scan_begin_arg / 1000000;
> + devpriv->ai_interval = 1;
> + devpriv->ai_timer = cmd->scan_begin_arg / 1000000;
> }
> - if (this_usbduxsub->ai_timer < 1) {
> - up(&this_usbduxsub->sem);
> - return -EINVAL;
> + if (devpriv->ai_timer < 1) {
> + ret = -EINVAL;
> + goto ai_cmd_exit;
> }
> - this_usbduxsub->ai_counter = this_usbduxsub->ai_timer;
> +
> + devpriv->ai_counter = devpriv->ai_timer;
>
> if (cmd->stop_src == TRIG_COUNT) {
> /* data arrives as one packet */
> - this_usbduxsub->ai_sample_count = cmd->stop_arg;
> - this_usbduxsub->ai_continous = 0;
> + devpriv->ai_sample_count = cmd->stop_arg;
> + devpriv->ai_continous = 0;
> } else {
> /* continous acquisition */
> - this_usbduxsub->ai_continous = 1;
> - this_usbduxsub->ai_sample_count = 0;
> + devpriv->ai_continous = 1;
> + devpriv->ai_sample_count = 0;
> }
>
> if (cmd->start_src == TRIG_NOW) {
> /* enable this acquisition operation */
> - this_usbduxsub->ai_cmd_running = 1;
> ret = usbduxsub_submit_inurbs(dev);
> if (ret < 0) {
> - this_usbduxsub->ai_cmd_running = 0;
> /* fixme: unlink here?? */
> - up(&this_usbduxsub->sem);
> - return ret;
> + goto ai_cmd_exit;
> }
> + devpriv->ai_cmd_running = 1;
> s->async->inttrig = NULL;
> } else {
> /* TRIG_INT */
> @@ -968,8 +961,11 @@ static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
> /* wait for an internal signal */
> s->async->inttrig = usbdux_ai_inttrig;
> }
> - up(&this_usbduxsub->sem);
> - return 0;
> +
> +ai_cmd_exit:
> + up(&devpriv->sem);
> +
> + return ret;
> }
>
> /* Mode 0 is used to get a single conversion on demand */
>
--
-=( Ian Abbott @ MEV Ltd. E-mail: <abbotti at mev.co.uk> )=-
-=( Tel: +44 (0)161 477 1898 FAX: +44 (0)161 718 3587 )=-
More information about the devel
mailing list