staging: comedi: ni_mio_common: only do counter commands for ni_pcimio
authorIan Abbott <abbotti@mev.co.uk>
Fri, 10 May 2013 13:07:17 +0000 (14:07 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 May 2013 21:38:47 +0000 (17:38 -0400)
"ni_mio_common.c" holds common code included by "ni_pcimio.c",
"ni_atmio.c" and "ni_mio_cs.c", including a common initialization
function `ni_E_init()`.  Amongst other things, this initializes some
counter subdevices to support comedi instructions and asynchronous
commands.  However, even though it sets up the handlers to support
asynchronous commands on these subdevices, the handlers will return an
error unless the `PCIDMA` macro is defined (which is defined only in
"ni_pcimio.c").  If the `PCIDMA` macro is not defined, the comedi core
will needlessly allocate buffers to support the asynchronous commands.
Also, `s->async_dma_dir` is set to `DMA_BIDIRECTIONAL`, causing the
physical pages for the buffers to be allocated using
`dma_alloc_coherent()`.

If the comedi core cannot call `dma_alloc_coherent()` because
`CONFIG_HAS_DMA` is not defined, it will fail to allocate the buffers,
which ultimately causes `ni_E_init()` to fail.

Avoid the wastage and prevent the failure by only setting up
asynchronous command support for the counter subdevices if the `PCIDMA`
macro is defined.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/ni_mio_common.c

index a46d579016d9571eef12db6bff2e95beea47e4d2..8c5dee9b3b05188c85110ee171fb179d354bd858 100644 (file)
@@ -310,9 +310,11 @@ static int ni_gpct_insn_read(struct comedi_device *dev,
 static int ni_gpct_insn_config(struct comedi_device *dev,
                               struct comedi_subdevice *s,
                               struct comedi_insn *insn, unsigned int *data);
+#ifdef PCIDMA
 static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
 static int ni_gpct_cmdtest(struct comedi_device *dev,
                           struct comedi_subdevice *s, struct comedi_cmd *cmd);
+#endif
 static int ni_gpct_cancel(struct comedi_device *dev,
                          struct comedi_subdevice *s);
 static void handle_gpct_interrupt(struct comedi_device *dev,
@@ -4617,9 +4619,7 @@ static int ni_E_init(struct comedi_device *dev)
        for (j = 0; j < NUM_GPCT; ++j) {
                s = &dev->subdevices[NI_GPCT_SUBDEV(j)];
                s->type = COMEDI_SUBD_COUNTER;
-               s->subdev_flags =
-                   SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ
-                   /* | SDF_CMD_WRITE */ ;
+               s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
                s->n_chan = 3;
                if (board->reg_type & ni_reg_m_series_mask)
                        s->maxdata = 0xffffffff;
@@ -4628,11 +4628,14 @@ static int ni_E_init(struct comedi_device *dev)
                s->insn_read = &ni_gpct_insn_read;
                s->insn_write = &ni_gpct_insn_write;
                s->insn_config = &ni_gpct_insn_config;
+#ifdef PCIDMA
+               s->subdev_flags |= SDF_CMD_READ /* | SDF_CMD_WRITE */;
                s->do_cmd = &ni_gpct_cmd;
                s->len_chanlist = 1;
                s->do_cmdtest = &ni_gpct_cmdtest;
                s->cancel = &ni_gpct_cancel;
                s->async_dma_dir = DMA_BIDIRECTIONAL;
+#endif
                s->private = &devpriv->counter_dev->counters[j];
 
                devpriv->counter_dev->counters[j].chip_index = 0;
@@ -5216,10 +5219,10 @@ static int ni_gpct_insn_write(struct comedi_device *dev,
        return ni_tio_winsn(counter, insn, data);
 }
 
+#ifdef PCIDMA
 static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 {
        int retval;
-#ifdef PCIDMA
        struct ni_gpct *counter = s->private;
 /* const struct comedi_cmd *cmd = &s->async->cmd; */
 
@@ -5233,23 +5236,20 @@ static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
        ni_e_series_enable_second_irq(dev, counter->counter_index, 1);
        retval = ni_tio_cmd(counter, s->async);
-#else
-       retval = -ENOTSUPP;
-#endif
        return retval;
 }
+#endif
 
+#ifdef PCIDMA
 static int ni_gpct_cmdtest(struct comedi_device *dev,
                           struct comedi_subdevice *s, struct comedi_cmd *cmd)
 {
-#ifdef PCIDMA
        struct ni_gpct *counter = s->private;
 
        return ni_tio_cmdtest(counter, cmd);
-#else
        return -ENOTSUPP;
-#endif
 }
+#endif
 
 static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {