[PATCH 17/26] staging: comedi: ni_labpc: only allocate necessary subdevices

H Hartley Sweeten hsweeten at visionengravers.com
Wed Mar 20 01:07:39 UTC 2013


Each comedi_subdevice uses one of the minors allocated to the
comedi subsystem. The devices used with this driver need a minimum
of 2 and a maximum of 5 subdevices.

Only allocate and initialize the number of subdevices actually needed
by the device.

Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>
Cc: Ian Abbott <abbotti at mev.co.uk>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/staging/comedi/drivers/ni_labpc.c | 49 ++++++++++++++++++-------------
 1 file changed, 29 insertions(+), 20 deletions(-)

diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
index dea4cfc..1c00ed2 100644
--- a/drivers/staging/comedi/drivers/ni_labpc.c
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -1564,6 +1564,7 @@ int labpc_common_attach(struct comedi_device *dev,
 	const struct labpc_boardinfo *thisboard = comedi_board(dev);
 	struct labpc_private *devpriv = dev->private;
 	struct comedi_subdevice *s;
+	int subdev;
 	int i;
 	short lsb, msb;
 	int ret;
@@ -1595,12 +1596,20 @@ int labpc_common_attach(struct comedi_device *dev,
 		dev->irq = irq;
 	}
 
-	ret = comedi_alloc_subdevices(dev, 5);
+	/* Only allocate the subdevices needed */
+	subdev = 1 +			/* all boards have ai */
+		 thisboard->has_ao +	/* only on some boards have ao */
+		 1 +			/* all boards have 8255 dio */
+		 (thisboard->register_layout == labpc_1200_layout)
+		 ? 2 : 0;		/* the calib and memory devices */
+	ret = comedi_alloc_subdevices(dev, subdev);
 	if (ret)
 		return ret;
 
+	subdev = 0;
+
 	/* analog input subdevice */
-	s = &dev->subdevices[0];
+	s = &dev->subdevices[subdev++];
 	s->type		= COMEDI_SUBD_AI;
 	s->subdev_flags	= SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
 	s->n_chan	= 8;
@@ -1616,9 +1625,9 @@ int labpc_common_attach(struct comedi_device *dev,
 		s->cancel	= labpc_cancel;
 	}
 
-	/* analog output */
-	s = &dev->subdevices[1];
 	if (thisboard->has_ao) {
+		/* analog output */
+		s = &dev->subdevices[subdev++];
 		/*
 		 * Could provide command support, except it only has a
 		 * one sample hardware buffer for analog output and no
@@ -1639,23 +1648,19 @@ int labpc_common_attach(struct comedi_device *dev,
 			devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(i));
 			devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(i));
 		}
-	} else {
-		s->type = COMEDI_SUBD_UNUSED;
 	}
 
 	/* 8255 dio */
-	s = &dev->subdevices[2];
-	/*  if board uses io memory we have to give a custom callback
-	 * function to the 8255 driver */
+	s = &dev->subdevices[subdev++];
 	if (thisboard->memory_mapped_io)
 		subdev_8255_init(dev, s, labpc_dio_mem_callback,
 				 (unsigned long)(dev->iobase + DIO_BASE_REG));
 	else
 		subdev_8255_init(dev, s, NULL, dev->iobase + DIO_BASE_REG);
 
-	/*  calibration subdevices for boards that have one */
-	s = &dev->subdevices[3];
 	if (thisboard->register_layout == labpc_1200_layout) {
+		/* calibration subdevice */
+		s = &dev->subdevices[subdev++];
 		s->type = COMEDI_SUBD_CALIB;
 		s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
 		s->n_chan = 16;
@@ -1665,12 +1670,9 @@ int labpc_common_attach(struct comedi_device *dev,
 
 		for (i = 0; i < s->n_chan; i++)
 			write_caldac(dev, i, s->maxdata / 2);
-	} else
-		s->type = COMEDI_SUBD_UNUSED;
 
-	/* EEPROM */
-	s = &dev->subdevices[4];
-	if (thisboard->register_layout == labpc_1200_layout) {
+		/* EEPROM */
+		s = &dev->subdevices[subdev++];
 		s->type = COMEDI_SUBD_MEMORY;
 		s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
 		s->n_chan = EEPROM_SIZE;
@@ -1680,8 +1682,7 @@ int labpc_common_attach(struct comedi_device *dev,
 
 		for (i = 0; i < EEPROM_SIZE; i++)
 			devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i);
-	} else
-		s->type = COMEDI_SUBD_UNUSED;
+	}
 
 	return 0;
 }
@@ -1689,8 +1690,16 @@ EXPORT_SYMBOL_GPL(labpc_common_attach);
 
 void labpc_common_detach(struct comedi_device *dev)
 {
-	if (dev->subdevices)
-		subdev_8255_cleanup(dev, &dev->subdevices[2]);
+	struct comedi_subdevice *s;
+	int i;
+
+	if (dev->subdevices) {
+		for (i = 0; i < dev->n_subdevices; i++) {
+			s = &dev->subdevices[i];
+			if (s->type == COMEDI_SUBD_DIO)
+				subdev_8255_cleanup(dev, s);
+		}
+	}
 	if (dev->irq)
 		free_irq(dev->irq, dev);
 }
-- 
1.8.1.4




More information about the devel mailing list