staging: comedi: cb_pcidas64: use auto_attach method
authorIan Abbott <abbotti@mev.co.uk>
Fri, 2 Nov 2012 19:17:57 +0000 (19:17 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 6 Nov 2012 08:28:57 +0000 (09:28 +0100)
This driver does not need to support manual attachment of supported PCI
devices.  Replace the `attach()` hook with an `auto_attach()` hook.
This will be called via `comedi_pci_auto_config()` at PCI probe time.

The `auto_attach()` calls new function `cb_pcidas64_find_pci_board()` to
find the correct entry in `pcidas64_boards[]` for the PCI device.

This driver no longer increments the PCI reference count 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/cb_pcidas64.c

index 0ae7ef5856c616ebd46a9d0f4f48cd64b5351611..69db96ff3d559002d78d6cb5ca74724ba20098b7 100644 (file)
@@ -1645,57 +1645,38 @@ static inline void warn_external_queue(struct comedi_device *dev)
                     "Use internal AI channel queue (channels must be consecutive and use same range/aref)");
 }
 
-static struct pci_dev *cb_pcidas64_find_pci_dev(struct comedi_device *dev,
-                                               struct comedi_devconfig *it)
+static const struct pcidas64_board
+*cb_pcidas64_find_pci_board(struct pci_dev *pcidev)
 {
-       struct pci_dev *pcidev = NULL;
-       int bus = it->options[0];
-       int slot = it->options[1];
-       int i;
+       unsigned int i;
 
-       for_each_pci_dev(pcidev) {
-               if (bus || slot) {
-                       if (bus != pcidev->bus->number ||
-                           slot != PCI_SLOT(pcidev->devfn))
-                               continue;
-               }
-               if (pcidev->vendor != PCI_VENDOR_ID_CB)
-                       continue;
-
-               for (i = 0; i < ARRAY_SIZE(pcidas64_boards); i++) {
-                       if (pcidas64_boards[i].device_id != pcidev->device)
-                               continue;
-                       dev->board_ptr = pcidas64_boards + i;
-                       return pcidev;
-               }
-       }
-       dev_err(dev->class_dev,
-               "No supported board found! (req. bus %d, slot %d)\n",
-               bus, slot);
+       for (i = 0; i < ARRAY_SIZE(pcidas64_boards); i++)
+               if (pcidev->device == pcidas64_boards[i].device_id)
+                       return &pcidas64_boards[i];
        return NULL;
 }
 
-/*
- * Attach is called by the Comedi core to configure the driver
- * for a particular board.
- */
-static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int __devinit auto_attach(struct comedi_device *dev,
+                                unsigned long context_unused)
 {
        struct pcidas64_private *devpriv;
-       struct pci_dev *pcidev;
+       struct pci_dev *pcidev = comedi_to_pci_dev(dev);
        uint32_t local_range, local_decode;
        int retval;
 
+       dev->board_ptr = cb_pcidas64_find_pci_board(pcidev);
+       if (!dev->board_ptr) {
+               dev_err(dev->class_dev,
+                       "cb_pcidas64: does not support pci %s\n",
+                       pci_name(pcidev));
+               return -EINVAL;
+       }
+
        devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
        if (!devpriv)
                return -ENOMEM;
        dev->private = devpriv;
 
-       pcidev = cb_pcidas64_find_pci_dev(dev, it);
-       if (!pcidev)
-               return -EIO;
-       comedi_set_hw_dev(dev, &pcidev->dev);
-
        if (comedi_pci_enable(pcidev, dev->driver->driver_name)) {
                dev_warn(dev->class_dev,
                         "failed to enable PCI device and request regions\n");
@@ -1838,8 +1819,6 @@ static void detach(struct comedi_device *dev)
        if (pcidev) {
                if (dev->iobase)
                        comedi_pci_disable(pcidev);
-
-               pci_dev_put(pcidev);
        }
 }
 
@@ -4240,7 +4219,7 @@ static void i2c_write(struct comedi_device *dev, unsigned int address,
 static struct comedi_driver cb_pcidas64_driver = {
        .driver_name    = "cb_pcidas64",
        .module         = THIS_MODULE,
-       .attach         = attach,
+       .auto_attach    = auto_attach,
        .detach         = detach,
 };