Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

staging: comedi: das16: use comedi_async 'scans_done' to detect EOA



Refactor das16_interrupt() to use the comedi_async 'scans_done' member to
detect the End-of-Acquisition for the async command. Use the helper function
comedi_nsamples_left() to determine if DMA needs to be restarted.

This allows the removal of the private data 'adc_byte_count' and fixes a
possible integer overflow issue when that value is calculated.

Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 29538110
Loading
Loading
Loading
Loading
+16 −21
Original line number Diff line number Diff line
@@ -440,7 +440,6 @@ struct das16_private_struct {
	struct comedi_isadma	*dma;
	unsigned int		clockbase;
	unsigned int		ctrl_reg;
	unsigned long		adc_byte_count;
	unsigned int		divisor1;
	unsigned int		divisor2;
	struct timer_list	timer;
@@ -458,8 +457,9 @@ static void das16_interrupt(struct comedi_device *dev)
	struct comedi_isadma *dma = devpriv->dma;
	struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
	unsigned long spin_flags;
	unsigned int residue;
	unsigned int nbytes;
	unsigned int nsamples;
	int num_bytes, residue;

	spin_lock_irqsave(&dev->spinlock, spin_flags);
	if (!(devpriv->ctrl_reg & DAS16_CTRL_DMAE)) {
@@ -475,36 +475,33 @@ static void das16_interrupt(struct comedi_device *dev)
	residue = comedi_isadma_disable_on_sample(desc->chan,
						  comedi_bytes_per_sample(s));

	/*  figure out how many points to read */
	/* figure out how many samples to read */
	if (residue > desc->size) {
		dev_err(dev->class_dev, "residue > transfer size!\n");
		async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
		num_bytes = 0;
	} else
		num_bytes = desc->size - residue;

	if (cmd->stop_src == TRIG_COUNT &&
					num_bytes >= devpriv->adc_byte_count) {
		num_bytes = devpriv->adc_byte_count;
		async->events |= COMEDI_CB_EOA;
		async->events |= COMEDI_CB_ERROR;
		nbytes = 0;
	} else {
		nbytes = desc->size - residue;
	}
	nsamples = comedi_bytes_to_samples(s, nbytes);

	dma->cur_dma = 1 - dma->cur_dma;
	devpriv->adc_byte_count -= num_bytes;

	/* re-enable dma */
	if (!(async->events & COMEDI_CB_CANCEL_MASK)) {
		struct comedi_isadma_desc *nxt_desc = &dma->desc[dma->cur_dma];
	/* restart DMA if more samples are needed */
	if (nsamples && nsamples < comedi_nsamples_left(s, nsamples + 1)) {
		struct comedi_isadma_desc *nxt_desc;

		dma->cur_dma = 1 - dma->cur_dma;
		nxt_desc = &dma->desc[dma->cur_dma];
		nxt_desc->size = nxt_desc->maxsize;
		comedi_isadma_program(nxt_desc);
	}

	spin_unlock_irqrestore(&dev->spinlock, spin_flags);

	nsamples = comedi_bytes_to_samples(s, num_bytes);
	comedi_buf_write_samples(s, desc->virt_addr, nsamples);

	if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
		async->events |= COMEDI_CB_EOA;

	comedi_handle_events(dev, s);
}

@@ -688,8 +685,6 @@ static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
		return -1;
	}

	devpriv->adc_byte_count = cmd->stop_arg * comedi_bytes_per_scan(s);

	if (devpriv->can_burst)
		outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV_REG);