X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/446346b22245a238d8d70390797b9749eac03788..3367930de7bb1e08bed6463ff3ed66f242bf8fc0:/lincan/src/unican.c diff --git a/lincan/src/unican.c b/lincan/src/unican.c index df556d6..10cc185 100644 --- a/lincan/src/unican.c +++ b/lincan/src/unican.c @@ -1,10 +1,36 @@ -/* unican.c - * Linux CAN-bus device driver. - * Written for new CAN driver version by Pavel Pisa - OCERA team member - * email:pisa@cmp.felk.cvut.cz - * This software is released under the GPL-License. - * Version lincan-0.3 17 Jun 2004 - */ +/**************************************************************************/ +/* File: unican.c - Unicontrols PCAN,PCAN-PCI, VCAN boards support */ +/* */ +/* LinCAN - (Not only) Linux CAN bus driver */ +/* Copyright (C) 2002-2009 DCE FEE CTU Prague */ +/* Copyright (C) 2002-2009 Pavel Pisa */ +/* Funded by OCERA and FRESCOR IST projects */ +/* Based on CAN driver code by Arnaud Westenberg */ +/* */ +/* 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" @@ -347,6 +373,34 @@ int unican_stop_chip(struct canchip_t *chip) return 0; } +/** + * unican_attach_to_chip: - attaches to the chip, setups registers and state + * @chip: pointer to chip state structure + * + * Return Value: negative value reports error. + * File: src/sja1000p.c + */ +int unican_attach_to_chip(struct canchip_t *chip) +{ + return 0; +} + +/** + * unican_release_chip: - called before chip structure removal if %CHIP_ATTACHED is set + * @chip: pointer to chip state structure + * + * Return Value: negative value reports error. + * File: src/sja1000p.c + */ +int unican_release_chip(struct canchip_t *chip) +{ + sCAN_CARD *chipext = (sCAN_CARD *)chip->chip_data; + + unican_stop_chip(chip); + cl2_clear_interrupt(chipext); + + return 0; +} /** * unican_remote_request: - configures message object and asks for RTR message @@ -665,12 +719,12 @@ int unican_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj) */ int unican_request_io(struct candevice_t *candev) { - unsigned long remap_addr; + can_ioptr_t remap_addr; if (!can_request_mem_region(candev->io_addr,IO_RANGE,DEVICE_NAME " - unican")) { CANMSG("Unable to request IO-memory: 0x%lx\n",candev->io_addr); return -ENODEV; } - if ( !( remap_addr = (long) ioremap( candev->io_addr, IO_RANGE ) ) ) { + if ( !( remap_addr = ioremap( candev->io_addr, IO_RANGE ) ) ) { CANMSG("Unable to access I/O memory at: 0x%lx\n", candev->io_addr); can_release_mem_region(candev->io_addr,IO_RANGE); return -ENODEV; @@ -690,7 +744,7 @@ int unican_request_io(struct candevice_t *candev) */ int unican_release_io(struct candevice_t *candev) { - iounmap((void*)candev->dev_base_addr); + iounmap(candev->dev_base_addr); can_release_mem_region(candev->io_addr,IO_RANGE); return 0; } @@ -784,7 +838,7 @@ int unican_init_chip_data(struct candevice_t *candev, int chipnr) chip->int_clk_reg = 0x0; chip->int_bus_reg = 0x0; chip->max_objects = 1; - chip->chip_base_addr=candev->io_addr; + chip->chip_base_addr=candev->dev_base_addr; CANMSG("initializing unican chip operations\n"); chip->chipspecops->chip_config=unican_chip_config; @@ -803,6 +857,8 @@ int unican_init_chip_data(struct candevice_t *candev, int chipnr) chip->chipspecops->enable_configuration=unican_enable_configuration; chip->chipspecops->disable_configuration=unican_disable_configuration; chip->chipspecops->set_btregs=unican_set_btregs; + chip->chipspecops->attach_to_chip=unican_attach_to_chip; + chip->chipspecops->release_chip=unican_release_chip; chip->chipspecops->start_chip=unican_start_chip; chip->chipspecops->stop_chip=unican_stop_chip; chip->chipspecops->irq_handler=unican_irq_handler; @@ -861,7 +917,7 @@ int unican_register(struct hwspecops_t *hwspecops) int unican_pci_request_io(struct candevice_t *candev) { - unsigned long remap_addr; + can_ioptr_t remap_addr; #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21)) if(pci_request_region(candev->sysdevptr.pcidev, 0, "unican_pci") != 0){ @@ -875,11 +931,10 @@ int unican_pci_request_io(struct candevice_t *candev) } #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; + candev->io_addr=pci_resource_start(candev->sysdevptr.pcidev,0); + candev->res_addr=candev->io_addr; - if ( !( remap_addr = (long) ioremap( candev->io_addr, IO_RANGE ) ) ) { + if ( !( remap_addr = 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); @@ -892,7 +947,8 @@ int unican_pci_request_io(struct candevice_t *candev) 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); + can_ioptr2ulong(candev->dev_base_addr), + can_ioptr2ulong(candev->chip[0]->chip_base_addr)); return 0; } @@ -900,7 +956,7 @@ int unican_pci_request_io(struct candevice_t *candev) int unican_pci_release_io(struct candevice_t *candev) { - iounmap((void*)candev->dev_base_addr); + iounmap(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))*/ @@ -914,24 +970,25 @@ 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)); - + pcidev = can_pci_get_next_untaken_device(UNICAN_PCI_VENDOR, UNICAN_PCI_ID); + if(pcidev == NULL) + return -ENODEV; + if (pci_enable_device (pcidev)){ printk(KERN_CRIT "Setup of Unican PCI failed\n"); + can_pci_dev_put(pcidev); 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"); + can_pci_dev_put(pcidev); 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->io_addr=pci_resource_start(pcidev,0); + candev->res_addr=candev->io_addr; + candev->dev_base_addr=NULL; /*candev->flags |= CANDEV_PROGRAMMABLE_IRQ;*/ @@ -942,6 +999,11 @@ int unican_pci_init_hw_data(struct candevice_t *candev) return 0; } +void unican_pci_done_hw_data(struct candevice_t *candev) +{ + struct pci_dev *pcidev = candev->sysdevptr.pcidev; + can_pci_dev_put(pcidev); +} int unican_pci_init_chip_data(struct candevice_t *candev, int chipnr) { @@ -958,6 +1020,7 @@ int unican_pci_register(struct hwspecops_t *hwspecops) hwspecops->release_io = unican_pci_release_io; hwspecops->reset = unican_reset; hwspecops->init_hw_data = unican_pci_init_hw_data; + hwspecops->done_hw_data = unican_pci_done_hw_data; hwspecops->init_chip_data = unican_pci_init_chip_data; hwspecops->init_obj_data = unican_init_obj_data; hwspecops->write_register = NULL;