[PATCH 3/6] staging: comedi: comedi_test: change end-of-acquisition test

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In the "comedi_test" module's acquisition timer function
`waveform_ai_interrupt()`, move the code for ending the acquisition
outside the scan loop.  Determine if the number of scans to be done is
sufficient to end the acquisition before entering the scan loop.  On
leaving the scan loop, set the `COMEDI_CB_EOA` event if the acquisition
is ending.  Only reschedule the timer if the acquisition is not ending.

Remove the somewhat useless `timer_running` flag from the private data.
This was intended to stop the timer function adding the timer back on
the timer queue periodically, but the flag setting wasn't synchronized
with the timer and we already use `del_timer_sync()` to synchronize
removal from the queue.

Signed-off-by: Ian Abbott <abbotti@xxxxxxxxx>
---
 drivers/staging/comedi/drivers/comedi_test.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c
index c401f67..48255b3 100644
--- a/drivers/staging/comedi/drivers/comedi_test.c
+++ b/drivers/staging/comedi/drivers/comedi_test.c
@@ -70,7 +70,6 @@ struct waveform_private {
 	unsigned long ai_count;	/* number of conversions remaining */
 	unsigned int scan_period;	/* scan period in usec */
 	unsigned int convert_period;	/* conversion period in usec */
-	unsigned timer_running:1;
 	unsigned int ao_loopbacks[N_CHANS];
 };
 
@@ -176,6 +175,7 @@ static void waveform_ai_interrupt(unsigned long arg)
 	unsigned long elapsed_time;
 	unsigned int num_scans;
 	struct timeval now;
+	bool stopping = false;
 
 	do_gettimeofday(&now);
 
@@ -189,6 +189,15 @@ static void waveform_ai_interrupt(unsigned long arg)
 	    (devpriv->usec_remainder + elapsed_time) % devpriv->scan_period;
 	async->events = 0;
 
+	if (cmd->stop_src == TRIG_COUNT) {
+		unsigned int remaining = cmd->stop_arg - devpriv->ai_count;
+		if (num_scans >= remaining) {
+			/* about to finish */
+			num_scans = remaining;
+			stopping = true;
+		}
+	}
+
 	for (i = 0; i < num_scans; i++) {
 		for (j = 0; j < cmd->chanlist_len; j++) {
 			cfc_write_to_buffer(dev->read_subdev,
@@ -205,18 +214,15 @@ static void waveform_ai_interrupt(unsigned long arg)
 							  devpriv->
 							  convert_period));
 		}
-		devpriv->ai_count++;
-		if (cmd->stop_src == TRIG_COUNT
-		    && devpriv->ai_count >= cmd->stop_arg) {
-			async->events |= COMEDI_CB_EOA;
-			break;
-		}
 	}
 
+	devpriv->ai_count += i;
 	devpriv->usec_current += elapsed_time;
 	devpriv->usec_current %= devpriv->usec_period;
 
-	if ((async->events & COMEDI_CB_EOA) == 0 && devpriv->timer_running)
+	if (stopping)
+		async->events |= COMEDI_CB_EOA;
+	else
 		mod_timer(&devpriv->timer, jiffies + 1);
 
 	comedi_event(dev, dev->read_subdev);
@@ -315,7 +321,6 @@ static int waveform_ai_cmd(struct comedi_device *dev,
 		return -1;
 	}
 
-	devpriv->timer_running = 1;
 	devpriv->ai_count = 0;
 	devpriv->scan_period = cmd->scan_begin_arg / nano_per_micro;
 
@@ -342,7 +347,6 @@ static int waveform_ai_cancel(struct comedi_device *dev,
 {
 	struct waveform_private *devpriv = dev->private;
 
-	devpriv->timer_running = 0;
 	del_timer_sync(&devpriv->timer);
 	return 0;
 }
-- 
1.8.0

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel


[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux