[PATCH 1/8] staging: comedi: gsc_hpdi: use auto_attach method

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

 



This driver does not need to support manual attachment of supported PCI
devices.  Replace the `attach()` hook (`hpdi_attach()`) with an
`auto_attach()` hook (`hpdi_auto_attach()`).  This will be called via
`comedi_pci_auto_config()` at PCI probe time.

This driver no longer increments the PCI reference during attachment, so
remove the call to `pci_dev_put()` when detaching the device.

Signed-off-by: Ian Abbott <abbotti@xxxxxxxxx>
---
 drivers/staging/comedi/drivers/gsc_hpdi.c | 59 ++++++++++++-------------------
 1 file changed, 22 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c
index 4809295..f468c1e 100644
--- a/drivers/staging/comedi/drivers/gsc_hpdi.c
+++ b/drivers/staging/comedi/drivers/gsc_hpdi.c
@@ -472,51 +472,37 @@ static int setup_dma_descriptors(struct comedi_device *dev,
 	return transfer_size;
 }
 
-static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static const struct hpdi_board *hpdi_find_board(struct pci_dev *pcidev)
 {
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(hpdi_boards); i++)
+		if (pcidev->device == hpdi_boards[i].device_id &&
+		    pcidev->subsystem_device == hpdi_boards[i].subdevice_id)
+			return &hpdi_boards[i];
+	return NULL;
+}
+
+static int __devinit hpdi_auto_attach(struct comedi_device *dev,
+				      unsigned long context_unused)
+{
+	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
 	struct hpdi_private *devpriv;
-	struct pci_dev *pcidev;
 	int i;
 	int retval;
 
-	dev_dbg(dev->class_dev, "gsc_hpdi\n");
+	dev->board_ptr = hpdi_find_board(pcidev);
+	if (!dev->board_ptr) {
+		dev_err(dev->class_dev, "gsc_hpdi: pci %s not supported\n",
+			pci_name(pcidev));
+		return -EINVAL;
+	}
 
 	devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
 	if (!devpriv)
 		return -ENOMEM;
 	dev->private = devpriv;
-
-	pcidev = NULL;
-	for (i = 0; i < ARRAY_SIZE(hpdi_boards) &&
-		    dev->board_ptr == NULL; i++) {
-		do {
-			pcidev = pci_get_subsys(PCI_VENDOR_ID_PLX,
-						hpdi_boards[i].device_id,
-						PCI_VENDOR_ID_PLX,
-						hpdi_boards[i].subdevice_id,
-						pcidev);
-			/*  was a particular bus/slot requested? */
-			if (it->options[0] || it->options[1]) {
-				/*  are we on the wrong bus/slot? */
-				if (pcidev->bus->number != it->options[0] ||
-				    PCI_SLOT(pcidev->devfn) != it->options[1])
-					continue;
-			}
-			if (pcidev) {
-				devpriv->hw_dev = pcidev;
-				dev->board_ptr = hpdi_boards + i;
-				break;
-			}
-		} while (pcidev != NULL);
-	}
-	if (dev->board_ptr == NULL) {
-		dev_warn(dev->class_dev, "no hpdi card found\n");
-		return -EIO;
-	}
-
-	dev_warn(dev->class_dev,
-		 "found %s on bus %i, slot %i\n", board(dev)->name,
-		 pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+	devpriv->hw_dev = pcidev;
 
 	if (comedi_pci_enable(pcidev, dev->driver->driver_name)) {
 		dev_warn(dev->class_dev,
@@ -624,7 +610,6 @@ static void hpdi_detach(struct comedi_device *dev)
 				devpriv-> dma_desc_phys_addr);
 		if (devpriv->hpdi_phys_iobase)
 			comedi_pci_disable(devpriv->hw_dev);
-		pci_dev_put(devpriv->hw_dev);
 	}
 }
 
@@ -974,7 +959,7 @@ static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 static struct comedi_driver gsc_hpdi_driver = {
 	.driver_name	= "gsc_hpdi",
 	.module		= THIS_MODULE,
-	.attach		= hpdi_attach,
+	.auto_attach	= hpdi_auto_attach,
 	.detach		= hpdi_detach,
 };
 
-- 
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