X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/97078fff5202521b758c9081d75580880417a123..11132ea490f9e860744ee4f851c67e7fb4444231:/lincan/src/setup.c diff --git a/lincan/src/setup.c b/lincan/src/setup.c index a8f76cc..d234eb9 100644 --- a/lincan/src/setup.c +++ b/lincan/src/setup.c @@ -1,33 +1,30 @@ /* setup.c * Linux CAN-bus device driver. * Written by Arnaud Westenberg email:arnaud@wanadoo.nl + * Rewritten for new CAN queues by Pavel Pisa - OCERA team member + * email:pisa@cmp.felk.cvut.cz * This software is released under the GPL-License. - * Version 0.7 6 Aug 2001 + * Version lincan-0.2 9 Jul 2003 */ #define __NO_VERSION__ #include #include -#if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS) -#define MODVERSIONS -#endif - -#if defined (MODVERSIONS) -#include -#endif #include -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) #include #else #include #endif #include +#include #include ".supported_cards.h" #include "../include/main.h" +#include "../include/devcommon.h" #include "../include/setup.h" #include "../include/pip.h" #include "../include/pccan.h" @@ -61,10 +58,10 @@ extern int bfadcan_register(struct hwspecops_t *hwspecops); extern int pikronisa_register(struct hwspecops_t *hwspecops); int init_device_struct(int card); -int init_hwspecops(int card); -int init_chip_struct(int card); -int init_obj_struct(int card, int chip); -int init_chipspecops(int card, int chipnr); +int init_hwspecops(struct candevice_t *candev); +int init_chip_struct(struct candevice_t *candev); +int init_obj_struct(struct candevice_t *candev, struct chip_t *hostchip, int minorbase); +int init_chipspecops(struct candevice_t *candev, int chipnr); int add_mem_to_list(void *address_p) { @@ -144,6 +141,39 @@ int del_mem_list(void) return 0; } +int can_request_io_region(unsigned long start, unsigned long n, const char *name) +{ + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) + if(check_region(start,n)) return 0; + request_region(start,n,name); + return 1; + #else + return (request_region(start,n,name))?1:0; + #endif +} + +void can_release_io_region(unsigned long start, unsigned long n) +{ + release_region(start,n); +} + +/* This function shifts all base address structures acording to address + translation between physical and virtual address mappings */ +int can_base_addr_fixup(struct candevice_t *candev, unsigned long new_base) +{ + unsigned long offs; + int i, j; + + offs=new_base-candev->dev_base_addr; + candev->dev_base_addr=new_base; + for(i=0;inr_all_chips;i++){ + candev->chip[i]->chip_base_addr += offs; + for(j=0;jchip[i]->max_objects;j++) + candev->chip[i]->msgobj[j]->obj_base_addr += offs; + } + return 0; +} + /* The function init_hw_struct is used to initialize the hardware structure. */ int init_hw_struct(void) { @@ -168,32 +198,40 @@ int init_hw_struct(void) */ int init_device_struct(int card) { - hardware_p->candevice[card]=(struct candevice_t *)kmalloc(sizeof(struct candevice_t),GFP_KERNEL); - if (hardware_p->candevice[card]==NULL) + struct candevice_t *candev; + + candev=(struct candevice_t *)kmalloc(sizeof(struct candevice_t),GFP_KERNEL); + if (candev==NULL) return -ENOMEM; else - if ( add_mem_to_list(hardware_p->candevice[card]) ) + if ( add_mem_to_list(candev) ) return -ENOMEM; - candevices_p[card]=hardware_p->candevice[card]; + memset(candev, 0, sizeof(struct candevice_t)); + + hardware_p->candevice[card]=candev; + candev->candev_idx=card; + + candev=candev; - hardware_p->candevice[card]->hwname=hw[card]; - hardware_p->candevice[card]->io_addr=io[card]; + candev->hwname=hw[card]; + candev->io_addr=io[card]; + candev->dev_base_addr=io[card]; - hardware_p->candevice[card]->hwspecops=(struct hwspecops_t *)kmalloc(sizeof(struct hwspecops_t),GFP_KERNEL); - if (hardware_p->candevice[card]->hwspecops==NULL) + candev->hwspecops=(struct hwspecops_t *)kmalloc(sizeof(struct hwspecops_t),GFP_KERNEL); + if (candev->hwspecops==NULL) return -ENOMEM; else - if ( add_mem_to_list(hardware_p->candevice[card]->hwspecops) ) + if ( add_mem_to_list(candev->hwspecops) ) return -ENOMEM; - if (init_hwspecops(card)) + if (init_hwspecops(candev)) return -ENODEV; - if (candevices_p[card]->hwspecops->init_hw_data(card)) + if (candev->hwspecops->init_hw_data(candev)) return -ENODEV; - if (init_chip_struct(card)) + if (init_chip_struct(candev)) return -ENODEV; return 0; @@ -202,38 +240,44 @@ int init_device_struct(int card) /* The function init_chip_struct is used to initialize all chip_t structures * on one hardware board. */ -int init_chip_struct(int card) +int init_chip_struct(struct candevice_t *candev) { static int irq_count=0; int i=0; /* Alocate and initialize the chip structures */ - for (i=0; i < candevices_p[card]->nr_82527_chips+candevices_p[card]->nr_sja1000_chips; i++) { - candevices_p[card]->chip[i]=(struct chip_t *)kmalloc(sizeof(struct chip_t),GFP_KERNEL); - if (candevices_p[card]->chip[i]==NULL) + for (i=0; i < candev->nr_all_chips; i++) { + candev->chip[i]=(struct chip_t *)kmalloc(sizeof(struct chip_t),GFP_KERNEL); + if (candev->chip[i]==NULL) return -ENOMEM; else - if ( add_mem_to_list(candevices_p[card]->chip[i]) ) + if ( add_mem_to_list(candev->chip[i]) ) return -ENOMEM; - candevices_p[card]->chip[i]->chipspecops=(struct chipspecops_t *)kmalloc(sizeof(struct chipspecops_t),GFP_KERNEL); - if (candevices_p[card]->chip[i]->chipspecops==NULL) + memset(candev->chip[i], 0, sizeof(struct chip_t)); + + candev->chip[i]->write_register=candev->hwspecops->write_register; + candev->chip[i]->read_register=candev->hwspecops->read_register; + + candev->chip[i]->chipspecops=(struct chipspecops_t *)kmalloc(sizeof(struct chipspecops_t),GFP_KERNEL); + if (candev->chip[i]->chipspecops==NULL) return -ENOMEM; else - if ( add_mem_to_list(candevices_p[card]->chip[i]->chipspecops) ) + if ( add_mem_to_list(candev->chip[i]->chipspecops) ) return -ENOMEM; - chips_p[irq_count]=candevices_p[card]->chip[i]; - candevices_p[card]->chip[i]->hostdevice=candevices_p[card]; - candevices_p[card]->chip[i]->chip_irq=irq[irq_count]; - candevices_p[card]->chip[i]->flags=0x0; + chips_p[irq_count]=candev->chip[i]; + candev->chip[i]->chip_idx=i; + candev->chip[i]->hostdevice=candev; + candev->chip[i]->chip_irq=irq[irq_count]; + candev->chip[i]->flags=0x0; - candevices_p[card]->hwspecops->init_chip_data(card,i); + candev->hwspecops->init_chip_data(candev,i); - if (init_chipspecops(card,i)) + if (init_chipspecops(candev,i)) return -ENODEV; - init_obj_struct(card, irq_count); + init_obj_struct(candev, candev->chip[i], minor[irq_count]); irq_count++; } @@ -241,46 +285,47 @@ int init_chip_struct(int card) return 0; } -int init_obj_struct(int card, int chip) +int init_obj_struct(struct candevice_t *candev, struct chip_t *hostchip, int minorbase) { + struct canque_ends_t *qends; static int obj_count=0; - int i=0,max_objects=0; + int i,max_objects; + struct msgobj_t *obj; - if (!strcmp(chips_p[chip]->chip_type,"i82527")) - max_objects=15; - else - max_objects=1; + max_objects=hostchip->max_objects; for (i=0; imsgobj[i]=(struct msgobj_t *)kmalloc(sizeof(struct msgobj_t),GFP_KERNEL); - if (chips_p[chip]->msgobj[i] == NULL) + obj=(struct msgobj_t *)kmalloc(sizeof(struct msgobj_t),GFP_KERNEL); + hostchip->msgobj[i]=obj; + if (obj == NULL) return -ENOMEM; else - if ( add_mem_to_list(chips_p[chip]->msgobj[i]) ) + if ( add_mem_to_list(obj) ) return -ENOMEM; - chips_p[chip]->msgobj[i]->fifo=(struct canfifo_t *)kmalloc(sizeof(struct canfifo_t),GFP_KERNEL); - if (chips_p[chip]->msgobj[i]->fifo == NULL) - return -ENOMEM; - else - if ( add_mem_to_list(chips_p[chip]->msgobj[i]->fifo) ) - return -ENOMEM; + memset(obj, 0, sizeof(struct msgobj_t)); + + atomic_set(&obj->obj_used,0); + INIT_LIST_HEAD(&obj->obj_users); + qends = (struct canque_ends_t *)kmalloc(sizeof(struct canque_ends_t), GFP_KERNEL); + if(qends == NULL) return -ENOMEM; + if(add_mem_to_list(qends)) return -ENOMEM; + memset(qends, 0, sizeof(struct canque_ends_t)); + obj->hostchip=hostchip; + obj->object=i+1; + obj->qends=qends; + obj->tx_qedge=NULL; + obj->tx_slot=NULL; + obj->flags = 0x0; + + canqueue_ends_init_chip(qends, hostchip, obj); - if (minor[0] == -1) { - objects_p[obj_count]=chips_p[chip]->msgobj[i]; - objects_p[obj_count]->hostchip=chips_p[chip]; - objects_p[obj_count]->object=i+1; - objects_p[obj_count]->minor=obj_count; - } - else { - objects_p[minor[chip]+i]=chips_p[chip]->msgobj[i]; - objects_p[minor[chip]+i]->hostchip=chips_p[chip]; - objects_p[minor[chip]+i]->object=i+1; - objects_p[minor[chip]+i]->minor=minor[chip]+i; - } + if (minorbase == -1) minorbase=obj_count; + if ((minorbase >= 0) && (minorbase+iminor=minorbase+i; + } else obj->minor=-1; - chips_p[chip]->msgobj[i]->flags = 0x0; - - candevices_p[card]->hwspecops->init_obj_data(chip,i); + candev->hwspecops->init_obj_data(hostchip,i); obj_count++; } @@ -288,101 +333,106 @@ int init_obj_struct(int card, int chip) } -int init_hwspecops(int card) +int init_hwspecops(struct candevice_t *candev) { #ifdef ENABLE_CARD_template - if (!strcmp(candevices_p[card]->hwname,"template")) { - template_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"template")) { + template_register(candev->hwspecops); } #endif #ifdef ENABLE_CARD_pip - if (!strcmp(candevices_p[card]->hwname,"pip5")) { - pip5_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"pip5")) { + pip5_register(candev->hwspecops); } - else if (!strcmp(candevices_p[card]->hwname,"pip6")) { - pip6_register(candevices_p[card]->hwspecops); + else if (!strcmp(candev->hwname,"pip6")) { + pip6_register(candev->hwspecops); } #endif #ifdef ENABLE_CARD_smartcan - if (!strcmp(candevices_p[card]->hwname,"smartcan")) { - smartcan_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"smartcan")) { + smartcan_register(candev->hwspecops); } #endif #ifdef ENABLE_CARD_nsi - if (!strcmp(candevices_p[card]->hwname,"nsican")) { - nsi_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"nsican")) { + nsi_register(candev->hwspecops); } #endif #ifdef ENABLE_CARD_cc_can104 - if (!strcmp(candevices_p[card]->hwname,"cc104")) { - cc104_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"cc104")) { + cc104_register(candev->hwspecops); } #endif #ifdef ENABLE_CARD_aim104 - if (!strcmp(candevices_p[card]->hwname,"aim104")) { - aim104_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"aim104")) { + aim104_register(candev->hwspecops); } #endif #ifdef ENABLE_CARD_pc_i03 - if (!strcmp(candevices_p[card]->hwname,"pc-i03")) { - pci03_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"pc-i03")) { + pci03_register(candev->hwspecops); } #endif #ifdef ENABLE_CARD_pcm3680 - if (!strcmp(candevices_p[card]->hwname,"pcm3680")) { - pcm3680_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"pcm3680")) { + pcm3680_register(candev->hwspecops); } #endif #ifdef ENABLE_CARD_pccan - if (!strcmp(candevices_p[card]->hwname,"pccan-f") | - !strcmp(candevices_p[card]->hwname,"pccan-s") ) { - pccanf_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"pccan-f") | + !strcmp(candev->hwname,"pccan-s") ) { + pccanf_register(candev->hwspecops); } - if (!strcmp(candevices_p[card]->hwname,"pccan-d")) { - pccand_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"pccan-d")) { + pccand_register(candev->hwspecops); } - if (!strcmp(candevices_p[card]->hwname,"pccan-q")) { - pccanq_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"pccan-q")) { + pccanq_register(candev->hwspecops); } #endif #ifdef ENABLE_CARD_m437 - if (!strcmp(candevices_p[card]->hwname,"m437")) { - m437_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"m437")) { + m437_register(candev->hwspecops); } #endif #ifdef ENABLE_CARD_pcccan - if (!strcmp(candevices_p[card]->hwname,"pcccan")) { - pcccan_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"pcccan")) { + pcccan_register(candev->hwspecops); } #endif #ifdef ENABLE_CARD_ssv - if (!strcmp(candevices_p[card]->hwname,"ssv")) { - ssv_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"ssv")) { + ssv_register(candev->hwspecops); } #endif #ifdef ENABLE_CARD_bfadcan - if (!strcmp(candevices_p[card]->hwname,"bfadcan")) { - bfadcan_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"bfadcan")) { + bfadcan_register(candev->hwspecops); } #endif #ifdef ENABLE_CARD_pikronisa - if (!strcmp(candevices_p[card]->hwname,"pikronisa")) { - pikronisa_register(candevices_p[card]->hwspecops); + if (!strcmp(candev->hwname,"pikronisa")) { + pikronisa_register(candev->hwspecops); } #endif return 0; } -int init_chipspecops(int card, int chipnr) +int init_chipspecops(struct candevice_t *candev, int chipnr) { - if (!strcmp(candevices_p[card]->chip[chipnr]->chip_type,"i82527")) { - i82527_register(candevices_p[card]->chip[chipnr]->chipspecops); + candev->chip[chipnr]->max_objects=0; + + if (!strcmp(candev->chip[chipnr]->chip_type,"i82527")) { + candev->chip[chipnr]->max_objects=15; + i82527_register(candev->chip[chipnr]->chipspecops); } - if (!strcmp(candevices_p[card]->chip[chipnr]->chip_type,"sja1000")) { - sja1000_register(candevices_p[card]->chip[chipnr]->chipspecops); + if (!strcmp(candev->chip[chipnr]->chip_type,"sja1000")) { + candev->chip[chipnr]->max_objects=1; + sja1000_register(candev->chip[chipnr]->chipspecops); } - if (!strcmp(candevices_p[card]->chip[chipnr]->chip_type,"sja1000p")) { - sja1000p_register(candevices_p[card]->chip[chipnr]->chipspecops); + if (!strcmp(candev->chip[chipnr]->chip_type,"sja1000p")) { + candev->chip[chipnr]->max_objects=1; + sja1000p_register(candev->chip[chipnr]->chipspecops); } return 0;