On 2014-07-15 01:21, H Hartley Sweeten wrote:
This board has 8 digital output and 8 digital input channels. The direction of these channels is not configurable. For convienence all 16 channels are packed into one DIO subdevice. The (*insn_config) for this subdevice currently uses the comedi core provided comedi_dio_insn_config() function to handle the instructions. This function handles the INSN_CONFIG_DIO_INPUT and INSN_CONFIG_DIO_OUTPUT instructions which are used to change the configuration of the channels. After calling the core function, this driver "fixes" the subdevice io_bits and returns success. These instructions should be returning -EINVAL since the channels are not configurable. Refactor the (*insn_config) to only handle the INSN_CONFIG_DIO_QUERY instruction and return -EINVAL for all others. Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx> Cc: Ian Abbott <abbotti@xxxxxxxxx> Cc: Greg Kroah-Hartman <gregk@xxxxxxxxxxxxxxxxxxx> --- drivers/staging/comedi/drivers/ni_daq_700.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c index 16b52b6..ba22951 100644 --- a/drivers/staging/comedi/drivers/ni_daq_700.c +++ b/drivers/staging/comedi/drivers/ni_daq_700.c @@ -113,14 +113,19 @@ static int daq700_dio_insn_config(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - int ret; - - ret = comedi_dio_insn_config(dev, s, insn, data, 0); - if (ret) - return ret; + unsigned int mask = 1 << CR_CHAN(insn->chanspec); - /* The DIO channels are not configurable, fix the io_bits */ - s->io_bits = 0x00ff; + /* + * The DIO channels are not configurable, only the query instruction + * is supported. + */ + switch (data[0]) { + case INSN_CONFIG_DIO_QUERY: + data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT; + break; + default: + return -EINVAL; + } return insn->n; }
DIO subdevices ought to be able to handle INSN_CONFIG_DIO_INPUT, INSN_CONFIG_DIO_OUTPUT and INSN_CONFIG_DIO_QUERY as a mimimum. It could return an error if you try and configure a fixed output as an input for example:
ret = comedi_dio_insn_config(dev, s, insn, data, 0); if (ret) return ret; if (s->io_bits != 0x00ff) { /* The DIO channels are not configurable, fix the io_bits */ s->io_bits = 0x00ff; return -EINVAL; } return insn->n; -- -=( Ian Abbott @ MEV Ltd. E-mail: <abbotti@xxxxxxxxx> )=- -=( Tel: +44 (0)161 477 1898 FAX: +44 (0)161 718 3587 )=- _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel