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);
#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
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
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);
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");
{
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){
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;
}
{
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);
}
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;
}
/* 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;
}
/*#undef CONFIG_DEVFS_FS*/
#ifdef CONFIG_DEVFS_FS
+#include <linux/devfs_fs_kernel.h>
#include <linux/miscdevice.h>
#endif
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.
for(i=0;i<MAX_TOT_MSGOBJS;i++) {
if(!objects_p[i]) continue;
dev_minor=objects_p[i]->minor;
+ #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
#ifdef CONFIG_DEVFS_FS
for(i=0;i<MAX_TOT_MSGOBJS;i++) {
+ #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,50))
if(devfs_handles[i])
devfs_unregister(devfs_handles[i]);
+ #else
+ int dev_minor;
+ if(!objects_p[i]) continue;
+ dev_minor=objects_p[i]->minor;
+ if(minor>=0)
+ devfs_remove("can%d", dev_minor);
+ #endif
}
#endif
i=0;
#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
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;
}
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;
}
{
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;
}
{
/* 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;
}
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)