From a04de50cf23df317ce49eb091a05d03a3ef0c2c3 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Sat, 18 Oct 2003 21:05:14 +0000 Subject: [PATCH] give warning and return error if user attempts to use ao command and ai external queue at the same time. --- comedi/drivers/cb_pcidas64.c | 60 +++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/comedi/drivers/cb_pcidas64.c b/comedi/drivers/cb_pcidas64.c index 8f7855eb..b749dbb0 100644 --- a/comedi/drivers/cb_pcidas64.c +++ b/comedi/drivers/cb_pcidas64.c @@ -1572,6 +1572,13 @@ int alloc_and_init_dma_members(comedi_device *dev) } return 0; } + +static inline void warn_external_queue(comedi_device *dev) +{ + comedi_error(dev, "AO command and AI external channel queue cannot be used simultaneously."); + comedi_error(dev, "Use internal AI channel queue (channels must be consecutive and use same range/aref)"); +} + /* * Attach is called by the Comedi core to configure the driver * for a particular board. @@ -2421,7 +2428,7 @@ static int use_internal_queue_6xxx(const comedi_cmd *cmd) return 1; } -static void setup_channel_queue(comedi_device *dev, const comedi_cmd *cmd) +static int setup_channel_queue(comedi_device *dev, const comedi_cmd *cmd) { unsigned short bits; int i; @@ -2448,6 +2455,11 @@ static void setup_channel_queue(comedi_device *dev, const comedi_cmd *cmd) }else { // use external queue + if(dev->write_subdev && dev->write_subdev->busy) + { + warn_external_queue(dev); + return -EBUSY; + } priv(dev)->hw_config_bits |= EXT_QUEUE_BIT; writew(priv(dev)->hw_config_bits, priv(dev)->main_iobase + HW_CONFIG_REG); // clear DAC buffer to prevent weird interactions @@ -2503,6 +2515,7 @@ static void setup_channel_queue(comedi_device *dev, const comedi_cmd *cmd) i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data, sizeof(i2c_data)); } } + return 0; } static inline void load_first_dma_descriptor(comedi_device *dev, unsigned int dma_channel, @@ -2535,10 +2548,15 @@ static int ai_cmd(comedi_device *dev,comedi_subdevice *s) uint32_t bits; unsigned int i; unsigned long flags; + int retval; disable_ai_pacing( dev ); abort_dma(dev, 1); + retval = setup_channel_queue(dev, cmd); + if(retval < 0) + return retval; + // make sure internal calibration source is turned off writew(0, priv(dev)->main_iobase + CALIBRATION_REG); @@ -2609,8 +2627,6 @@ static int ai_cmd(comedi_device *dev,comedi_subdevice *s) comedi_spin_lock_irqsave( &dev->spinlock, flags ); - setup_channel_queue(dev, cmd); - /* enable pacing, triggering, etc */ bits = ADC_ENABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT; if(cmd->flags & TRIG_WAKE_EOS) @@ -3033,12 +3049,6 @@ static int ao_winsn(comedi_device *dev, comedi_subdevice *s, set_dac_range_bits( dev, &priv(dev)->dac_control1_bits, chan, range ); writew(priv(dev)->dac_control1_bits, priv(dev)->main_iobase + DAC_CONTROL1_REG); - // clear buffer - writew(0, priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG); - /* clear queue pointer too, since external queue has - * weird interactions with ao fifo */ - writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG); - // write to channel if( board(dev)->layout == LAYOUT_4020 ) { @@ -3196,6 +3206,9 @@ static int prep_ao_dma(comedi_device *dev, const comedi_cmd *cmd) unsigned int num_bytes; int i; + /* clear queue pointer too, since external queue has + * weird interactions with ao fifo */ + writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG); writew(0, priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG); num_bytes = (DAC_FIFO_SIZE / 2) * bytes_in_sample; @@ -3222,10 +3235,26 @@ static int prep_ao_dma(comedi_device *dev, const comedi_cmd *cmd) return 0; } +static inline int external_ai_queue_in_use(comedi_device *dev) +{ + if(dev->read_subdev->busy) + return 0; + if(board(dev)->layout == LAYOUT_4020) + return 0; + else if(use_internal_queue_6xxx(&dev->read_subdev->async->cmd)) + return 0; + return 1; +} + static int ao_cmd(comedi_device *dev,comedi_subdevice *s) { comedi_cmd *cmd = &s->async->cmd; + if(external_ai_queue_in_use(dev)) + { + warn_external_queue(dev); + return -EBUSY; + } /* disable analog output system during setup */ writew(0x0, priv(dev)->main_iobase + DAC_CONTROL0_REG); @@ -3246,8 +3275,6 @@ static int ao_cmd(comedi_device *dev,comedi_subdevice *s) static int ao_inttrig(comedi_device *dev, comedi_subdevice *s, unsigned int trig_num) { comedi_cmd *cmd = &s->async->cmd; - static const int timeout = 1000; - int i; int retval; if(trig_num!=0)return -EINVAL; @@ -3255,17 +3282,6 @@ static int ao_inttrig(comedi_device *dev, comedi_subdevice *s, unsigned int trig retval = prep_ao_dma(dev, cmd); if(retval < 0) return -EPIPE; - for(i = 0; i < timeout; i++) - { - //XXX - if(i > 10) break; - } - if(i == timeout) - { - comedi_error(dev, "timed out waiting for fifo to fill"); - return -ETIMEDOUT; - } - set_dac_control0_reg(dev, cmd); if(cmd->start_src == TRIG_INT) -- 2.26.2