Use comedi_dio_insn_bits() to handle the boilerplate code to update
the subdevice s->state for DIO and DO subdevices.

Signed-off-by: H Hartley Sweeten <hswee...@visionengravers.com>
Cc: Ian Abbott <abbo...@mev.co.uk>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 drivers/staging/comedi/drivers/8255.c              | 25 ++------
 .../comedi/drivers/addi-data/hwdrv_apci1564.c      |  7 +--
 .../comedi/drivers/addi-data/hwdrv_apci3200.c      |  7 +--
 drivers/staging/comedi/drivers/addi_apci_1516.c    |  8 +--
 drivers/staging/comedi/drivers/addi_apci_2032.c    |  8 +--
 drivers/staging/comedi/drivers/addi_apci_2200.c    |  8 +--
 drivers/staging/comedi/drivers/addi_apci_3501.c    |  8 +--
 drivers/staging/comedi/drivers/addi_apci_3xxx.c    |  8 +--
 drivers/staging/comedi/drivers/adl_pci6208.c       |  9 +--
 drivers/staging/comedi/drivers/adl_pci7x3x.c       | 13 +----
 drivers/staging/comedi/drivers/adl_pci9111.c       |  9 +--
 drivers/staging/comedi/drivers/adl_pci9118.c       |  9 ++-
 drivers/staging/comedi/drivers/adv_pci1710.c       |  9 ++-
 drivers/staging/comedi/drivers/adv_pci1723.c       | 13 ++---
 drivers/staging/comedi/drivers/adv_pci_dio.c       | 24 ++++----
 drivers/staging/comedi/drivers/aio_iiro_16.c       |  4 +-
 drivers/staging/comedi/drivers/amplc_pc263.c       | 17 +++---
 drivers/staging/comedi/drivers/amplc_pci263.c      | 17 +++---
 drivers/staging/comedi/drivers/cb_das16_cs.c       |  9 +--
 drivers/staging/comedi/drivers/contec_pci_dio.c    | 12 +---
 drivers/staging/comedi/drivers/das16.c             |  9 +--
 drivers/staging/comedi/drivers/das800.c            |  6 +-
 drivers/staging/comedi/drivers/dmm32at.c           | 66 +++++++++-------------
 drivers/staging/comedi/drivers/dt2801.c            | 21 ++++---
 drivers/staging/comedi/drivers/dt2811.c            |  8 +--
 drivers/staging/comedi/drivers/dt2817.c            | 44 ++++++---------
 drivers/staging/comedi/drivers/dt282x.c            | 10 ++--
 drivers/staging/comedi/drivers/dt3000.c            |  9 ++-
 drivers/staging/comedi/drivers/dt9812.c            |  9 +--
 drivers/staging/comedi/drivers/dyna_pci10xx.c      | 20 ++-----
 drivers/staging/comedi/drivers/icp_multi.c         | 11 +---
 drivers/staging/comedi/drivers/multiq3.c           |  8 +--
 drivers/staging/comedi/drivers/ni_6527.c           | 28 +++------
 drivers/staging/comedi/drivers/ni_670x.c           | 11 +---
 drivers/staging/comedi/drivers/ni_at_ao.c          |  8 +--
 drivers/staging/comedi/drivers/ni_atmio16d.c       |  9 ++-
 drivers/staging/comedi/drivers/ni_daq_700.c        | 18 +++---
 drivers/staging/comedi/drivers/ni_mio_common.c     | 20 +++----
 drivers/staging/comedi/drivers/ni_pcidio.c         |  9 ++-
 drivers/staging/comedi/drivers/pcl711.c            | 12 ++--
 drivers/staging/comedi/drivers/pcl726.c            | 11 ++--
 drivers/staging/comedi/drivers/pcl730.c            | 16 ++----
 drivers/staging/comedi/drivers/pcl812.c            | 11 ++--
 drivers/staging/comedi/drivers/pcl818.c            | 18 ++----
 drivers/staging/comedi/drivers/quatech_daqp_cs.c   |  8 +--
 drivers/staging/comedi/drivers/rtd520.c            |  8 +--
 drivers/staging/comedi/drivers/rti800.c            |  8 +--
 drivers/staging/comedi/drivers/s526.c              |  9 +--
 48 files changed, 211 insertions(+), 438 deletions(-)

diff --git a/drivers/staging/comedi/drivers/8255.c 
b/drivers/staging/comedi/drivers/8255.c
index 2f070fd..d29f404 100644
--- a/drivers/staging/comedi/drivers/8255.c
+++ b/drivers/staging/comedi/drivers/8255.c
@@ -126,30 +126,17 @@ EXPORT_SYMBOL_GPL(subdev_8255_interrupt);
 
 static int subdev_8255_insn(struct comedi_device *dev,
                            struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+                           struct comedi_insn *insn,
+                           unsigned int *data)
 {
        struct subdev_8255_private *spriv = s->private;
        unsigned long iobase = spriv->iobase;
-       unsigned int mask;
-       unsigned int bits;
        unsigned int v;
 
-       mask = data[0];
-       bits = data[1];
-
-       if (mask) {
-               v = s->state;
-               v &= ~mask;
-               v |= (bits & mask);
-
-               if (mask & 0xff)
-                       spriv->io(1, _8255_DATA, v & 0xff, iobase);
-               if (mask & 0xff00)
-                       spriv->io(1, _8255_DATA + 1, (v >> 8) & 0xff, iobase);
-               if (mask & 0xff0000)
-                       spriv->io(1, _8255_DATA + 2, (v >> 16) & 0xff, iobase);
-
-               s->state = v;
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
+               spriv->io(1, _8255_DATA, s->state & 0xff, iobase);
+               spriv->io(1, _8255_DATA + 1, (s->state >> 8) & 0xff, iobase);
+               spriv->io(1, _8255_DATA + 2, (s->state >> 16) & 0xff, iobase);
        }
 
        v = spriv->io(0, _8255_DATA, 0, iobase);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c 
b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
index e3cc429..fca64e4 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
@@ -260,18 +260,13 @@ static int apci1564_do_insn_bits(struct comedi_device 
*dev,
                                 unsigned int *data)
 {
        struct addi_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
 
        s->state = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
                        APCI1564_DIGITAL_OP_RW);
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outl(s->state, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
                        APCI1564_DIGITAL_OP_RW);
-       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c 
b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
index 32dce03..6487721 100644
--- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
@@ -623,16 +623,11 @@ static int apci3200_do_insn_bits(struct comedi_device 
*dev,
                                 unsigned int *data)
 {
        struct addi_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
 
        s->state = inl(devpriv->i_IobaseAddon) & 0xf;
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outl(s->state, devpriv->i_IobaseAddon);
-       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c 
b/drivers/staging/comedi/drivers/addi_apci_1516.c
index 08674c1..9761ab0 100644
--- a/drivers/staging/comedi/drivers/addi_apci_1516.c
+++ b/drivers/staging/comedi/drivers/addi_apci_1516.c
@@ -90,16 +90,10 @@ static int apci1516_do_insn_bits(struct comedi_device *dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
        s->state = inw(dev->iobase + APCI1516_DO_REG);
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outw(s->state, dev->iobase + APCI1516_DO_REG);
-       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c 
b/drivers/staging/comedi/drivers/addi_apci_2032.c
index 6b0ea16..e3f7a53 100644
--- a/drivers/staging/comedi/drivers/addi_apci_2032.c
+++ b/drivers/staging/comedi/drivers/addi_apci_2032.c
@@ -57,16 +57,10 @@ static int apci2032_do_insn_bits(struct comedi_device *dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
        s->state = inl(dev->iobase + APCI2032_DO_REG);
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outl(s->state, dev->iobase + APCI2032_DO_REG);
-       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c 
b/drivers/staging/comedi/drivers/addi_apci_2200.c
index 92ac8ec..1740442 100644
--- a/drivers/staging/comedi/drivers/addi_apci_2200.c
+++ b/drivers/staging/comedi/drivers/addi_apci_2200.c
@@ -50,16 +50,10 @@ static int apci2200_do_insn_bits(struct comedi_device *dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
        s->state = inw(dev->iobase + APCI2200_DO_REG);
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outw(s->state, dev->iobase + APCI2200_DO_REG);
-       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c 
b/drivers/staging/comedi/drivers/addi_apci_3501.c
index d9650ff..85076a0 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3501.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3501.c
@@ -161,16 +161,10 @@ static int apci3501_do_insn_bits(struct comedi_device 
*dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
        s->state = inl(dev->iobase + APCI3501_DO_REG);
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outl(s->state, dev->iobase + APCI3501_DO_REG);
-       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c 
b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
index cf5dd10..40e8d56 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3xxx.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
@@ -664,16 +664,10 @@ static int apci3xxx_do_insn_bits(struct comedi_device 
*dev,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
        s->state = inl(dev->iobase + 48) & 0xf;
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outl(s->state, dev->iobase + 48);
-       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c 
b/drivers/staging/comedi/drivers/adl_pci6208.c
index a67ad57..3e7c812 100644
--- a/drivers/staging/comedi/drivers/adl_pci6208.c
+++ b/drivers/staging/comedi/drivers/adl_pci6208.c
@@ -141,15 +141,8 @@ static int pci6208_do_insn_bits(struct comedi_device *dev,
                                struct comedi_insn *insn,
                                unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outw(s->state, dev->iobase + PCI6208_DIO);
-       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/adl_pci7x3x.c 
b/drivers/staging/comedi/drivers/adl_pci7x3x.c
index 81b7203..1ae6b7c 100644
--- a/drivers/staging/comedi/drivers/adl_pci7x3x.c
+++ b/drivers/staging/comedi/drivers/adl_pci7x3x.c
@@ -112,21 +112,10 @@ static int adl_pci7x3x_do_insn_bits(struct comedi_device 
*dev,
                                    unsigned int *data)
 {
        unsigned long reg = (unsigned long)s->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outl(s->state, dev->iobase + reg);
-       }
 
-       /*
-        * NOTE: The output register is not readable.
-        * This returned state will not be correct until all the
-        * outputs have been updated.
-        */
        data[1] = s->state;
 
        return insn->n;
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c 
b/drivers/staging/comedi/drivers/adl_pci9111.c
index 78cea19..d759e10 100644
--- a/drivers/staging/comedi/drivers/adl_pci9111.c
+++ b/drivers/staging/comedi/drivers/adl_pci9111.c
@@ -813,15 +813,8 @@ static int pci9111_do_insn_bits(struct comedi_device *dev,
                                struct comedi_insn *insn,
                                unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outw(s->state, dev->iobase + PCI9111_DIO_REG);
-       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c 
b/drivers/staging/comedi/drivers/adl_pci9118.c
index 22196ad..e41b38f 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -671,13 +671,12 @@ static int pci9118_insn_bits_di(struct comedi_device *dev,
 
 static int pci9118_insn_bits_do(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outl(s->state & 0x0f, dev->iobase + PCI9118_DO);
-       }
+
        data[1] = s->state;
 
        return insn->n;
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c 
b/drivers/staging/comedi/drivers/adv_pci1710.c
index f84df46..d2aa065 100644
--- a/drivers/staging/comedi/drivers/adv_pci1710.c
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -549,13 +549,12 @@ static int pci171x_insn_bits_di(struct comedi_device *dev,
 */
 static int pci171x_insn_bits_do(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outw(s->state, dev->iobase + PCI171x_DO);
-       }
+
        data[1] = s->state;
 
        return insn->n;
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c 
b/drivers/staging/comedi/drivers/adv_pci1723.c
index b793d69..4eeac3a 100644
--- a/drivers/staging/comedi/drivers/adv_pci1723.c
+++ b/drivers/staging/comedi/drivers/adv_pci1723.c
@@ -205,19 +205,16 @@ static int pci1723_dio_insn_config(struct comedi_device 
*dev,
        return insn->n;
 }
 
-/*
-  digital i/o bits read/write
-*/
 static int pci1723_dio_insn_bits(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outw(s->state, dev->iobase + PCI1723_WRITE_DIGITAL_OUTPUT_CMD);
-       }
+
        data[1] = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA);
+
        return insn->n;
 }
 
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c 
b/drivers/staging/comedi/drivers/adv_pci_dio.c
index f091fa0..40673f5 100644
--- a/drivers/staging/comedi/drivers/adv_pci_dio.c
+++ b/drivers/staging/comedi/drivers/adv_pci_dio.c
@@ -453,18 +453,18 @@ static int pci_dio_insn_bits_di_w(struct comedi_device 
*dev,
 */
 static int pci_dio_insn_bits_do_b(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
        const struct diosubd_data *d = (const struct diosubd_data *)s->private;
        int i;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
                for (i = 0; i < d->regs; i++)
                        outb((s->state >> (8 * i)) & 0xff,
                             dev->iobase + d->addr + i);
        }
+
        data[1] = s->state;
 
        return insn->n;
@@ -475,18 +475,18 @@ static int pci_dio_insn_bits_do_b(struct comedi_device 
*dev,
 */
 static int pci_dio_insn_bits_do_w(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
        const struct diosubd_data *d = (const struct diosubd_data *)s->private;
        int i;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
                for (i = 0; i < d->regs; i++)
                        outw((s->state >> (16 * i)) & 0xffff,
                             dev->iobase + d->addr + 2 * i);
        }
+
        data[1] = s->state;
 
        return insn->n;
@@ -646,7 +646,8 @@ static int pci1760_insn_bits_di(struct comedi_device *dev,
 */
 static int pci1760_insn_bits_do(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
        int ret;
        unsigned char omb[4] = {
@@ -657,14 +658,13 @@ static int pci1760_insn_bits_do(struct comedi_device *dev,
        };
        unsigned char imb[4];
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
                omb[0] = s->state;
                ret = pci1760_mbxrequest(dev, omb, imb);
                if (!ret)
                        return ret;
        }
+
        data[1] = s->state;
 
        return insn->n;
diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c 
b/drivers/staging/comedi/drivers/aio_iiro_16.c
index afe87cc..c8d36ef 100644
--- a/drivers/staging/comedi/drivers/aio_iiro_16.c
+++ b/drivers/staging/comedi/drivers/aio_iiro_16.c
@@ -45,9 +45,7 @@ static int aio_iiro_16_dio_insn_bits_write(struct 
comedi_device *dev,
                                           struct comedi_insn *insn,
                                           unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
                outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7);
                outb((s->state >> 8) & 0xff,
                     dev->iobase + AIO_IIRO_16_RELAY_8_15);
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c 
b/drivers/staging/comedi/drivers/amplc_pc263.c
index e710804..4d73f5e 100644
--- a/drivers/staging/comedi/drivers/amplc_pc263.c
+++ b/drivers/staging/comedi/drivers/amplc_pc263.c
@@ -57,17 +57,16 @@ static const struct pc263_board pc263_boards[] = {
 
 static int pc263_do_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
-       /* The insn data is a mask in data[0] and the new data
-        * in data[1], each channel cooresponding to a bit. */
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-               /* Write out the new digital output lines */
-               outb(s->state & 0xFF, dev->iobase);
-               outb(s->state >> 8, dev->iobase + 1);
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
+               outb(s->state & 0xff, dev->iobase);
+               outb((s->state >> 8) & 0xff, dev->iobase + 1);
        }
+
+       data[1] = s->state;
+
        return insn->n;
 }
 
diff --git a/drivers/staging/comedi/drivers/amplc_pci263.c 
b/drivers/staging/comedi/drivers/amplc_pci263.c
index 145bb48..48a53c1 100644
--- a/drivers/staging/comedi/drivers/amplc_pci263.c
+++ b/drivers/staging/comedi/drivers/amplc_pci263.c
@@ -44,17 +44,16 @@ The state of the outputs can be read.
 
 static int pci263_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       /* The insn data is a mask in data[0] and the new data
-        * in data[1], each channel cooresponding to a bit. */
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-               /* Write out the new digital output lines */
-               outb(s->state & 0xFF, dev->iobase);
-               outb(s->state >> 8, dev->iobase + 1);
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
+               outb(s->state & 0xff, dev->iobase);
+               outb((s->state >> 8) & 0xff, dev->iobase + 1);
        }
+
+       data[1] = s->state;
+
        return insn->n;
 }
 
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c 
b/drivers/staging/comedi/drivers/cb_das16_cs.c
index 0ce93da..8f3d2cb 100644
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -325,14 +325,11 @@ static int das16cs_ao_rinsn(struct comedi_device *dev,
 
 static int das16cs_dio_insn_bits(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outw(s->state, dev->iobase + DAS16CS_DIO);
-       }
 
        data[1] = inw(dev->iobase + DAS16CS_DIO);
 
diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c 
b/drivers/staging/comedi/drivers/contec_pci_dio.c
index e781716..0b19298 100644
--- a/drivers/staging/comedi/drivers/contec_pci_dio.c
+++ b/drivers/staging/comedi/drivers/contec_pci_dio.c
@@ -40,17 +40,11 @@ Configuration Options: not applicable, uses comedi PCI auto 
config
 
 static int contec_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outw(s->state, dev->iobase + PIO1616L_DO_REG);
-       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/das16.c 
b/drivers/staging/comedi/drivers/das16.c
index 1b0793f..a53d99f 100644
--- a/drivers/staging/comedi/drivers/das16.c
+++ b/drivers/staging/comedi/drivers/das16.c
@@ -952,15 +952,8 @@ static int das16_do_insn_bits(struct comedi_device *dev,
                              struct comedi_insn *insn,
                              unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outb(s->state, dev->iobase + DAS16_DIO_REG);
-       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/das800.c 
b/drivers/staging/comedi/drivers/das800.c
index 11e1611..941050e 100644
--- a/drivers/staging/comedi/drivers/das800.c
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -630,13 +630,9 @@ static int das800_do_insn_bits(struct comedi_device *dev,
                               unsigned int *data)
 {
        struct das800_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
        unsigned long irq_flags;
 
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
                devpriv->do_bits = s->state << 4;
 
                spin_lock_irqsave(&dev->spinlock, irq_flags);
diff --git a/drivers/staging/comedi/drivers/dmm32at.c 
b/drivers/staging/comedi/drivers/dmm32at.c
index 118a4fd..46df9a6 100644
--- a/drivers/staging/comedi/drivers/dmm32at.c
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -596,52 +596,38 @@ static int dmm32at_ao_rinsn(struct comedi_device *dev,
 
 static int dmm32at_dio_insn_bits(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
        struct dmm32at_private *devpriv = dev->private;
-       unsigned char diobits;
-
-       /* The insn data is a mask in data[0] and the new data
-        * in data[1], each channel cooresponding to a bit. */
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-               /* Write out the new digital output lines */
-               /* outw(s->state,dev->iobase + DMM32AT_DIO); */
-       }
+       unsigned int val;
 
-       /* get access to the DIO regs */
-       outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL);
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
+               /* get access to the DIO regs */
+               outb(DMM32AT_DIOACC, dev->iobase + DMM32AT_CNTRL);
 
-       /* if either part of dio is set for output */
-       if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) ||
-           ((devpriv->dio_config & DMM32AT_DIRCH) == 0)) {
-               diobits = (s->state & 0x00ff0000) >> 16;
-               outb(diobits, dev->iobase + DMM32AT_DIOC);
-       }
-       if ((devpriv->dio_config & DMM32AT_DIRB) == 0) {
-               diobits = (s->state & 0x0000ff00) >> 8;
-               outb(diobits, dev->iobase + DMM32AT_DIOB);
-       }
-       if ((devpriv->dio_config & DMM32AT_DIRA) == 0) {
-               diobits = (s->state & 0x000000ff);
-               outb(diobits, dev->iobase + DMM32AT_DIOA);
+               /* if either part of dio is set for output */
+               if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) ||
+                   ((devpriv->dio_config & DMM32AT_DIRCH) == 0)) {
+                       val = (s->state & 0x00ff0000) >> 16;
+                       outb(val, dev->iobase + DMM32AT_DIOC);
+               }
+               if ((devpriv->dio_config & DMM32AT_DIRB) == 0) {
+                       val = (s->state & 0x0000ff00) >> 8;
+                       outb(val, dev->iobase + DMM32AT_DIOB);
+               }
+               if ((devpriv->dio_config & DMM32AT_DIRA) == 0) {
+                       val = (s->state & 0x000000ff);
+                       outb(val, dev->iobase + DMM32AT_DIOA);
+               }
        }
 
-       /* now read the state back in */
-       s->state = inb(dev->iobase + DMM32AT_DIOC);
-       s->state <<= 8;
-       s->state |= inb(dev->iobase + DMM32AT_DIOB);
-       s->state <<= 8;
-       s->state |= inb(dev->iobase + DMM32AT_DIOA);
-       data[1] = s->state;
-
-       /* on return, data[1] contains the value of the digital
-        * input and output lines. */
-       /* data[1]=inw(dev->iobase + DMM32AT_DIO); */
-       /* or we could just return the software copy of the output values if
-        * it was a purely digital output subdevice */
-       /* data[1]=s->state; */
+       val = inb(dev->iobase + DMM32AT_DIOA);
+       val |= inb(dev->iobase + DMM32AT_DIOB) << 8;
+       val |= inb(dev->iobase + DMM32AT_DIOC) << 16;
+       s->state = val;
+
+       data[1] = val;
 
        return insn->n;
 }
diff --git a/drivers/staging/comedi/drivers/dt2801.c 
b/drivers/staging/comedi/drivers/dt2801.c
index 38918a1..d1acf82 100644
--- a/drivers/staging/comedi/drivers/dt2801.c
+++ b/drivers/staging/comedi/drivers/dt2801.c
@@ -528,23 +528,22 @@ static int dt2801_ao_insn_write(struct comedi_device *dev,
 
 static int dt2801_dio_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       int which = 0;
-
-       if (s == &dev->subdevices[3])
-               which = 1;
+       unsigned int val;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
                dt2801_writecmd(dev, DT_C_WRITE_DIG);
-               dt2801_writedata(dev, which);
+               dt2801_writedata(dev, (s == &dev->subdevices[3]) ? 1 : 0);
                dt2801_writedata(dev, s->state);
        }
+
        dt2801_writecmd(dev, DT_C_READ_DIG);
-       dt2801_writedata(dev, which);
-       dt2801_readdata(dev, data + 1);
+       dt2801_writedata(dev, (s == &dev->subdevices[3]) ? 1 : 0);
+       dt2801_readdata(dev, &val);
+
+       data[1] = val;
 
        return insn->n;
 }
diff --git a/drivers/staging/comedi/drivers/dt2811.c 
b/drivers/staging/comedi/drivers/dt2811.c
index a41a571..7da032f 100644
--- a/drivers/staging/comedi/drivers/dt2811.c
+++ b/drivers/staging/comedi/drivers/dt2811.c
@@ -353,11 +353,11 @@ static int dt2811_di_insn_bits(struct comedi_device *dev,
 
 static int dt2811_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       s->state &= ~data[0];
-       s->state |= data[0] & data[1];
-       outb(s->state, dev->iobase + DT2811_DIO);
+       if (comedi_dio_insn_bits(dev, s, insn, data))
+               outb(s->state, dev->iobase + DT2811_DIO);
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/dt2817.c 
b/drivers/staging/comedi/drivers/dt2817.c
index f4a8529..5de1330 100644
--- a/drivers/staging/comedi/drivers/dt2817.c
+++ b/drivers/staging/comedi/drivers/dt2817.c
@@ -80,36 +80,24 @@ static int dt2817_dio_insn_config(struct comedi_device *dev,
 
 static int dt2817_dio_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       unsigned int changed;
-
-       /* It's questionable whether it is more important in
-        * a driver like this to be deterministic or fast.
-        * We choose fast. */
-
-       if (data[0]) {
-               changed = s->state;
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
-               changed ^= s->state;
-               changed &= s->io_bits;
-               if (changed & 0x000000ff)
-                       outb(s->state & 0xff, dev->iobase + DT2817_DATA + 0);
-               if (changed & 0x0000ff00)
-                       outb((s->state >> 8) & 0xff,
-                            dev->iobase + DT2817_DATA + 1);
-               if (changed & 0x00ff0000)
-                       outb((s->state >> 16) & 0xff,
-                            dev->iobase + DT2817_DATA + 2);
-               if (changed & 0xff000000)
-                       outb((s->state >> 24) & 0xff,
-                            dev->iobase + DT2817_DATA + 3);
+       unsigned int val;
+
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
+               outb(s->state & 0xff, dev->iobase + DT2817_DATA + 0);
+               outb((s->state >> 8) & 0xff, dev->iobase + DT2817_DATA + 1);
+               outb((s->state >> 16) & 0xff, dev->iobase + DT2817_DATA + 2);
+               outb((s->state >> 24) & 0xff, dev->iobase + DT2817_DATA + 3);
        }
-       data[1] = inb(dev->iobase + DT2817_DATA + 0);
-       data[1] |= (inb(dev->iobase + DT2817_DATA + 1) << 8);
-       data[1] |= (inb(dev->iobase + DT2817_DATA + 2) << 16);
-       data[1] |= (inb(dev->iobase + DT2817_DATA + 3) << 24);
+
+       val = inb(dev->iobase + DT2817_DATA + 0);
+       val |= (inb(dev->iobase + DT2817_DATA + 1) << 8);
+       val |= (inb(dev->iobase + DT2817_DATA + 2) << 16);
+       val |= (inb(dev->iobase + DT2817_DATA + 3) << 24);
+
+       data[1] = val;
 
        return insn->n;
 }
diff --git a/drivers/staging/comedi/drivers/dt282x.c 
b/drivers/staging/comedi/drivers/dt282x.c
index da3ee85..5340601 100644
--- a/drivers/staging/comedi/drivers/dt282x.c
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -967,14 +967,12 @@ static int dt282x_ao_cancel(struct comedi_device *dev,
 
 static int dt282x_dio_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
-
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outw(s->state, dev->iobase + DT2821_DIODAT);
-       }
+
        data[1] = inw(dev->iobase + DT2821_DIODAT);
 
        return insn->n;
diff --git a/drivers/staging/comedi/drivers/dt3000.c 
b/drivers/staging/comedi/drivers/dt3000.c
index 64ef875..02f1aee 100644
--- a/drivers/staging/comedi/drivers/dt3000.c
+++ b/drivers/staging/comedi/drivers/dt3000.c
@@ -665,13 +665,12 @@ static int dt3k_dio_insn_config(struct comedi_device *dev,
 
 static int dt3k_dio_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[1] & data[0];
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                dt3k_writesingle(dev, SUBS_DOUT, 0, s->state);
-       }
+
        data[1] = dt3k_readsingle(dev, SUBS_DIN, 0, 0);
 
        return insn->n;
diff --git a/drivers/staging/comedi/drivers/dt9812.c 
b/drivers/staging/comedi/drivers/dt9812.c
index b5e6f33..38c6397 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -580,15 +580,8 @@ static int dt9812_do_insn_bits(struct comedi_device *dev,
                               struct comedi_insn *insn,
                               unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                dt9812_digital_out(dev, s->state);
-       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/dyna_pci10xx.c 
b/drivers/staging/comedi/drivers/dyna_pci10xx.c
index fd525f4..4fdca4c 100644
--- a/drivers/staging/comedi/drivers/dyna_pci10xx.c
+++ b/drivers/staging/comedi/drivers/dyna_pci10xx.c
@@ -147,33 +147,23 @@ static int dyna_pci10xx_di_insn_bits(struct comedi_device 
*dev,
        return insn->n;
 }
 
-/* digital output bit interface */
 static int dyna_pci10xx_do_insn_bits(struct comedi_device *dev,
-                             struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                                    struct comedi_subdevice *s,
+                                    struct comedi_insn *insn,
+                                    unsigned int *data)
 {
        struct dyna_pci10xx_private *devpriv = dev->private;
 
-       /* The insn data is a mask in data[0] and the new data
-        * in data[1], each channel cooresponding to a bit.
-        * s->state contains the previous write data
-        */
        mutex_lock(&devpriv->mutex);
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
                smp_mb();
                outw_p(s->state, devpriv->BADR3);
                udelay(10);
        }
 
-       /*
-        * On return, data[1] contains the value of the digital
-        * input and output lines. We just return the software copy of the
-        * output values if it was a purely digital output subdevice.
-        */
        data[1] = s->state;
        mutex_unlock(&devpriv->mutex);
+
        return insn->n;
 }
 
diff --git a/drivers/staging/comedi/drivers/icp_multi.c 
b/drivers/staging/comedi/drivers/icp_multi.c
index 3889d23..a1cd651 100644
--- a/drivers/staging/comedi/drivers/icp_multi.c
+++ b/drivers/staging/comedi/drivers/icp_multi.c
@@ -348,18 +348,13 @@ static int icp_multi_insn_bits_di(struct comedi_device 
*dev,
 
 static int icp_multi_insn_bits_do(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
        struct icp_multi_private *devpriv = dev->private;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
-
-               printk(KERN_DEBUG "Digital outputs = %4x \n", s->state);
-
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                writew(s->state, devpriv->io_addr + ICP_MULTI_DO);
-       }
 
        data[1] = readw(devpriv->io_addr + ICP_MULTI_DI);
 
diff --git a/drivers/staging/comedi/drivers/multiq3.c 
b/drivers/staging/comedi/drivers/multiq3.c
index 9d75ea4..c33fa66 100644
--- a/drivers/staging/comedi/drivers/multiq3.c
+++ b/drivers/staging/comedi/drivers/multiq3.c
@@ -163,11 +163,11 @@ static int multiq3_di_insn_bits(struct comedi_device *dev,
 
 static int multiq3_do_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       s->state &= ~data[0];
-       s->state |= (data[0] & data[1]);
-       outw(s->state, dev->iobase + MULTIQ3_DIGOUT_PORT);
+       if (comedi_dio_insn_bits(dev, s, insn, data))
+               outw(s->state, dev->iobase + MULTIQ3_DIGOUT_PORT);
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/ni_6527.c 
b/drivers/staging/comedi/drivers/ni_6527.c
index c2745f2..25f9a12 100644
--- a/drivers/staging/comedi/drivers/ni_6527.c
+++ b/drivers/staging/comedi/drivers/ni_6527.c
@@ -163,29 +163,19 @@ static int ni6527_di_insn_bits(struct comedi_device *dev,
 
 static int ni6527_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        struct ni6527_private *devpriv = dev->private;
+       void __iomem *io_addr = devpriv->mite->daq_io_addr;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
-
-               /* The open relay state on the board cooresponds to 1,
-                * but in Comedi, it is represented by 0. */
-               if (data[0] & 0x0000ff) {
-                       writeb((s->state ^ 0xff),
-                              devpriv->mite->daq_io_addr + Port_Register(3));
-               }
-               if (data[0] & 0x00ff00) {
-                       writeb((s->state >> 8) ^ 0xff,
-                              devpriv->mite->daq_io_addr + Port_Register(4));
-               }
-               if (data[0] & 0xff0000) {
-                       writeb((s->state >> 16) ^ 0xff,
-                              devpriv->mite->daq_io_addr + Port_Register(5));
-               }
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
+               /* Outputs are inverted */
+               writeb(s->state ^ 0xff, io_addr + Port_Register(3));
+               writeb((s->state >> 8) ^ 0xff, io_addr + Port_Register(4));
+               writeb((s->state >> 16) ^ 0xff, io_addr + Port_Register(5));
        }
+
        data[1] = s->state;
 
        return insn->n;
diff --git a/drivers/staging/comedi/drivers/ni_670x.c 
b/drivers/staging/comedi/drivers/ni_670x.c
index e2926ce..c14d578 100644
--- a/drivers/staging/comedi/drivers/ni_670x.c
+++ b/drivers/staging/comedi/drivers/ni_670x.c
@@ -136,20 +136,15 @@ static int ni_670x_ao_rinsn(struct comedi_device *dev,
 
 static int ni_670x_dio_insn_bits(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
-                                struct comedi_insn *insn, unsigned int *data)
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
        struct ni_670x_private *devpriv = dev->private;
        void __iomem *io_addr = devpriv->mite->daq_io_addr +
                                        DIO_PORT0_DATA_OFFSET;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                writel(s->state, io_addr);
-       }
 
        data[1] = readl(io_addr);
 
diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c 
b/drivers/staging/comedi/drivers/ni_at_ao.c
index b9122fd..df8b58f 100644
--- a/drivers/staging/comedi/drivers/ni_at_ao.c
+++ b/drivers/staging/comedi/drivers/ni_at_ao.c
@@ -233,13 +233,11 @@ static int atao_ao_rinsn(struct comedi_device *dev, 
struct comedi_subdevice *s,
 
 static int atao_dio_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outw(s->state, dev->iobase + ATAO_DOUT);
-       }
 
        data[1] = inw(dev->iobase + ATAO_DIN);
 
diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c 
b/drivers/staging/comedi/drivers/ni_atmio16d.c
index bb3491f..ba6094c 100644
--- a/drivers/staging/comedi/drivers/ni_atmio16d.c
+++ b/drivers/staging/comedi/drivers/ni_atmio16d.c
@@ -558,13 +558,12 @@ static int atmio16d_ao_insn_write(struct comedi_device 
*dev,
 
 static int atmio16d_dio_insn_bits(struct comedi_device *dev,
                                  struct comedi_subdevice *s,
-                                 struct comedi_insn *insn, unsigned int *data)
+                                 struct comedi_insn *insn,
+                                 unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] | data[1]);
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outw(s->state, dev->iobase + MIO_16_DIG_OUT_REG);
-       }
+
        data[1] = inw(dev->iobase + MIO_16_DIG_IN_REG);
 
        return insn->n;
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c 
b/drivers/staging/comedi/drivers/ni_daq_700.c
index 404f83d..9b9049c 100644
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -72,18 +72,18 @@ Manuals:    Register level: 
http://www.ni.com/pdf/manuals/340698.pdf
 
 static int daq700_dio_insn_bits(struct comedi_device *dev,
                                struct comedi_subdevice *s,
-                               struct comedi_insn *insn, unsigned int *data)
+                               struct comedi_insn *insn,
+                               unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       unsigned int val;
 
-               if (data[0] & 0xff)
-                       outb(s->state & 0xff, dev->iobase + DIO_W);
-       }
+       if (comedi_dio_insn_bits(dev, s, insn, data))
+               outb(s->state & 0xff, dev->iobase + DIO_W);
+
+       val = s->state & 0xff;
+       val |= inb(dev->iobase + DIO_R) << 8;
 
-       data[1] = s->state & 0xff;
-       data[1] |= inb(dev->iobase + DIO_R) << 8;
+       data[1] = val;
 
        return insn->n;
 }
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c 
b/drivers/staging/comedi/drivers/ni_mio_common.c
index 4e02770..c2c5d1f 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -3547,28 +3547,22 @@ static int ni_dio_insn_config(struct comedi_device *dev,
 
 static int ni_dio_insn_bits(struct comedi_device *dev,
                            struct comedi_subdevice *s,
-                           struct comedi_insn *insn, unsigned int *data)
+                           struct comedi_insn *insn,
+                           unsigned int *data)
 {
        struct ni_private *devpriv = dev->private;
 
-#ifdef DEBUG_DIO
-       printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0], data[1]);
-#endif
-
-       if (data[0]) {
-               /* Perform check to make sure we're not using the
-                  serial part of the dio */
-               if ((data[0] & (DIO_SDIN | DIO_SDOUT))
-                   && devpriv->serial_interval_ns)
-                       return -EBUSY;
+       /* Make sure we're not using the serial part of the dio */
+       if ((data[0] & (DIO_SDIN | DIO_SDOUT)) && devpriv->serial_interval_ns)
+               return -EBUSY;
 
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
                devpriv->dio_output &= ~DIO_Parallel_Data_Mask;
                devpriv->dio_output |= DIO_Parallel_Data_Out(s->state);
                devpriv->stc_writew(dev, devpriv->dio_output,
                                    DIO_Output_Register);
        }
+
        data[1] = devpriv->stc_readw(dev, DIO_Parallel_Input_Register);
 
        return insn->n;
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c 
b/drivers/staging/comedi/drivers/ni_pcidio.c
index fad81bc..f6ca234 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -657,15 +657,14 @@ static int ni_pcidio_insn_config(struct comedi_device 
*dev,
 
 static int ni_pcidio_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        struct nidio96_private *devpriv = dev->private;
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= (data[0] & data[1]);
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                writel(s->state, devpriv->mite->daq_io_addr + Port_IO(0));
-       }
+
        data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0));
 
        return insn->n;
diff --git a/drivers/staging/comedi/drivers/pcl711.c 
b/drivers/staging/comedi/drivers/pcl711.c
index e859f85..a94bfd9 100644
--- a/drivers/staging/comedi/drivers/pcl711.c
+++ b/drivers/staging/comedi/drivers/pcl711.c
@@ -422,19 +422,15 @@ static int pcl711_di_insn_bits(struct comedi_device *dev,
        return insn->n;
 }
 
-/* Digital port write - Untested on 8112 */
 static int pcl711_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-       }
-       if (data[0] & 0x00ff)
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
                outb(s->state & 0xff, dev->iobase + PCL711_DO_LO);
-       if (data[0] & 0xff00)
                outb((s->state >> 8), dev->iobase + PCL711_DO_HI);
+       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/pcl726.c 
b/drivers/staging/comedi/drivers/pcl726.c
index a4d0bcc..aa5e000 100644
--- a/drivers/staging/comedi/drivers/pcl726.c
+++ b/drivers/staging/comedi/drivers/pcl726.c
@@ -196,18 +196,15 @@ static int pcl726_di_insn_bits(struct comedi_device *dev,
 
 static int pcl726_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
        const struct pcl726_board *board = comedi_board(dev);
 
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-       }
-       if (data[1] & 0x00ff)
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
                outb(s->state & 0xff, dev->iobase + board->do_lo);
-       if (data[1] & 0xff00)
                outb((s->state >> 8), dev->iobase + board->do_hi);
+       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/pcl730.c 
b/drivers/staging/comedi/drivers/pcl730.c
index 2a659f2..be0dc01 100644
--- a/drivers/staging/comedi/drivers/pcl730.c
+++ b/drivers/staging/comedi/drivers/pcl730.c
@@ -167,20 +167,14 @@ static int pcl730_do_insn_bits(struct comedi_device *dev,
                               unsigned int *data)
 {
        unsigned long reg = (unsigned long)s->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
 
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
-               if (mask & 0x00ff)
-                       outb(s->state & 0xff, dev->iobase + reg);
-               if ((mask & 0xff00) && (s->n_chan > 8))
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
+               outb(s->state & 0xff, dev->iobase + reg);
+               if (s->n_chan > 8)
                        outb((s->state >> 8) & 0xff, dev->iobase + reg + 1);
-               if ((mask & 0xff0000) && (s->n_chan > 16))
+               if (s->n_chan > 16)
                        outb((s->state >> 16) & 0xff, dev->iobase + reg + 2);
-               if ((mask & 0xff000000) && (s->n_chan > 24))
+               if (s->n_chan > 24)
                        outb((s->state >> 24) & 0xff, dev->iobase + reg + 3);
        }
 
diff --git a/drivers/staging/comedi/drivers/pcl812.c 
b/drivers/staging/comedi/drivers/pcl812.c
index 03a0989..11ac20e 100644
--- a/drivers/staging/comedi/drivers/pcl812.c
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -509,19 +509,16 @@ static int pcl812_di_insn_bits(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
-==============================================================================
-*/
 static int pcl812_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
                outb(s->state & 0xff, dev->iobase + PCL812_DO_LO);
                outb((s->state >> 8), dev->iobase + PCL812_DO_HI);
        }
+
        data[1] = s->state;
 
        return insn->n;
diff --git a/drivers/staging/comedi/drivers/pcl818.c 
b/drivers/staging/comedi/drivers/pcl818.c
index a52ba82..cd16c76 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -418,21 +418,15 @@ static int pcl818_di_insn_bits(struct comedi_device *dev,
        return insn->n;
 }
 
-/*
-==============================================================================
-   DIGITAL OUTPUT MODE0, 818 cards
-
-   only one sample per call is supported
-*/
 static int pcl818_do_insn_bits(struct comedi_device *dev,
                               struct comedi_subdevice *s,
-                              struct comedi_insn *insn, unsigned int *data)
+                              struct comedi_insn *insn,
+                              unsigned int *data)
 {
-       s->state &= ~data[0];
-       s->state |= (data[0] & data[1]);
-
-       outb(s->state & 0xff, dev->iobase + PCL818_DO_LO);
-       outb((s->state >> 8), dev->iobase + PCL818_DO_HI);
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
+               outb(s->state & 0xff, dev->iobase + PCL818_DO_LO);
+               outb((s->state >> 8), dev->iobase + PCL818_DO_HI);
+       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c 
b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
index 9775d36..a5f1c5c 100644
--- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -690,18 +690,12 @@ static int daqp_do_insn_bits(struct comedi_device *dev,
                             unsigned int *data)
 {
        struct daqp_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
 
        if (devpriv->stop)
                return -EIO;
 
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outb(s->state, dev->iobase + DAQP_DIGITAL_IO);
-       }
 
        data[1] = s->state;
 
diff --git a/drivers/staging/comedi/drivers/rtd520.c 
b/drivers/staging/comedi/drivers/rtd520.c
index 93c980c..84318e6 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -1217,15 +1217,9 @@ static int rtd_dio_insn_bits(struct comedi_device *dev,
                             unsigned int *data)
 {
        struct rtd_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
 
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                writew(s->state & 0xff, devpriv->las0 + LAS0_DIO0);
-       }
 
        data[1] = readw(devpriv->las0 + LAS0_DIO0) & 0xff;
 
diff --git a/drivers/staging/comedi/drivers/rti800.c 
b/drivers/staging/comedi/drivers/rti800.c
index cbb4ba5..c1b9be0 100644
--- a/drivers/staging/comedi/drivers/rti800.c
+++ b/drivers/staging/comedi/drivers/rti800.c
@@ -267,13 +267,7 @@ static int rti800_do_insn_bits(struct comedi_device *dev,
                               struct comedi_insn *insn,
                               unsigned int *data)
 {
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
-
+       if (comedi_dio_insn_bits(dev, s, insn, data)) {
                /* Outputs are inverted... */
                outb(s->state ^ 0xff, dev->iobase + RTI800_DO);
        }
diff --git a/drivers/staging/comedi/drivers/s526.c 
b/drivers/staging/comedi/drivers/s526.c
index d629463..58e5523 100644
--- a/drivers/staging/comedi/drivers/s526.c
+++ b/drivers/staging/comedi/drivers/s526.c
@@ -499,14 +499,11 @@ static int s526_ao_rinsn(struct comedi_device *dev, 
struct comedi_subdevice *s,
 
 static int s526_dio_insn_bits(struct comedi_device *dev,
                              struct comedi_subdevice *s,
-                             struct comedi_insn *insn, unsigned int *data)
+                             struct comedi_insn *insn,
+                             unsigned int *data)
 {
-       if (data[0]) {
-               s->state &= ~data[0];
-               s->state |= data[0] & data[1];
-
+       if (comedi_dio_insn_bits(dev, s, insn, data))
                outw(s->state, dev->iobase + REG_DIO);
-       }
 
        data[1] = inw(dev->iobase + REG_DIO) & 0xff;
 
-- 
1.8.3.2

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to