[PATCHv2 8/8] staging: comedi: das08: Add attach_pci() hook

Ian Abbott abbotti at mev.co.uk
Thu May 24 16:27:18 UTC 2012


Implement the attach_pci() hook.  This is called by
comedi_pci_auto_config() in preference to the old attach() hook and
avoids searching for the probed PCI device.  Factor out some common code
used by both the attach() and attach_pci() hooks into a couple of new
functions, das08_pci_attach_common() and das08_find_pci_board().

Signed-off-by: Ian Abbott <abbotti at mev.co.uk>
---
v2: Minor nit-picks.  (Was PATCH 9/9.)
---
 drivers/staging/comedi/drivers/das08.c |  118 +++++++++++++++++++++-----------
 1 files changed, 79 insertions(+), 39 deletions(-)

diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c
index 6d1fc7a..fd67f7c 100644
--- a/drivers/staging/comedi/drivers/das08.c
+++ b/drivers/staging/comedi/drivers/das08.c
@@ -945,6 +945,75 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase)
 EXPORT_SYMBOL_GPL(das08_common_attach);
 
 #if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI)
+static int das08_pci_attach_common(struct comedi_device *dev,
+				   struct pci_dev *pdev)
+{
+	unsigned long iobase;
+	unsigned long pci_iobase;
+	struct das08_private_struct *devpriv = dev->private;
+
+	devpriv->pdev = pdev;
+	/*  enable PCI device and reserve I/O spaces */
+	if (comedi_pci_enable(pdev, dev->driver->driver_name)) {
+		dev_err(dev->class_dev,
+			"Error enabling PCI device and requesting regions\n");
+		return -EIO;
+	}
+	/*  read base addresses */
+	pci_iobase = pci_resource_start(pdev, 1);
+	iobase = pci_resource_start(pdev, 2);
+	dev_info(dev->class_dev, "pcibase 0x%lx  iobase 0x%lx\n",
+		 pci_iobase, iobase);
+	devpriv->pci_iobase = pci_iobase;
+#if 0
+	/* We could enable pci-das08's interrupt here to make it possible
+	* to do timed input in this driver, but there is little point since
+	* conversions would have to be started by the interrupt handler
+	* so you might as well use comedi_rt_timer to emulate commands
+	*/
+	/* set source of interrupt trigger to counter2 output */
+	outb(CNTRL_INTR | CNTRL_DIR, pci_iobase + CNTRL);
+	/* Enable local interrupt 1 and pci interrupt */
+	outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR);
+#endif
+	return das08_common_attach(dev, iobase);
+}
+#endif
+
+#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI)
+static const struct das08_board_struct *
+das08_find_pci_board(struct pci_dev *pdev)
+{
+	unsigned int i;
+	for (i = 0; i < ARRAY_SIZE(das08_boards); i++)
+		if (das08_boards[i].bustype == pci &&
+		    pdev->device == das08_boards[i].id)
+			return &das08_boards[i];
+	return NULL;
+}
+#endif
+
+#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI)
+/* only called in the PCI probe path, via comedi_pci_auto_config() */
+static int __devinit das08_attach_pci(struct comedi_device *dev,
+				   struct pci_dev *pdev)
+{
+	int ret;
+
+	ret = alloc_private(dev, sizeof(struct das08_private_struct));
+	if (ret < 0)
+		return ret;
+	dev_info(dev->class_dev, "attach pci %s\n", pci_name(pdev));
+	dev->board_ptr = das08_find_pci_board(pdev);
+	if (dev->board_ptr == NULL) {
+		dev_err(dev->class_dev, "BUG! cannot determine board type!\n");
+		return -EINVAL;
+	}
+	return das08_pci_attach_common(dev, pdev);
+}
+#endif
+
+#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI)
 static struct pci_dev *das08_find_pci(struct comedi_device *dev,
 				      int bus, int slot)
 {
@@ -969,19 +1038,12 @@ static struct pci_dev *das08_find_pci(struct comedi_device *dev,
 			continue;
 		if (matchid == PCI_ANY_ID) {
 			/* wildcard board matches any supported PCI board */
-			unsigned int i;
-			for (i = 0; i < ARRAY_SIZE(das08_boards); i++) {
-				if (das08_boards[i].bustype != pci)
-					continue;
-				if (pdev->device == das08_boards[i].id) {
-					/* replace wildcard board_ptr */
-					dev->board_ptr = &das08_boards[i];
-					thisboard = comedi_board(dev);
-					break;
-				}
-			}
-			if (i == ARRAY_SIZE(das08_boards))
+			const struct das08_board_struct *foundboard;
+			foundboard = das08_find_pci_board(pdev);
+			if (foundboard == NULL)
 				continue;
+			/* replace wildcard board_ptr */
+			dev->board_ptr = thisboard = foundboard;
 		} else {
 			/* match specific PCI board */
 			if (pdev->device != matchid)
@@ -1019,36 +1081,11 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
 	dev_info(dev->class_dev, "attach\n");
 	if (IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) && thisboard->bustype == pci) {
-		unsigned long pci_iobase = 0;
 		struct pci_dev *pdev;
 		pdev = das08_find_pci(dev, it->options[0], it->options[1]);
 		if (pdev == NULL)
 			return -EIO;
-		thisboard = comedi_board(dev);	/* replaced wildcard board */
-		devpriv->pdev = pdev;
-		/*  enable PCI device and reserve I/O spaces */
-		if (comedi_pci_enable(pdev, DRV_NAME)) {
-			dev_err(dev->class_dev,
-				"Error enabling PCI device and requesting regions\n");
-			return -EIO;
-		}
-		/*  read base addresses */
-		pci_iobase = pci_resource_start(pdev, 1);
-		iobase = pci_resource_start(pdev, 2);
-		dev_info(dev->class_dev, "pcibase 0x%lx  iobase 0x%lx\n",
-			 pci_iobase, iobase);
-		devpriv->pci_iobase = pci_iobase;
-#if 0
-/* We could enable to pci-das08's interrupt here to make it possible
- * to do timed input in this driver, but there is little point since
- * conversions would have to be started by the interrupt handler
- * so you might as well use comedi_rt_timer to emulate commands
- */
-		/* set source of interrupt trigger to counter2 output */
-		outb(CNTRL_INTR | CNTRL_DIR, pci_iobase + CNTRL);
-		/* Enable local interrupt 1 and pci interrupt */
-		outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR);
-#endif
+		return das08_pci_attach_common(dev, pdev);
 	} else if (IS_ENABLED(CONFIG_COMEDI_DAS08_ISA) &&
 		   (thisboard->bustype == isa || thisboard->bustype == pc104)) {
 		iobase = it->options[0];
@@ -1057,9 +1094,9 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 			dev_err(dev->class_dev, "I/O port conflict\n");
 			return -EIO;
 		}
+		return das08_common_attach(dev, iobase);
 	} else
 		return -EIO;
-	return das08_common_attach(dev, iobase);
 }
 #endif /* DO_COMEDI_DRIVER_REGISTER */
 
@@ -1097,6 +1134,9 @@ static struct comedi_driver das08_driver = {
 	.driver_name = DRV_NAME,
 	.module = THIS_MODULE,
 	.attach = das08_attach,
+#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI)
+	.attach_pci = das08_attach_pci,
+#endif
 	.detach = das08_detach,
 	.board_name = &das08_boards[0].name,
 	.num_names = sizeof(das08_boards) / sizeof(struct das08_board_struct),
-- 
1.7.8.6




More information about the devel mailing list