[PATCH 07/15] staging: comedi: comedi_bond: use bitmap to record opened/closed minors

Ian Abbott abbotti at mev.co.uk
Fri Aug 23 13:45:02 UTC 2013


`do_dev_config()` currently records the comedi minor devices it has
opened by setting `devs_opened[minor]` to the pointer returned by
`comedi_open()`.  This is checked to avoid opening the same minor device
twice.  The pointer values in `devs_opened[]` aren't needed; we only
need to record which minor device numbers are being used.  Change
`devs_opened` to a bitmap (declared with `DECLARE_BITMAP()`) of length
`COMEDI_NUM_BOARD_MINORS` as the minor device numbers are range-checked
to fit in a bitmap of this length.  Use `test_and_set_bit()` to record
the minor device numbers we attempt to open with `comedi_open()`.

`bonding_detach()` calls `comedi_close()` to close the comedi minor
devices.  Since the minor device numbers may be repeated in its list of
bonded subdevices, it currently uses a simple `unsigned long
devs_closed` variable as a bitmap to keep track of which minor device
numbers it has already closed to avoid closing them twice.  As a single
`unsigned long` consists of less than `COMEDI_NUM_BOARD_MINORS` bits on
a 32-bit machine, change `devs_closed to a bitmap of this length using
`DECLARE_BITMAP()` and use `test_and_set_bit()` to avoid calling
`comedi_close()` more than once for each minor device number in use.

Signed-off-by: Ian Abbott <abbotti at mev.co.uk>
---
 drivers/staging/comedi/drivers/comedi_bond.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c
index dd93e4f..c0a427c 100644
--- a/drivers/staging/comedi/drivers/comedi_bond.c
+++ b/drivers/staging/comedi/drivers/comedi_bond.c
@@ -190,10 +190,10 @@ static void *realloc(const void *oldmem, size_t newlen, size_t oldlen)
 static int do_dev_config(struct comedi_device *dev, struct comedi_devconfig *it)
 {
 	struct comedi_bond_private *devpriv = dev->private;
+	DECLARE_BITMAP(devs_opened, COMEDI_NUM_BOARD_MINORS);
 	int i;
-	struct comedi_device *devs_opened[COMEDI_NUM_BOARD_MINORS];
 
-	memset(devs_opened, 0, sizeof(devs_opened));
+	memset(&devs_opened, 0, sizeof(devs_opened));
 	devpriv->name[0] = 0;
 	/*
 	 * Loop through all comedi devices specified on the command-line,
@@ -216,7 +216,7 @@ static int do_dev_config(struct comedi_device *dev, struct comedi_devconfig *it)
 				"Cannot bond this driver to itself!\n");
 			return -EINVAL;
 		}
-		if (devs_opened[minor]) {
+		if (test_and_set_bit(minor, devs_opened)) {
 			dev_err(dev->class_dev,
 				"Minor %d specified more than once!\n", minor);
 			return -EINVAL;
@@ -225,7 +225,7 @@ static int do_dev_config(struct comedi_device *dev, struct comedi_devconfig *it)
 		snprintf(file, sizeof(file), "/dev/comedi%u", minor);
 		file[sizeof(file) - 1] = 0;
 
-		d = devs_opened[minor] = comedi_open(file);
+		d = comedi_open(file);
 
 		if (!d) {
 			dev_err(dev->class_dev,
@@ -342,19 +342,19 @@ static int bonding_attach(struct comedi_device *dev,
 static void bonding_detach(struct comedi_device *dev)
 {
 	struct comedi_bond_private *devpriv = dev->private;
-	unsigned long devs_closed = 0;
 
 	if (devpriv) {
+		DECLARE_BITMAP(devs_closed, COMEDI_NUM_BOARD_MINORS);
+
+		memset(&devs_closed, 0, sizeof(devs_closed));
 		while (devpriv->ndevs-- && devpriv->devs) {
 			struct bonded_device *bdev;
 
 			bdev = devpriv->devs[devpriv->ndevs];
 			if (!bdev)
 				continue;
-			if (!(devs_closed & (0x1 << bdev->minor))) {
+			if (!test_and_set_bit(bdev->minor, devs_closed))
 				comedi_close(bdev->dev);
-				devs_closed |= (0x1 << bdev->minor);
-			}
 			kfree(bdev);
 		}
 		kfree(devpriv->devs);
-- 
1.8.3.2



More information about the devel mailing list