staging: comedi: amplc_pci224: use attach_pci() hook
authorIan Abbott <abbotti@mev.co.uk>
Fri, 30 Mar 2012 16:15:04 +0000 (17:15 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Apr 2012 18:23:18 +0000 (11:23 -0700)
Change the amplc_pci224 driver to use the new attach_pci() hook in
struct comedi_driver to auto-configure probed PCI devices.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/amplc_pci224.c

index 0f2cac2..fe65338 100644 (file)
@@ -430,11 +430,14 @@ struct pci224_private {
 static int pci224_attach(struct comedi_device *dev,
                         struct comedi_devconfig *it);
 static int pci224_detach(struct comedi_device *dev);
+static int pci224_attach_pci(struct comedi_device *dev,
+                            struct pci_dev *pci_dev);
 static struct comedi_driver driver_amplc_pci224 = {
        .driver_name = DRIVER_NAME,
        .module = THIS_MODULE,
        .attach = pci224_attach,
        .detach = pci224_detach,
+       .attach_pci = pci224_attach_pci,
        .board_name = &pci224_boards[0].name,
        .offset = sizeof(struct pci224_board),
        .num_names = ARRAY_SIZE(pci224_boards),
@@ -1312,6 +1315,20 @@ static irqreturn_t pci224_interrupt(int irq, void *d)
 }
 
 /*
+ * This function looks for a board matching the supplied PCI device.
+ */
+static const struct pci224_board
+*pci224_find_pci_board(struct pci_dev *pci_dev)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(pci224_boards); i++)
+               if (pci_dev->device == pci224_boards[i].devid)
+                       return &pci224_boards[i];
+       return NULL;
+}
+
+/*
  * This function looks for a PCI device matching the requested board name,
  * bus and slot.
  */
@@ -1336,17 +1353,12 @@ pci224_find_pci(struct comedi_device *dev, int bus, int slot,
                }
                if (thisboard->model == any_model) {
                        /* Match any supported model. */
-                       int i;
-
-                       for (i = 0; i < ARRAY_SIZE(pci224_boards); i++) {
-                               if (pci_dev->device == pci224_boards[i].devid) {
-                                       /* Change board_ptr to matched board. */
-                                       dev->board_ptr = &pci224_boards[i];
-                                       break;
-                               }
-                       }
-                       if (i == ARRAY_SIZE(pci224_boards))
+                       const struct pci224_board *board_ptr;
+                       board_ptr = pci224_find_pci_board(pci_dev);
+                       if (board_ptr == NULL)
                                continue;
+                       /* Change board_ptr to matched board. */
+                       dev->board_ptr = board_ptr;
                } else {
                        /* Match specific model name. */
                        if (thisboard->devid != pci_dev->device)
@@ -1370,35 +1382,16 @@ pci224_find_pci(struct comedi_device *dev, int bus, int slot,
 }
 
 /*
- * Attach is called by the Comedi core to configure the driver
- * for a particular board.  If you specified a board_name array
- * in the driver structure, dev->board_ptr contains that
- * address.
+ * Common part of attach and attach_pci.
  */
-static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+static int pci224_attach_common(struct comedi_device *dev,
+                               struct pci_dev *pci_dev, int *options)
 {
        struct comedi_subdevice *s;
-       struct pci_dev *pci_dev;
        unsigned int irq;
-       int bus = 0, slot = 0;
        unsigned n;
        int ret;
 
-       printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, DRIVER_NAME);
-
-       bus = it->options[0];
-       slot = it->options[1];
-       ret = alloc_private(dev, sizeof(struct pci224_private));
-       if (ret < 0) {
-               printk(KERN_ERR "comedi%d: error! out of memory!\n",
-                      dev->minor);
-               return ret;
-       }
-
-       ret = pci224_find_pci(dev, bus, slot, &pci_dev);
-       if (ret < 0)
-               return ret;
-
        devpriv->pci_dev = pci_dev;
        ret = comedi_pci_enable(pci_dev, DRIVER_NAME);
        if (ret < 0) {
@@ -1483,24 +1476,26 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                if (!s->range_table_list)
                        return -ENOMEM;
 
-               for (n = 2; n < 3 + s->n_chan; n++) {
-                       if (it->options[n] < 0 || it->options[n] > 1) {
-                               printk(KERN_WARNING "comedi%d: %s: warning! "
-                                      "bad options[%u]=%d\n",
-                                      dev->minor, DRIVER_NAME, n,
-                                      it->options[n]);
+               if (options) {
+                       for (n = 2; n < 3 + s->n_chan; n++) {
+                               if (options[n] < 0 || options[n] > 1) {
+                                       printk(KERN_WARNING
+                                              "comedi%d: %s: warning! bad options[%u]=%d\n",
+                                              dev->minor, DRIVER_NAME, n,
+                                              options[n]);
+                               }
                        }
                }
                for (n = 0; n < s->n_chan; n++) {
-                       if (n < COMEDI_NDEVCONFOPTS - 3 &&
-                           it->options[3 + n] == 1) {
-                               if (it->options[2] == 1)
+                       if (n < COMEDI_NDEVCONFOPTS - 3 && options &&
+                           options[3 + n] == 1) {
+                               if (options[2] == 1)
                                        range_table_list[n] = &range_pci234_ext;
                                else
                                        range_table_list[n] = &range_bipolar5;
 
                        } else {
-                               if (it->options[2] == 1) {
+                               if (options && options[2] == 1) {
                                        range_table_list[n] =
                                            &range_pci234_ext2;
                                } else {
@@ -1511,14 +1506,14 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
                devpriv->hwrange = hwrange_pci234;
        } else {
                /* PCI224 range options. */
-               if (it->options[2] == 1) {
+               if (options && options[2] == 1) {
                        s->range_table = &range_pci224_external;
                        devpriv->hwrange = hwrange_pci224_external;
                } else {
-                       if (it->options[2] != 0) {
+                       if (options && options[2] != 0) {
                                printk(KERN_WARNING "comedi%d: %s: warning! "
                                       "bad options[2]=%d\n",
-                                      dev->minor, DRIVER_NAME, it->options[2]);
+                                      dev->minor, DRIVER_NAME, options[2]);
                        }
                        s->range_table = &range_pci224_internal;
                        devpriv->hwrange = hwrange_pci224_internal;
@@ -1553,6 +1548,66 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 }
 
 /*
+ * _attach is called by the Comedi core to configure the driver
+ * for a particular board.  If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it)
+{
+       struct pci_dev *pci_dev;
+       int bus, slot;
+       int ret;
+
+       printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, DRIVER_NAME);
+
+       bus = it->options[0];
+       slot = it->options[1];
+       ret = alloc_private(dev, sizeof(struct pci224_private));
+       if (ret < 0) {
+               printk(KERN_ERR "comedi%d: error! out of memory!\n",
+                      dev->minor);
+               return ret;
+       }
+
+       ret = pci224_find_pci(dev, bus, slot, &pci_dev);
+       if (ret < 0)
+               return ret;
+
+       return pci224_attach_common(dev, pci_dev, it->options);
+}
+
+/*
+ * _attach_pci is called by comedi_pci_auto_config() in the Comedi core
+ * to configure a comedi device for a probed PCI device.
+ * dev->board_ptr is NULL on entry.
+ */
+static int
+pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev)
+{
+       int ret;
+
+       printk(KERN_DEBUG "comedi%d: %s: attach_pci %s\n", dev->minor,
+              DRIVER_NAME, pci_name(pci_dev));
+
+       ret = alloc_private(dev, sizeof(struct pci224_private));
+       if (ret < 0) {
+               printk(KERN_ERR "comedi%d: error! out of memory!\n",
+                      dev->minor);
+               return ret;
+       }
+
+       dev->board_ptr = pci224_find_pci_board(pci_dev);
+       if (dev->board_ptr == NULL) {
+               printk(KERN_ERR
+                      "comedi%d: %s: BUG! cannot determine board type!\n",
+                      dev->minor, DRIVER_NAME);
+               return -EINVAL;
+       }
+       return pci224_attach_common(dev, pci_dev, NULL);
+}
+
+/*
  * _detach is called to deconfigure a device.  It should deallocate
  * resources.
  * This function is also called when _attach() fails, so it should be