[PATCH 2/4] staging: comedi: adl_pci9118: split pci9118_attach()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Split most of the functionality of the attach routine `pci9118_attach()`
into a new function `pci9118_common_attach()` that can be called when
auto-attachment of devices is supported.  Move the enabling of the PCI
device and its i/o regions into this function.  Do the requesting of the
interrupt near the end of the function so it doesn't get enabled before
the device is ready.

Note that auto-attachment of PCI devices is currently broken in this
driver because the list of board names referred to by the `struct
comedi_driver` does not contain a "wildcard" entry matching the comedi
driver name.  This won't be a problem once support for the
`auto_attach()` method is added.

Signed-off-by: Ian Abbott <abbotti@xxxxxxxxx>
---
 drivers/staging/comedi/drivers/adl_pci9118.c | 143 ++++++++++++++-------------
 1 file changed, 77 insertions(+), 66 deletions(-)

diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index 01c9ba3..cc46d64 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -1873,12 +1873,6 @@ static struct pci_dev *pci9118_find_pci(struct comedi_device *dev,
 			    PCI_SLOT(pcidev->devfn) != slot)
 				continue;
 		}
-		/*
-		 * Look for device that isn't in use.
-		 * Enable PCI device and request regions.
-		 */
-		if (comedi_pci_enable(pcidev, "adl_pci9118"))
-			continue;
 		return pcidev;
 	}
 	dev_err(dev->class_dev,
@@ -1909,56 +1903,33 @@ static void pci9118_report_attach(struct comedi_device *dev, unsigned int irq)
 		 (devpriv->master ? "" : "no "), muxbuf);
 }
 
-static int pci9118_attach(struct comedi_device *dev,
-			  struct comedi_devconfig *it)
+static int pci9118_common_attach(struct comedi_device *dev, int disable_irq,
+				 int master, int ext_mux, int softsshdelay,
+				 int hw_err_mask)
 {
 	const struct boardtype *this_board = comedi_board(dev);
-	struct pci9118_private *devpriv;
-	struct pci_dev *pcidev;
+	struct pci9118_private *devpriv = dev->private;
+	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
 	struct comedi_subdevice *s;
 	int ret, pages, i;
-	unsigned short master;
 	unsigned int irq;
 	u16 u16w;
 
-	if (it->options[3] & 1)
-		master = 0;	/* user don't want use bus master */
-	else
-		master = 1;
-
-	devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
-	if (!devpriv)
-		return -ENOMEM;
-	dev->private = devpriv;
-
-	pcidev = pci9118_find_pci(dev, it);
-	if (!pcidev)
-		return -EIO;
-	comedi_set_hw_dev(dev, &pcidev->dev);
-
+	dev->board_name = this_board->name;
+	ret = comedi_pci_enable(pcidev, dev->board_name);
+	if (ret) {
+		dev_err(dev->class_dev,
+			"cannot enable PCI device %s\n", pci_name(pcidev));
+		return ret;
+	}
 	if (master)
 		pci_set_master(pcidev);
 
-	irq = pcidev->irq;
 	devpriv->iobase_a = pci_resource_start(pcidev, 0);
 	dev->iobase = pci_resource_start(pcidev, 2);
 
-	dev->board_name = this_board->name;
-
 	pci9118_reset(dev);
 
-	if (it->options[3] & 2)
-		irq = 0;	/* user don't want use IRQ */
-	if (irq > 0) {
-		if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
-				"ADLink PCI-9118", dev))
-			dev_warn(dev->class_dev,
-				 "unable to allocate IRQ %u, DISABLING IT\n",
-				 irq);
-		else
-			dev->irq = irq;
-	}
-
 	if (master) {		/* alloc DMA buffers */
 		devpriv->dma_doublebuf = 0;
 		for (i = 0; i < 2; i++) {
@@ -1984,32 +1955,29 @@ static int pci9118_attach(struct comedi_device *dev,
 				 "Can't allocate DMA buffer, DMA disabled!\n");
 			master = 0;
 		}
-
 		if (devpriv->dmabuf_virt[1])
 			devpriv->dma_doublebuf = 1;
-
 	}
-
 	devpriv->master = master;
-	devpriv->usemux = 0;
-	if (it->options[2] > 0) {
-		devpriv->usemux = it->options[2];
-		if (devpriv->usemux > 256)
-			devpriv->usemux = 256;	/* max 256 channels! */
-		if (it->options[4] > 0)
-			if (devpriv->usemux > 128) {
-				devpriv->usemux = 128;
-					/* max 128 channels with softare S&H! */
-			}
+
+	if (ext_mux > 0) {
+		if (ext_mux > 256)
+			ext_mux = 256;	/* max 256 channels! */
+		if (softsshdelay > 0)
+			if (ext_mux > 128)
+				ext_mux = 128;
+		devpriv->usemux = ext_mux;
+	} else {
+		devpriv->usemux = 0;
 	}
 
-	devpriv->softsshdelay = it->options[4];
-	if (devpriv->softsshdelay < 0) {
-					/* select sample&hold signal polarity */
-		devpriv->softsshdelay = -devpriv->softsshdelay;
+	if (softsshdelay < 0) {
+		/* select sample&hold signal polarity */
+		devpriv->softsshdelay = -softsshdelay;
 		devpriv->softsshsample = 0x80;
 		devpriv->softsshhold = 0x00;
 	} else {
+		devpriv->softsshdelay = softsshdelay;
 		devpriv->softsshsample = 0x00;
 		devpriv->softsshhold = 0x80;
 	}
@@ -2036,12 +2004,7 @@ static int pci9118_attach(struct comedi_device *dev,
 	s->range_table = this_board->rangelist_ai;
 	s->cancel = pci9118_ai_cancel;
 	s->insn_read = pci9118_insn_read_ai;
-	if (dev->irq) {
-		s->subdev_flags |= SDF_CMD_READ;
-		s->do_cmdtest = pci9118_ai_cmdtest;
-		s->do_cmd = pci9118_ai_cmd;
-		s->munge = pci9118_ai_munge;
-	}
+	s->munge = pci9118_ai_munge;
 
 	s = &dev->subdevices[1];
 	s->type = COMEDI_SUBD_AO;
@@ -2077,8 +2040,8 @@ static int pci9118_attach(struct comedi_device *dev,
 	devpriv->i8254_osc_base = 250;	/* 250ns=4MHz */
 	devpriv->ai_maskharderr = 0x10a;
 					/* default measure crash condition */
-	if (it->options[5])		/* disable some requested */
-		devpriv->ai_maskharderr &= ~it->options[5];
+	if (hw_err_mask)		/* disable some requested */
+		devpriv->ai_maskharderr &= ~hw_err_mask;
 
 	switch (this_board->ai_maxdata) {
 	case 0xffff:
@@ -2088,10 +2051,58 @@ static int pci9118_attach(struct comedi_device *dev,
 		devpriv->ai16bits = 0;
 		break;
 	}
+
+	if (disable_irq)
+		irq = 0;
+	else
+		irq = pcidev->irq;
+	if (irq > 0) {
+		if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
+				dev->board_name, dev)) {
+			dev_warn(dev->class_dev,
+				 "unable to allocate IRQ %u, DISABLING IT\n",
+				 irq);
+		} else {
+			dev->irq = irq;
+			/* Enable AI commands */
+			s = &dev->subdevices[0];
+			s->subdev_flags |= SDF_CMD_READ;
+			s->do_cmdtest = pci9118_ai_cmdtest;
+			s->do_cmd = pci9118_ai_cmd;
+		}
+	}
+
 	pci9118_report_attach(dev, irq);
 	return 0;
 }
 
+static int pci9118_attach(struct comedi_device *dev,
+			  struct comedi_devconfig *it)
+{
+	struct pci9118_private *devpriv;
+	struct pci_dev *pcidev;
+	int ext_mux, disable_irq, master, softsshdelay, hw_err_mask;
+
+	ext_mux = it->options[2];
+	master = ((it->options[3] & 1) == 0);
+	disable_irq = ((it->options[3] & 2) != 0);
+	softsshdelay = it->options[4];
+	hw_err_mask = it->options[5];
+
+	devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
+	if (!devpriv)
+		return -ENOMEM;
+	dev->private = devpriv;
+
+	pcidev = pci9118_find_pci(dev, it);
+	if (!pcidev)
+		return -EIO;
+	comedi_set_hw_dev(dev, &pcidev->dev);
+
+	return pci9118_common_attach(dev, disable_irq, master, ext_mux,
+				     softsshdelay, hw_err_mask);
+}
+
 static void pci9118_detach(struct comedi_device *dev)
 {
 	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
-- 
1.7.12.4

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel


[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux