Commit 9c922a90 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman
Browse files

staging: comedi: usbduxsigma: set *_cmd_running flags before submitting urbs



As pointed out by Ian Abbott, the *_cmd_running flags should be set
before submitting the urbs. There is a possible race condition where
an urb could complete and the flag is checked in the completion
routine before it's set.

Reported-by: default avatarIan Abbott <abbotti@mev.co.uk>
Acked-by: default avatarIan Abbott <abbotti@mev.co.uk>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b07dee7c
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -686,13 +686,14 @@ static int usbduxsigma_ai_inttrig(struct comedi_device *dev,

	down(&devpriv->sem);
	if (!devpriv->ai_cmd_running) {
		devpriv->ai_cmd_running = 1;
		ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
					      devpriv->n_ai_urbs, 1);
		if (ret < 0) {
			devpriv->ai_cmd_running = 0;
			up(&devpriv->sem);
			return ret;
		}
		devpriv->ai_cmd_running = 1;
		s->async->inttrig = NULL;
	}
	up(&devpriv->sem);
@@ -740,14 +741,15 @@ static int usbduxsigma_ai_cmd(struct comedi_device *dev,

	if (cmd->start_src == TRIG_NOW) {
		/* enable this acquisition operation */
		devpriv->ai_cmd_running = 1;
		ret = usbduxsigma_submit_urbs(dev, devpriv->ai_urbs,
					      devpriv->n_ai_urbs, 1);
		if (ret < 0) {
			devpriv->ai_cmd_running = 0;
			up(&devpriv->sem);
			return ret;
		}
		s->async->inttrig = NULL;
		devpriv->ai_cmd_running = 1;
	} else {	/* TRIG_INT */
		/* wait for an internal signal and submit the urbs later */
		s->async->inttrig = usbduxsigma_ai_inttrig;
@@ -876,13 +878,14 @@ static int usbduxsigma_ao_inttrig(struct comedi_device *dev,

	down(&devpriv->sem);
	if (!devpriv->ao_cmd_running) {
		devpriv->ao_cmd_running = 1;
		ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
					      devpriv->n_ao_urbs, 0);
		if (ret < 0) {
			devpriv->ao_cmd_running = 0;
			up(&devpriv->sem);
			return ret;
		}
		devpriv->ao_cmd_running = 1;
		s->async->inttrig = NULL;
	}
	up(&devpriv->sem);
@@ -1026,14 +1029,15 @@ static int usbduxsigma_ao_cmd(struct comedi_device *dev,

	if (cmd->start_src == TRIG_NOW) {
		/* enable this acquisition operation */
		devpriv->ao_cmd_running = 1;
		ret = usbduxsigma_submit_urbs(dev, devpriv->ao_urbs,
					      devpriv->n_ao_urbs, 0);
		if (ret < 0) {
			devpriv->ao_cmd_running = 0;
			up(&devpriv->sem);
			return ret;
		}
		s->async->inttrig = NULL;
		devpriv->ao_cmd_running = 1;
	} else {	/* TRIG_INT */
		/* wait for an internal signal and submit the urbs later */
		s->async->inttrig = usbduxsigma_ao_inttrig;
@@ -1237,10 +1241,12 @@ static int usbduxsigma_pwm_start(struct comedi_device *dev,

	memset(devpriv->pwm_urb->transfer_buffer, 0, devpriv->pwm_buf_sz);

	devpriv->pwm_cmd_running = 1;
	ret = usbduxsigma_submit_pwm_urb(dev);
	if (ret < 0)
	if (ret < 0) {
		devpriv->pwm_cmd_running = 0;
		return ret;
	devpriv->pwm_cmd_running = 1;
	}

	return 0;
}