+
+
+/* Unicontrols PCI board specific functions */
+
+#ifdef CAN_ENABLE_PCI_SUPPORT
+
+int unican_pci_request_io(struct candevice_t *candev)
+{
+ unsigned long remap_addr;
+
+ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
+ if(pci_request_region(candev->sysdevptr.pcidev, 0, "unican_pci") != 0){
+ CANMSG("Request of Unican PCI range failed\n");
+ return -ENODEV;
+ }
+ #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+ if(pci_request_regions(candev->sysdevptr.pcidev, "kv_pcican") != 0){
+ CANMSG("Request of Unican PCI range failed\n");
+ return -ENODEV;
+ }
+ #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+
+ candev->dev_base_addr=pci_resource_start(candev->sysdevptr.pcidev,0);
+ candev->io_addr=candev->dev_base_addr;
+ candev->res_addr=candev->dev_base_addr;
+
+ if ( !( remap_addr = (long) ioremap( candev->io_addr, IO_RANGE ) ) ) {
+ CANMSG("Unable to access I/O memory at: 0x%lx\n", candev->io_addr);
+ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
+ pci_release_region(candev->sysdevptr.pcidev, 0);
+ #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+ pci_release_regions(candev->sysdevptr.pcidev);
+ #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+ return -ENODEV;
+
+ }
+ can_base_addr_fixup(candev, remap_addr);
+ DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", candev->io_addr, candev->io_addr + IO_RANGE - 1);
+ DEBUGMSG("VMA: dev_base_addr: 0x%lx chip_base_addr: 0x%lx\n",
+ candev->dev_base_addr, candev->chip[0]->chip_base_addr);
+
+ return 0;
+}
+
+
+int unican_pci_release_io(struct candevice_t *candev)
+{
+ iounmap((void*)candev->dev_base_addr);
+ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
+ pci_release_region(candev->sysdevptr.pcidev, 0);
+ #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+ pci_release_regions(candev->sysdevptr.pcidev);
+ #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
+ return 0;
+}
+
+
+int unican_pci_init_hw_data(struct candevice_t *candev)
+{
+ struct pci_dev *pcidev = NULL;
+
+ do {
+ pcidev = pci_find_device(UNICAN_PCI_VENDOR, UNICAN_PCI_ID, pcidev);
+ if(pcidev == NULL) return -ENODEV;
+ } while(can_check_dev_taken(pcidev));
+
+ if (pci_enable_device (pcidev)){
+ printk(KERN_CRIT "Setup of Unican PCI failed\n");
+ return -EIO;
+ }
+ candev->sysdevptr.pcidev=pcidev;
+
+ if(!(pci_resource_flags(pcidev,0)&IORESOURCE_MEM)){
+ printk(KERN_CRIT "Unican PCI region 0 is not MEM\n");
+ return -EIO;
+ }
+ candev->dev_base_addr=pci_resource_start(pcidev,0);
+ candev->io_addr=candev->dev_base_addr;
+ candev->res_addr=candev->dev_base_addr;
+
+ /*candev->flags |= CANDEV_PROGRAMMABLE_IRQ;*/
+
+ candev->nr_82527_chips=0;
+ candev->nr_sja1000_chips=0;
+ candev->nr_all_chips=1;
+
+ return 0;
+}
+
+
+int unican_pci_init_chip_data(struct candevice_t *candev, int chipnr)
+{
+ int ret;
+ candev->chip[chipnr]->chip_irq=candev->sysdevptr.pcidev->irq;
+ ret = unican_init_chip_data(candev, chipnr);
+ candev->chip[chipnr]->flags |= CHIP_IRQ_PCI;
+ return ret;
+}
+
+int unican_pci_register(struct hwspecops_t *hwspecops)
+{
+ hwspecops->request_io = unican_pci_request_io;
+ hwspecops->release_io = unican_pci_release_io;
+ hwspecops->reset = unican_reset;
+ hwspecops->init_hw_data = unican_pci_init_hw_data;
+ hwspecops->init_chip_data = unican_pci_init_chip_data;
+ hwspecops->init_obj_data = unican_init_obj_data;
+ hwspecops->write_register = NULL;
+ hwspecops->read_register = NULL;
+ hwspecops->program_irq = unican_program_irq;
+ return 0;
+}
+
+#endif /*CAN_ENABLE_PCI_SUPPORT*/
+
+#ifdef CAN_ENABLE_VME_SUPPORT
+
+#include "unican_vme.c"
+
+#endif /*CAN_ENABLE_VME_SUPPORT*/