From 8c0ae37c63dd4bc42fcb84da2eeb4a4978a2ebc0 Mon Sep 17 00:00:00 2001 From: ppisa Date: Thu, 28 Aug 2003 21:50:24 +0000 Subject: [PATCH] Fixes for SMP kernels and build for 2.2.xx and 2.6.xx kernels --- lincan/include/main.h | 2 ++ lincan/src/Makefile | 6 +++--- lincan/src/can_queue.c | 21 +++++++++++---------- lincan/src/m437.c | 5 +++-- lincan/src/main.c | 15 +++++++++++++++ lincan/src/pcm3680.c | 13 +++---------- lincan/src/pikronisa.c | 6 +++--- lincan/src/setup.c | 18 ++++++++++++++++++ 8 files changed, 58 insertions(+), 28 deletions(-) diff --git a/lincan/include/main.h b/lincan/include/main.h index 81f1818..81e8e60 100644 --- a/lincan/include/main.h +++ b/lincan/include/main.h @@ -260,4 +260,6 @@ extern inline unsigned canobj_read_reg(const struct chip_t *chip, const struct m int can_base_addr_fixup(struct candevice_t *candev, unsigned long new_base); int can_request_io_region(unsigned long start, unsigned long n, const char *name); void can_release_io_region(unsigned long start, unsigned long n); +int can_request_mem_region(unsigned long start, unsigned long n, const char *name); +void can_release_mem_region(unsigned long start, unsigned long n); diff --git a/lincan/src/Makefile b/lincan/src/Makefile index 8f5cfa2..910189f 100644 --- a/lincan/src/Makefile +++ b/lincan/src/Makefile @@ -13,11 +13,11 @@ #KERNEL_LOCATION=/usr/src/linux #KERNEL_LOCATION=/usr/src/linux-2.2.19 #KERNEL_LOCATION=/usr/src/linux-2.2.22 -#KERNEL_LOCATION=/usr/src/linux-2.5.69 +#KERNEL_LOCATION=/usr/src/linux-2.6.0-test4 #KERNEL_LOCATION=/home/cvs/ocera/ocera-build/kernel/linux # Enable debugging messages -DEBUG = y +#DEBUG = y # You can comment out the hardware you don't need. This will result in a smaller # driver. By default, all hardware is supported in the driver. See the README @@ -149,7 +149,7 @@ install_this_module: make_this_module clean: rm -f $(M_OBJS) $(MX_OBJS) $(O_OBJS) $(OX_OBJS) $(obj-m) $(obj-m:%.o=%.ko) \ - .*.o.flags .*.o.cmd .*.ko.cmd .depend .supported_cards.h *~ + $(obj-m:%.o=%.mod.o) .*.o.flags .*.o.cmd .*.ko.cmd .depend .supported_cards.h *~ ifndef KERNEL_MODULE_V26 include $(KERNEL_LOCATION)/Rules.make diff --git a/lincan/src/can_queue.c b/lincan/src/can_queue.c index ad6160c..83b0839 100644 --- a/lincan/src/can_queue.c +++ b/lincan/src/can_queue.c @@ -239,6 +239,7 @@ int canque_filter_msg2edges(struct canque_ends_t *qends, struct canmsg_t *msg) edge=list_entry(entry,struct canque_edge_t,inpeers); if(canque_fifo_test_fl(&edge->fifo,BLOCK)||canque_fifo_test_fl(&edge->fifo,DEAD)) continue; + /* FIXME: the next comparison should be outside of ends lock */ if((msg->id^edge->filtid)&edge->filtmask) continue; atomic_inc(&edge->edge_used); @@ -483,6 +484,7 @@ struct canque_edge_t *canque_new_edge_kern(int slotsnr) if(qedge == NULL) return NULL; memset(qedge,0,sizeof(struct canque_edge_t)); + spin_lock_init(&qedge->fifo.fifo_lock); if(canque_fifo_init_slots(&qedge->fifo, slotsnr)<0){ kfree(qedge); DEBUGQUE("canque_new_edge_kern failed\n"); @@ -530,8 +532,12 @@ int canqueue_disconnect_edge(struct canque_edge_t *qedge) { int ret; unsigned long flags; - spin_lock_irqsave(&qedge->inends->ends_lock,flags); - spin_lock(&qedge->outends->ends_lock); + struct canque_ends_t *inends, *outends; + + inends=qedge->inends; + if(inends) spin_lock_irqsave(&inends->ends_lock,flags); + outends=qedge->outends; + if(outends) spin_lock(&outends->ends_lock); spin_lock(&qedge->fifo.fifo_lock); if(atomic_read(&qedge->edge_used)==0) { if(qedge->outends){ @@ -545,8 +551,8 @@ int canqueue_disconnect_edge(struct canque_edge_t *qedge) ret=1; } else ret=-1; spin_unlock(&qedge->fifo.fifo_lock); - spin_unlock(&qedge->outends->ends_lock); - spin_unlock_irqrestore(&qedge->inends->ends_lock,flags); + if(outends) spin_unlock(&outends->ends_lock); + if(inends) spin_unlock_irqrestore(&inends->ends_lock,flags); DEBUGQUE("canqueue_disconnect_edge %d returned %d\n",qedge->edge_num,ret); return ret; } @@ -602,20 +608,15 @@ void canqueue_block_list(struct canque_ends_t *qends, struct list_head *list) { struct canque_edge_t *edge; struct list_head *entry; - unsigned long flags; - spin_lock_irqsave(&qends->ends_lock, flags); + /* has to be called with qends->ends_lock already locked */ list_for_each(entry,&qends->inlist){ if(list == &qends->inlist) edge=list_entry(list->next,struct canque_edge_t,inpeers); else edge=list_entry(list->next,struct canque_edge_t,outpeers); canque_fifo_set_fl(&edge->fifo,BLOCK); - /*spin_unlock_irqrestore(&qends->ends_lock, flags);*/ - /* Loop can be break by interrupts and preempts there */ - /*spin_lock_irqsave(&qends->ends_lock, flags);*/ } - spin_unlock_irqrestore(&qends->ends_lock, flags); } diff --git a/lincan/src/m437.c b/lincan/src/m437.c index 7405160..c2073ed 100644 --- a/lincan/src/m437.c +++ b/lincan/src/m437.c @@ -60,13 +60,14 @@ static long base = 0L; int m437_request_io(struct candevice_t *candev) { - if (!request_mem_region(candev->io_addr,IO_RANGE,DEVICE_NAME)) { + if (!can_request_mem_region(candev->io_addr,IO_RANGE,DEVICE_NAME)) { CANMSG("Unable to request IO-memory: 0x%lx\n",candev->io_addr); return -ENODEV; } if ( !( base = (long) 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; } @@ -116,7 +117,7 @@ int m437_release_io(struct candevice_t *candev) /* release I/O memory mapping */ iounmap((void*)base); - release_mem_region(candev->io_addr,IO_RANGE); + can_release_mem_region(candev->io_addr,IO_RANGE); return 0; } diff --git a/lincan/src/main.c b/lincan/src/main.c index d04c39c..d52cabf 100644 --- a/lincan/src/main.c +++ b/lincan/src/main.c @@ -41,6 +41,7 @@ /*#undef CONFIG_DEVFS_FS*/ #ifdef CONFIG_DEVFS_FS +#include #include #endif @@ -101,8 +102,10 @@ struct canhardware_t *hardware_p=&canhardware; struct chip_t *chips_p[MAX_TOT_CHIPS]; struct msgobj_t *objects_p[MAX_TOT_MSGOBJS]; #ifdef CONFIG_DEVFS_FS +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,60)) devfs_handle_t devfs_handles[MAX_TOT_MSGOBJS]; #endif +#endif /* Pointers to dynamically allocated memory are maintained in a linked list * to ease memory deallocation. @@ -205,11 +208,15 @@ int init_module(void) for(i=0;iminor; + #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,50)) sprintf (dev_name, "can%d", dev_minor); devfs_handles[i]=devfs_register(NULL, dev_name, DEVFS_FL_DEFAULT, major, dev_minor, S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, &can_fops, (void*)objects_p[i]); + #else + devfs_mk_cdev(MKDEV(major, dev_minor), S_IFCHR | S_IRUGO | S_IWUGO, "can%d", dev_minor); + #endif } } #endif @@ -257,8 +264,16 @@ void cleanup_module(void) #ifdef CONFIG_DEVFS_FS for(i=0;iminor; + if(minor>=0) + devfs_remove("can%d", dev_minor); + #endif } #endif i=0; diff --git a/lincan/src/pcm3680.c b/lincan/src/pcm3680.c index 2736035..a1ccf4a 100644 --- a/lincan/src/pcm3680.c +++ b/lincan/src/pcm3680.c @@ -19,13 +19,6 @@ #include "../include/i82527.h" #include "../include/sja1000p.h" -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) /* may need correction */ - #ifndef request_mem_region - #define request_mem_region(start,size,dev) (1) - #define release_mem_region(start,size) - #endif /*request_mem_region*/ -#endif /* 2.4.0 */ - /* * IO_RANGE is the io-memory range that gets reserved, please adjust according * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or @@ -50,13 +43,13 @@ int pcm3680_request_io(struct candevice_t *candev) { unsigned long remap_addr; - if (!request_mem_region(candev->io_addr,IO_RANGE,DEVICE_NAME " - pcm3680")) { + if (!can_request_mem_region(candev->io_addr,IO_RANGE,DEVICE_NAME " - pcm3680")) { CANMSG("Unable to request IO-memory: 0x%lx\n",candev->io_addr); return -ENODEV; } if ( !( remap_addr = (long) ioremap( candev->io_addr, IO_RANGE ) ) ) { CANMSG("Unable to access I/O memory at: 0x%lx\n", candev->io_addr); - release_mem_region(candev->io_addr,IO_RANGE); + can_release_mem_region(candev->io_addr,IO_RANGE); return -ENODEV; } @@ -80,7 +73,7 @@ int pcm3680_request_io(struct candevice_t *candev) int pcm3680_release_io(struct candevice_t *candev) { iounmap((void*)candev->dev_base_addr); - release_mem_region(candev->io_addr,IO_RANGE); + can_release_mem_region(candev->io_addr,IO_RANGE); return 0; } diff --git a/lincan/src/pikronisa.c b/lincan/src/pikronisa.c index fb6e3dc..703adad 100644 --- a/lincan/src/pikronisa.c +++ b/lincan/src/pikronisa.c @@ -44,13 +44,13 @@ int pikronisa_request_io(struct candevice_t *candev) { int remap_addr; - if (!request_mem_region(candev->io_addr,IO_RANGE,DEVICE_NAME " - pikronisa")) { + if (!can_request_mem_region(candev->io_addr,IO_RANGE,DEVICE_NAME " - pikronisa")) { CANMSG("Unable to request IO-memory: 0x%lx\n",candev->io_addr); return -ENODEV; } if ( !( remap_addr = (long) ioremap( candev->io_addr, IO_RANGE ) ) ) { CANMSG("Unable to access I/O memory at: 0x%lx\n", candev->io_addr); - release_mem_region(candev->io_addr,IO_RANGE); + can_release_mem_region(candev->io_addr,IO_RANGE); return -ENODEV; } @@ -75,7 +75,7 @@ int pikronisa_release_io(struct candevice_t *candev) { /* release I/O memory mapping */ iounmap((void*)candev->dev_base_addr); - release_mem_region(candev->io_addr,IO_RANGE); + can_release_mem_region(candev->io_addr,IO_RANGE); return 0; } diff --git a/lincan/src/setup.c b/lincan/src/setup.c index d234eb9..88f0450 100644 --- a/lincan/src/setup.c +++ b/lincan/src/setup.c @@ -157,6 +157,24 @@ void can_release_io_region(unsigned long start, unsigned long n) release_region(start,n); } +int can_request_mem_region(unsigned long start, unsigned long n, const char *name) +{ + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) + return 1; + #else + return (request_mem_region(start,n,name))?1:0; + #endif +} + +void can_release_mem_region(unsigned long start, unsigned long n) +{ + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) + return; + #else + release_mem_region(start,n); + #endif +} + /* 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) -- 2.39.2