[PATCH 2/3] staging: comedi: drivers: move comedi_async 'cur_chan' tracking into the core

Ian Abbott abbotti at mev.co.uk
Fri Oct 31 11:25:29 UTC 2014


On 30/10/14 18:38, H Hartley Sweeten wrote:
> The commedi_async 'cur_chan' member is used to track the current position
> in the chanlist for a scan. Currently only a couple comedi drivers use
> this member.
>
> For aeshtetics, move the 'cur_chan' tracking into the core for non-SDF_PACKED
> subdevices. The 'cur_chan' will be updated after reading or writing samples
> to the async buffer by comedi_inc_scan_progress(). All non-SDF_PACKED subdevices
> will then automatiaclly track the 'cur_chan'.
>
> Some of the drivers and were using the 'cur_chan' overflow to detect the
> end of scan, comedi_inc_scan_progress() detects the end of scan and sets
> the COMEDI_CB_EOS event. Those drivers just need to detect the event.
>
> Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>
> Cc: Ian Abbott <abbotti at mev.co.uk>
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> ---
>   drivers/staging/comedi/drivers.c                          |  7 +++++++
>   drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c |  2 --
>   drivers/staging/comedi/drivers/adl_pci9118.c              |  8 ++------
>   drivers/staging/comedi/drivers/adv_pci1710.c              | 13 ++-----------
>   drivers/staging/comedi/drivers/ni_mio_common.c            |  8 --------
>   drivers/staging/comedi/drivers/pcl812.c                   | 13 ++++---------
>   drivers/staging/comedi/drivers/pcl816.c                   |  6 +-----
>   drivers/staging/comedi/drivers/pcl818.c                   |  6 +-----
>   drivers/staging/comedi/drivers/rtd520.c                   |  3 ---
>   9 files changed, 17 insertions(+), 49 deletions(-)
>
> diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
> index ff2df85..9c55dc7 100644
> --- a/drivers/staging/comedi/drivers.c
> +++ b/drivers/staging/comedi/drivers.c
> @@ -341,8 +341,15 @@ void comedi_inc_scan_progress(struct comedi_subdevice *s,
>   			      unsigned int num_bytes)
>   {
>   	struct comedi_async *async = s->async;
> +	struct comedi_cmd *cmd = &async->cmd;
>   	unsigned int scan_length = comedi_bytes_per_scan(s);
>
> +	/* track the 'cur_chan' for non-SDF_PACKED subdevices */
> +	if (!(s->subdev_flags & SDF_PACKED)) {
> +		async->cur_chan += comedi_bytes_to_samples(s, num_bytes);
> +		async->cur_chan %= cmd->chanlist_len;
> +	}
> +
>   	async->scan_progress += num_bytes;
>   	if (async->scan_progress >= scan_length) {
>   		async->scan_progress %= scan_length;
> diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
> index 6b65ce6..facd2c4 100644
> --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
> +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
> @@ -1167,8 +1167,6 @@ static void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,
>
>   	devpriv->ui_AiActualScan +=
>   		(s->async->cur_chan + num_samples) / cmd->scan_end_arg;
> -	s->async->cur_chan += num_samples;
> -	s->async->cur_chan %= cmd->scan_end_arg;
>
>   	comedi_buf_write_samples(s, dma_buffer, num_samples);
>   }
> diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
> index 83c3813..4060973 100644
> --- a/drivers/staging/comedi/drivers/adl_pci9118.c
> +++ b/drivers/staging/comedi/drivers/adl_pci9118.c
> @@ -483,8 +483,6 @@ static void move_block_from_dma(struct comedi_device *dev,
>   	num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples);
>   	devpriv->ai_act_scan +=
>   	    (s->async->cur_chan + num_samples) / cmd->scan_end_arg;
> -	s->async->cur_chan += num_samples;
> -	s->async->cur_chan %= cmd->scan_end_arg;
>
>   	comedi_buf_write_samples(s, dma_buffer, num_samples);
>   }
> @@ -612,10 +610,8 @@ static void interrupt_pci9118_ai_onesample(struct comedi_device *dev,
>   	sampl = inl(dev->iobase + PCI9118_AI_FIFO_REG);
>
>   	comedi_buf_write_samples(s, &sampl, 1);
> -	s->async->cur_chan++;
> -	if (s->async->cur_chan >= cmd->scan_end_arg) {
> -							/* one scan done */
> -		s->async->cur_chan %= cmd->scan_end_arg;
> +
> +	if (s->async->events & COMEDI_CB_EOS) {

Alternatively, you could check if s->async->cur_chan == 0 to indicate 
the end of scan.

>   		devpriv->ai_act_scan++;
>   		if (!devpriv->ai_neverending) {
>   			/* all data sampled? */
> diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
> index 075df1c..b7083eb 100644
> --- a/drivers/staging/comedi/drivers/adv_pci1710.c
> +++ b/drivers/staging/comedi/drivers/adv_pci1710.c
> @@ -772,12 +772,7 @@ static void pci1710_handle_every_sample(struct comedi_device *dev,
>   		val &= s->maxdata;
>   		comedi_buf_write_samples(s, &val, 1);
>
> -		s->async->cur_chan++;
> -		if (s->async->cur_chan >= cmd->chanlist_len)
> -			s->async->cur_chan = 0;
> -
> -
> -		if (s->async->cur_chan == 0) {	/*  one scan done */
> +		if (s->async->events & COMEDI_CB_EOS) {

I like the original test better.

>   			devpriv->ai_act_scan++;
>   			if (cmd->stop_src == TRIG_COUNT &&
>   			    devpriv->ai_act_scan >= cmd->stop_arg) {
> @@ -800,7 +795,6 @@ static int move_block_from_fifo(struct comedi_device *dev,
>   				struct comedi_subdevice *s, int n, int turn)
>   {
>   	struct pci1710_private *devpriv = dev->private;
> -	struct comedi_cmd *cmd = &s->async->cmd;
>   	unsigned int val;
>   	int ret;
>   	int i;
> @@ -817,11 +811,8 @@ static int move_block_from_fifo(struct comedi_device *dev,
>   		val &= s->maxdata;
>   		comedi_buf_write_samples(s, &val, 1);
>
> -		s->async->cur_chan++;
> -		if (s->async->cur_chan >= cmd->chanlist_len) {
> -			s->async->cur_chan = 0;
> +		if (s->async->events & COMEDI_CB_EOS)

This won't work as it's in a loop and the COMEDI_CB_EOS event would 
remain set for the subsequent iterations of the loop.  You could just 
check whether cur_chan == 0 to detect end of scan.

>   			devpriv->ai_act_scan++;
> -		}
>   	}
>   	return 0;
>   }
> diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
> index 32236ef..2dfd951 100644
> --- a/drivers/staging/comedi/drivers/ni_mio_common.c
> +++ b/drivers/staging/comedi/drivers/ni_mio_common.c
> @@ -1125,14 +1125,10 @@ static void ni_ao_fifo_load(struct comedi_device *dev,
>   			    struct comedi_subdevice *s, int n)
>   {
>   	struct ni_private *devpriv = dev->private;
> -	struct comedi_async *async = s->async;
> -	struct comedi_cmd *cmd = &async->cmd;
> -	int chan;
>   	int i;
>   	unsigned short d;
>   	u32 packed_data;
>
> -	chan = async->cur_chan;
>   	for (i = 0; i < n; i++) {
>   		comedi_buf_read_samples(s, &d, 1);
>
> @@ -1141,7 +1137,6 @@ static void ni_ao_fifo_load(struct comedi_device *dev,
>   			/* 6711 only has 16 bit wide ao fifo */
>   			if (!devpriv->is_6711) {
>   				comedi_buf_read_samples(s, &d, 1);
> -				chan++;
>   				i++;
>   				packed_data |= (d << 16) & 0xffff0000;
>   			}
> @@ -1149,10 +1144,7 @@ static void ni_ao_fifo_load(struct comedi_device *dev,
>   		} else {
>   			ni_writew(dev, d, DAC_FIFO_Data);
>   		}
> -		chan++;
> -		chan %= cmd->chanlist_len;
>   	}
> -	async->cur_chan = chan;
>   }
>
>   /*
> diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
> index 1088607..6aaee06 100644
> --- a/drivers/staging/comedi/drivers/pcl812.c
> +++ b/drivers/staging/comedi/drivers/pcl812.c
> @@ -843,12 +843,8 @@ static bool pcl812_ai_next_chan(struct comedi_device *dev,
>   	struct pcl812_private *devpriv = dev->private;
>   	struct comedi_cmd *cmd = &s->async->cmd;
>
> -	s->async->cur_chan++;
> -	if (s->async->cur_chan >= cmd->chanlist_len) {
> -		s->async->cur_chan = 0;
> +	if (s->async->events & COMEDI_CB_EOS)

This one won't work either, as pcl812_ai_next_chan() is called several 
times in a loop and the COMEDI_CB_EOS event remains set for subsequent 
iterations.

>   		devpriv->ai_act_scan++;
> -		s->async->events |= COMEDI_CB_EOS;
> -	}
>
>   	if (cmd->stop_src == TRIG_COUNT &&
>   	    devpriv->ai_act_scan >= cmd->stop_arg) {
> @@ -864,6 +860,7 @@ static void pcl812_handle_eoc(struct comedi_device *dev,
>   			      struct comedi_subdevice *s)
>   {
>   	struct comedi_cmd *cmd = &s->async->cmd;
> +	unsigned int chan = s->async->cur_chan;
>   	unsigned int next_chan;
>   	unsigned short val;
>
> @@ -877,10 +874,8 @@ static void pcl812_handle_eoc(struct comedi_device *dev,
>   	comedi_buf_write_samples(s, &val, 1);
>
>   	/* Set up next channel. Added by abbotti 2010-01-20, but untested. */
> -	next_chan = s->async->cur_chan + 1;
> -	if (next_chan >= cmd->chanlist_len)
> -		next_chan = 0;
> -	if (cmd->chanlist[s->async->cur_chan] != cmd->chanlist[next_chan])
> +	next_chan = s->async->cur_chan;
> +	if (cmd->chanlist[chan] != cmd->chanlist[next_chan])
>   		pcl812_ai_set_chan_range(dev, cmd->chanlist[next_chan], 0);
>
>   	pcl812_ai_next_chan(dev, s);
> diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
> index 053eed0..b8e9e3b 100644
> --- a/drivers/staging/comedi/drivers/pcl816.c
> +++ b/drivers/staging/comedi/drivers/pcl816.c
> @@ -289,12 +289,8 @@ static bool pcl816_ai_next_chan(struct comedi_device *dev,
>   	struct pcl816_private *devpriv = dev->private;
>   	struct comedi_cmd *cmd = &s->async->cmd;
>
> -	s->async->cur_chan++;
> -	if (s->async->cur_chan >= cmd->chanlist_len) {
> -		s->async->cur_chan = 0;
> +	if (s->async->events & COMEDI_CB_EOS)

Ditto.

>   		devpriv->ai_act_scan++;
> -		s->async->events |= COMEDI_CB_EOS;
> -	}
>
>   	if (cmd->stop_src == TRIG_COUNT &&
>   	    devpriv->ai_act_scan >= cmd->stop_arg) {
> diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
> index e6d897b..cf437d6 100644
> --- a/drivers/staging/comedi/drivers/pcl818.c
> +++ b/drivers/staging/comedi/drivers/pcl818.c
> @@ -525,12 +525,8 @@ static bool pcl818_ai_next_chan(struct comedi_device *dev,
>   	if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len)
>   		devpriv->act_chanlist_pos = 0;
>
> -	s->async->cur_chan++;
> -	if (s->async->cur_chan >= cmd->chanlist_len) {
> -		s->async->cur_chan = 0;
> +	if (s->async->events & COMEDI_CB_EOS)

Ditto.

>   		devpriv->ai_act_scan--;
> -		s->async->events |= COMEDI_CB_EOS;
> -	}
>
>   	if (cmd->stop_src == TRIG_COUNT && devpriv->ai_act_scan == 0) {
>   		/* all data sampled */
> diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
> index 19596756..fb71fd6 100644
> --- a/drivers/staging/comedi/drivers/rtd520.c
> +++ b/drivers/staging/comedi/drivers/rtd520.c
> @@ -628,9 +628,6 @@ static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
>   		if (!comedi_buf_write_samples(s, &d, 1))
>   			return -1;
>
> -		async->cur_chan++;
> -		async->cur_chan %= cmd->chanlist_len;
> -
>   		if (devpriv->ai_count > 0)	/* < 0, means read forever */
>   			devpriv->ai_count--;
>   	}
>


-- 
-=( Ian Abbott @ MEV Ltd.    E-mail: <abbotti at mev.co.uk> )=-
-=(                          Web: http://www.mev.co.uk/  )=-


More information about the devel mailing list