]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/src/nsi_canpci.c
LinCAN PCI cards support updated to support PCI devices reference counting.
[lincan.git] / lincan / src / nsi_canpci.c
index d8194be6b3e1d4f2950e8aca3adc837507ca1776..1fee22726cb4693a5a85a65296e0a699371cd4a5 100644 (file)
@@ -375,43 +375,25 @@ int nsi_canpci_reset(struct candevice_t *candev)
  */
 
 int nsi_canpci_init_hw_data(struct candevice_t *candev) 
-     {
-  struct pci_dev *pcidev = NULL;
+{
+       struct pci_dev *pcidev;
 
-  /* looking for NSI CANPCI ident on the pci bus*/
-  do
-  {
-    pcidev = pci_find_device(NSI_VENDOR_ID, NSI_CANPCI_DEVICE_ID, pcidev);
-  }
-  while(can_check_dev_taken(pcidev));
-  
-  if(pcidev == NULL) 
-  {
-       do
-       {
-       pcidev = pci_find_device(NSI_VENDOR_ID, NSI_CANPCI_DEVICE_ID+1, pcidev);
-       }
-       while(can_check_dev_taken(pcidev));
-       if(pcidev == NULL) 
-       {
+       /* looking for NSI CANPCI ident on the pci bus*/
+       pcidev = can_pci_get_next_untaken_device(NSI_VENDOR_ID, NSI_CANPCI_DEVICE_ID);
+       if(pcidev == NULL)
+               pcidev = can_pci_get_next_untaken_device(NSI_VENDOR_ID, NSI_CANPCI_DEVICE_ID+1);
+       if(pcidev == NULL) {
                CANMSG ("Error : NSI CAN PCI device not found\n");
                return -ENODEV;
        }
-       else
-       {
-               CANMSG ("NSI CANPCI OPTO device found\n");
-       }
-  }
-  else
-  {
+
        CANMSG ("NSI CANPCI device found\n");  
-  }
-    
+
   /* enable it */
   if (pci_enable_device (pcidev))
   {
     CANMSG ("Cannot enable PCI device\n");
-    return -EIO;
+    goto error_io;
   }
   CANMSG ("NSI CANPCI device started\n");
   candev->sysdevptr.pcidev = pcidev;
@@ -436,30 +418,30 @@ int nsi_canpci_init_hw_data(struct candevice_t *candev)
                        pci_release_region(pcidev,0);
                        pci_release_region(pcidev,1);
                        pci_release_region(pcidev,2);                   
-                       return -EIO;
+                       goto error_io;
                        }
                }
                else
                {
                pci_release_region(pcidev,0);
                pci_release_region(pcidev,1);
-               return -EIO;
+               goto error_io;
                }
        }
        else
        {
        pci_release_region(pcidev,0);
-       return -EIO;
+       goto error_io;
        }
   }  
   else
   {
-       return -EIO;
+       goto error_io;
   }
   candev->dev_base_addr=(unsigned long)(kmalloc(sizeof(t_CardArray),GFP_ATOMIC));  
   
   if((unsigned long)candev->dev_base_addr==0)
-       return -EIO;
+       goto error_io;
   //PLX register 
   ((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[0]=ioremap(pci_resource_start(pcidev,0),pci_resource_len(pcidev,0) );
   //PLX IO
@@ -472,8 +454,20 @@ int nsi_canpci_init_hw_data(struct candevice_t *candev)
   //Short acces to plx register
   candev->io_addr=(unsigned long)(((t_CardArray*)(candev->dev_base_addr))->addr_BAR_remap[0]);
   return 0;  
+
+error_io:
+       can_pci_dev_put(pcidev);
+       return -EIO;
 }
 
+
+void nsi_canpci_done_hw_data(struct candevice_t *candev)
+{
+       struct pci_dev *pcidev = candev->sysdevptr.pcidev;
+       can_pci_dev_put(pcidev);
+}
+
+
 /* The function template_init_chip_data is used to initialize the hardware
  * structure containing information about the CAN chips.
  * CHIP_TYPE represents the type of CAN chip. CHIP_TYPE can be "i82527" or
@@ -564,6 +558,7 @@ int nsi_canpci_register(struct hwspecops_t *hwspecops)
        hwspecops->release_io = nsi_canpci_release_io;
        hwspecops->reset = nsi_canpci_reset;
        hwspecops->init_hw_data = nsi_canpci_init_hw_data;
+       hwspecops->done_hw_data = nsi_canpci_done_hw_data;
        hwspecops->init_chip_data = nsi_canpci_init_chip_data;
        hwspecops->init_obj_data = nsi_canpci_init_obj_data;
        hwspecops->write_register = nsi_canpci_write_register;