staging: comedi: ni_mio_common: only do counter commands for ni_pcimio
"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>
This commit is contained in:
parent
4efc4bbdc1
commit
bd304a736a
|
@ -310,9 +310,11 @@ static int ni_gpct_insn_read(struct comedi_device *dev,
|
||||||
static int ni_gpct_insn_config(struct comedi_device *dev,
|
static int ni_gpct_insn_config(struct comedi_device *dev,
|
||||||
struct comedi_subdevice *s,
|
struct comedi_subdevice *s,
|
||||||
struct comedi_insn *insn, unsigned int *data);
|
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_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
|
||||||
static int ni_gpct_cmdtest(struct comedi_device *dev,
|
static int ni_gpct_cmdtest(struct comedi_device *dev,
|
||||||
struct comedi_subdevice *s, struct comedi_cmd *cmd);
|
struct comedi_subdevice *s, struct comedi_cmd *cmd);
|
||||||
|
#endif
|
||||||
static int ni_gpct_cancel(struct comedi_device *dev,
|
static int ni_gpct_cancel(struct comedi_device *dev,
|
||||||
struct comedi_subdevice *s);
|
struct comedi_subdevice *s);
|
||||||
static void handle_gpct_interrupt(struct comedi_device *dev,
|
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) {
|
for (j = 0; j < NUM_GPCT; ++j) {
|
||||||
s = &dev->subdevices[NI_GPCT_SUBDEV(j)];
|
s = &dev->subdevices[NI_GPCT_SUBDEV(j)];
|
||||||
s->type = COMEDI_SUBD_COUNTER;
|
s->type = COMEDI_SUBD_COUNTER;
|
||||||
s->subdev_flags =
|
s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
|
||||||
SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ
|
|
||||||
/* | SDF_CMD_WRITE */ ;
|
|
||||||
s->n_chan = 3;
|
s->n_chan = 3;
|
||||||
if (board->reg_type & ni_reg_m_series_mask)
|
if (board->reg_type & ni_reg_m_series_mask)
|
||||||
s->maxdata = 0xffffffff;
|
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_read = &ni_gpct_insn_read;
|
||||||
s->insn_write = &ni_gpct_insn_write;
|
s->insn_write = &ni_gpct_insn_write;
|
||||||
s->insn_config = &ni_gpct_insn_config;
|
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->do_cmd = &ni_gpct_cmd;
|
||||||
s->len_chanlist = 1;
|
s->len_chanlist = 1;
|
||||||
s->do_cmdtest = &ni_gpct_cmdtest;
|
s->do_cmdtest = &ni_gpct_cmdtest;
|
||||||
s->cancel = &ni_gpct_cancel;
|
s->cancel = &ni_gpct_cancel;
|
||||||
s->async_dma_dir = DMA_BIDIRECTIONAL;
|
s->async_dma_dir = DMA_BIDIRECTIONAL;
|
||||||
|
#endif
|
||||||
s->private = &devpriv->counter_dev->counters[j];
|
s->private = &devpriv->counter_dev->counters[j];
|
||||||
|
|
||||||
devpriv->counter_dev->counters[j].chip_index = 0;
|
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);
|
return ni_tio_winsn(counter, insn, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PCIDMA
|
||||||
static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
#ifdef PCIDMA
|
|
||||||
struct ni_gpct *counter = s->private;
|
struct ni_gpct *counter = s->private;
|
||||||
/* const struct comedi_cmd *cmd = &s->async->cmd; */
|
/* 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_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
|
||||||
ni_e_series_enable_second_irq(dev, counter->counter_index, 1);
|
ni_e_series_enable_second_irq(dev, counter->counter_index, 1);
|
||||||
retval = ni_tio_cmd(counter, s->async);
|
retval = ni_tio_cmd(counter, s->async);
|
||||||
#else
|
|
||||||
retval = -ENOTSUPP;
|
|
||||||
#endif
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PCIDMA
|
||||||
static int ni_gpct_cmdtest(struct comedi_device *dev,
|
static int ni_gpct_cmdtest(struct comedi_device *dev,
|
||||||
struct comedi_subdevice *s, struct comedi_cmd *cmd)
|
struct comedi_subdevice *s, struct comedi_cmd *cmd)
|
||||||
{
|
{
|
||||||
#ifdef PCIDMA
|
|
||||||
struct ni_gpct *counter = s->private;
|
struct ni_gpct *counter = s->private;
|
||||||
|
|
||||||
return ni_tio_cmdtest(counter, cmd);
|
return ni_tio_cmdtest(counter, cmd);
|
||||||
#else
|
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue