Module: xenomai-2.5
Branch: master
Commit: b4978903c759ab09805c51aac573e7522df649a6
URL:    
http://git.xenomai.org/?p=xenomai-2.5.git;a=commit;h=b4978903c759ab09805c51aac573e7522df649a6

Author: Alexis Berlemont <alexis.berlem...@gmail.com>
Date:   Sat Sep  4 00:30:43 2010 +0200

analogy: [pcimio] rework the mite setup procedures

---

 .../analogy/national_instruments/mio_common.c      |  116 +++++++++++++-------
 1 files changed, 76 insertions(+), 40 deletions(-)

diff --git a/ksrc/drivers/analogy/national_instruments/mio_common.c 
b/ksrc/drivers/analogy/national_instruments/mio_common.c
index f9e6dba..a1a50dc 100644
--- a/ksrc/drivers/analogy/national_instruments/mio_common.c
+++ b/ksrc/drivers/analogy/national_instruments/mio_common.c
@@ -402,25 +402,30 @@ static int ni_request_gpct_mite_channel(a4l_dev_t * dev,
 static int ni_request_cdo_mite_channel(a4l_dev_t *dev)
 {
        unsigned long flags;
+       int err = 0;
 
        a4l_lock_irqsave(&devpriv->mite_channel_lock, flags);
+
+       /* No channel should be allocated... */
        BUG_ON(devpriv->cdo_mite_chan);
+       /* ...until now */
        devpriv->cdo_mite_chan =
                mite_request_channel(devpriv->mite, devpriv->cdo_mite_ring);
-       if (devpriv->cdo_mite_chan == NULL) {
-               a4l_unlock_irqrestore(&devpriv->mite_channel_lock,
-                                     flags);
+
+       if (devpriv->cdo_mite_chan) {
+               devpriv->cdo_mite_chan->dir = A4L_OUTPUT;
+               ni_set_cdo_dma_channel(dev, devpriv->cdo_mite_chan->channel);
+       } else {
+               err = -EBUSY;
                a4l_err(dev,
                        "ni_request_cdo_mite_channel: "
                        "failed to reserve mite dma channel "
                        "for correlated digital outut.");
-               return -EBUSY;
        }
-       devpriv->cdo_mite_chan->dir = A4L_OUTPUT;
-       ni_set_cdo_dma_channel(dev, devpriv->cdo_mite_chan->channel);
+
        a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 
-       return 0;
+       return err;
 }
 
 void ni_release_ai_mite_channel(a4l_dev_t *dev)
@@ -1425,13 +1430,18 @@ static void ni_ai_munge32(a4l_subd_t *subd, void *buf, 
unsigned long size)
 static int ni_ai_setup_MITE_dma(a4l_subd_t *subd)
 {
        a4l_dev_t *dev = subd->dev;
-       int retval;
+       unsigned long flags;
+       int err;
 
-       retval = ni_request_ai_mite_channel(dev);
-       if (retval)
-               return retval;
+       err = ni_request_ai_mite_channel(dev);
+       if (err < 0)
+               return err;
+
+       err = mite_buf_change(devpriv->ai_mite_chan->ring, subd);
+       if (err < 0)
+               return err;
 
-       mite_buf_change(devpriv->ai_mite_chan->ring, subd);
+       a4l_lock_irqsave(&devpriv->mite_channel_lock, flags);
 
        switch (boardtype.reg_type) {
        case ni_reg_611x:
@@ -1449,36 +1459,74 @@ static int ni_ai_setup_MITE_dma(a4l_subd_t *subd)
        /* start the MITE */
        mite_dma_arm(devpriv->ai_mite_chan);
 
+       a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+
        return 0;
 }
 
 static int ni_ao_setup_MITE_dma(a4l_subd_t *subd)
 {
        a4l_dev_t *dev = subd->dev;
-
-       int retval;
        unsigned long flags;
+       int err;
 
-       retval = ni_request_ao_mite_channel(dev);
-       if (retval)
-               return retval;
+       err = ni_request_ao_mite_channel(dev);
+       if (err < 0)
+               return err;
 
-       if (devpriv->ao_mite_chan) {
+       err = mite_buf_change(devpriv->ao_mite_chan->ring, subd);
+       if (err < 0)
+               return err;
 
-               mite_buf_change(devpriv->ao_mite_chan->ring, subd);
+       a4l_lock_irqsave(&devpriv->mite_channel_lock, flags);
+
+       if (devpriv->ao_mite_chan) {
 
                if (boardtype.reg_type & (ni_reg_611x | ni_reg_6713)) {
                        mite_prep_dma(devpriv->ao_mite_chan, 32, 32);
                } else {
-                       /* doing 32 instead of 16 bit wide transfers from memory
-                          makes the mite do 32 bit pci transfers, doubling pci 
bandwidth. */
+                       /* Doing 32 instead of 16 bit wide transfers
+                          from memory makes the mite do 32 bit pci
+                          transfers, doubling pci bandwidth. */
                        mite_prep_dma(devpriv->ao_mite_chan, 16, 32);
                }
                mite_dma_arm(devpriv->ao_mite_chan);
        } else
-               retval = -EIO;
+               err = -EIO;
 
-       return retval;
+       a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+
+       return err;
+}
+
+static int ni_cdo_setup_MITE_dma(a4l_subd_t *subd)
+{
+       a4l_dev_t *dev = subd->dev;
+       unsigned long flags;
+       int err;
+
+       err = ni_request_cdo_mite_channel(dev);
+       if (err < 0)
+               return err;
+
+       /* No need to get a lock to setup the ring buffer */
+       err = mite_buf_change(devpriv->cdo_mite_chan->ring, subd);
+       if (err < 0)
+               return err;
+       
+       a4l_lock_irqsave(&devpriv->mite_channel_lock, flags);
+
+       /* This test should be useless but one never knows */
+       if (devpriv->cdo_mite_chan) {
+               /* Configure the DMA transfer */
+               mite_prep_dma(devpriv->cdo_mite_chan, 32, 32);
+               mite_dma_arm(devpriv->cdo_mite_chan);   
+       } else 
+               err = -EIO;
+
+       a4l_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+       
+       return err;
 }
 
 #endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */
@@ -3420,10 +3468,6 @@ int ni_cdio_cmd(a4l_subd_t *subd, a4l_cmd_t *cmd)
                        "output command with no lines configured as outputs");
                return -EIO;
        }
-
-       retval = ni_request_cdo_mite_channel(dev);
-       if (retval < 0)
-               return retval;
        
        return 0;
 }
@@ -3444,8 +3488,7 @@ int ni_cdio_cancel(a4l_subd_t *subd)
 int ni_cdo_inttrig(a4l_subd_t *subd, lsampl_t trignum)
 {
        a4l_dev_t *dev = subd->dev;
-       unsigned long flags;
-       int retval = 0;
+       int err;
        unsigned i;
        const unsigned timeout = 1000;
 
@@ -3454,17 +3497,10 @@ int ni_cdo_inttrig(a4l_subd_t *subd, lsampl_t trignum)
           more than once per command (and doing things like trying to
           allocate the ao dma channel multiple times) */
 
-       if (devpriv->cdo_mite_chan) {
-               mite_buf_change(devpriv->cdo_mite_chan->ring, subd);
-               mite_prep_dma(devpriv->cdo_mite_chan, 32, 32);
-               mite_dma_arm(devpriv->cdo_mite_chan);
-       } else {
-               a4l_err(dev, "ni_cdo_inttrig: BUG: no cdo mite channel?");
-               retval = -EIO;
-       }
-       if (retval < 0)
-               return retval;
-
+       err = ni_cdo_setup_MITE_dma(subd);
+       if (err < 0)
+               return err;
+ 
        /* wait for dma to fill output fifo */
        for (i = 0; i < timeout; ++i) {
                if (ni_readl(M_Offset_CDIO_Status) & CDO_FIFO_Full_Bit)


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to