Implement the attach_pci() hook. This is called by comedi_pci_auto_config() in preference to the old attach() hook and avoids searching for the probed PCI device. Factor out some common code used by both the attach() and attach_pci() hooks into a couple of new functions, das08_pci_attach_common() and das08_find_pci_board(). Signed-off-by: Ian Abbott <abbotti@xxxxxxxxx> --- drivers/staging/comedi/drivers/das08.c | 114 +++++++++++++++++++++---------- 1 files changed, 77 insertions(+), 37 deletions(-) diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 7ec18a8..b84cc00 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -978,6 +978,74 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) EXPORT_SYMBOL_GPL(das08_common_attach); #if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) +static int das08_pci_attach_common(struct comedi_device *dev, + struct pci_dev *pdev) +{ + unsigned long iobase; + unsigned long pci_iobase; + struct das08_private_struct *devpriv = dev->private; + + devpriv->pdev = pdev; + /* enable PCI device and reserve I/O spaces */ + if (comedi_pci_enable(pdev, dev->driver->driver_name)) { + dev_err(dev->class_dev, + "Error enabling PCI device and requesting regions\n"); + return -EIO; + } + /* read base addresses */ + pci_iobase = pci_resource_start(pdev, 1); + iobase = pci_resource_start(pdev, 2); + dev_info(dev->class_dev, "pcibase 0x%lx iobase 0x%lx\n", + pci_iobase, iobase); + devpriv->pci_iobase = pci_iobase; +#if 0 + /* We could enable pci-das08's interrupt here to make it possible + * to do timed input in this driver, but there is little point since + * conversions would have to be started by the interrupt handler + * so you might as well use comedi_rt_timer to emulate commands + */ + /* set source of interrupt trigger to counter2 output */ + outb(CNTRL_INTR | CNTRL_DIR, pci_iobase + CNTRL); + /* Enable local interrupt 1 and pci interrupt */ + outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR); +#endif + return das08_common_attach(dev, iobase); +} +#endif + +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) +static const struct das08_board_struct +*das08_find_pci_board(struct pci_dev *pdev) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(das08_boards); i++) + if (das08_boards[i].bustype == pci && + pdev->device == das08_boards[i].id) + return &das08_boards[i]; + return NULL; +} +#endif + +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) +/* only called in the PCI probe path, via comedi_pci_auto_config() */ +static int __devinit das08_attach_pci(struct comedi_device *dev, + struct pci_dev *pdev) +{ + int ret; + ret = alloc_private(dev, sizeof(struct das08_private_struct)); + if (ret < 0) + return ret; + dev_info(dev->class_dev, "attach pci %s\n", pci_name(pdev)); + dev->board_ptr = das08_find_pci_board(pdev); + if (dev->board_ptr == NULL) { + dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); + return -EINVAL; + } + return das08_pci_attach_common(dev, pdev); +} +#endif + +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) static int das08_find_pci(struct comedi_device *dev, int bus, int slot, struct pci_dev **pci_dev_p) { @@ -995,19 +1063,12 @@ static int das08_find_pci(struct comedi_device *dev, int bus, int slot, continue; if (thisboard->id == PCI_ANY_ID) { /* wildcard board matches any supported PCI board */ - unsigned int i; - for (i = 0; i < ARRAY_SIZE(das08_boards); i++) { - if (das08_boards[i].bustype != pci) - continue; - if (pdev->device == das08_boards[i].id) { - /* replace wildcard board_ptr */ - dev->board_ptr = &das08_boards[i]; - thisboard = comedi_board(dev); - break; - } - } - if (i == ARRAY_SIZE(das08_boards)) + const struct das08_board_struct *foundboard = + das08_find_pci_board(pdev); + if (foundboard == NULL) continue; + /* replace wildcard board_ptr */ + dev->board_ptr = thisboard = foundboard; } else { /* match specific PCI board */ if (pdev->device != thisboard->id) @@ -1034,7 +1095,6 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) int ret; unsigned long iobase; #if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) - unsigned long pci_iobase = 0; struct pci_dev *pdev = NULL; #endif const struct das08_board_struct *thisboard = comedi_board(dev); @@ -1059,30 +1119,7 @@ static int das08_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (ret < 0) return ret; thisboard = comedi_board(dev); /* replaced wildcard board */ - devpriv->pdev = pdev; - /* enable PCI device and reserve I/O spaces */ - if (comedi_pci_enable(pdev, dev->driver->driver_name)) { - dev_err(dev->class_dev, - "Error enabling PCI device and requesting regions\n"); - return -EIO; - } - /* read base addresses */ - pci_iobase = pci_resource_start(pdev, 1); - iobase = pci_resource_start(pdev, 2); - dev_info(dev->class_dev, "pcibase 0x%lx iobase 0x%lx\n", - pci_iobase, iobase); - devpriv->pci_iobase = pci_iobase; -#if 0 -/* We could enable to pci-das08's interrupt here to make it possible - * to do timed input in this driver, but there is little point since - * conversions would have to be started by the interrupt handler - * so you might as well use comedi_rt_timer to emulate commands - */ - /* set source of interrupt trigger to counter2 output */ - outb(CNTRL_INTR | CNTRL_DIR, pci_iobase + CNTRL); - /* Enable local interrupt 1 and pci interrupt */ - outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR); -#endif + return das08_pci_attach_common(dev, pdev); break; #endif /* IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) */ default: @@ -1134,6 +1171,9 @@ static struct comedi_driver das08_driver = { .driver_name = DRV_NAME, .module = THIS_MODULE, .attach = das08_attach, +#if IS_ENABLED(CONFIG_COMEDI_DAS08_PCI) + .attach_pci = das08_attach_pci, +#endif .detach = das08_common_detach, .board_name = &das08_boards[0].name, .num_names = sizeof(das08_boards) / sizeof(struct das08_board_struct), -- 1.7.8.6 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/devel