From f38fbafe93ca78aa49e7da1c19ca85e3006e2f7f Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Sun, 11 Jun 2006 23:33:28 +0000 Subject: [PATCH] More pci fixes. --- comedi/drivers/adl_pci6208.c | 6 +- comedi/drivers/adl_pci7432.c | 4 +- comedi/drivers/adl_pci8164.c | 4 +- comedi/drivers/adl_pci9111.c | 66 +++++++-------- comedi/drivers/adv_pci_dio.c | 20 ++--- comedi/drivers/amplc_dio200.c | 24 +++--- comedi/drivers/amplc_pc236.c | 32 +++---- comedi/drivers/amplc_pc263.c | 31 +++---- comedi/drivers/amplc_pci224.c | 31 +++---- comedi/drivers/amplc_pci230.c | 24 +++--- comedi/drivers/cb_pcidas.c | 12 +-- comedi/drivers/cb_pcidas64.c | 12 +-- comedi/drivers/cb_pcidda.c | 36 +++----- comedi/drivers/cb_pcimdas.c | 11 +-- comedi/drivers/cb_pcimdda.c | 39 ++++----- comedi/drivers/contec_pci_dio.c | 9 +- comedi/drivers/daqboard2000.c | 146 ++++++++++++++++---------------- comedi/drivers/das08.c | 11 +-- comedi/drivers/dt3000.c | 5 +- comedi/drivers/gsc_hpdi.c | 12 +-- comedi/drivers/ke_counter.c | 38 ++++----- comedi/drivers/me4000.c | 113 ++++++++++++------------ comedi/drivers/me_daq.c | 70 ++++++--------- comedi/drivers/rtd520.c | 91 +++++++++----------- comedi/drivers/s626.c | 86 +++++++++---------- 25 files changed, 425 insertions(+), 508 deletions(-) diff --git a/comedi/drivers/adl_pci6208.c b/comedi/drivers/adl_pci6208.c index b44700a7..ba577e89 100644 --- a/comedi/drivers/adl_pci6208.c +++ b/comedi/drivers/adl_pci6208.c @@ -100,7 +100,6 @@ MODULE_DEVICE_TABLE(pci, pci6208_pci_table); typedef struct{ int data; struct pci_dev *pci_dev; /* for a PCI device */ - int pci_setup; /* non-zero in PCI set up okay */ lsampl_t ao_readback[2]; /* Used for AO readback */ }pci6208_private; @@ -157,9 +156,6 @@ static int pci6208_attach(comedi_device *dev,comedi_devconfig *it) retval = pci6208_pci_setup(devpriv->pci_dev, &io_base, dev->minor); if (retval < 0) return retval; - // Allow resources to be freed and PCI device to be disabled. - devpriv->pci_setup = 1; - dev->iobase=io_base; dev->board_name = thisboard->name; @@ -209,7 +205,7 @@ static int pci6208_detach(comedi_device *dev) printk("comedi%d: pci6208: remove\n",dev->minor); if(devpriv && devpriv->pci_dev){ - if (devpriv->pci_setup) { + if(dev->iobase) { pci_release_regions(devpriv->pci_dev); pci_disable_device(devpriv->pci_dev); } diff --git a/comedi/drivers/adl_pci7432.c b/comedi/drivers/adl_pci7432.c index aa3ff86a..7b9dea21 100644 --- a/comedi/drivers/adl_pci7432.c +++ b/comedi/drivers/adl_pci7432.c @@ -60,7 +60,6 @@ MODULE_DEVICE_TABLE(pci, adl_pci7432_pci_table); typedef struct{ int data; struct pci_dev *pci_dev; - int pci_setup; } adl_pci7432_private; #define devpriv ((adl_pci7432_private *)dev->private) @@ -118,7 +117,6 @@ static int adl_pci7432_attach(comedi_device *dev,comedi_devconfig *it) printk("comedi%d: I/O port conflict\n", dev->minor); return -EIO; } - devpriv->pci_setup = 1; /* Allow resources to be freed on detach */ dev->iobase = pci_resource_start ( pcidev, 2 ); printk ( "comedi: base addr %4lx\n", dev->iobase ); @@ -159,7 +157,7 @@ static int adl_pci7432_detach(comedi_device *dev) printk("comedi%d: pci7432: remove\n",dev->minor); if (devpriv && devpriv->pci_dev) { - if (devpriv->pci_setup) { + if (dev->iobase) { pci_release_regions(devpriv->pci_dev); pci_disable_device(devpriv->pci_dev); } diff --git a/comedi/drivers/adl_pci8164.c b/comedi/drivers/adl_pci8164.c index a614e26d..e764c2b8 100644 --- a/comedi/drivers/adl_pci8164.c +++ b/comedi/drivers/adl_pci8164.c @@ -72,7 +72,6 @@ MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table); typedef struct{ int data; struct pci_dev *pci_dev; - int pci_setup; } adl_pci8164_private; #define devpriv ((adl_pci8164_private *)dev->private) @@ -136,7 +135,6 @@ static int adl_pci8164_attach(comedi_device *dev,comedi_devconfig *it) printk("comedi%d: I/O port conflict\n", dev->minor); return -EIO; } - devpriv->pci_setup = 1; /* Allow resources to be freed on detach */ dev->iobase = pci_resource_start ( pcidev, 2 ); printk ( "comedi: base addr %4lx\n", dev->iobase ); @@ -197,7 +195,7 @@ static int adl_pci8164_detach(comedi_device *dev) printk("comedi%d: pci8164: remove\n",dev->minor); if (devpriv && devpriv->pci_dev) { - if (devpriv->pci_setup) { + if (dev->iobase) { pci_release_regions(devpriv->pci_dev); pci_disable_device(devpriv->pci_dev); } diff --git a/comedi/drivers/adl_pci9111.c b/comedi/drivers/adl_pci9111.c index 7731575a..cb07eaff 100644 --- a/comedi/drivers/adl_pci9111.c +++ b/comedi/drivers/adl_pci9111.c @@ -1262,6 +1262,10 @@ static int pci9111_attach(comedi_device *dev,comedi_devconfig *it) int error,i; pci9111_board_struct* board; + if(alloc_private(dev, sizeof(pci9111_private_data_struct)) < 0) + { + return -ENOMEM; + } // // Probe the device to determine what device in the series it is. // @@ -1290,6 +1294,7 @@ static int pci9111_attach(comedi_device *dev,comedi_devconfig *it) dev->board_ptr = pci9111_boards + i; board = (pci9111_board_struct *) dev->board_ptr; + dev_private->pci_device = pci_device; goto found; } } @@ -1330,7 +1335,6 @@ found: if(pci_enable_device (pci_device) < 0) { printk("comedi%d: Failed to enable PCI device\n", dev->minor); - pci_dev_put(pci_device); return -EIO; } @@ -1348,22 +1352,11 @@ found: if(pci_request_regions(pci_device, PCI9111_DRIVER_NAME)) { printk("comedi%d: I/O port conflict\n",dev->minor); - pci_dev_put(pci_device); return -EIO; } dev->iobase=io_base; dev->board_name = board->name; - - if(alloc_private(dev,sizeof(pci9111_private_data_struct))<0) - { - pci_release_regions(pci_device); - pci_disable_device(pci_device); - pci_dev_put(pci_device); - return -ENOMEM; - } - - dev_private->pci_device = pci_device; dev_private->io_range = io_range; dev_private->is_valid=0; dev_private->lcr_io_base=lcr_io_base; @@ -1456,29 +1449,32 @@ found: static int pci9111_detach(comedi_device *dev) { - // Reset device - - if (dev->private!=0) - { - if (dev_private->is_valid) pci9111_reset(dev); - - } - - // Release previously allocated irq - - if (dev->irq!=0) - { - comedi_free_irq(dev->irq,dev); - } - - if (dev_private!=0 && dev_private->pci_device!=0) - { - pci_release_regions(dev_private->pci_device); - pci_disable_device(dev_private->pci_device); - pci_dev_put(dev_private->pci_device); - } - - return 0; + // Reset device + + if (dev->private!=0) + { + if (dev_private->is_valid) pci9111_reset(dev); + + } + + // Release previously allocated irq + + if (dev->irq!=0) + { + comedi_free_irq(dev->irq,dev); + } + + if (dev_private!=0 && dev_private->pci_device!=0) + { + if(dev->iobase) + { + pci_release_regions(dev_private->pci_device); + pci_disable_device(dev_private->pci_device); + } + pci_dev_put(dev_private->pci_device); + } + + return 0; } diff --git a/comedi/drivers/adv_pci_dio.c b/comedi/drivers/adv_pci_dio.c index 7f72948a..15ab391b 100644 --- a/comedi/drivers/adv_pci_dio.c +++ b/comedi/drivers/adv_pci_dio.c @@ -330,7 +330,6 @@ struct pci_dio_private_st { pci_dio_private *next; // next private struct struct pci_dev *pcidev; // pointer to board's pci_dev char valid; // card is usable - char enabled; // PCI card is enabled char GlobalIrqEnabled;// 1= any IRQ source is enabled // PCI-1760 specific data unsigned char IDICntEnable; // counter's counting enable status @@ -915,9 +914,7 @@ static int pci_dio_attach(comedi_device *dev, comedi_devconfig *it) if (pci_request_regions(pcidev, driver_pci_dio.driver_name)) { rt_printk(", Error: Can't allocate PCI device!\n"); return -EIO; - } - devpriv->enabled=1; - + } iobase=pci_resource_start(pcidev, this_board->main_pci_region); rt_printk(", b:s:f=%d:%d:%d, io=0x%4x", pcidev->bus->number, PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->devfn), @@ -1027,9 +1024,12 @@ static int pci_dio_detach(comedi_device *dev) s->private=NULL; } - if (devpriv->enabled) { - pci_release_regions(devpriv->pcidev); - pci_disable_device(devpriv->pcidev); + if (devpriv->pcidev) { + if (dev->iobase) { + pci_release_regions(devpriv->pcidev); + pci_disable_device(devpriv->pcidev); + } + pci_dev_put(devpriv->pcidev); } if (devpriv->prev) { @@ -1040,11 +1040,7 @@ static int pci_dio_detach(comedi_device *dev) if (devpriv->next) { devpriv->next->prev=devpriv->prev; } - - if (devpriv->pcidev) { - pci_dev_put(devpriv->pcidev); - } - } + } return 0; } diff --git a/comedi/drivers/amplc_dio200.c b/comedi/drivers/amplc_dio200.c index 4005fc06..3f4b8fe5 100644 --- a/comedi/drivers/amplc_dio200.c +++ b/comedi/drivers/amplc_dio200.c @@ -1198,6 +1198,11 @@ dio200_attach(comedi_device *dev,comedi_devconfig *it) printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, DIO200_DRIVER_NAME); + if ((ret=alloc_private(dev,sizeof(dio200_private))) < 0) { + printk(KERN_ERR "comedi%d: error! out of memory!\n", dev->minor); + return ret; + } + /* Process options. */ switch (thisboard->bustype) { case isa_bustype: @@ -1212,6 +1217,7 @@ dio200_attach(comedi_device *dev,comedi_devconfig *it) if ((ret=dio200_find_pci(dev, bus, slot, &pci_dev)) < 0) return ret; + devpriv->pci_dev = pci_dev; break; default: printk(KERN_ERR "comedi%d: %s: BUG! cannot determine board type!\n", @@ -1220,14 +1226,6 @@ dio200_attach(comedi_device *dev,comedi_devconfig *it) break; } - if ((ret=alloc_private(dev,sizeof(dio200_private))) < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", dev->minor); - if (pci_dev) { - pci_dev_put(pci_dev); - } - return ret; - } - devpriv->intr_sd = -1; /* Enable device and reserve I/O spaces. */ @@ -1236,7 +1234,6 @@ dio200_attach(comedi_device *dev,comedi_devconfig *it) if (ret < 0) { printk(KERN_ERR "comedi%d: error! cannot enable PCI device!\n", dev->minor); - pci_dev_put(pci_dev); return ret; } iobase = pci_resource_start(pci_dev, 2); @@ -1245,10 +1242,8 @@ dio200_attach(comedi_device *dev,comedi_devconfig *it) if (ret < 0) { printk(KERN_ERR "comedi%d: I/O port conflict (PCI)!\n", dev->minor); - pci_dev_put(pci_dev); return ret; } - devpriv->pci_dev = pci_dev; } else { ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE); if (ret < 0) { @@ -1383,8 +1378,11 @@ dio200_detach(comedi_device *dev) } if (devpriv) { if (devpriv->pci_dev) { - pci_release_regions(devpriv->pci_dev); - pci_disable_device(devpriv->pci_dev); + if(dev->iobase) + { + pci_release_regions(devpriv->pci_dev); + pci_disable_device(devpriv->pci_dev); + } pci_dev_put(devpriv->pci_dev); } else if (dev->iobase) { release_region(dev->iobase, DIO200_IO_SIZE); diff --git a/comedi/drivers/amplc_pc236.c b/comedi/drivers/amplc_pc236.c index 15678535..398766a8 100644 --- a/comedi/drivers/amplc_pc236.c +++ b/comedi/drivers/amplc_pc236.c @@ -172,7 +172,14 @@ static int pc236_attach(comedi_device *dev,comedi_devconfig *it) int ret; printk("comedi%d: %s: ",dev->minor, PC236_DRIVER_NAME); - +/* + * Allocate the private structure area. alloc_private() is a + * convenient macro defined in comedidev.h. + */ + if ((ret=alloc_private(dev,sizeof(pc236_private))) < 0) { + printk("out of memory!\n"); + return ret; + } /* Process options. */ switch (thisboard->bustype) { case isa_bustype: @@ -219,6 +226,7 @@ static int pc236_attach(comedi_device *dev,comedi_devconfig *it) if (((pci_dev->class ^ pci_id->class) & pci_id->class_mask) != 0) continue; /* Found a match. */ + devpriv->pci_dev = pci_dev; break; } if (!pci_dev) { @@ -238,30 +246,16 @@ static int pc236_attach(comedi_device *dev,comedi_devconfig *it) dev->board_name = thisboard->name; printk("%s ", dev->board_name); -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if ((ret=alloc_private(dev,sizeof(pc236_private))) < 0) { - printk("out of memory!\n"); - if (pci_dev) - pci_dev_put(pci_dev); - return ret; - } - /* Enable device and reserve I/O spaces. */ if (pci_dev) { if ((ret=pci_enable_device(pci_dev)) < 0) { printk("error enabling PCI device!\n"); - pci_dev_put(pci_dev); return ret; } if ((ret=pci_request_regions(pci_dev, PC236_DRIVER_NAME)) < 0) { printk("I/O port conflict (PCI)!\n"); - pci_dev_put(pci_dev); return ret; } - devpriv->pci_dev = pci_dev; devpriv->lcr_iobase = pci_resource_start(pci_dev, 1); iobase = pci_resource_start(pci_dev, 2); irq = pci_dev->irq; @@ -347,14 +341,16 @@ static int pc236_detach(comedi_device *dev) } if (devpriv) { if (devpriv->pci_dev) { - pci_release_regions(devpriv->pci_dev); - pci_disable_device(devpriv->pci_dev); + if(dev->iobase) + { + pci_release_regions(devpriv->pci_dev); + pci_disable_device(devpriv->pci_dev); + } pci_dev_put(devpriv->pci_dev); } else if (dev->iobase) { release_region(dev->iobase, PC236_IO_SIZE); } } - return 0; } diff --git a/comedi/drivers/amplc_pc263.c b/comedi/drivers/amplc_pc263.c index 1aa4bc5a..82bb27a8 100644 --- a/comedi/drivers/amplc_pc263.c +++ b/comedi/drivers/amplc_pc263.c @@ -148,7 +148,14 @@ static int pc263_attach(comedi_device *dev,comedi_devconfig *it) int ret; printk("comedi%d: %s: ",dev->minor, PC263_DRIVER_NAME); - +/* + * Allocate the private structure area. alloc_private() is a + * convenient macro defined in comedidev.h. + */ + if ((ret=alloc_private(dev,sizeof(pc263_private))) < 0) { + printk("out of memory!\n"); + return ret; + } /* Process options. */ switch (thisboard->bustype) { case isa_bustype: @@ -192,6 +199,7 @@ static int pc263_attach(comedi_device *dev,comedi_devconfig *it) if (((pci_dev->class ^ pci_id->class) & pci_id->class_mask) != 0) continue; /* Found a match. */ + devpriv->pci_dev = pci_dev; break; } if (!pci_dev) { @@ -211,30 +219,16 @@ static int pc263_attach(comedi_device *dev,comedi_devconfig *it) dev->board_name = thisboard->name; printk("%s ", dev->board_name); -/* - * Allocate the private structure area. alloc_private() is a - * convenient macro defined in comedidev.h. - */ - if ((ret=alloc_private(dev,sizeof(pc263_private))) < 0) { - printk("out of memory!\n"); - if (pci_dev) - pci_dev_put(pci_dev); - return ret; - } - /* Enable device and reserve I/O spaces. */ if (pci_dev) { if ((ret=pci_enable_device(pci_dev)) < 0) { printk("error enabling PCI device!\n"); - pci_dev_put(pci_dev); return ret; } if ((ret=pci_request_regions(pci_dev, PC263_DRIVER_NAME)) < 0) { printk("I/O port conflict (PCI)!\n"); - pci_dev_put(pci_dev); return ret; } - devpriv->pci_dev = pci_dev; iobase = pci_resource_start(pci_dev, 2); } else { if ((ret=pc263_request_region(iobase, PC263_IO_SIZE)) < 0) { @@ -295,8 +289,11 @@ static int pc263_detach(comedi_device *dev) if (devpriv) { if (devpriv->pci_dev) { - pci_release_regions(devpriv->pci_dev); - pci_disable_device(devpriv->pci_dev); + if(dev->iobase) + { + pci_release_regions(devpriv->pci_dev); + pci_disable_device(devpriv->pci_dev); + } pci_dev_put(devpriv->pci_dev); } else if (dev->iobase) { release_region(dev->iobase, PC263_IO_SIZE); diff --git a/comedi/drivers/amplc_pci224.c b/comedi/drivers/amplc_pci224.c index c6377a35..01907854 100644 --- a/comedi/drivers/amplc_pci224.c +++ b/comedi/drivers/amplc_pci224.c @@ -1334,33 +1334,25 @@ pci224_attach(comedi_device *dev,comedi_devconfig *it) bus = it->options[0]; slot = it->options[1]; - + if ((ret=alloc_private(dev,sizeof(pci224_private))) < 0) { + printk(KERN_ERR "comedi%d: error! out of memory!\n", + dev->minor); + return ret; + } if ((ret=pci224_find_pci(dev, bus, slot, &pci_dev)) < 0) return ret; + devpriv->pci_dev = pci_dev; if ((ret=pci_enable_device(pci_dev)) < 0) { printk(KERN_ERR "comedi%d: error! cannot enable PCI device!\n", dev->minor); - pci_dev_put(pci_dev); return ret; } if (pci_request_regions(pci_dev, DRIVER_NAME)) { printk(KERN_ERR "comedi%d: error! cannot allocate PCI regions!\n", dev->minor); - pci_dev_put(pci_dev); return -EIO; } - - if ((ret=alloc_private(dev,sizeof(pci224_private))) < 0) { - printk(KERN_ERR "comedi%d: error! out of memory!\n", - dev->minor); - pci_release_regions(pci_dev); - pci_disable_device(pci_dev); - pci_dev_put(pci_dev); - return ret; - } - - devpriv->pci_dev = pci_dev; spin_lock_init(&devpriv->ao_spinlock); devpriv->iobase1 = pci_resource_start(pci_dev, 2); @@ -1400,14 +1392,14 @@ pci224_attach(comedi_device *dev,comedi_devconfig *it) PCI224_DACCON_FIFOENAB | PCI224_DACCON_FIFOINTR_EMPTY); outw(devpriv->daccon | PCI224_DACCON_FIFORESET, dev->iobase + PCI224_DACCON); - + /* Allocate subdevices. There is only one! */ if ((ret=alloc_subdevices(dev, 1)) < 0) { printk(KERN_ERR "comedi%d: error! out of memory!\n", dev->minor); return ret; } - + s = dev->subdevices + 0; /* Analog output subdevice. */ s->type = COMEDI_SUBD_AO; @@ -1545,8 +1537,11 @@ pci224_detach(comedi_device *dev) kfree(devpriv->ao_scan_order); } if (devpriv->pci_dev) { - pci_release_regions(devpriv->pci_dev); - pci_disable_device(devpriv->pci_dev); + if(dev->iobase) + { + pci_release_regions(devpriv->pci_dev); + pci_disable_device(devpriv->pci_dev); + } pci_dev_put(devpriv->pci_dev); } } diff --git a/comedi/drivers/amplc_pci230.c b/comedi/drivers/amplc_pci230.c index 6c59ea25..8e4b4305 100644 --- a/comedi/drivers/amplc_pci230.c +++ b/comedi/drivers/amplc_pci230.c @@ -337,6 +337,11 @@ static int pci230_attach(comedi_device *dev,comedi_devconfig *it) printk("comedi%d: amplc_pci230\n",dev->minor); + /* Allocate the private structure area using alloc_private(). + * Macro defined in comedidev.h - memsets struct fields to 0. */ + if((alloc_private(dev,sizeof(struct pci230_private)))<0){ + return -ENOMEM; + } /* Find card */ for(pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pci_dev != NULL ; pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) { @@ -353,11 +358,11 @@ static int pci230_attach(comedi_device *dev,comedi_devconfig *it) printk("comedi%d: amplc_pci230: No PCI230 found\n",dev->minor); return -EIO; } + devpriv->pci_dev = pci_dev; dev->board_ptr = pci230_boards+i; /* Read base addressses of the PCI230's two I/O regions from PCI configuration register. */ if(pci_enable_device(pci_dev)<0){ - pci_dev_put(pci_dev); return -EIO; } @@ -367,21 +372,11 @@ static int pci230_attach(comedi_device *dev,comedi_devconfig *it) /* Reserve I/O spaces. */ if(pci_request_regions(pci_dev,"PCI230")<0){ printk("comedi%d: amplc_pci230: I/O space conflict\n",dev->minor); - pci_dev_put(pci_dev); return -EIO; } printk("comedi%d: amplc_pci230: I/O region 1 0x%04x I/O region 2 0x%04x\n",dev->minor, pci_iobase, iobase); - /* Allocate the private structure area using alloc_private(). - * Macro defined in comedidev.h - memsets struct fields to 0. */ - if((alloc_private(dev,sizeof(struct pci230_private)))<0){ - pci_release_regions(pci_dev); - pci_disable_device(pci_dev); - pci_dev_put(pci_dev); - return -ENOMEM; - } - devpriv->pci_dev = pci_dev; devpriv->pci_iobase = pci_iobase; dev->iobase = iobase; @@ -490,8 +485,11 @@ static int pci230_detach(comedi_device *dev) if(devpriv){ if(devpriv->pci_dev){ - pci_release_regions(devpriv->pci_dev); - pci_disable_device(devpriv->pci_dev); + if(dev->iobase) + { + pci_release_regions(devpriv->pci_dev); + pci_disable_device(devpriv->pci_dev); + } pci_dev_put(devpriv->pci_dev); } } diff --git a/comedi/drivers/cb_pcidas.c b/comedi/drivers/cb_pcidas.c index d89ae308..0dd7c5b5 100644 --- a/comedi/drivers/cb_pcidas.c +++ b/comedi/drivers/cb_pcidas.c @@ -543,6 +543,7 @@ static int cb_pcidas_attach(comedi_device *dev, comedi_devconfig *it) continue; } } + devpriv->pci_dev = pcidev; dev->board_ptr = cb_pcidas_boards + index; goto found; } @@ -563,17 +564,13 @@ found: if(pci_enable_device(pcidev)) { printk(" Failed to enable PCI device\n"); - pci_dev_put(pcidev); return -EIO; } if(pci_request_regions(pcidev, "cb_pcidas")) { printk(" I/O port conflict\n"); - pci_dev_put(pcidev); return -EIO; } - devpriv->pci_dev = pcidev; - /* * Initialize devpriv->control_status and devpriv->adc_fifo to point to * their base address. @@ -743,8 +740,11 @@ static int cb_pcidas_detach(comedi_device *dev) subdev_8255_cleanup(dev,dev->subdevices + 2); if(devpriv && devpriv->pci_dev) { - pci_release_regions(devpriv->pci_dev); - pci_disable_device(devpriv->pci_dev); + if(devpriv->s5933_config) + { + pci_release_regions(devpriv->pci_dev); + pci_disable_device(devpriv->pci_dev); + } pci_dev_put(devpriv->pci_dev); } diff --git a/comedi/drivers/cb_pcidas64.c b/comedi/drivers/cb_pcidas64.c index 5c28fc9c..20de6ecb 100644 --- a/comedi/drivers/cb_pcidas64.c +++ b/comedi/drivers/cb_pcidas64.c @@ -1679,6 +1679,7 @@ static int attach(comedi_device *dev, comedi_devconfig *it) continue; } } + priv(dev)->hw_dev = pcidev; dev->board_ptr = pcidas64_boards + index; break; } @@ -1697,20 +1698,16 @@ static int attach(comedi_device *dev, comedi_devconfig *it) if( pci_enable_device( pcidev ) ) { printk(KERN_WARNING " failed to enable PCI device\n"); - pci_dev_put( pcidev ); return -EIO; } if( pci_request_regions( pcidev, driver_cb_pcidas.driver_name ) ) { /* Couldn't allocate io space */ printk(KERN_WARNING " failed to allocate io memory\n"); - pci_dev_put( pcidev ); return -EIO; } pci_set_master( pcidev ); - priv(dev)->hw_dev = pcidev; - //Initialize dev->board_name dev->board_name = board(dev)->name; @@ -1815,8 +1812,11 @@ static int detach(comedi_device *dev) if(priv(dev)->ao_dma_desc) pci_free_consistent(priv(dev)->hw_dev, sizeof(struct plx_dma_desc) * AO_DMA_RING_COUNT, priv(dev)->ao_dma_desc, priv(dev)->ao_dma_desc_bus_addr ); - pci_release_regions(priv(dev)->hw_dev); - pci_disable_device(priv(dev)->hw_dev); + if(priv(dev)->main_phys_iobase) + { + pci_release_regions(priv(dev)->hw_dev); + pci_disable_device(priv(dev)->hw_dev); + } pci_dev_put(priv(dev)->hw_dev); } } diff --git a/comedi/drivers/cb_pcidda.c b/comedi/drivers/cb_pcidda.c index d2c1f3d5..100d1054 100644 --- a/comedi/drivers/cb_pcidda.c +++ b/comedi/drivers/cb_pcidda.c @@ -288,32 +288,24 @@ static int cb_pcidda_attach(comedi_device *dev, comedi_devconfig *it) pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) { if(pcidev->vendor==PCI_VENDOR_ID_CB){ if(it->options[0] || it->options[1]){ - if(pcidev->bus->number==it->options[0] && - PCI_SLOT(pcidev->devfn)==it->options[1]){ - break; + if(pcidev->bus->number != it->options[0] || + PCI_SLOT(pcidev->devfn) != it->options[1]){ + continue; + } + } + for(index=0;indexdevice){ + goto found; } - }else{ - break; } } } - if(!pcidev){ printk("Not a ComputerBoards/MeasurementComputing card on requested position\n"); return -EIO; } - - for(index=0;indexdevice){ - goto found; - } - } - printk("Not a supported ComputerBoards/MeasurementComputing card on " - "requested position\n"); - pci_dev_put(pcidev); - return -EIO; - found: + devpriv->pci_dev = pcidev; dev->board_ptr = cb_pcidda_boards+index; // "thisboard" macro can be used from here. printk("Found %s at requested position\n",thisboard->name); @@ -325,7 +317,6 @@ found: if(pci_enable_device(pcidev)) { printk("cb_pcidda: failed to enable PCI device\n"); - pci_dev_put(pcidev); return -EIO; } @@ -335,10 +326,8 @@ found: if (pci_request_regions(pcidev, thisboard->name)) { printk("cb_pcidda: I/O port conflict\n"); - pci_dev_put(pcidev); return -EIO; } - devpriv->pci_dev = pcidev; devpriv->digitalio = pci_resource_start(devpriv->pci_dev, DIGITALIO_BADRINDEX); devpriv->dac = pci_resource_start(devpriv->pci_dev, DAC_BADRINDEX); @@ -412,8 +401,11 @@ static int cb_pcidda_detach(comedi_device *dev) { if(devpriv->pci_dev) { - pci_release_regions(devpriv->pci_dev); - pci_disable_device(devpriv->pci_dev); + if(devpriv->dac) + { + pci_release_regions(devpriv->pci_dev); + pci_disable_device(devpriv->pci_dev); + } pci_dev_put(devpriv->pci_dev); } } diff --git a/comedi/drivers/cb_pcimdas.c b/comedi/drivers/cb_pcimdas.c index 66c32347..16ee8575 100644 --- a/comedi/drivers/cb_pcimdas.c +++ b/comedi/drivers/cb_pcimdas.c @@ -235,6 +235,7 @@ static int cb_pcimdas_attach(comedi_device *dev,comedi_devconfig *it) continue; } } + devpriv->pci_dev = pcidev; dev->board_ptr = cb_pcimdas_boards + index; goto found; } @@ -262,16 +263,13 @@ found: if(pci_enable_device(pcidev)) { printk(" Failed to enable PCI device\n"); - pci_dev_put(pcidev); return -EIO; } if(pci_request_regions(pcidev, "cb_pcimdas")) { printk(" I/O port conflict\n"); - pci_dev_put(pcidev); return -EIO; } - devpriv->pci_dev = pcidev; devpriv->BADR0 = pci_resource_start(devpriv->pci_dev, 0); devpriv->BADR1 = pci_resource_start(devpriv->pci_dev, 1); @@ -372,8 +370,11 @@ static int cb_pcimdas_detach(comedi_device *dev) { if(devpriv->pci_dev) { - pci_release_regions(devpriv->pci_dev); - pci_disable_device(devpriv->pci_dev); + if(devpriv->BADR0) + { + pci_release_regions(devpriv->pci_dev); + pci_disable_device(devpriv->pci_dev); + } pci_dev_put(devpriv->pci_dev); } } diff --git a/comedi/drivers/cb_pcimdda.c b/comedi/drivers/cb_pcimdda.c index e6e2ac40..8734345f 100644 --- a/comedi/drivers/cb_pcimdda.c +++ b/comedi/drivers/cb_pcimdda.c @@ -334,29 +334,28 @@ static int attach(comedi_device *dev,comedi_devconfig *it) */ static int detach(comedi_device *dev) { - if (devpriv) { + if (devpriv) { - if (devpriv->registers && thisboard) { - devpriv->registers = 0; - } + if (dev->subdevices && devpriv->attached_to_8255) { + /* de-register us from the 8255 driver */ + subdev_8255_cleanup(dev,dev->subdevices + 2); + devpriv->attached_to_8255 = 0; + } - if (dev->subdevices && devpriv->attached_to_8255) { - /* de-register us from the 8255 driver */ - subdev_8255_cleanup(dev,dev->subdevices + 2); - devpriv->attached_to_8255 = 0; - } + if (devpriv->pci_dev) { + if(devpriv->registers) + { + pci_release_regions(devpriv->pci_dev); + pci_disable_device(devpriv->pci_dev); + } + pci_dev_put(devpriv->pci_dev); + } - if (devpriv->pci_dev) { - pci_release_regions(devpriv->pci_dev); - pci_disable_device(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); - } + if (devpriv->attached_successfully && thisboard) + printk("comedi%d: %s: detached\n", dev->minor, thisboard->name); - if (devpriv->attached_successfully && thisboard) - printk("comedi%d: %s: detached\n", dev->minor, thisboard->name); + } - } - return 0; } @@ -466,20 +465,18 @@ static int probe(comedi_device *dev, const comedi_devconfig *it) } /* found ! */ + devpriv->pci_dev = pcidev; dev->board_ptr = boards + index; if (pci_enable_device(pcidev)) { printk("cb_pcimdda: Failed to enable PCI device\n"); - pci_dev_put(pcidev); return -EIO; } if (pci_request_regions(pcidev, thisboard->name)) { printk("cb_pcimdda: I/O port conflict\n"); - pci_dev_put(pcidev); return -EIO; } - devpriv->pci_dev = pcidev; registers = pci_resource_start(devpriv->pci_dev, REGS_BADRINDEX); devpriv->registers = registers; devpriv->dio_registers diff --git a/comedi/drivers/contec_pci_dio.c b/comedi/drivers/contec_pci_dio.c index 7c29abaa..0bb31009 100644 --- a/comedi/drivers/contec_pci_dio.c +++ b/comedi/drivers/contec_pci_dio.c @@ -112,6 +112,7 @@ static int contec_attach(comedi_device *dev,comedi_devconfig *it) if ( pcidev->vendor == PCI_VENDOR_ID_CONTEC && pcidev->device == PCI_DEVICE_ID_PIO1616L ) { + devpriv->pci_dev = pcidev; if (pci_enable_device(pcidev)) { printk("error enabling PCI device!\n"); return -EIO; @@ -120,7 +121,6 @@ static int contec_attach(comedi_device *dev,comedi_devconfig *it) printk("I/O port conflict!\n"); return -EIO; } - devpriv->pci_dev = pcidev; dev->iobase = pci_resource_start ( pcidev, 0 ); printk ( " base addr %lx ", dev->iobase ); @@ -160,8 +160,11 @@ static int contec_detach(comedi_device *dev) printk("comedi%d: contec: remove\n",dev->minor); if (devpriv && devpriv->pci_dev) { - pci_release_regions(devpriv->pci_dev); - pci_disable_device(devpriv->pci_dev); + if(dev->iobase) + { + pci_release_regions(devpriv->pci_dev); + pci_disable_device(devpriv->pci_dev); + } pci_dev_put(devpriv->pci_dev); } diff --git a/comedi/drivers/daqboard2000.c b/comedi/drivers/daqboard2000.c index d6d57d78..38f70706 100644 --- a/comedi/drivers/daqboard2000.c +++ b/comedi/drivers/daqboard2000.c @@ -682,64 +682,55 @@ static int daqboard2000_8255_cb(int dir, int port, int data, unsigned long ioadd static int daqboard2000_attach(comedi_device *dev, comedi_devconfig *it) { - int result = 0; - comedi_subdevice *s; - struct pci_dev *card = NULL; - void *aux_data; - unsigned int aux_len; - - printk("comedi%d: daqboard2000:", dev->minor); - - /* FIXME: we should handle multiple cards, have to make David decide - how, so we will be consistent among all PCI card drivers... */ - card = pci_get_device(0x1616, 0x0409, NULL); - - if (!card) { - printk(" no daqboard2000 found\n"); - result = -EIO; - goto out; - }else{ - u32 id; - int i; - id = ((u32)card->subsystem_device << 16) | card->subsystem_vendor; - for(i=0;iboard_ptr=boardtypes+i; - } - } - if(!dev->board_ptr){ - printk(" unknown subsystem id %08x (pretend it is an ids2)",id); - dev->board_ptr=boardtypes; - } - } - - if((result = pci_enable_device(card))<0){ - pci_dev_put(card); - goto out; - } - - if((result = pci_request_regions(card, "daqboard2000")) < 0) { - pci_dev_put(card); - goto out; - } + int result = 0; + comedi_subdevice *s; + struct pci_dev *card = NULL; + void *aux_data; + unsigned int aux_len; + + printk("comedi%d: daqboard2000:", dev->minor); + + result = alloc_private(dev,sizeof(daqboard2000_private)); + if(result < 0){ + return -ENOMEM; + } + /* FIXME: we should handle multiple cards, have to make David decide + how, so we will be consistent among all PCI card drivers... */ + card = pci_get_device(0x1616, 0x0409, NULL); + if (!card) { + printk(" no daqboard2000 found\n"); + return -EIO; + }else{ + u32 id; + int i; + devpriv->pci_dev = card; + id = ((u32)card->subsystem_device << 16) | card->subsystem_vendor; + for(i=0;iboard_ptr=boardtypes+i; + } + } + if(!dev->board_ptr){ + printk(" unknown subsystem id %08x (pretend it is an ids2)",id); + dev->board_ptr=boardtypes; + } + } - result = alloc_private(dev,sizeof(daqboard2000_private)); - if(result<0){ - pci_release_regions(card); - pci_disable_device(card); - pci_dev_put(card); - goto out; - } - devpriv->pci_dev = card; + if((result = pci_enable_device(card))<0){ + return -EIO; + } + if((result = pci_request_regions(card, "daqboard2000")) < 0) { + return -EIO; + } + devpriv->plx = ioremap(pci_resource_start(card,0), DAQBOARD2000_PLX_SIZE); + devpriv->daq = ioremap(pci_resource_start(card,2), DAQBOARD2000_DAQ_SIZE); - result = alloc_subdevices(dev, 3); - if(result<0)goto out; - - devpriv->plx = ioremap(pci_resource_start(card,0), DAQBOARD2000_PLX_SIZE); - devpriv->daq = ioremap(pci_resource_start(card,2), DAQBOARD2000_DAQ_SIZE); - readl(devpriv->plx + 0x6c); + result = alloc_subdevices(dev, 3); + if(result<0)goto out; + + readl(devpriv->plx + 0x6c); /* u8 interrupt; @@ -800,26 +791,31 @@ out: static int daqboard2000_detach(comedi_device * dev) { - printk("comedi%d: daqboard2000: remove\n", dev->minor); - - if(dev->subdevices) - subdev_8255_cleanup(dev,dev->subdevices+2); - - if (devpriv && devpriv->daq) { - iounmap(devpriv->daq); - } - if (devpriv && devpriv->plx) { - iounmap(devpriv->plx); - } - if (dev->irq) { - free_irq(dev->irq, dev); - } - if (devpriv && devpriv->pci_dev) { - pci_release_regions(devpriv->pci_dev); - pci_disable_device(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); - } - return 0; + printk("comedi%d: daqboard2000: remove\n", dev->minor); + + if(dev->subdevices) + subdev_8255_cleanup(dev,dev->subdevices+2); + + if (dev->irq) { + free_irq(dev->irq, dev); + } + if(devpriv) + { + if(devpriv->daq) + iounmap(devpriv->daq); + if(devpriv->plx) + iounmap(devpriv->plx); + if(devpriv->pci_dev) + { + if(devpriv->daq) + { + pci_release_regions(devpriv->pci_dev); + pci_disable_device(devpriv->pci_dev); + } + pci_dev_put(devpriv->pci_dev); + } + } + return 0; } COMEDI_INITCLEANUP(driver_daqboard2000); diff --git a/comedi/drivers/das08.c b/comedi/drivers/das08.c index 154f2353..319ca23c 100644 --- a/comedi/drivers/das08.c +++ b/comedi/drivers/das08.c @@ -955,19 +955,17 @@ static int das08_attach(comedi_device *dev,comedi_devconfig *it) printk("No pci das08 cards found\n"); return -EIO; } + devpriv->pdev = pdev; // enable PCI device if(pci_enable_device(pdev)){ printk(" Error enabling PCI device\n"); - pci_dev_put(pdev); return -EIO; } // reserve I/O spaces if(pci_request_regions(pdev, "das08")){ printk(" I/O port conflict\n"); - pci_dev_put(pdev); return -EIO; } - devpriv->pdev = pdev; // read base addresses pci_iobase = pci_resource_start(pdev, 1); iobase = pci_resource_start(pdev, 2); @@ -1008,8 +1006,11 @@ int das08_common_detach(comedi_device *dev) if(devpriv){ if(devpriv->pdev){ - pci_release_regions(devpriv->pdev); - pci_disable_device(devpriv->pdev); + if(devpriv->pci_iobase) + { + pci_release_regions(devpriv->pdev); + pci_disable_device(devpriv->pdev); + } pci_dev_put(devpriv->pdev); } } diff --git a/comedi/drivers/dt3000.c b/comedi/drivers/dt3000.c index 183ea70e..c5e2a88a 100644 --- a/comedi/drivers/dt3000.c +++ b/comedi/drivers/dt3000.c @@ -253,7 +253,6 @@ MODULE_DEVICE_TABLE(pci, dt3k_pci_table); typedef struct{ struct pci_dev *pci_dev; - int pci_enabled; unsigned long phys_addr; void *io_addr; unsigned int lock; @@ -858,7 +857,7 @@ static int dt3000_detach(comedi_device *dev) { if(devpriv->pci_dev) { - if (devpriv->pci_enabled) + if(devpriv->phys_addr) { pci_release_regions(devpriv->pci_dev); pci_disable_device(devpriv->pci_dev); @@ -906,8 +905,6 @@ static int setup_pci(comedi_device *dev) ret = pci_request_regions(devpriv->pci_dev, "dt3000"); if(ret<0)return ret; - devpriv->pci_enabled = 1; - addr=pci_resource_start(devpriv->pci_dev,0); devpriv->phys_addr=addr; offset = devpriv->phys_addr & ~PAGE_MASK; diff --git a/comedi/drivers/gsc_hpdi.c b/comedi/drivers/gsc_hpdi.c index 1e3b27a2..d9abfe3d 100644 --- a/comedi/drivers/gsc_hpdi.c +++ b/comedi/drivers/gsc_hpdi.c @@ -561,6 +561,7 @@ static int hpdi_attach(comedi_device *dev, comedi_devconfig *it) } if( pcidev ) { + priv(dev)->hw_dev = pcidev; dev->board_ptr = hpdi_boards + i; break; } @@ -578,20 +579,16 @@ static int hpdi_attach(comedi_device *dev, comedi_devconfig *it) if( pci_enable_device( pcidev ) ) { printk(KERN_WARNING " failed enable PCI device\n"); - pci_dev_put( pcidev ); return -EIO; } if( pci_request_regions( pcidev, driver_hpdi.driver_name ) ) { /* Couldn't allocate io space */ printk(KERN_WARNING " failed to allocate io memory\n"); - pci_dev_put( pcidev ); return -EIO; } pci_set_master( pcidev ); - priv(dev)->hw_dev = pcidev; - //Initialize dev->board_name dev->board_name = board(dev)->name; @@ -679,8 +676,11 @@ static int hpdi_detach(comedi_device *dev) if( priv(dev)->dma_desc ) pci_free_consistent( priv(dev)->hw_dev, sizeof( struct plx_dma_desc ) * NUM_DMA_DESCRIPTORS, priv(dev)->dma_desc, priv(dev)->dma_desc_phys_addr ); - pci_release_regions( priv(dev)->hw_dev ); - pci_disable_device( priv(dev)->hw_dev ); + if(priv(dev)->hpdi_phys_iobase) + { + pci_release_regions( priv(dev)->hw_dev ); + pci_disable_device( priv(dev)->hw_dev ); + } pci_dev_put(priv(dev)->hw_dev); } } diff --git a/comedi/drivers/ke_counter.c b/comedi/drivers/ke_counter.c index 54308062..47aa95d3 100644 --- a/comedi/drivers/ke_counter.c +++ b/comedi/drivers/ke_counter.c @@ -148,6 +148,12 @@ static int cnt_attach(comedi_device *dev, comedi_devconfig *it) int io_base; int error, i; + /* allocate device private structure */ + if((error = alloc_private(dev, sizeof(cnt_device_private))) < 0) + { + return error; + } + /* Probe the device to determine what device in the series it is. */ for(pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pci_device != NULL ; pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) @@ -183,19 +189,18 @@ static int cnt_attach(comedi_device *dev, comedi_devconfig *it) found: printk("comedi%d: found %s at PCI bus %d, slot %d\n",dev->minor, board->name, pci_device->bus->number, PCI_SLOT(pci_device->devfn)); + devpriv->pcidev = pci_device; dev->board_name = board->name; /* enable PCI device */ if((error = pci_enable_device(pci_device)) < 0) { - pci_dev_put(pci_device); return error; } /* request PCI regions */ if((error = pci_request_regions(pci_device, CNT_DRIVER_NAME)) < 0) { - pci_dev_put(pci_device); return error; } @@ -203,15 +208,6 @@ found: io_base = pci_resource_start(pci_device, 0); dev->iobase = io_base & PCI_BASE_ADDRESS_IO_MASK; - /* allocate device private structure */ - if((error = alloc_private(dev, sizeof(cnt_device_private))) < 0) - { - pci_dev_put(pci_device); - return error; - } - - devpriv->pcidev = pci_device; - /* allocate the subdevice structures */ if((error = alloc_subdevices(dev, 1)) < 0) { @@ -244,13 +240,15 @@ found: static int cnt_detach(comedi_device *dev) { - if (devpriv && devpriv->pcidev) - { - pci_release_regions(devpriv->pcidev); - pci_disable_device(devpriv->pcidev); - pci_dev_put(devpriv->pcidev); - } - - printk("comedi%d: " CNT_DRIVER_NAME " remove\n",dev->minor); - return 0; + if (devpriv && devpriv->pcidev) + { + if(dev->iobase) + { + pci_release_regions(devpriv->pcidev); + pci_disable_device(devpriv->pcidev); + } + pci_dev_put(devpriv->pcidev); + } + printk("comedi%d: " CNT_DRIVER_NAME " remove\n",dev->minor); + return 0; } diff --git a/comedi/drivers/me4000.c b/comedi/drivers/me4000.c index d694ea14..1e0897bf 100644 --- a/comedi/drivers/me4000.c +++ b/comedi/drivers/me4000.c @@ -401,29 +401,33 @@ static int me4000_probe(comedi_device *dev, comedi_devconfig *it){ CALL_PDEBUG("In me4000_probe()\n"); + /* Allocate private memory */ + if(alloc_private(dev, sizeof(me4000_info_t)) < 0){ + return -ENOMEM; + } /* * Probe the device to determine what device in the series it is. */ for(pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pci_device != NULL ; pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) { - if(pci_device->vendor == PCI_VENDOR_ID_MEILHAUS){ - for(i = 0; i < ME4000_BOARD_VERSIONS; i++){ - if(me4000_boards[i].device_id == pci_device->device){ - /* Was a particular bus/slot requested? */ - if((it->options[0] != 0) || (it->options[1] != 0)){ - /* Are we on the wrong bus/slot? */ - if(pci_device->bus->number != it->options[0] || - PCI_SLOT(pci_device->devfn) != it->options[1]){ - continue; + if(pci_device->vendor == PCI_VENDOR_ID_MEILHAUS){ + for(i = 0; i < ME4000_BOARD_VERSIONS; i++){ + if(me4000_boards[i].device_id == pci_device->device){ + /* Was a particular bus/slot requested? */ + if((it->options[0] != 0) || (it->options[1] != 0)){ + /* Are we on the wrong bus/slot? */ + if(pci_device->bus->number != it->options[0] || + PCI_SLOT(pci_device->devfn) != it->options[1]){ + continue; + } + } + dev->board_ptr = me4000_boards + i; + board = (me4000_board_t *) dev->board_ptr; + info->pci_dev_p = pci_device; + goto found; + } } - } - - dev->board_ptr = me4000_boards + i; - board = (me4000_board_t *) dev->board_ptr; - goto found; } - } - } } printk(KERN_ERR"comedi%d: me4000: me4000_probe(): No supported board found (req. bus/slot : %d/%d)\n", @@ -436,87 +440,75 @@ found: dev->minor, me4000_boards[i].name, pci_device->bus->number, PCI_SLOT(pci_device->devfn)); - /* Allocate private memory */ - if(alloc_private(dev, sizeof(me4000_info_t)) < 0){ - pci_dev_put(pci_device); - return -ENOMEM; - } - /* Set data in device structure */ dev->board_name = board->name; /* Enable PCI device */ result = pci_enable_device(pci_device); if(result){ - printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot enable PCI device\n", dev->minor); - pci_dev_put(pci_device); - return result; + printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot enable PCI device\n", dev->minor); + return result; } /* Request the PCI register regions */ result = pci_request_regions(pci_device, dev->board_name); if (result < 0){ - printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot request I/O regions\n", dev->minor); - pci_dev_put(pci_device); - return result; + printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot request I/O regions\n", dev->minor); + return result; } - /* Get the PCI base registers */ result = get_registers(dev, pci_device); if(result){ - printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot get registers\n", dev->minor); - pci_release_regions(pci_device); - pci_disable_device(pci_device); - pci_dev_put(pci_device); - return result; + printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot get registers\n", dev->minor); + return result; } - /* Initialize board info (sets info->pci_dev_p) */ + /* Initialize board info */ result = init_board_info(dev, pci_device); if (result){ - printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init baord info\n", dev->minor); - return result; + printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init baord info\n", dev->minor); + return result; } /* Init analog output context */ result = init_ao_context(dev); if (result){ - printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init ao context\n", dev->minor); - return result; + printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init ao context\n", dev->minor); + return result; } /* Init analog input context */ result = init_ai_context(dev); if (result){ - printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init ai context\n", dev->minor); - return result; + printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init ai context\n", dev->minor); + return result; } /* Init digital I/O context */ result = init_dio_context(dev); if (result){ - printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init dio context\n", dev->minor); - return result; + printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init dio context\n", dev->minor); + return result; } /* Init counter context */ result = init_cnt_context(dev); if (result){ - printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init cnt context\n", dev->minor); - return result; + printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init cnt context\n", dev->minor); + return result; } /* Download the xilinx firmware */ result = xilinx_download(dev); if(result){ - printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Can't download firmware\n", dev->minor); - return result; + printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Can't download firmware\n", dev->minor); + return result; } /* Make a hardware reset */ result = reset_board(dev); if(result){ - printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Can't reset board\n", dev->minor); - return result; + printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Can't reset board\n", dev->minor); + return result; } return 0; @@ -574,7 +566,6 @@ static int get_registers(comedi_device *dev, struct pci_dev *pci_dev_p){ static int init_board_info(comedi_device *dev, struct pci_dev *pci_dev_p){ int result; - info->pci_dev_p = pci_dev_p; CALL_PDEBUG("In init_board_info()\n"); @@ -856,17 +847,21 @@ static int reset_board(comedi_device *dev){ static int me4000_detach(comedi_device *dev){ - CALL_PDEBUG("In me4000_detach()\n"); - - if(info){ - if(info->pci_dev_p) { - reset_board(dev); - pci_release_regions(info->pci_dev_p); - pci_dev_put(info->pci_dev_p); + CALL_PDEBUG("In me4000_detach()\n"); + + if(info){ + if(info->pci_dev_p) { + reset_board(dev); + if(info->plx_regbase) + { + pci_release_regions(info->pci_dev_p); + pci_disable_device(info->pci_dev_p); + } + pci_dev_put(info->pci_dev_p); + } } - } - return 0; + return 0; } diff --git a/comedi/drivers/me_daq.c b/comedi/drivers/me_daq.c index 60f49180..9ef943e3 100644 --- a/comedi/drivers/me_daq.c +++ b/comedi/drivers/me_daq.c @@ -688,6 +688,12 @@ static int me_attach(comedi_device *dev,comedi_devconfig *it) unsigned int regbase_tmp; int result, error, i; + // Allocate private memory + if(alloc_private(dev,sizeof(me_private_data_struct)) < 0) + { + return -ENOMEM; + } + // // Probe the device to determine what device in the series it is. // @@ -713,6 +719,7 @@ static int me_attach(comedi_device *dev,comedi_devconfig *it) dev->board_ptr = me_boards + i; board = (me_board_struct *) dev->board_ptr; + dev_private->pci_device = pci_device; goto found; } } @@ -729,19 +736,10 @@ found: dev->minor, me_boards[i].name, pci_device->bus->number, PCI_SLOT(pci_device->devfn)); - // Allocate private memory - - if(alloc_private(dev,sizeof(me_private_data_struct)) < 0) - { - pci_dev_put(pci_device); - return -ENOMEM; - } - // Enable PCI device if(pci_enable_device(pci_device) < 0) { printk("comedi%d: Failed to enable PCI device\n", dev->minor); - pci_dev_put(pci_device); return -EIO; } @@ -749,25 +747,19 @@ found: if(pci_request_regions(pci_device, ME_DRIVER_NAME) < 0) { printk("comedi%d: I/O memory conflict\n", dev->minor); - pci_dev_put(pci_device); return -EIO; } // Set data in device structure dev->board_name = board->name; - dev_private->pci_device = pci_device; // Read PLX register base address [PCI_BASE_ADDRESS #0]. plx_regbase_tmp = pci_resource_start(pci_device, 0); plx_regbase_size_tmp = pci_resource_end(pci_device, 0) - plx_regbase_tmp + 1; - - if(plx_regbase_tmp & PCI_BASE_ADDRESS_SPACE) - { - printk("comedi%d: PLX space is not MEM\n", dev->minor); - return -EIO; - } + dev_private->plx_regbase = ioremap(plx_regbase_tmp, plx_regbase_size_tmp); + dev_private->plx_regbase_size = plx_regbase_size_tmp; // Read Swap base address [PCI_BASE_ADDRESS #5]. @@ -808,22 +800,11 @@ found: } /*----------------------------------------------------- Workaround end -----*/ - plx_regbase_tmp &= PCI_BASE_ADDRESS_MEM_MASK; - dev_private->plx_regbase_size = plx_regbase_size_tmp; - dev_private->plx_regbase = ioremap(plx_regbase_tmp, plx_regbase_size_tmp); // Read Meilhaus register base address [PCI_BASE_ADDRESS #2]. me_regbase_tmp = pci_resource_start(pci_device, 2); me_regbase_size_tmp = pci_resource_end(pci_device, 2) - me_regbase_tmp + 1; - - if(me_regbase_tmp & PCI_BASE_ADDRESS_SPACE) - { - printk("comedi%d: Meilhaus space is not MEM\n", dev->minor); - return -EIO; - } - - me_regbase_tmp &= PCI_BASE_ADDRESS_MEM_MASK; dev_private->me_regbase_size = me_regbase_size_tmp; dev_private->me_regbase = ioremap(me_regbase_tmp, me_regbase_size_tmp); @@ -895,20 +876,21 @@ found: static int me_detach(comedi_device *dev) { - if(dev_private) - { - if (dev_private->me_regbase) - { - me_reset(dev); - } - - if(dev_private->pci_device) - { - pci_release_regions(dev_private->pci_device); - pci_disable_device(dev_private->pci_device); - pci_dev_put(dev_private->pci_device); - } - } - - return 0; + if(dev_private) + { + if (dev_private->me_regbase) + { + me_reset(dev); + } + if(dev_private->pci_device) + { + if(dev_private->plx_regbase) + { + pci_release_regions(dev_private->pci_device); + pci_disable_device(dev_private->pci_device); + } + pci_dev_put(dev_private->pci_device); + } + } + return 0; } diff --git a/comedi/drivers/rtd520.c b/comedi/drivers/rtd520.c index 0abcbebe..5bb8f9a1 100644 --- a/comedi/drivers/rtd520.c +++ b/comedi/drivers/rtd520.c @@ -774,50 +774,41 @@ static int rtd_attach ( /* * Probe the device to determine what device in the series it is. */ - for(pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pcidev != NULL ; + for(pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pcidev != NULL ; pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) { - if (pcidev->vendor == PCI_VENDOR_ID_RTD) { - if (it->options[0] || it->options[1]) { - if (pcidev->bus->number == it->options[0] - && PCI_SLOT(pcidev->devfn) == it->options[1]) { - DPRINTK("rtd520: found bus=%d slot=%d\n", - it->options[0], it->options[1]); - break; /* found it */ + if (pcidev->vendor == PCI_VENDOR_ID_RTD) { + if (it->options[0] || it->options[1]) { + if (pcidev->bus->number != it->options[0] + || PCI_SLOT(pcidev->devfn) != it->options[1]) { + continue; + } + } + break; /* found one */ } - } else { /* specific board/slot not specified */ - break; /* found one */ - } } - } - if (!pcidev) { - if (it->options[0] && it->options[1]) { - printk ("No RTD card at bus=%d slot=%d.\n", - it->options[0], it->options[1]); - } else { - printk ("No RTD card found.\n"); + if (it->options[0] && it->options[1]) { + printk ("No RTD card at bus=%d slot=%d.\n", + it->options[0], it->options[1]); + } else { + printk ("No RTD card found.\n"); + } + return -EIO; + } + devpriv->pci_dev = pcidev; + if (pcidev->device != thisboard->device_id) { + printk ("Found an RTD card, but not the supported type (%x).\n", + pcidev->device); + return -EIO; } - return -EIO; - } - - if (pcidev->device != thisboard->device_id) { - printk ("Found an RTD card, but not the supported type (%x).\n", - pcidev->device); - pci_dev_put(pcidev); - return -EIO; - } dev->board_name = thisboard->name; - if((ret=pci_enable_device(pcidev))<0){ - pci_dev_put(pcidev); - return ret; - } - if((ret=pci_request_regions(pcidev, "rtd520"))<0){ - pci_dev_put(pcidev); - return ret; - } - - devpriv->pci_dev = pcidev; + if((ret=pci_enable_device(pcidev))<0){ + return ret; + } + if((ret=pci_request_regions(pcidev, "rtd520"))<0){ + return ret; + } /* * Initialize base addresses @@ -928,19 +919,14 @@ static int rtd_attach ( s->n_chan=3; s->maxdata=0xffff; - /* check if our interrupt is available and get it */ - dev->irq = devpriv->pci_dev->irq; - if (dev->irq > 0) { - if((ret=comedi_request_irq (dev->irq, rtd_interrupt, - SA_SHIRQ, "rtd520", dev)) < 0) { - printk("Could not get interrupt! (%d)\n", dev->irq); - dev->irq = 0; - return ret; + /* check if our interrupt is available and get it */ + if((ret=comedi_request_irq (devpriv->pci_dev->irq, rtd_interrupt, + SA_SHIRQ, "rtd520", dev)) < 0) { + printk("Could not get interrupt! (%d)\n", devpriv->pci_dev->irq); + return ret; } + dev->irq = devpriv->pci_dev->irq; printk("( irq=%d )", dev->irq); - } else { - printk("( NO IRQ )"); - } #ifdef USE_DMA if (dev->irq > 0) { @@ -1164,9 +1150,12 @@ static int rtd_detach ( iounmap (devpriv->lcfg); } if (devpriv->pci_dev) { - pci_release_regions(devpriv->pci_dev); - pci_disable_device(devpriv->pci_dev); - pci_dev_put(devpriv->pci_dev); + if(devpriv->las0) + { + pci_release_regions(devpriv->pci_dev); + pci_disable_device(devpriv->pci_dev); + } + pci_dev_put(devpriv->pci_dev); } } diff --git a/comedi/drivers/s626.c b/comedi/drivers/s626.c index ea6ac1a5..0ff5791f 100644 --- a/comedi/drivers/s626.c +++ b/comedi/drivers/s626.c @@ -487,6 +487,7 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) return -ENOMEM; pdev=pci_get_device(PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, NULL); + devpriv->pdev = pdev; if(pdev==NULL) { printk("s626_attach: Board not present!!!"); @@ -495,18 +496,14 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) if((result = pci_enable_device(pdev))<0){ printk("s626_attach: pci_enable_device fails\n"); - pci_dev_put(pdev); return -ENODEV; } if((result = pci_request_regions(pdev, "s626"))<0){ printk("s626_attach: pci_request_regions fails\n"); - pci_dev_put(pdev); return -ENODEV; } - devpriv->pdev = pdev; - resourceStart=(uint64_t)pci_resource_start(devpriv->pdev,0); devpriv->base_addr=ioremap(resourceStart, SIZEOF_ADDRESS_SPACE); @@ -1201,46 +1198,47 @@ static irqreturn_t s626_irq_handler(int irq,void *d,struct pt_regs * regs) static int s626_detach(comedi_device *dev) { - - if(devpriv){ - //stop ai_command - devpriv->ai_cmd_running=0; - - if(devpriv->base_addr){ - //interrupt mask - WR7146( P_IER, 0 ); // Disable master interrupt. - WR7146( P_ISR, IRQ_GPIO3 | IRQ_RPS1 ); // Clear board's IRQ status - // flag. - - // Disable the watchdog timer and battery charger. - WriteMISC2(dev,0); - - // Close all interfaces on 7146 device. - WR7146( P_MC1, MC1_SHUTDOWN ); - WR7146( P_ACON1, ACON1_BASE ); - - CloseDMAB(dev,&devpriv->RPSBuf,DMABUF_SIZE); - CloseDMAB(dev,&devpriv->ANABuf,DMABUF_SIZE); - } - - if(dev->irq){ - comedi_free_irq(dev->irq,dev); - } - - if(devpriv->base_addr){ - iounmap(devpriv->base_addr); - } - - if(devpriv->pdev){ - pci_release_regions(devpriv->pdev); - pci_disable_device(devpriv->pdev); - pci_dev_put(devpriv->pdev); - } - } - - DEBUG("s626_detach: S626 detached!\n"); - - return 0; + if(devpriv){ + //stop ai_command + devpriv->ai_cmd_running=0; + + if(devpriv->base_addr){ + //interrupt mask + WR7146( P_IER, 0 ); // Disable master interrupt. + WR7146( P_ISR, IRQ_GPIO3 | IRQ_RPS1 ); // Clear board's IRQ status flag. + + // Disable the watchdog timer and battery charger. + WriteMISC2(dev,0); + + // Close all interfaces on 7146 device. + WR7146( P_MC1, MC1_SHUTDOWN ); + WR7146( P_ACON1, ACON1_BASE ); + + CloseDMAB(dev,&devpriv->RPSBuf,DMABUF_SIZE); + CloseDMAB(dev,&devpriv->ANABuf,DMABUF_SIZE); + } + + if(dev->irq){ + comedi_free_irq(dev->irq,dev); + } + + if(devpriv->base_addr){ + iounmap(devpriv->base_addr); + } + + if(devpriv->pdev){ + if(devpriv->base_addr) + { + pci_release_regions(devpriv->pdev); + pci_disable_device(devpriv->pdev); + } + pci_dev_put(devpriv->pdev); + } + } + + DEBUG("s626_detach: S626 detached!\n"); + + return 0; } /* -- 2.26.2