Currently the DMA buffers are switched before writing the current samples to
the async buffer. This works but when the EOA event happens we end up with an
outstanding DMA operation in progress that gets terminated by the (*cancel).

Avoid the outstanding DMA operation by switching the DMA buffers after writing
the samples. The driver will detect the EOA event and not retart the DMA.

Signed-off-by: H Hartley Sweeten <hswee...@visionengravers.com>
Cc: Ian Abbott <abbo...@mev.co.uk>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 drivers/staging/comedi/drivers/adl_pci9118.c | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c 
b/drivers/staging/comedi/drivers/adl_pci9118.c
index 498e0c7..4111fe9 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -608,17 +608,6 @@ static void interrupt_pci9118_ai_dma(struct comedi_device 
*dev,
        struct comedi_cmd *cmd = &s->async->cmd;
        struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[devpriv->dma_actbuf];
        unsigned int nsamples = comedi_bytes_to_samples(s, dmabuf->use_size);
-       unsigned int next_dma_buf;
-
-       if (devpriv->dma_doublebuf) {   /*
-                                        * switch DMA buffers if is used
-                                        * double buffering
-                                        */
-               next_dma_buf = 1 - devpriv->dma_actbuf;
-               pci9118_amcc_setup_dma(dev, next_dma_buf);
-               if (devpriv->ai_do == 4)
-                       interrupt_pci9118_ai_mode4_switch(dev, next_dma_buf);
-       }
 
        if (nsamples) {
                nsamples = defragment_dma_buffer(dev, s, dmabuf->virt,
@@ -631,14 +620,14 @@ static void interrupt_pci9118_ai_dma(struct comedi_device 
*dev,
                        s->async->events |= COMEDI_CB_EOA;
        }
 
-       if (devpriv->dma_doublebuf) {
-               /* switch dma buffers */
-               devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
-       } else {
-               /* restart DMA if is not used double buffering */
-               pci9118_amcc_setup_dma(dev, 0);
+       if (!(s->async->events & COMEDI_CB_CANCEL_MASK)) {
+               /* restart DMA on next active buffer */
+               if (devpriv->dma_doublebuf)
+                       devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
+               pci9118_amcc_setup_dma(dev, devpriv->dma_actbuf);
                if (devpriv->ai_do == 4)
-                       interrupt_pci9118_ai_mode4_switch(dev, 0);
+                       interrupt_pci9118_ai_mode4_switch(dev,
+                                                         devpriv->dma_actbuf);
        }
 }
 
-- 
2.0.3

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

Reply via email to