struct comedi_device *comedi_open(const char *path);
 int comedi_close(struct comedi_device *dev);
+int comedi_dio_get_config(struct comedi_device *dev, unsigned int subdev,
+                         unsigned int chan, unsigned int *io);
 int comedi_dio_config(struct comedi_device *dev, unsigned int subdev,
                      unsigned int chan, unsigned int io);
 int comedi_dio_bitfield(struct comedi_device *dev, unsigned int subdev,
 
                                   struct comedi_insn *insn, unsigned int *data)
 {
        struct comedi_bond_private *devpriv = dev->private;
-       int chan = CR_CHAN(insn->chanspec), ret, io_bits = s->io_bits;
-       unsigned int chanid_offset;
-       unsigned int io;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       int ret;
        struct bonded_device *bdev;
        struct bonded_device **devs;
 
-       if (chan < 0 || chan >= devpriv->nchans)
-               return -EINVAL;
-
        /*
-        * Locate bonded subdevice.
+        * Locate bonded subdevice and adjust channel.
         */
-       chanid_offset = 0;
        devs = devpriv->devs;
-       for (bdev = *devs++; chan >= chanid_offset + bdev->nchans;
-            bdev = *devs++)
-               chanid_offset += bdev->nchans;
+       for (bdev = *devs++; chan >= bdev->nchans; bdev = *devs++)
+               chan -= bdev->nchans;
 
        /*
         * The input or output configuration of each digital line is
         * configured by a special insn_config instruction.  chanspec
         * contains the channel to be changed, and data[0] contains the
-        * value COMEDI_INPUT or COMEDI_OUTPUT.
+        * configuration instruction INSN_CONFIG_DIO_OUTPUT,
+        * INSN_CONFIG_DIO_INPUT or INSN_CONFIG_DIO_QUERY.
+        *
+        * Note that INSN_CONFIG_DIO_OUTPUT == COMEDI_OUTPUT,
+        * and INSN_CONFIG_DIO_INPUT == COMEDI_INPUT.  This is deliberate ;)
         */
        switch (data[0]) {
        case INSN_CONFIG_DIO_OUTPUT:
-               io = COMEDI_OUTPUT;     /* is this really necessary? */
-               io_bits |= 1 << chan;
-               break;
        case INSN_CONFIG_DIO_INPUT:
-               io = COMEDI_INPUT;      /* is this really necessary? */
-               io_bits &= ~(1 << chan);
+               ret = comedi_dio_config(bdev->dev, bdev->subdev, chan, data[0]);
                break;
        case INSN_CONFIG_DIO_QUERY:
-               data[1] =
-                   (io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
-               return insn->n;
+               ret = comedi_dio_get_config(bdev->dev, bdev->subdev, chan,
+                                           &data[1]);
                break;
        default:
-               return -EINVAL;
+               ret = -EINVAL;
                break;
        }
-       /* 'real' channel id for this subdev.. */
-       chan -= chanid_offset;
-       ret = comedi_dio_config(bdev->dev, bdev->subdev, chan, io);
-       if (ret != 1)
-               return -EINVAL;
-       /*
-        * Finally, save the new io_bits values since we didn't get an error
-        * above.
-        */
-       s->io_bits = io_bits;
-       return insn->n;
+       if (ret >= 0)
+               ret = insn->n;
+       return ret;
 }
 
 static void *realloc(const void *oldmem, size_t newlen, size_t oldlen)
 
        return ret;
 }
 
+int comedi_dio_get_config(struct comedi_device *dev, unsigned int subdev,
+                         unsigned int chan, unsigned int *io)
+{
+       struct comedi_insn insn;
+       unsigned int data[2];
+       int ret;
+
+       memset(&insn, 0, sizeof(insn));
+       insn.insn = INSN_CONFIG;
+       insn.n = 2;
+       insn.subdev = subdev;
+       insn.chanspec = CR_PACK(chan, 0, 0);
+       data[0] = INSN_CONFIG_DIO_QUERY;
+       data[1] = 0;
+       ret = comedi_do_insn(dev, &insn, data);
+       if (ret >= 0)
+               *io = data[1];
+       return ret;
+}
+EXPORT_SYMBOL_GPL(comedi_dio_get_config);
+
 int comedi_dio_config(struct comedi_device *dev, unsigned int subdev,
                      unsigned int chan, unsigned int io)
 {