--- multiqpci.c.orig	2006-07-31 10:50:48.000000000 +0100
+++ multiqpci.c	2006-08-01 15:17:56.000000000 +0100
@@ -1791,44 +1791,43 @@ static int MQPCI_attach(comedi_device * 
       struct pci_dev* pcidev = NULL;
       uint16_t chan;
       unsigned int IsBoardRevA = 0;
-      u16 subvendor_id, subdevice_id;
+      int bus, slot;
       //    Allocate private structure area
 
       result = alloc_private(dev,sizeof(struct MQPCI_private));
       if(result<0)return -ENOMEM;
 
+      bus = it->options[0];
+      slot= it->options[1];
+
       // probe the card
-      // should use pci_find_subsys if kernel >= 2.4	
-      // this a workaround with kernel 2.2
       // search for device
+      // match PCI bus and slot specified in options if non-zero
 
-      // pci_for_each_dev(pcidev)
-      pcidev = pci_find_subsys(VENDORID_MQ,
-			       DEVICEID_MQ,
-			       SUBVENDORID_MQ,
-			       SUBDEVICEID_MQ,
-			       NULL);
-      if (pcidev != NULL) goto found;
-
-/* 	{ */
-/* 		// is it not righ vendor card? */
-/* 		if(pcidev->vendor != VENDORID_MQ) */
-/* 			continue; */
-/* 		// loop through cards supported by this driver */
-/* 			if(pcidev->device != DEVICEID_MQ) */
-/* 				continue; */
-/* 			// found it, check sub vendor */
-/* 			pci_read_config_word(pcidev,0x2c,&subvendor_id); */
-/* 			if (subvendor_id != SUBVENDORID_MQ) */
-/* 				continue; */
-/* 		 	// and subdevice as well */
-/* 		 	pci_read_config_word(pcidev,0x2e,&subdevice_id); */
-/* 		 	if (subdevice_id != SUBDEVICEID_MQ) */
-/* 		 		continue; */
-			
-/* 			goto found; */
-		
-/* 	} */
+	for (
+			pcidev = pci_get_subsys(VENDORID_MQ,
+						DEVICEID_MQ,
+						SUBVENDORID_MQ,
+						SUBDEVICEID_MQ,
+						NULL);
+			pcidev != NULL;
+			pcidev = pci_get_subsys(VENDORID_MQ,
+						DEVICEID_MQ,
+						SUBVENDORID_MQ,
+						SUBDEVICEID_MQ,
+						pcidev)
+	    ) {
+		if (bus || slot)
+		{
+			/* Match specified bus and slot. */
+			if (bus != pcidev->bus->number
+					|| slot != PCI_SLOT(pvidev->devfn))
+			{
+				continue;
+			}
+		}
+		goto found;
+	}
 
 	printk("No supported ComputerBoards/MeasurementComputing card found\n");
 	return -EIO;
@@ -1844,7 +1843,16 @@ found:
 
       // enable the card
       if (pci_enable_device(pcidev))
-	return -EIO;
+        {
+	  printk("comedi%d: Could not enable PCI device\n",dev->minor);
+	  return -EIO;
+	}
+      // request PCI regions
+      if (pci_request_regions(pcidev, "multiqpci"))
+	{
+	  printk("comedi%d: I/O port conflict\n",dev->minor);
+	  return -EIO;
+	}
       // set master
       pci_set_master(pcidev);
       	
@@ -1855,16 +1863,6 @@ found:
       printk("Physial address : 0x%lx\n",iobase);
       devpriv->phys_iobase = iobase;
       	
-      // check if the region is available
-      if (check_mem_region(iobase,SIZEOF_ADDRESS_SPACE) < 0)
-	{
-	  printk("comedi%d: I/O port conflict\n",dev->minor);
-	  return -EIO;
-	}
-
-      // request memory region
-      request_mem_region(iobase,SIZEOF_ADDRESS_SPACE,"multiqpci");
-
       // use io remap the adddress
       iobase = (unsigned long)ioremap(iobase,SIZEOF_ADDRESS_SPACE);
 
@@ -1903,6 +1901,16 @@ found:
       devpriv->dma_desc = pci_alloc_consistent(devpriv->hw_dev, sizeof(struct plx_dma_desc) * 3,
 		&devpriv->dma_desc_phys_addr);
       */		
+
+      if (!devpriv->m_ADCBuf.m_pBuffer
+		      || !devpriv->m_RPSBuf.m_pBuffer
+		      || !devpriv->m_TIMBuf.m_pBuffer
+		      /* || !devpriv->dma_desc */
+	 )
+	{
+	  printk("Unable to DMA buffer for MultiQ PCI\n",pcidev->irq);
+	  return -ENOMEM;
+	}
       		
       // Init the RPS0 program, which is used to generate
       // hardware time delays.
@@ -2084,34 +2092,47 @@ found:
 static int MQPCI_detach(comedi_device * dev)
 {
   printk("comedi%d: multiqpci: removed\n", dev->minor);
-  // unmap
-// Disable interrupts.
- MQPCI_InterruptMask(dev);
 
-		// Disable the watchdog timer and battery charger.
-		MQPCI_WriteMISC2(dev, 0);
+  if (!devpriv)
+    return 0;
 
-		// Close all interfaces on 7146 device.
-		writel(MC1_SHUTDOWN,dev->iobase+P_MC1);
+  if (dev->iobase) {
+    // Disable interrupts.
+    MQPCI_InterruptMask(dev);
 
-		writel(ACON1_BASE,dev->iobase+P_ACON1);
+    // Disable the watchdog timer and battery charger.
+    MQPCI_WriteMISC2(dev, 0);
 
+    // Close all interfaces on 7146 device.
+    writel(MC1_SHUTDOWN,dev->iobase+P_MC1);
 
-  // free DMA buffer
-  
-pci_free_consistent(devpriv->m_sCard,ADC_DMABUF_SIZE,devpriv->m_ADCBuf.m_pBuffer,devpriv->m_ADCBuf.m_nBusAddress);
+    writel(ACON1_BASE,dev->iobase+P_ACON1);
 
-  
-pci_free_consistent(devpriv->m_sCard,RPS_DMABUF_SIZE,devpriv->m_RPSBuf.m_pBuffer,devpriv->m_RPSBuf.m_nBusAddress);
+    // unmap
+    iounmap((void*)dev->iobase);
+  }
+
+//  if (dev->irq) { free_irq(dev->irq,dev); }
 
+  // free DMA buffer
   
-pci_free_consistent(devpriv->m_sCard,TIM_DMABUF_SIZE,devpriv->m_TIMBuf.m_pBuffer,devpriv->m_TIMBuf.m_nBusAddress);
+  if (devpriv->m_ADCBuf.m_pBuffer)
+     pci_free_consistent(devpriv->m_sCard,ADC_DMABUF_SIZE,devpriv->m_ADCBuf.m_pBuffer,devpriv->m_ADCBuf.m_nBusAddress);
 
+  if (devpriv->m_RPSBuf.m_pBuffer)
+    pci_free_consistent(devpriv->m_sCard,RPS_DMABUF_SIZE,devpriv->m_RPSBuf.m_pBuffer,devpriv->m_RPSBuf.m_nBusAddress);
 
-  iounmap((void*)dev->iobase);
+  if (devpriv->m_TIMBuf.m_pBuffer)
+    pci_free_consistent(devpriv->m_sCard,TIM_DMABUF_SIZE,devpriv->m_TIMBuf.m_pBuffer,devpriv->m_TIMBuf.m_nBusAddress);
 
-  if (dev->iobase) { release_mem_region(devpriv->phys_iobase, MQPCI_SIZE); }
-//  if (dev->irq) { free_irq(dev->irq,dev); }
+  // release PCI device and regions
+  if (devpriv->m_sCard) {
+    if (dev->iobase) {
+      pci_release_regions(devpriv->m_sCard);
+      pci_disable_device(devpriv->m_sCard);
+    }
+    pci_dev_put(devpriv->m_sCard);
+  }
 
   return 0;
 }

