staging: comedi: gsc_hpdi: use auto_attach method
authorIan Abbott <abbotti@mev.co.uk>
Thu, 1 Nov 2012 16:28:27 +0000 (16:28 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 1 Nov 2012 19:33:22 +0000 (12:33 -0700)
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@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/gsc_hpdi.c

index 48092958d73bccc71850c72f8995668821933e37..f468c1efab9063922446baca2bcf86d26747aaf3 100644 (file)
@@ -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,
 };