Module: xenomai-head Branch: master Commit: b4978903c759ab09805c51aac573e7522df649a6 URL: http://git.xenomai.org/?p=xenomai-head.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