]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/src/ipci165.c
LinCAN PCI cards support updated to support PCI devices reference counting.
[lincan.git] / lincan / src / ipci165.c
index 097523164e5bca6efb54458f3581716c569cdb50..6b90ed0236e3ade276ded0247fc2c061fe29881e 100644 (file)
@@ -1,10 +1,37 @@
-/* ipci165.c
- * Linux CAN-bus device driver for IXXAT iPC-I 165 (PCI) compatible HW.
- * Written for new CAN driver version by Radim Kalas
- * email:kalas@unicontrols.cz
- * This software is released under the GPL-License.
- * Version lincan-0.3  17 Jun 2004
- */
+/**************************************************************************/
+/* File: ipci165.c - support for IXXAT iPC-I 165 (PCI) compatible HW      */
+/*                                                                        */
+/* LinCAN - (Not only) Linux CAN bus driver                               */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz>   */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz>             */
+/* Copyright (C) 2004-2005 Radim Kalas <kalas@unicontrols.cz>             */
+/* Funded by OCERA and FRESCOR IST projects                               */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl>      */
+/*                                                                        */
+/* LinCAN is free software; you can redistribute it and/or modify it      */
+/* under terms of the GNU General Public License as published by the      */
+/* Free Software Foundation; either version 2, or (at your option) any    */
+/* later version.  LinCAN is distributed in the hope that it will be      */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty    */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU    */
+/* General Public License for more details. You should have received a    */
+/* copy of the GNU General Public License along with LinCAN; see file     */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
+/* Cambridge, MA 02139, USA.                                              */
+/*                                                                        */
+/* To allow use of LinCAN in the compact embedded systems firmware        */
+/* and RT-executives (RTEMS for example), main authors agree with next    */
+/* special exception:                                                     */
+/*                                                                        */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce    */
+/* an application image/executable, does not by itself cause the          */
+/* resulting application image/executable to be covered by                */
+/* the GNU General Public License.                                        */
+/* This exception does not however invalidate any other reasons           */
+/* why the executable file might be covered by the GNU Public License.    */
+/* Publication of enhanced or derived LinCAN files is required although.  */
+/**************************************************************************/
 
 #include "../include/can.h"
 #include "../include/can_sysdep.h"
 
 #include <ctype.h>
 
+#ifndef IRQF_SHARED
+#define IRQF_SHARED SA_SHIRQ
+#endif  /*IRQF_SHARED*/
+
 can_irqreturn_t ipci165_irq_handler(CAN_IRQ_HANDLER_ARGS(irq_number, dev_id));
 int ipci165_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
                       int sampl_pt, int flags);
@@ -321,7 +352,7 @@ int ipci165_connect_irq(struct candevice_t *candev)
   /* install interrupt routine */
   if (request_irq(candev->sysdevptr.pcidev->irq,
                   ipci165_irq_handler,
-                  SA_SHIRQ,
+                  IRQF_SHARED,
                   DEVICE_NAME,
                   candev))
     return -ENODEV;
@@ -1352,21 +1383,20 @@ int ipci165_reset(struct candevice_t *candev)
 int ipci165_init_hw_data(struct candevice_t *candev)
 {
   struct pci_dev *pcidev = NULL;
-  unsigned short SubsystemID;
 
   DEBUGMSG ("ipci165_init_hw_data\n");
 
   /* find iPC-I 165 on PCI bus */
   do
   {
-    pcidev = pci_find_device(IPCI165_VENDOR_ID, IPCI165_DEVICE_ID, pcidev);
-    if(pcidev == NULL) return -ENODEV;
+    pcidev = can_pci_get_device(IPCI165_VENDOR_ID, IPCI165_DEVICE_ID, pcidev);
+    if(pcidev == NULL)
+      return -ENODEV;
 
     /* check subvendor ID */
-    pci_read_config_word (pcidev, PCI_SUBSYSTEM_ID, &SubsystemID);
-    if ((SubsystemID != IPCI165_SUBSYSTEM_ID) &&
-        (SubsystemID != CP350_SUBSYSTEM_ID))
-      break;
+    if ((pcidev->subsystem_vendor != IPCI165_SUBSYSTEM_ID) &&
+        (pcidev->subsystem_vendor != CP350_SUBSYSTEM_ID))
+      continue;
   }
   while(can_check_dev_taken(pcidev));
 
@@ -1374,6 +1404,7 @@ int ipci165_init_hw_data(struct candevice_t *candev)
   if (pci_enable_device (pcidev))
   {
     CANMSG ("Cannot enable PCI device\n");
+    can_pci_dev_put(pcidev);
     return -EIO;
   }
 
@@ -1392,6 +1423,12 @@ int ipci165_init_hw_data(struct candevice_t *candev)
   return 0;
 }
 
+void ipci165_done_hw_data(struct candevice_t *candev)
+{
+  struct pci_dev *pcidev = candev->sysdevptr.pcidev;
+  can_pci_dev_put(pcidev);
+}
+
 #define CHIP_TYPE "ipci165"
 
 /**
@@ -1516,6 +1553,7 @@ int ipci165_register(struct hwspecops_t *hwspecops)
   hwspecops->release_io = ipci165_release_io;
   hwspecops->reset = ipci165_reset;
   hwspecops->init_hw_data = ipci165_init_hw_data;
+  hwspecops->done_hw_data = ipci165_done_hw_data;
   hwspecops->init_chip_data = ipci165_init_chip_data;
   hwspecops->init_obj_data = ipci165_init_obj_data;
   hwspecops->write_register = NULL;