Commit 10b799d2 authored by Ian Abbott's avatar Ian Abbott Committed by Greg Kroah-Hartman

staging: comedi: comedi_bond: don't map channels individually

The private data structure (`struct comedi_bond_private`) for the
overall "comedi_bond" device maps each channel individually to a pointer
to the `struct bonded_device` it belongs to via array member
`chan_id_dev_map[MAX_CHANS]`. This speeds up look-ups from channel
number to bonded device a bit, but the length of the array used to look
this up is currently fixed at `MAX_CHANS` (256) and there are no
overflow checks when filling the array.

In practice, there will only be a few bonded devices (actually bonded
subdevices) and it is practical to just skip through the list until we
reach the one containing the desired channel.

The only place where the bonded device is looked up from the channel
number is in `bonding_dio_insn_config()`.  Change it to do the look-up
by skipping through the list of bonded devices and remove the
`chan_id_dev_map[]` member.  The `chanid_offset` member of `struct
bonded_device` is also no longer needed as the value can be derived
while skipping through the list of bonded devices, so remove that member
as well.
Signed-off-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f59ebeda
...@@ -53,18 +53,12 @@ ...@@ -53,18 +53,12 @@
#include "../comedilib.h" #include "../comedilib.h"
#include "../comedidev.h" #include "../comedidev.h"
/* The maxiumum number of channels per subdevice. */
#define MAX_CHANS 256
struct bonded_device { struct bonded_device {
struct comedi_device *dev; struct comedi_device *dev;
unsigned minor; unsigned minor;
unsigned subdev; unsigned subdev;
unsigned subdev_type; unsigned subdev_type;
unsigned nchans; unsigned nchans;
unsigned chanid_offset; /* The offset into our unified linear
* channel-id's of chanid 0 on this
* subdevice. */
}; };
struct comedi_bond_private { struct comedi_bond_private {
...@@ -72,7 +66,6 @@ struct comedi_bond_private { ...@@ -72,7 +66,6 @@ struct comedi_bond_private {
char name[MAX_BOARD_NAME]; char name[MAX_BOARD_NAME];
struct bonded_device **devs; struct bonded_device **devs;
unsigned ndevs; unsigned ndevs;
struct bonded_device *chan_id_dev_map[MAX_CHANS];
unsigned nchans; unsigned nchans;
}; };
...@@ -133,12 +126,22 @@ static int bonding_dio_insn_config(struct comedi_device *dev, ...@@ -133,12 +126,22 @@ static int bonding_dio_insn_config(struct comedi_device *dev,
{ {
struct comedi_bond_private *devpriv = dev->private; struct comedi_bond_private *devpriv = dev->private;
int chan = CR_CHAN(insn->chanspec), ret, io_bits = s->io_bits; int chan = CR_CHAN(insn->chanspec), ret, io_bits = s->io_bits;
unsigned int chanid_offset;
unsigned int io; unsigned int io;
struct bonded_device *bdev; struct bonded_device *bdev;
struct bonded_device **devs;
if (chan < 0 || chan >= devpriv->nchans) if (chan < 0 || chan >= devpriv->nchans)
return -EINVAL; return -EINVAL;
bdev = devpriv->chan_id_dev_map[chan];
/*
* Locate bonded subdevice.
*/
chanid_offset = 0;
devs = devpriv->devs;
for (bdev = *devs++; chan >= chanid_offset + bdev->nchans;
bdev = *devs++)
chanid_offset += bdev->nchans;
/* /*
* The input or output configuration of each digital line is * The input or output configuration of each digital line is
...@@ -165,7 +168,7 @@ static int bonding_dio_insn_config(struct comedi_device *dev, ...@@ -165,7 +168,7 @@ static int bonding_dio_insn_config(struct comedi_device *dev,
break; break;
} }
/* 'real' channel id for this subdev.. */ /* 'real' channel id for this subdev.. */
chan -= bdev->chanid_offset; chan -= chanid_offset;
ret = comedi_dio_config(bdev->dev, bdev->subdev, chan, io); ret = comedi_dio_config(bdev->dev, bdev->subdev, chan, io);
if (ret != 1) if (ret != 1)
return -EINVAL; return -EINVAL;
...@@ -252,12 +255,7 @@ static int do_dev_config(struct comedi_device *dev, struct comedi_devconfig *it) ...@@ -252,12 +255,7 @@ static int do_dev_config(struct comedi_device *dev, struct comedi_devconfig *it)
bdev->subdev = sdev; bdev->subdev = sdev;
bdev->subdev_type = COMEDI_SUBD_DIO; bdev->subdev_type = COMEDI_SUBD_DIO;
bdev->nchans = nchans; bdev->nchans = nchans;
bdev->chanid_offset = devpriv->nchans; devpriv->nchans += nchans;
/* map channel id's to bonded_device * pointer.. */
while (nchans--)
devpriv->chan_id_dev_map[devpriv->nchans++] =
bdev;
/* /*
* Now put bdev pointer at end of devpriv->devs array * Now put bdev pointer at end of devpriv->devs array
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment