diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/pcmuio.c')
-rw-r--r-- | drivers/staging/comedi/drivers/pcmuio.c | 72 |
1 files changed, 58 insertions, 14 deletions
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c index 31ea20c2d39e..433270ceda4f 100644 --- a/drivers/staging/comedi/drivers/pcmuio.c +++ b/drivers/staging/comedi/drivers/pcmuio.c @@ -77,10 +77,10 @@ Configuration Options: #include <linux/interrupt.h> #include <linux/slab.h> + #include "../comedidev.h" -#include "pcm_common.h" -#include <linux/pci.h> /* for PCI devices */ +#include "comedi_fc.h" #define CHANS_PER_PORT 8 #define PORTS_PER_ASIC 6 @@ -92,7 +92,6 @@ Configuration Options: #define INTR_PORTS_PER_SUBDEV (INTR_CHANS_PER_ASIC/CHANS_PER_PORT) #define MAX_DIO_CHANS (PORTS_PER_ASIC*2*CHANS_PER_PORT) #define MAX_ASICS (MAX_DIO_CHANS/CHANS_PER_ASIC) -#define SDEV_NO ((int)(s - dev->subdevices)) #define CALC_N_SUBDEVS(nchans) ((nchans)/MAX_CHANS_PER_SUBDEV + (!!((nchans)%MAX_CHANS_PER_SUBDEV)) /*+ (nchans > INTR_CHANS_PER_ASIC ? 2 : 1)*/) /* IO Memory sizes */ #define ASIC_IOSIZE (0x10) @@ -740,11 +739,59 @@ static int pcmuio_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } -static int -pcmuio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_cmd *cmd) +static int pcmuio_cmdtest(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_cmd *cmd) { - return comedi_pcm_cmdtest(dev, s, cmd); + int err = 0; + + /* Step 1 : check if triggers are trivially valid */ + + err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT); + err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); + err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); + err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); + err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); + + if (err) + return 1; + + /* Step 2a : make sure trigger sources are unique */ + + err |= cfc_check_trigger_is_unique(cmd->start_src); + err |= cfc_check_trigger_is_unique(cmd->stop_src); + + /* Step 2b : and mutually compatible */ + + if (err) + return 2; + + /* Step 3: check if arguments are trivially valid */ + + err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); + err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); + + switch (cmd->stop_src) { + case TRIG_COUNT: + /* any count allowed */ + break; + case TRIG_NONE: + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); + break; + default: + break; + } + + if (err) + return 3; + + /* step 4: fix up any arguments */ + + /* if (err) return 4; */ + + return 0; } static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) @@ -791,14 +838,11 @@ static int pcmuio_attach(struct comedi_device *dev, struct comedi_devconfig *it) chans_left = CHANS_PER_ASIC * board->num_asics; n_subdevs = CALC_N_SUBDEVS(chans_left); - devpriv->sprivs = - kcalloc(n_subdevs, sizeof(struct pcmuio_subdev_private), - GFP_KERNEL); - if (!devpriv->sprivs) { - dev_warn(dev->class_dev, - "cannot allocate subdevice private data structures\n"); + devpriv->sprivs = kcalloc(n_subdevs, + sizeof(struct pcmuio_subdev_private), + GFP_KERNEL); + if (!devpriv->sprivs) return -ENOMEM; - } ret = comedi_alloc_subdevices(dev, n_subdevs); if (ret) |