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;
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;
printk("comedi%d: pci6208: remove\n",dev->minor);
if(devpriv && devpriv->pci_dev){
- pci_release_regions(devpriv->pci_dev);
+ if (devpriv->pci_setup) {
+ pci_release_regions(devpriv->pci_dev);
+ pci_disable_device(devpriv->pci_dev);
+ }
pci_dev_put(devpriv->pci_dev);
}
pci6208_pci_setup(struct pci_dev *pci_dev, int *io_base_ptr, int dev_minor)
{
int io_base, io_range, lcr_io_base, lcr_io_range;
+
+ // Enable PCI device
+ if (pci_enable_device(pci_dev) < 0) {
+ printk("comedi%d: Failed to enable PCI device\n", dev_minor);
+ return -EIO;
+ }
// Read local configuration register base address [PCI_BASE_ADDRESS #1].
lcr_io_base = pci_resource_start(pci_dev, 1);
typedef struct{
int data;
struct pci_dev *pci_dev;
+ int pci_setup;
} adl_pci7432_private;
-#define devpriv ((pci7432_private *)dev->private)
+#define devpriv ((adl_pci7432_private *)dev->private)
static int adl_pci7432_attach(comedi_device *dev,comedi_devconfig *it);
static int adl_pci7432_detach(comedi_device *dev);
if ( pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
pcidev->device == PCI_DEVICE_ID_PCI7432 ) {
+ devpriv->pci_dev = pcidev;
+ if (pci_enable_device(pcidev) < 0) {
+ printk("comedi%d: Failed to enable PCI device\n", dev->minor);
+ return -EIO;
+ }
+ if (pci_request_regions(pcidev, "adl_pci7432") < 0) {
+ 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 );
s->io_bits = 0xffffffff;
s->range_table = &range_digital;
s->insn_bits = adl_pci7432_do_insn_bits;
+
+ break;
}
}
{
printk("comedi%d: pci7432: remove\n",dev->minor);
+ if (devpriv && devpriv->pci_dev) {
+ if (devpriv->pci_setup) {
+ pci_release_regions(devpriv->pci_dev);
+ pci_disable_device(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+
return 0;
}
typedef struct{
int data;
struct pci_dev *pci_dev;
+ int pci_setup;
} adl_pci8164_private;
-#define devpriv ((pci8164_private *)dev->private)
+#define devpriv ((adl_pci8164_private *)dev->private)
static int adl_pci8164_attach(comedi_device *dev,comedi_devconfig *it);
static int adl_pci8164_detach(comedi_device *dev);
if ( pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
pcidev->device == PCI_DEVICE_ID_PCI8164 ) {
+ devpriv->pci_dev = pcidev;
+ if (pci_enable_device(pcidev) < 0) {
+ printk("comedi%d: Failed to enable PCI device\n", dev->minor);
+ return -EIO;
+ }
+ if (pci_request_regions(pcidev, "adl_pci8164") < 0) {
+ 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 );
s->insn_read = adl_pci8164_insn_read_buf1;
s->insn_write = adl_pci8164_insn_write_buf1;
+ break;
}
}
{
printk("comedi%d: pci8164: remove\n",dev->minor);
+ if (devpriv && devpriv->pci_dev) {
+ if (devpriv->pci_setup) {
+ pci_release_regions(devpriv->pci_dev);
+ pci_disable_device(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+
return 0;
}
lcr_io_base,
lcr_io_range);
+ // 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;
+ }
+
// Read PCI6308 register base address [PCI_BASE_ADDRESS #2].
io_base = pci_resource_start (pci_device, 2);
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;
}
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);
}
static int pci9118_attach(comedi_device *dev,comedi_devconfig *it);
static int pci9118_detach(comedi_device *dev);
-static unsigned short pci_list_builded=0; /*=1 list of cards is know */
+static unsigned short pci_list_builded=0; /*>0 list of cards is known */
typedef struct {
char *name; // driver name
int iobase_a; // base+size for AMCC chip
struct pcilst_struct *amcc; // ptr too AMCC data
unsigned int master; // master capable
- unsigned char allocated; // we have blocked card
struct pci_dev *pcidev; // ptr to actual pcidev
unsigned int usemux; // we want to use external multiplexor!
#ifdef PCI9118_PARANOIDCHECK
unsigned char pci_bus,pci_slot,pci_func;
u16 u16w;
- if (!pci_list_builded) {
+ if (pci_list_builded++ == 0) {
pci_card_list_init(PCI_VENDOR_ID_AMCC,0);
- pci_list_builded=1;
}
rt_printk("comedi%d: adl_pci9118: board=%s",dev->minor,this_board->name);
master=1;
}
- /* this call pci_enable_device() and pci_set_master() */
+ /* this call pci_enable_device(), pci_request_regions(),
+ * and pci_set_master() */
if ((card=select_and_alloc_pci_card(PCI_VENDOR_ID_AMCC, this_board->device_id, it->options[0], it->options[1], master))==NULL)
return -EIO;
rt_printk(", b:s:f=%d:%d:%d, io=0x%4x, 0x%4x",pci_bus,pci_slot,pci_func,iobase_9,iobase_a);
- if (!request_region(iobase_9, this_board->iorange_9118, "ADLink PCI-9118")) {
- rt_printk("I/O port conflict\n");
- return -EIO;
- }
-
dev->iobase=iobase_9;
dev->board_name = this_board->name;
- if((ret=alloc_private(dev,sizeof(pci9118_private)))<0)
+ if((ret=alloc_private(dev,sizeof(pci9118_private)))<0) {
+ pci_card_free(card);
+ rt_printk(" - Allocation failed!\n");
return -ENOMEM;
+ }
devpriv->amcc=card;
devpriv->pcidev=card->pcidev;
- if (!request_region(iobase_a, this_board->iorange_amcc, "ADLink PCI-9118")) {
- rt_printk("I/O port conflict\n");
- return -EIO;
- }
devpriv->iobase_a=iobase_a;
if (it->options[3]&2) irq=0; // user don't want use IRQ
{
if (dev->private) {
if (devpriv->valid) pci9118_reset(dev);
- if (devpriv->iobase_a) release_region(devpriv->iobase_a,this_board->iorange_amcc);
- if (devpriv->allocated) pci_card_free(devpriv->amcc);
+ if(dev->irq) comedi_free_irq(dev->irq,dev);
+ if (devpriv->amcc) pci_card_free(devpriv->amcc);
if (devpriv->dmabuf_virt[0]) free_pages((unsigned long)devpriv->dmabuf_virt[0],devpriv->dmabuf_pages[0]);
if (devpriv->dmabuf_virt[1]) free_pages((unsigned long)devpriv->dmabuf_virt[1],devpriv->dmabuf_pages[1]);
}
- if(dev->irq) comedi_free_irq(dev->irq,dev);
-
- if(dev->iobase) release_region(dev->iobase,this_board->iorange_9118);
-
- if (pci_list_builded) {
+ if (--pci_list_builded == 0) {
pci_card_list_cleanup(PCI_VENDOR_ID_AMCC);
- pci_list_builded=0;
}
return 0;
static int pci1710_attach(comedi_device *dev,comedi_devconfig *it);
static int pci1710_detach(comedi_device *dev);
-static unsigned short pci_list_builded=0; /*=1 list of card is know */
+static unsigned short pci_list_builded=0; /*>0 list of card is known */
typedef struct {
char *name; // driver name
};
typedef struct{
+ struct pcilst_struct *amcc; // ptr to AMCC data
char valid; // card is usable
char neverending_ai; // we do unlimited AI
unsigned int CntrlReg; // Control register
unsigned int iobase;
unsigned char pci_bus,pci_slot,pci_func;
- if (!pci_list_builded) {
+ if (pci_list_builded++ == 0) {
pci_card_list_init(PCI_VENDOR_ID_ADVANTECH,
#ifdef PCI171X_EXTDEBUG
1
0
#endif
);
- pci_list_builded=1;
}
rt_printk("comedi%d: adv_pci1710: board=%s",dev->minor,this_board->name);
- /* this call pci_enable_device() */
+ /* this call pci_enable_device() and pci_request_regions() */
if ((card=select_and_alloc_pci_card(PCI_VENDOR_ID_ADVANTECH, this_board->device_id, it->options[0], it->options[1], 0))==NULL)
return -EIO;
rt_printk(", b:s:f=%d:%d:%d, io=0x%4x",pci_bus,pci_slot,pci_func,iobase);
- if (!request_region(iobase, this_board->iorange, "Advantech PCI-1710")) {
- pci_card_free(card);
- rt_printk("I/O port conflict\n");
- return -EIO;
- }
-
dev->iobase=iobase;
dev->board_name = this_board->name;
if((ret=alloc_private(dev,sizeof(pci1710_private)))<0) {
- release_region(dev->iobase, this_board->iorange);
pci_card_free(card);
+ rt_printk(" - Allocation failed!\n");
return -ENOMEM;
}
+ devpriv->amcc = card;
+
n_subdevices = 0;
if (this_board->n_aichan) n_subdevices++;
if (this_board->n_aochan) n_subdevices++;
if (this_board->n_counter) n_subdevices++;
if((ret=alloc_subdevices(dev, n_subdevices))<0) {
- release_region(dev->iobase, this_board->iorange);
- pci_card_free(card);
+ rt_printk(" - Allocation failed!\n");
return ret;
}
static int pci1710_detach(comedi_device *dev)
{
- if (dev->private)
+ if (dev->private) {
if (devpriv->valid) pci1710_reset(dev);
-
- if (dev->irq) comedi_free_irq(dev->irq,dev);
- if (dev->iobase) release_region(dev->iobase,this_board->iorange);
+ if (dev->irq) comedi_free_irq(dev->irq,dev);
+ if (devpriv->amcc) pci_card_free(devpriv->amcc);
+ }
- if (pci_list_builded) {
+ if (--pci_list_builded == 0) {
pci_card_list_cleanup(PCI_VENDOR_ID_ADVANTECH);
- pci_list_builded=0;
}
{
pci_dio_private *pr, *prev;
- if (!pci_priv) { // well, first card in system
- pci_priv=devpriv;
- return 1;
- }
-
- for (pr=pci_priv, prev=NULL; pr!=NULL; prev=pr, pr=pr->next)
+ for (pr=pci_priv, prev=NULL; pr!=NULL; prev=pr, pr=pr->next) {
if (pr->pcidev==pcidev) {
if (it->options[0]||it->options[1]) {
if ((pr->pcidev->bus->number==it->options[0])&&
}
return 0; // this card is used, look for another
}
+ }
+
+ if (prev) {
+ devpriv->prev=prev;
+ prev->next = devpriv;
+ } else {
+ pci_priv = devpriv;
+ }
- if (prev) { devpriv->prev=prev; }
- { pci_priv=devpriv; }
+ devpriv->pcidev = pcidev;
return 1;
}
ret=CheckAndAllocCard(dev, it, pcidev);
if (ret==1) { found=1; break; }
if (ret>1) {
- pci_dio_detach(dev);
- pci_dev_put(pcidev);
return -EIO;
}
}
if (!found) {
rt_printk(", Error: Requested type of the card was not found!\n");
- pci_dio_detach(dev);
return -EIO;
}
- 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),
- iobase);
-
- if (pci_request_regions(pcidev, driver_pci_dio.driver_name)) {
- pci_dio_detach(dev);
- pci_dev_put(pcidev);
- rt_printk(", Error: Cann't allocate PCI device!\n");
+ if (pci_enable_device(pcidev)) {
+ rt_printk(", Error: Can't enable PCI device!\n");
return -EIO;
}
- devpriv->pcidev=pcidev;
-
- if (pci_enable_device(pcidev)) {
- pci_dio_detach(dev);
- rt_printk(", Error: Cann't enable PCI device!\n");
+ 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),
+ iobase);
+
dev->iobase=iobase;
dev->board_name=this_board->name;
if((ret=alloc_subdevices(dev, n_subdevices))<0) {
rt_printk(", Error: Cann't allocate subdevice memory!\n");
- pci_dio_detach(dev);
return ret;
}
s->private=NULL;
}
- if (devpriv->enabled)
+ if (devpriv->enabled) {
+ pci_release_regions(devpriv->pcidev);
pci_disable_device(devpriv->pcidev);
+ }
+
+ if (devpriv->prev) {
+ devpriv->prev->next=devpriv->next;
+ } else {
+ pci_priv=devpriv->next;
+ }
+ if (devpriv->next) {
+ devpriv->next->prev=devpriv->prev;
+ }
if (devpriv->pcidev) {
- pci_release_regions(devpriv->pcidev);
pci_dev_put(devpriv->pcidev);
}
-
- if (devpriv->prev) { devpriv->prev->next=devpriv->next; }
- { pci_priv=devpriv->next; }
- if (devpriv->next) { devpriv->next->prev=devpriv->prev; }
-
}
return 0;
amcc->pci_bus=pcidev->bus->number;
amcc->pci_slot=PCI_SLOT(pcidev->devfn);
amcc->pci_func=PCI_FUNC(pcidev->devfn);
+ /* Note: resources may be invalid if PCI device
+ * not enabled, but they are corrected in
+ * pci_card_alloc. */
for (i=0;i<5;i++)
amcc->io_addr[i]=pci_resource_start(pcidev, i);
amcc->irq=pcidev->irq;
/* mark card as used */
int pci_card_alloc(struct pcilst_struct *amcc, char master)
{
- if (!amcc) return -1;
+ int i;
+
+ if (!amcc) {
+ rt_printk(" - BUG!! amcc is NULL!\n");
+ return -1;
+ }
if (amcc->used) return 1;
- if (pci_enable_device(amcc->pcidev)) return -1;
+ if (pci_enable_device(amcc->pcidev)) {
+ rt_printk(" - Can't enable PCI device!\n");
+ return -1;
+ }
+ /* Resources will be accurate now. */
+ for (i=0;i<5;i++)
+ amcc->io_addr[i]=pci_resource_start(amcc->pcidev, i);
+ amcc->irq=amcc->pcidev->irq;
+ /* Request regions on behalf of client. */
+ if (pci_request_regions(amcc->pcidev, "amcc_s5933")) {
+ rt_printk(" - I/O port conflict!\n");
+ return -1;
+ }
if (master) pci_set_master(amcc->pcidev);
amcc->used=1;
if (!amcc->used) return 1;
amcc->used=0;
+ pci_release_regions(amcc->pcidev);
+ pci_disable_device(amcc->pcidev);
return 0;
}
struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id, unsigned short device_id, unsigned short pci_bus, unsigned short pci_slot, char master)
{
struct pcilst_struct *card;
+ int err;
if ((pci_bus<1)&&(pci_slot<1)) { // use autodetection
if ((card=find_free_pci_card_by_device(vendor_id,device_id))==NULL) {
}
- if (pci_card_alloc(card, master)!=0) {
- rt_printk(" - Can't allocate card!\n");
+ if ((err=pci_card_alloc(card, master))!=0) {
+ if (err > 0)
+ rt_printk(" - Can't allocate card!\n");
+ /* else: error already printed. */
return NULL;
}
feel free to suggest moving the variable to the comedi_device struct. */
typedef struct {
struct pci_dev *pci_dev; /* PCI device */
- int share_irq;
int intr_sd;
} dio200_private;
static int
dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
{
- if (!request_region(from, extent, DIO200_DRIVER_NAME)) {
+ if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
minor, from, extent);
return -EIO;
printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
DIO200_DRIVER_NAME);
- /* Get card bus position and base address. */
+ /* Process options. */
switch (thisboard->bustype) {
case isa_bustype:
iobase = it->options[0];
if ((ret=dio200_find_pci(dev, bus, slot, &pci_dev)) < 0)
return ret;
-
- 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;
- }
- iobase = pci_resource_start(pci_dev, 2);
- irq = pci_dev->irq;
break;
default:
printk(KERN_ERR "comedi%d: %s: BUG! cannot determine board type!\n",
return ret;
}
- devpriv->pci_dev = pci_dev;
- devpriv->share_irq = share_irq;
devpriv->intr_sd = -1;
- /* Reserve I/O spaces. */
- ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE);
- if (ret < 0) {
- return ret;
+ /* Enable device and reserve I/O spaces. */
+ if (pci_dev) {
+ ret = pci_enable_device(pci_dev);
+ 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);
+ irq = pci_dev->irq;
+ ret = pci_request_regions(pci_dev, DIO200_DRIVER_NAME);
+ 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) {
+ return ret;
+ }
}
dev->iobase = iobase;
}
}
}
- if (dev->iobase) {
- release_region(dev->iobase, DIO200_IO_SIZE);
- }
- if (devpriv && devpriv->pci_dev) {
- pci_dev_put(devpriv->pci_dev);
+ if (devpriv) {
+ if (devpriv->pci_dev) {
+ 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);
+ }
}
if (dev->board_name) {
printk(KERN_INFO "comedi%d: %s removed\n",
struct pci_dev *pci_dev;
int lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */
int enable_irq;
- int share_irq;
}pc236_private;
#define devpriv ((pc236_private *)dev->private)
comedi_subdevice *s;
struct pci_dev *pci_dev = NULL;
int iobase = 0, irq = 0;
- int lcr_iobase = 0;
int bus = 0, slot = 0;
struct pci_device_id *pci_id;
int share_irq = 0;
printk("comedi%d: %s: ",dev->minor, PC236_DRIVER_NAME);
- /* Get card bus position and base address. */
+ /* Process options. */
switch (thisboard->bustype) {
case isa_bustype:
iobase = it->options[0];
printk("no %s found!\n", thisboard->fancy_name);
return -EIO;
}
- if ((ret=pci_enable_device(pci_dev)) < 0) {
- printk("error enabling PCI device!\n");
- pci_dev_put(pci_dev);
- return ret;
- }
- lcr_iobase = pci_resource_start(pci_dev, 1);
- iobase = pci_resource_start(pci_dev, 2);
- irq = pci_dev->irq;
break;
default:
printk("bug! cannot determine board type!\n");
return ret;
}
- devpriv->pci_dev = pci_dev;
- devpriv->share_irq = share_irq;
-
- /* Reserve I/O spaces. */
- if (lcr_iobase) {
- if ((ret=pc236_request_region(lcr_iobase, PC236_LCR_IO_SIZE)) < 0) {
+ /* 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;
+ } else {
+ if ((ret=pc236_request_region(iobase, PC236_IO_SIZE)) < 0) {
return ret;
}
- devpriv->lcr_iobase = lcr_iobase;
- }
- if ((ret=pc236_request_region(iobase, PC236_IO_SIZE)) < 0) {
- return ret;
}
dev->iobase = iobase;
if (dev->subdevices) {
subdev_8255_cleanup(dev, dev->subdevices+0);
}
- if (dev->iobase) {
- release_region(dev->iobase, PC236_IO_SIZE);
- }
if (devpriv) {
- if (devpriv->lcr_iobase)
- release_region(devpriv->lcr_iobase, PC236_LCR_IO_SIZE);
- if (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);
+ } else if (dev->iobase) {
+ release_region(dev->iobase, PC236_IO_SIZE);
+ }
}
return 0;
*/
static int pc236_request_region(unsigned long from, unsigned long extent)
{
- if (!request_region(from, extent, PC236_DRIVER_NAME)) {
+ if (!from || !request_region(from, extent, PC236_DRIVER_NAME)) {
printk("I/O port conflict (%#lx,%lu)!\n", from, extent);
return -EIO;
}
printk("comedi%d: %s: ",dev->minor, PC263_DRIVER_NAME);
- /* Get card bus position and base address. */
+ /* Process options. */
switch (thisboard->bustype) {
case isa_bustype:
iobase = it->options[0];
printk("no %s found!\n", thisboard->fancy_name);
return -EIO;
}
- if ((ret=pci_enable_device(pci_dev)) < 0) {
- printk("error enabling PCI device!\n");
- pci_dev_put(pci_dev);
- return ret;
- }
- iobase = pci_resource_start(pci_dev, 2);
break;
default:
printk("bug! cannot determine board type!\n");
return ret;
}
- devpriv->pci_dev = pci_dev;
-
- /* Reserve I/O space. */
- if ((ret=pc263_request_region(iobase, PC263_IO_SIZE)) < 0) {
- 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) {
+ return ret;
+ }
}
dev->iobase = iobase;
{
printk("comedi%d: %s: remove\n", dev->minor, PC263_DRIVER_NAME);
- if (dev->iobase)
- release_region(dev->iobase, PC263_IO_SIZE);
- if (devpriv && devpriv->pci_dev)
- pci_dev_put(devpriv->pci_dev);
-
+ if (devpriv) {
+ if (devpriv->pci_dev) {
+ 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);
+ }
+ }
+
return 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;
}
}
if (devpriv->pci_dev) {
pci_release_regions(devpriv->pci_dev);
+ pci_disable_device(devpriv->pci_dev);
pci_dev_put(devpriv->pci_dev);
}
}
pci_iobase = pci_resource_start(pci_dev, 2);
iobase = pci_resource_start(pci_dev, 3);
+ /* 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;
-
- /* Reserve I/O spaces. */
- if(pci_request_regions(pci_dev,"PCI230")<0){
- printk("comedi%d: amplc_pci230: I/O space conflict\n",dev->minor);
- return -EIO;
- }
devpriv->pci_iobase = pci_iobase;
dev->iobase = iobase;
if(devpriv){
if(devpriv->pci_dev){
- if(devpriv->pci_iobase)
- pci_release_regions(devpriv->pci_dev);
+ pci_release_regions(devpriv->pci_dev);
+ pci_disable_device(devpriv->pci_dev);
pci_dev_put(devpriv->pci_dev);
}
}
comedi_subdevice *s;
struct pci_dev* pcidev;
int index;
- unsigned long s5933_config, control_status, adc_fifo,
- pacer_counter_dio, ao_registers;
- int err;
int i;
printk("comedi%d: cb_pcidas: ",dev->minor);
continue;
}
}
- devpriv->pci_dev = pcidev;
dev->board_ptr = cb_pcidas_boards + index;
goto found;
}
found:
printk("Found %s on bus %i, slot %i\n", cb_pcidas_boards[index].name,
- devpriv->pci_dev->bus->number, PCI_SLOT(devpriv->pci_dev->devfn));
+ pcidev->bus->number, PCI_SLOT(pcidev->devfn));
/*
- * Initialize devpriv->control_status and devpriv->adc_fifo to point to
- * their base address.
+ * Enable PCI device and reserve I/O ports.
*/
- if(pci_enable_device(devpriv->pci_dev))
- return -EIO;
- s5933_config = pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX);
- control_status = pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX);
- adc_fifo = pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX);
- pacer_counter_dio = pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX);
- ao_registers = pci_resource_start(devpriv->pci_dev, AO_BADRINDEX);
-
- // reserve io ports
- err = 0;
- if(request_region(s5933_config, AMCC_OP_REG_SIZE, "cb_pcidas"))
- devpriv->s5933_config = s5933_config;
- else
- err++;
- if(request_region(control_status, CONT_STAT_SIZE, "cb_pcidas"))
- devpriv->control_status = control_status;
- else
- err++;
- if(request_region(adc_fifo, ADC_FIFO_SIZE, "cb_pcidas"))
- devpriv->adc_fifo = adc_fifo;
- else
- err++;
- if(request_region(pacer_counter_dio, PACER_SIZE, "cb_pcidas"))
- devpriv->pacer_counter_dio = pacer_counter_dio;
- else
- err++;
- if(thisboard->ao_nchan)
+ if(pci_enable_device(pcidev))
{
- if(request_region(ao_registers, AO_SIZE, "cb_pcidas"))
- devpriv->ao_registers = ao_registers;
- else
- err++;
+ printk(" Failed to enable PCI device\n");
+ pci_dev_put(pcidev);
+ return -EIO;
}
- if(err)
+ 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.
+ */
+ devpriv->s5933_config = pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX);
+ devpriv->control_status = pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX);
+ devpriv->adc_fifo = pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX);
+ devpriv->pacer_counter_dio = pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX);
+ if(thisboard->ao_nchan)
+ {
+ devpriv->ao_registers = pci_resource_start(devpriv->pci_dev, AO_BADRINDEX);
+ }
// get irq
if(comedi_request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt, SA_SHIRQ, "cb_pcidas", dev ))
#ifdef CB_PCIDAS_DEBUG
rt_printk("detaching, incsr is 0x%x\n", inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR));
#endif
- release_region(devpriv->s5933_config, AMCC_OP_REG_SIZE);
}
- if(devpriv->control_status)
- release_region(devpriv->control_status, CONT_STAT_SIZE);
- if(devpriv->adc_fifo)
- release_region(devpriv->adc_fifo, ADC_FIFO_SIZE);
- if(devpriv->pacer_counter_dio)
- release_region(devpriv->pacer_counter_dio, PACER_SIZE);
- if(devpriv->ao_registers)
- release_region(devpriv->ao_registers, AO_SIZE);
}
if(dev->irq)
comedi_free_irq(dev->irq, dev);
if(dev->subdevices)
subdev_8255_cleanup(dev,dev->subdevices + 2);
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;
}
if( pci_enable_device( pcidev ) )
{
+ printk(KERN_WARNING " failed to enable PCI device\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;
-
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;
priv(dev)->plx9080_phys_iobase = pci_resource_start(pcidev, PLX9080_BADDRINDEX);
priv(dev)->main_phys_iobase = pci_resource_start(pcidev, MAIN_BADDRINDEX);
iounmap((void*)priv(dev)->main_iobase);
if(priv(dev)->dio_counter_iobase)
iounmap((void*)priv(dev)->dio_counter_iobase);
- if(priv(dev)->plx9080_phys_iobase ||
- priv(dev)->main_phys_iobase || priv(dev)->dio_counter_phys_iobase)
- pci_release_regions( priv(dev)->hw_dev );
// free pci dma buffers
for(i = 0; i < ai_dma_ring_count(board(dev)); i++)
{
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);
pci_dev_put(priv(dev)->hw_dev);
}
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);
* Initialize devpriv->control_status and devpriv->adc_fifo to point to
* their base address.
*/
- if(pci_enable_device(devpriv->pci_dev))
+ if(pci_enable_device(pcidev))
+ {
+ printk("cb_pcidda: failed to enable PCI device\n");
+ pci_dev_put(pcidev);
return -EIO;
+ }
/*
* Allocate the I/O ports.
*/
- if (pci_request_regions(devpriv->pci_dev, thisboard->name))
+ 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);
*/
if(devpriv)
{
- if(devpriv->digitalio)
- release_region(devpriv->digitalio, DIGITALIO_SIZE);
- if(devpriv->dac)
- release_region(devpriv->dac, 8 + thisboard->ao_chans*2);
if(devpriv->pci_dev)
+ {
+ pci_release_regions(devpriv->pci_dev);
+ pci_disable_device(devpriv->pci_dev);
pci_dev_put(devpriv->pci_dev);
+ }
}
// cleanup 8255
if(dev->subdevices)
continue;
}
}
- devpriv->pci_dev = pcidev;
dev->board_ptr = cb_pcimdas_boards + index;
goto found;
}
found:
printk("Found %s on bus %i, slot %i\n", cb_pcimdas_boards[index].name,
- devpriv->pci_dev->bus->number, PCI_SLOT(devpriv->pci_dev->devfn));
+ pcidev->bus->number, PCI_SLOT(pcidev->devfn));
// Warn about non-tested features
switch(thisboard->device_id)
"PLEASE REPORT USAGE TO <mocelet@sucs.org>\n");
};
- if(pci_request_regions(devpriv->pci_dev, "cb_pcimdas"))
+ 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);
devpriv->BADR2 = pci_resource_start(devpriv->pci_dev, 2);
devpriv->BADR3 = pci_resource_start(devpriv->pci_dev, 3);
devpriv->BADR4 = pci_resource_start(devpriv->pci_dev, 4);
- if(pci_enable_device(devpriv->pci_dev))
- return -EIO;
#ifdef CBPCIMDAS_DEBUG
printk("devpriv->BADR0 = %d\n",devpriv->BADR0);
printk("devpriv->BADR1 = %d\n",devpriv->BADR1);
}
#endif
printk("comedi%d: cb_pcimdas: remove\n",dev->minor);
+ if(dev->irq)
+ comedi_free_irq(dev->irq, dev);
if(devpriv)
{
- if(devpriv->BADR0)
+ if(devpriv->pci_dev)
{
pci_release_regions(devpriv->pci_dev);
- }
- if(devpriv->pci_dev)
+ pci_disable_device(devpriv->pci_dev);
pci_dev_put(devpriv->pci_dev);
+ }
}
-
- if(dev->irq)
- comedi_free_irq(dev->irq, dev);
return 0;
}
if (devpriv) {
if (devpriv->registers && thisboard) {
- release_region(devpriv->registers, REG_SZ);
devpriv->registers = 0;
}
}
if (devpriv->pci_dev) {
+ pci_release_regions(devpriv->pci_dev);
+ pci_disable_device(devpriv->pci_dev);
pci_dev_put(devpriv->pci_dev);
}
}
/* found ! */
- /* todo: if we support more than 1 board, revise
- this to be more generic */
- devpriv->pci_dev = pcidev;
- pci_enable_device(devpriv->pci_dev); /* make sure board is on */
dev->board_ptr = boards + index;
- registers = pci_resource_start(devpriv->pci_dev, REGS_BADRINDEX);
- request_region(registers, REG_SZ,thisboard->name);
-#if 0
+ 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 failed to allocate ports "
- "0x%x to 0x%x\n", registers,
- registers + REG_SZ - 1);
- return -EBUSY;
+ printk("cb_pcimdda: I/O port conflict\n");
+ pci_dev_put(pcidev);
+ return -EIO;
}
-#endif
+ devpriv->pci_dev = pcidev;
+ registers = pci_resource_start(devpriv->pci_dev, REGS_BADRINDEX);
devpriv->registers = registers;
devpriv->dio_registers
= devpriv->registers + thisboard->dio_offset;
if ( pcidev->vendor == PCI_VENDOR_ID_CONTEC &&
pcidev->device == PCI_DEVICE_ID_PIO1616L ) {
+ if (pci_enable_device(pcidev)) {
+ printk("error enabling PCI device!\n");
+ return -EIO;
+ }
+ if (pci_request_regions(pcidev, "contec_pci_dio")) {
+ 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 );
s->range_table = &range_digital;
s->insn_bits = contec_do_insn_bits;
+ printk("attached\n");
+
+ return 1;
}
}
- printk("attached\n");
+ printk("card not present!\n");
- return 1;
+ return -EIO;
}
{
printk("comedi%d: contec: remove\n",dev->minor);
- if (devpriv && devpriv->pci_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(" no daqboard2000 found\n");
result = -EIO;
goto out;
- }
-
- if((result = pci_enable_device(card))<0){
- pci_dev_put(card);
- goto out;
- }
-
- if (card->hdr_type == PCI_HEADER_TYPE_NORMAL) {
+ }else{
u32 id;
int i;
- pci_read_config_dword(card, PCI_SUBSYSTEM_VENDOR_ID, &id);
+ id = ((u32)card->subsystem_device << 16) | card->subsystem_vendor;
for(i=0;i<n_boardtypes;i++){
if(boardtypes[i].id==id){
printk(" %s",boardtypes[i].name);
printk(" unknown subsystem id %08x (pretend it is an ids2)",id);
dev->board_ptr=boardtypes;
}
- }else{
- printk(" abnormal pci header type !?!?\n");
- result=-EIO;
+ }
+
+ 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;
+ }
+
result = alloc_private(dev,sizeof(daqboard2000_private));
if(result<0){
+ pci_release_regions(card);
+ pci_disable_device(card);
pci_dev_put(card);
goto out;
}
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;
comedi_subdevice *s;
int ret;
- // allocate ioports for non-pcmcia boards
- if(thisboard->bustype != pcmcia)
+ // allocate ioports for non-pcmcia, non-pci boards
+ if((thisboard->bustype != pcmcia) && (thisboard->bustype != pci))
{
printk(" iobase 0x%lx\n", iobase);
if(!request_region(iobase, thisboard->iosize,"das08")){
printk("No pci das08 cards found\n");
return -EIO;
}
- devpriv->pdev = pdev;
- // read base addresses
- if(pci_enable_device(pdev))
+ // enable PCI device
+ if(pci_enable_device(pdev)){
+ printk(" Error enabling PCI device\n");
+ pci_dev_put(pdev);
return -EIO;
- pci_iobase = pci_resource_start(pdev, 1);
- iobase = pci_resource_start(pdev, 2);
- printk("pcibase 0x%lx ", pci_iobase);
- // reserve io ports for 9052 pci chip
- if(!request_region(pci_iobase,PCIDAS08_SIZE,"das08")){
+ }
+ // 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);
+ printk("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
if(dev->subdevices)
subdev_8255_cleanup(dev,dev->subdevices+4);
- // deallocate ioports for non-pcmcia boards
- if(thisboard->bustype != pcmcia)
+ // deallocate ioports for non-pcmcia, non-pci boards
+ if((thisboard->bustype != pcmcia) && (thisboard->bustype != pci))
{
if(dev->iobase)
release_region(dev->iobase, thisboard->iosize);
}
if(devpriv){
- if(devpriv->pci_iobase){
- release_region(devpriv->pci_iobase, PCIDAS08_SIZE);
- }
if(devpriv->pdev){
+ pci_release_regions(devpriv->pdev);
+ pci_disable_device(devpriv->pdev);
pci_dev_put(devpriv->pdev);
}
}
typedef struct{
struct pci_dev *pci_dev;
+ int pci_enabled;
unsigned long phys_addr;
void *io_addr;
unsigned int lock;
if(devpriv)
{
- if(devpriv->pci_dev) pci_dev_put(devpriv->pci_dev);
+ if(devpriv->pci_dev)
+ {
+ if (devpriv->pci_enabled)
+ {
+ pci_release_regions(devpriv->pci_dev);
+ pci_disable_device(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
if(devpriv->io_addr) iounmap(devpriv->io_addr);
}
/* XXX */
static int dt_pci_probe(comedi_device *dev)
{
int board;
+ int ret;
devpriv->pci_dev=dt_pci_find_device(NULL,&board);
- dev->board_ptr=dt3k_boardtypes+board;
+ if(board >= 0)
+ dev->board_ptr=dt3k_boardtypes+board;
if(!devpriv->pci_dev)
return 0;
- setup_pci(dev);
+ if ((ret=setup_pci(dev)) < 0)
+ return ret;
return 1;
}
ret = pci_enable_device(devpriv->pci_dev);
if(ret<0)return ret;
+ 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;
if( pci_enable_device( pcidev ) )
{
+ printk(KERN_WARNING " failed enable PCI device\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;
-
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;
priv(dev)->plx9080_phys_iobase = pci_resource_start(pcidev, PLX9080_BADDRINDEX);
priv(dev)->hpdi_phys_iobase = pci_resource_start(pcidev, HPDI_BADDRINDEX);
}
if( priv(dev)->hpdi_iobase )
iounmap((void*)priv(dev)->hpdi_iobase);
- if( priv(dev)->plx9080_phys_iobase ||
- priv(dev)->hpdi_phys_iobase )
- pci_release_regions( priv(dev)->hw_dev );
// free pci dma buffers
for( i = 0; i < NUM_DMA_BUFFERS; i++ )
{
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 );
pci_dev_put(priv(dev)->hw_dev);
}
Data & Structure declarations
==============================================================================
*/
-static unsigned short pci_list_builded=0; /*=1 list of card is know */
+static unsigned short pci_list_builded=0; /*>0 list of card is known */
typedef struct {
char *name; // driver name
COMEDI_INITCLEANUP(driver_icp_multi);
typedef struct{
+ struct pcilst_struct *card; // pointer to card
char valid; // card is usable
void *io_addr; // Pointer to mapped io address
unsigned long phys_iobase; // Physical io address
return ret;
// Initialise list of PCI cards in system, if not already done so
- if (!pci_list_builded) {
+ if (pci_list_builded++ == 0) {
pci_card_list_init(PCI_VENDOR_ID_ICP,
#ifdef ICP_MULTI_EXTDEBUG
1
0
#endif
);
- pci_list_builded=1;
}
printk("Anne's comedi%d: icp_multi: board=%s", dev->minor, this_board->name);
if ((card=select_and_alloc_pci_card(PCI_VENDOR_ID_ICP, this_board->device_id, it->options[0], it->options[1]))==NULL)
return -EIO;
+ devpriv->card = card;
+
if ((pci_card_data(card, &pci_bus, &pci_slot, &pci_func, &io_addr[0], &irq, &master))<0) {
- pci_card_free(card);
printk(" - Can't get configuration data!\n");
return -EIO;
}
iobase=io_addr[2];
-
- if(!request_mem_region(iobase, ICP_MULTI_SIZE, "icp_multi"))
- {
- /* Couldn't allocate io space */
- printk(KERN_WARNING "couldn't allocate IO space\n");
- return -EIO;
- }
devpriv->phys_iobase = iobase;
printk(", b:s:f=%d:%d:%d, io=0x%8lx \n", pci_bus, pci_slot, pci_func, iobase);
if (this_board->n_ctrs) n_subdevices++;
if((ret=alloc_subdevices(dev, n_subdevices))<0) {
- pci_card_free(card);
return ret;
}
if (dev->irq)
comedi_free_irq(dev->irq,dev);
- if (dev->private && devpriv->io_addr) {
+ if (dev->private && devpriv->io_addr)
iounmap(devpriv->io_addr);
- release_mem_region(devpriv->phys_iobase, ICP_MULTI_SIZE);
- }
- if (pci_list_builded) {
+ if (dev->private && devpriv->card)
+ pci_card_free(devpriv->card);
+
+ if (--pci_list_builded == 0) {
pci_card_list_cleanup(PCI_VENDOR_ID_ICP);
- pci_list_builded=0;
}
inova->pci_bus=pcidev->bus->number;
inova->pci_slot=PCI_SLOT(pcidev->devfn);
inova->pci_func=PCI_FUNC(pcidev->devfn);
+ /* Note: resources may be invalid if PCI device
+ * not enabled, but they are corrected in
+ * pci_card_alloc. */
for (i=0;i<5;i++)
inova->io_addr[i]=pci_resource_start(pcidev, i);
inova->irq=pcidev->irq;
/* mark card as used */
static int pci_card_alloc(struct pcilst_struct *inova)
{
- if (!inova) return -1;
+ int i;
+
+ if (!inova) {
+ rt_printk(" - BUG!! inova is NULL!\n");
+ return -1;
+ }
if (inova->used) return 1;
- if(pci_enable_device(inova->pcidev)) return -1;
+ if(pci_enable_device(inova->pcidev)) {
+ rt_printk(" - Can't enable PCI device!\n");
+ return -1;
+ }
+ /* Resources will be accurate now. */
+ for (i=0;i<5;i++)
+ inova->io_addr[i]=pci_resource_start(inova->pcidev, i);
+ inova->irq=inova->pcidev->irq;
+ /* Request regions on behalf of client. */
+ if (pci_request_regions(inova->pcidev, "icp_multi")) {
+ rt_printk(" - I/O port conflict!\n");
+ return -1;
+ }
inova->used=1;
return 0;
}
if (!inova->used) return 1;
inova->used=0;
+ pci_release_regions(inova->pcidev);
+ pci_disable_device(inova->pcidev);
return 0;
}
static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id, unsigned short device_id, unsigned short pci_bus, unsigned short pci_slot)
{
struct pcilst_struct *card;
+ int err;
if ((pci_bus<1)&(pci_slot<1)) { // use autodetection
if ((card=find_free_pci_card_by_device(vendor_id,device_id))==NULL) {
}
- if (pci_card_alloc(card)!=0) {
- rt_printk(" - Can't allocate card!\n");
+ if ((err=pci_card_alloc(card))!=0) {
+ if (err > 0)
+ rt_printk(" - Can't allocate card!\n");
+ /* else: error already printed. */
return NULL;
}
board->name, pci_device->bus->number, PCI_SLOT(pci_device->devfn));
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;
+ }
+
/* read register base address [PCI_BASE_ADDRESS #0] */
io_base = pci_resource_start(pci_device, 0);
- request_region(io_base & PCI_BASE_ADDRESS_IO_MASK, 0x08, CNT_DRIVER_NAME);
dev->iobase = io_base & PCI_BASE_ADDRESS_IO_MASK;
/* allocate device private structure */
static int cnt_detach(comedi_device *dev)
{
- if (dev->iobase)
- {
- release_region(dev->iobase, 0x08);
- }
- if (devpriv->pcidev)
+ if (devpriv && devpriv->pcidev)
{
+ pci_release_regions(devpriv->pcidev);
+ pci_disable_device(devpriv->pcidev);
pci_dev_put(devpriv->pcidev);
}
/* Set data in device structure */
dev->board_name = board->name;
- info->pci_dev_p = pci_device;
- /* Get the PCI base registers */
- result = get_registers(dev, pci_device);
+ /* Enable PCI device */
+ result = pci_enable_device(pci_device);
if(result){
- printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot get registers\n", dev->minor);
- goto PROBE_ERROR_1;
+ printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot enable PCI device\n", dev->minor);
+ pci_dev_put(pci_device);
+ 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);
- goto PROBE_ERROR_1;
+ pci_dev_put(pci_device);
+ return result;
}
- /* Initialize board info */
+ /* 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;
+ }
+ /* Initialize board info (sets info->pci_dev_p) */
result = init_board_info(dev, pci_device);
if (result){
printk(KERN_ERR"comedi%d: me4000: me4000_probe(): Cannot init baord info\n", dev->minor);
- goto PROBE_ERROR_2;
+ 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);
- goto PROBE_ERROR_2;
+ 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);
- goto PROBE_ERROR_2;
+ 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);
- goto PROBE_ERROR_2;
+ 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);
- goto PROBE_ERROR_2;
+ 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);
- goto PROBE_ERROR_2;
+ 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);
- goto PROBE_ERROR_2;
+ return result;
}
return 0;
-
-PROBE_ERROR_2:
- pci_release_regions(pci_device);
-
-PROBE_ERROR_1:
-
- return result;
}
CALL_PDEBUG("In me4000_detach()\n");
if(info){
- reset_board(dev);
-
if(info->pci_dev_p) {
+ reset_board(dev);
pci_release_regions(info->pci_dev_p);
pci_dev_put(info->pci_dev_p);
}
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;
+ }
+
+ // Request PCI regions
+ 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;
{
if(dev_private)
{
- me_reset(dev);
+ 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);
}
}
iounmap(mite->daq_io_addr);
mite->daq_io_addr=NULL;
}
- if( mite->used )
+ if( mite->used ){
pci_release_regions( mite->pcidev );
+ pci_disable_device( mite->pcidev );
+ }
mite->used = 0;
}
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);
+ 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;
+
/*
* Initialize base addresses
*/
devpriv->las1 = ioremap_nocache(physLas1, LAS1_PCISIZE);
devpriv->lcfg = ioremap_nocache(physLcfg, LCFG_PCISIZE);
+ if(!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg){
+ return -ENOMEM;
+ }
+
DPRINTK ("%s: LAS0=%lx, LAS1=%lx, CFG=%lx.\n", dev->board_name,
physLas0, physLas1, physLcfg);
{ /* The RTD driver does this */
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;
}
printk("( irq=%d )", dev->irq);
int index;
#endif
- DPRINTK("comedi%d: rtd520: removing (%ld ints)\n(int status 0x%x, overrun status 0x%x, fifo status 0x%x)...\n",
- dev->minor, devpriv->intCount,
- 0xffff & RtdInterruptStatus (dev),
- 0xffff & RtdInterruptOverrunStatus (dev),
- (0xffff & RtdFifoStatus (dev)) ^ 0x6666);
+ DPRINTK("comedi%d: rtd520: removing (%ld ints)\n",
+ dev->minor, (devpriv ? devpriv->intCount : 0L));
+ if (devpriv && devpriv->lcfg) {
+ DPRINTK("(int status 0x%x, overrun status 0x%x, fifo status 0x%x)...\n",
+ 0xffff & RtdInterruptStatus (dev),
+ 0xffff & RtdInterruptOverrunStatus (dev),
+ (0xffff & RtdFifoStatus (dev)) ^ 0x6666);
+ }
if (devpriv) {
/* Shut down any board ops by resetting it */
#ifdef USE_DMA
- RtdDma0Control (dev, 0); /* disable DMA */
- RtdDma1Control (dev, 0); /* disable DMA */
- RtdPlxInterruptWrite (dev, ICS_PIE | ICS_PLIE);
+ if (devpriv->lcfg) {
+ RtdDma0Control (dev, 0); /* disable DMA */
+ RtdDma1Control (dev, 0); /* disable DMA */
+ RtdPlxInterruptWrite (dev, ICS_PIE | ICS_PLIE);
+ }
#endif /* USE_DMA */
- RtdResetBoard (dev);
- RtdInterruptMask (dev, 0);
- RtdInterruptClearMask (dev,~0);
- RtdInterruptClear(dev); /* clears bits set by mask */
+ if (devpriv->las0) {
+ RtdResetBoard (dev);
+ RtdInterruptMask (dev, 0);
+ RtdInterruptClearMask (dev,~0);
+ RtdInterruptClear(dev); /* clears bits set by mask */
+ }
#ifdef USE_DMA
/* release DMA */
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);
}
}
uint64_t resourceStart;
dma_addr_t appdma;
comedi_subdevice *s;
+ struct pci_dev *pdev;
if(alloc_private(dev,sizeof(s626_private))<0)
return -ENOMEM;
- devpriv->pdev=NULL;
-
- devpriv->pdev=pci_find_device(PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, NULL);
+ pdev=pci_get_device(PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, NULL);
- if(devpriv->pdev==NULL) {
+ if(pdev==NULL) {
printk("s626_attach: Board not present!!!");
return -ENODEV;
}
- if((result = pci_enable_device(devpriv->pdev))<0){
+ 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);
static int s626_detach(comedi_device *dev)
{
- //stop ai_command
- devpriv->ai_cmd_running=0;
-
- //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(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(dev->irq){
+ comedi_free_irq(dev->irq,dev);
+ }
+
+ if(devpriv->base_addr){
+ iounmap(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");