]> rtime.felk.cvut.cz Git - lincan.git/commitdiff
LinCAN can be compiled in mode with RT-Linux chip worker threads now.
authorppisa <ppisa>
Thu, 1 Jan 2004 22:54:26 +0000 (22:54 +0000)
committerppisa <ppisa>
Thu, 1 Jan 2004 22:54:26 +0000 (22:54 +0000)
Setup tested to work with Virtual and PCM3680 boards now.

38 files changed:
lincan/include/can_queue.h
lincan/include/can_sysdep.h
lincan/include/constants.h
lincan/include/i82527.h
lincan/include/irq.h
lincan/include/main.h
lincan/include/setup.h
lincan/include/sja1000.h
lincan/src/Makefile.omk
lincan/src/aim104.c
lincan/src/bfadcan.c
lincan/src/can_devrtl.c [new file with mode: 0644]
lincan/src/can_quekern.c
lincan/src/can_quertl.c [new file with mode: 0644]
lincan/src/can_queue.c
lincan/src/cc_can104.c
lincan/src/close.c
lincan/src/devcommon.c
lincan/src/finish.c
lincan/src/i82527.c
lincan/src/irq.c
lincan/src/m437.c
lincan/src/main.c
lincan/src/nsi.c
lincan/src/open.c
lincan/src/pc_i03.c
lincan/src/pccan.c
lincan/src/pcccan.c
lincan/src/pcm3680.c
lincan/src/pikronisa.c
lincan/src/pip.c
lincan/src/setup.c
lincan/src/sja1000.c
lincan/src/sja1000p.c
lincan/src/smartcan.c
lincan/src/ssv.c
lincan/src/template.c
lincan/src/virtual.c

index 2fc422f4f38d080a294da19df4f7a752d9b7d2fa..aacfd846f2b52ebfada182ef72a91897a8810d5b 100644 (file)
@@ -39,6 +39,7 @@
  * @flist: pointer to list of the free slots associated with queue
  * @entry: pointer to the memory allocated for the list slots.
  * @fifo_lock: the lock to ensure atomicity of slot manipulation operations.
+ * @slotnr:  number of allocated slots
  *
  * This structure represents CAN FIFO queue. It is implemented as 
  * a single linked list of slots prepared for processing. The empty slots
@@ -52,6 +53,7 @@ struct canque_fifo_t {
        struct canque_slot_t *flist;    /* points the first entry in the free list */
        struct canque_slot_t *entry;    /* points to first allocated entry */
        can_spinlock_t fifo_lock;       /* can_spin_lock_irqsave / can_spin_unlock_irqrestore */
+       int    slotsnr;
 };
 
 #define CAN_FIFOF_DESTROY_b    15
@@ -65,6 +67,8 @@ struct canque_fifo_t {
 #define CAN_FIFOF_INACTIVE_b   7
 #define CAN_FIFOF_FREEONEMPTY_b        6
 #define CAN_FIFOF_READY_b      5
+#define CAN_FIFOF_NOTIFYPEND_b 4
+#define CAN_FIFOF_RTL_MEM_b    3
 
 #define CAN_FIFOF_DESTROY      (1<<CAN_FIFOF_DESTROY_b)
 #define CAN_FIFOF_ERROR                (1<<CAN_FIFOF_ERROR_b)
@@ -77,6 +81,8 @@ struct canque_fifo_t {
 #define CAN_FIFOF_INACTIVE     (1<<CAN_FIFOF_INACTIVE_b)
 #define CAN_FIFOF_FREEONEMPTY  (1<<CAN_FIFOF_FREEONEMPTY_b)
 #define CAN_FIFOF_READY                (1<<CAN_FIFOF_READY_b)
+#define CAN_FIFOF_NOTIFYPEND    (1<<CAN_FIFOF_NOTIFYPEND_b)
+#define CAN_FIFOF_RTL_MEM       (1<<CAN_FIFOF_RTL_MEM_b)
 
 #define canque_fifo_test_fl(fifo,fifo_fl) \
   test_bit(CAN_FIFOF_##fifo_fl##_b,&(fifo)->fifo_flags)
@@ -137,7 +143,7 @@ int canque_fifo_put_inslot(struct canque_fifo_t *fifo, struct canque_slot_t *slo
        can_spin_irqflags_t flags;
        slot->next=NULL;
        can_spin_lock_irqsave(&fifo->fifo_lock, flags);
-       if(*fifo->tail) printk(KERN_CRIT "canque_fifo_put_inslot: fifo->tail != NULL\n");
+       if(*fifo->tail) can_printk(KERN_CRIT "canque_fifo_put_inslot: fifo->tail != NULL\n");
        *fifo->tail=slot;
        fifo->tail=&slot->next;
        ret=0;
@@ -253,9 +259,7 @@ int canque_fifo_again_outslot(struct canque_fifo_t *fifo, struct canque_slot_t *
 
 int canque_fifo_flush_slots(struct canque_fifo_t *fifo);
 
-int canque_fifo_init_slots(struct canque_fifo_t *fifo, int slotsnr);
-
-int canque_fifo_done(struct canque_fifo_t *fifo);
+int canque_fifo_init_slots(struct canque_fifo_t *fifo);
 
 #define CANQUEUE_PRIO_NR  3
 
@@ -281,6 +285,9 @@ struct chip_t;
  * @edge_used: the atomic usage counter, mainly used for safe destruction of the edge.
  * @edge_prio: the assigned queue priority from the range 0 to %CANQUEUE_PRIO_NR-1
  * @edge_num: edge sequential number intended for debugging purposes only
+ * @pending_peers: edges with pending delayed events (RTL->Linux calls)
+ * @pending_inops: bitmask of pending operations
+ * @pending_outops: bitmask of pending operations
  *
  * This structure represents one direction connection from messages source 
  * (@inends) to message consumer (@outends) fifo ends hub. The edge contains
@@ -298,6 +305,11 @@ struct canque_edge_t {
        atomic_t edge_used;
        int edge_prio;
        int edge_num;
+    #ifdef CAN_WITH_RTL
+       struct list_head pending_peers;
+       unsigned long pending_inops;
+       unsigned long pending_outops;
+    #endif /*CAN_WITH_RTL*/
 };
 
 /**
@@ -322,6 +334,7 @@ struct canque_edge_t {
  * @context: space to store ends user specific information
  * @endinfo: space to store some other ends usage specific informations
  *     mainly for waking-up by the notify calls.
+ * @dead_peers: used to chain ends wanting for postponed destruction
  *
  * Structure represents place to connect edges to for CAN communication entity.
  * The zero, one or more incoming and outgoing edges can be connected to
@@ -345,10 +358,23 @@ struct canque_ends_t {
                        struct fasync_struct *fasync;
                    #endif /*CAN_ENABLE_KERN_FASYNC*/
                } fileinfo;
+           #ifdef CAN_WITH_RTL
+               struct {
+                       rtl_spinlock_t rtl_lock;
+                       rtl_wait_t rtl_readq;
+                       rtl_wait_t rtl_writeq;
+                       rtl_wait_t rtl_emptyq;
+                       unsigned long pend_flags;
+               } rtlinfo;
+           #endif /*CAN_WITH_RTL*/
                struct {
-                       wait_queue_head_t daemonq;
                        struct msgobj_t *msgobj;
                        struct chip_t *chip;
+                   #ifndef CAN_WITH_RTL
+                       wait_queue_head_t daemonq;
+                   #else /*CAN_WITH_RTL*/
+                       pthread_t worker_thread;
+                   #endif /*CAN_WITH_RTL*/
                } chipinfo;
        } endinfo;
        struct list_head dead_peers;
@@ -367,7 +393,8 @@ struct canque_ends_t {
 #define CANQUEUE_NOTIFY_ERRTX_SEND 0x11002 /* tx send error */
 #define CANQUEUE_NOTIFY_ERRTX_BUS  0x11003 /* tx bus error */
 
-#define CAN_ENDSF_DEAD (1<<0)
+#define CAN_ENDSF_DEAD   (1<<0)
+#define CAN_ENDSF_MEM_RTL (1<<1)
 
 /**
  * canque_notify_inends - request to send notification to the input ends
@@ -636,6 +663,10 @@ struct canque_edge_t *canque_next_outedge(struct canque_ends_t *qends, struct ca
 
 /* Linux kernel specific functions */
 
+int canque_fifo_init_kern(struct canque_fifo_t *fifo, int slotsnr);
+
+int canque_fifo_done_kern(struct canque_fifo_t *fifo);
+
 struct canque_edge_t *canque_new_edge_kern(int slotsnr);
 
 int canque_get_inslot4id_wait_kern(struct canque_ends_t *qends,
@@ -651,7 +682,33 @@ int canqueue_ends_init_kern(struct canque_ends_t *qends);
 
 int canqueue_ends_dispose_kern(struct canque_ends_t *qends, int sync);
 
+void canqueue_ends_dispose_postpone(struct canque_ends_t *qends);
+
 void canqueue_kern_initialize(void);
 
+#ifdef CAN_WITH_RTL
+/* RT-Linux specific functions */
+
+void canqueue_rtl_initialize(void);
+void canqueue_rtl_done(void);
+
+int canqueue_rtl2lin_check_and_pend(struct canque_ends_t *qends,
+                        struct canque_edge_t *qedge, int what);
+
+struct canque_edge_t *canque_new_edge_rtl(int slotsnr);
+
+void canque_dispose_edge_rtl(struct canque_edge_t *qedge);
+
+void canque_ends_free_rtl(struct canque_ends_t *qends);
+
+int canqueue_ends_dispose_rtl(struct canque_ends_t *qends, int sync);
+
+#else /*CAN_WITH_RTL*/
+
+static inline int canqueue_rtl2lin_check_and_pend(struct canque_ends_t *qends,
+                       struct canque_edge_t *qedge, int what) { return 0; }
+
+#endif /*CAN_WITH_RTL*/
+
 
 #endif /*_CAN_QUEUE_H*/
index 0297e219fb8c8a7faa1b697c1e869847ae55dfc7..1de145449c9fd3237eabe20185a4d46bc302dbac 100644 (file)
@@ -1,6 +1,14 @@
 #ifndef _CAN_SYSDEP_H
 #define _CAN_SYSDEP_H
 
+#ifdef CAN_WITH_RTL
+#include <rtl.h>
+#include <rtl_sync.h>
+#include <rtl_core.h>
+#include <rtl_mutex.h>
+#include <rtl_sched.h>
+#endif /*CAN_WITH_RTL*/
+
 /*#define __NO_VERSION__*/
 /*#include <linux/module.h>*/
 
@@ -13,6 +21,7 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <asm/errno.h>
+
 #include <asm/io.h>
 #include <asm/atomic.h>
 #include <asm/irq.h>
 
 #endif /* Linux kernel < 2.5.7 or >= 2.6.0 */
 
-
+#ifndef CAN_WITH_RTL
 #if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68)) && !defined(IRQ_RETVAL))
-  typedef void irqreturn_t;
-  #define IRQ_NONE
-  #define IRQ_HANDLED
-  #define IRQ_RETVAL(x)
+  typedef void can_irqreturn_t;
+  #define CAN_IRQ_NONE
+  #define CAN_IRQ_HANDLED
+  #define CAN_IRQ_RETVAL(x)
+#else /* <=2.5.67 */
+  typedef irqreturn_t can_irqreturn_t;
+  #define CAN_IRQ_NONE    IRQ_NONE
+  #define CAN_IRQ_HANDLED IRQ_HANDLED
+  #define CAN_IRQ_RETVAL  IRQ_RETVAL
 #endif /* <=2.5.67 */
+#else /*CAN_WITH_RTL*/
+  typedef int can_irqreturn_t;
+  #define CAN_IRQ_NONE        0
+  #define CAN_IRQ_HANDLED     1
+  #define CAN_IRQ_RETVAL(x)   ((x) != 0)
+#endif /*CAN_WITH_RTL*/
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,33))
    #define can_synchronize_irq(irqnum) synchronize_irq()
@@ -75,6 +95,7 @@
 #define CAN_ENABLE_KERN_FASYNC
 
 #ifndef CAN_WITH_RTL
+/* Standard LINUX kernel */
 
 #define can_spinlock_t             spinlock_t
 #define can_spin_irqflags_t        unsigned long
 #define can_spin_unlock_irqrestore spin_unlock_irqrestore
 #define can_spin_lock_init         spin_lock_init
 
+#if defined(CONFIG_PREEMPT) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+#define can_preempt_disable        preempt_disable
+#define can_preempt_enable         preempt_enable
+#else /*CONFIG_PREEMPT*/
+#define can_preempt_disable()      do { } while (0)
+#define can_preempt_enable()       do { } while (0)
+#endif /*CONFIG_PREEMPT*/
+
+#define can_enable_irq             enable_irq
+#define can_disable_irq            disable_irq
+
+#define can_printk                 printk
+
 #else /*CAN_WITH_RTL*/
 
 #define can_spinlock_t             rtl_spinlock_t
 #define can_spin_unlock_irqrestore rtl_spin_unlock_irqrestore
 #define can_spin_lock_init         rtl_spin_lock_init
 
+#define can_preempt_disable()      do { } while (0)
+#define can_preempt_enable()       do { } while (0)
+
+#define can_enable_irq             rtl_hard_enable_irq
+#define can_disable_irq            rtl_hard_disable_irq
+
+#define can_printk                 rtl_printf
+
 #endif /*CAN_WITH_RTL*/
 
 #endif /*_CAN_SYSDEP_H*/
index 6e716439cca227ce4b35d0db1fac233b11c18390..ce0cbbd96ccf85fedbbb7ae1a0eb5103ee1e9457 100644 (file)
 #define MAX_BUF_LENGTH 64
 //#define MAX_BUF_LENGTH 4
 
-#define IE (1<<1)
-#define SIE (1<<2)
-#define EIE (1<<3)
 
 /* These flags can be used for the msgobj_t structure flags data entry */
-#define OBJ_OPENED (1<<0)
-#define OBJ_BUFFERS_ALLOCATED (1<<1)
-#define OBJ_TX_REQUEST (1<<2)
-#define OBJ_TX_LOCK (1<<3)
+#define MSGOBJ_OPENED_b                   0
+#define MSGOBJ_TX_REQUEST_b       1
+#define MSGOBJ_TX_LOCK_b           2
+#define MSGOBJ_IRQ_REQUEST_b       3
+#define MSGOBJ_WORKER_WAKE_b       4
+
+#define MSGOBJ_OPENED              (1<<MSGOBJ_OPENED_b)
+#define MSGOBJ_TX_REQUEST          (1<<MSGOBJ_TX_REQUEST_b)
+#define MSGOBJ_TX_LOCK             (1<<MSGOBJ_TX_LOCK_b)
+#define MSGOBJ_IRQ_REQUEST         (1<<MSGOBJ_IRQ_REQUEST_b)
+#define MSGOBJ_WORKER_WAKE         (1<<MSGOBJ_WORKER_WAKE_b)
+
+#define can_msgobj_test_fl(obj,obj_fl) \
+  test_bit(MSGOBJ_##obj_fl##_b,&(obj)->obj_flags)
+#define can_msgobj_set_fl(obj,obj_fl) \
+  set_bit(MSGOBJ_##obj_fl##_b,&(obj)->obj_flags)
+#define can_msgobj_clear_fl(obj,obj_fl) \
+  clear_bit(MSGOBJ_##obj_fl##_b,&(obj)->obj_flags)
+#define can_msgobj_test_and_set_fl(obj,obj_fl) \
+  test_and_set_bit(MSGOBJ_##obj_fl##_b,&(obj)->obj_flags)
+#define can_msgobj_test_and_clear_fl(obj,obj_fl) \
+  test_and_clear_bit(MSGOBJ_##obj_fl##_b,&(obj)->obj_flags)
+
 
 /* These flags can be used for the chip_t structure flags data entry */
 #define CHIP_CONFIGURED  (1<<0)
index c80ed0057cafe92389bc3114ed2d52597c09881c..c857b993675939ec5e458796c1a98e9c91c2fbf4 100644 (file)
@@ -31,7 +31,7 @@ int i82527_set_btregs(struct chip_t *chip, unsigned short btr0,
 int i82527_start_chip(struct chip_t *chip);
 int i82527_stop_chip(struct chip_t *chip);
 int i82527_check_tx_stat(struct chip_t *chip);
-irqreturn_t i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
+can_irqreturn_t i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
 
 #define MSG_OFFSET(object) ((object)*0x10)
 
index 959a94bf9da5749554d00c040cb0eeb44a546f44..6d262e2194cac4439c55840ec1774b89b5de9ddd 100644 (file)
@@ -7,6 +7,6 @@
  * Version lincan-0.2  9 Jul 2003
  */
 
-irqreturn_t i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
-irqreturn_t sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
-irqreturn_t dummy_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
+can_irqreturn_t i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
+can_irqreturn_t sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
+can_irqreturn_t dummy_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
index 4bb0e0e500b0ae9e3cb3abb06f55ced206239e3d..4d42d4df0624417dff0d5bb8d9f9292ffe044882 100644 (file)
 #include "./can_queue.h"
 
 #ifdef CAN_DEBUG
-       #define DEBUGMSG(fmt,args...) printk(KERN_ERR "can.o (debug): " fmt,\
+       #define DEBUGMSG(fmt,args...) can_printk(KERN_ERR "can.o (debug): " fmt,\
        ##args)
 #else
        #define DEBUGMSG(fmt,args...)
 #endif
 
-#define CANMSG(fmt,args...) printk(KERN_ERR "can.o: " fmt,##args)
+#define CANMSG(fmt,args...) can_printk(KERN_ERR "can.o: " fmt,##args)
 
 
 /**
@@ -152,6 +152,12 @@ struct chip_t {
        struct candevice_t *hostdevice;
        
        int max_objects;        /* 1 for sja1000, 15 for i82527 */
+
+    #ifdef CAN_WITH_RTL
+       pthread_t worker_thread;
+       rtl_spinlock_t rtl_lock;
+       unsigned long pend_flags;
+    #endif /*CAN_WITH_RTL*/
 };
 
 /**
@@ -179,7 +185,7 @@ struct msgobj_t {
        unsigned long obj_base_addr;
        unsigned int minor;     /* associated device minor number  */
        unsigned int object;    /* object number in chip_t +1 for debug printk */
-       unsigned long flags; 
+       unsigned long obj_flags; 
        int ret;
 
        struct canque_ends_t *qends;
@@ -297,7 +303,7 @@ struct chipspecops_t {
                                                        unsigned short btr1);
        int (*start_chip)(struct chip_t *chip);
        int (*stop_chip)(struct chip_t *chip);
-       irqreturn_t (*irq_handler)(int irq, void *dev_id, struct pt_regs *regs);
+       can_irqreturn_t (*irq_handler)(int irq, void *dev_id, struct pt_regs *regs);
 };
 
 struct mem_addr {
index 686b83ab006940895b2b0b707ffbeb69fd53e1c5..ae031f82717ef6479ab84446991dd9af4d98cbca 100644 (file)
@@ -12,3 +12,5 @@ int list_hw(void);
 void *can_checked_malloc(size_t size);
 int can_checked_free(void *address_p);
 int can_del_mem_list(void);
+int can_chip_setup_irq(struct chip_t *chip);
+void can_chip_free_irq(struct chip_t *chip);
index 35865b8a9e623018bdf155445cf074986b49a7a7..9046539b0af325107caca2d70da281d0f5ff6cda 100644 (file)
@@ -23,7 +23,7 @@ int sja1000_set_btregs(struct chip_t *chip, unsigned short btr0,
                                                        unsigned short btr1);
 int sja1000_start_chip(struct chip_t *chip);
 int sja1000_stop_chip(struct chip_t *chip);
-irqreturn_t sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
+can_irqreturn_t sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
 
 /* BasicCAN mode address map */
 #define SJACR          0x00    /* Control register */
index 20ab731a58296183a9a0498f6742efabe8af59be..bbdcba749462fb4a6a9a3aeb360234ee2c04e8e8 100644 (file)
@@ -1,6 +1,6 @@
-rtlinux_INCLUDES = -I $(srcdir)/../include
+rtlinux_INCLUDES = -I $(srcdir)/../include -DCAN_WITH_RTL
 kernel_INCLUDES = -I $(srcdir)/../include
-#kernel_INCLUDES += -DCAN_DEBUG
+kernel_INCLUDES += -DCAN_DEBUG
 kernel_INCLUDES += -DWITH_DEVFS_FS
 
 kernel_MODULES = lincan
@@ -11,8 +11,9 @@ lincan_cards_SOURCES = pip.c pccan.c smartcan.c nsi.c cc_can104.c \
                pc_i03.c pcm3680.c aim104.c m437.c pcccan.c ssv.c \
                bfadcan.c pikronisa.c virtual.c template.c
 
-lincan_SOURCES = can_queue.c can_quekern.c devcommon.c main.c modparms.c \
-               setup.c finish.c irq.c boardlist.c \
+lincan_SOURCES = can_queue.c can_quekern.c can_quertl.c main.c modparms.c \
+               devcommon.c can_devrtl.c setup.c finish.c irq.c boardlist.c \
                sja1000p.c sja1000.c i82527.c  \
                open.c proc.c close.c write.c read.c \
                ioctl.c select.c fasync.c proc.c $(lincan_cards_SOURCES)
+               
index 63ef735a6186f5405ff7827bedfd66c13d381595..cc2480612839223737003a7cc1cd73142c2acb23 100644 (file)
@@ -191,7 +191,7 @@ int aim104_init_chip_data(struct candevice_t *candev, int chipnr)
 int aim104_init_obj_data(struct chip_t *chip, int objnr)
 {
        chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr;
-       chip->msgobj[objnr]->flags=0;
+       chip->msgobj[objnr]->obj_flags=0;
        
        return 0;
 }
index 21de5c7f388f55a0ee23e93efa534efbbf85924e..2853ed147e8ff53c1c2a03a4ef6ec27252fd5024 100644 (file)
@@ -238,7 +238,6 @@ int bfadcan_init_chip_data(struct candevice_t *candev, int chipnr)
 int bfadcan_init_obj_data(struct chip_t *chip, int objnr)
 {
        chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr+(objnr+1)*0x10;
-       chip->msgobj[objnr]->flags=0;
        
        return 0;
 }
diff --git a/lincan/src/can_devrtl.c b/lincan/src/can_devrtl.c
new file mode 100644 (file)
index 0000000..182eb42
--- /dev/null
@@ -0,0 +1,166 @@
+/* can_devrtl.c - CAN message queues functions for the RT-Linux
+ * Linux CAN-bus device driver.
+ * New CAN queues by Pavel Pisa - OCERA team member
+ * email:pisa@cmp.felk.cvut.cz
+ * This software is released under the GPL-License.
+ * Version lincan-0.2  9 Jul 2003
+ */
+
+#ifdef CAN_WITH_RTL
+
+#include "../include/can.h"
+#include "../include/can_sysdep.h"
+#include "../include/can_queue.h"
+#include "../include/main.h"
+#include "../include/setup.h"
+
+#include <rtl_malloc.h>
+
+unsigned int can_rtl_isr( unsigned int irq_num, struct pt_regs *r )
+{
+       struct chip_t *chip;
+       struct candevice_t *candev;
+       int board_nr;
+       int chip_nr;
+       pthread_t thread=NULL;
+
+       DEBUGMSG("can_rtl_isr invoked for irq %d\n",irq_num);
+       
+       /* I hate next loop, but RT-Linux does not provide context to ISR */
+       for (board_nr=hardware_p->nr_boards; board_nr--; ) {
+               if((candev=hardware_p->candevice[board_nr])==NULL)
+                       continue;
+               for(chip_nr=candev->nr_all_chips; chip_nr--; ) {
+                       if((chip=candev->chip[chip_nr])==NULL)
+                               continue;
+                       if(chip->chip_irq!=irq_num) continue;
+
+                       set_bit(MSGOBJ_IRQ_REQUEST_b,&chip->pend_flags);
+                       set_bit(MSGOBJ_WORKER_WAKE_b,&chip->pend_flags);
+                       
+                       if(!chip->worker_thread) continue;
+                       thread=chip->worker_thread;
+                       pthread_kill(thread,RTL_SIGNAL_WAKEUP);
+               }
+       }
+
+       /*rtl_global_pend_irq(irq_num);*/
+
+       /*if(thread) rtl_reschedule_thread(thread);*/
+
+       rtl_schedule();
+
+       return 0;
+}
+
+
+
+/*
+RTL_MARK_READY(pthread_self())
+RTL_MARK_SUSPENDED(pthread_self());
+return rtl_schedule();
+can_enable_irq
+can_disable_irq 
+rtl_critical( state )
+rtl_end_critical( state )
+rtl_request_global_irq( irq, isr ); 
+rtl_free_global_irq( irq )
+*/
+
+void * can_chip_worker_thread(void *arg)
+{
+       struct chip_t *chip = (struct chip_t *) arg;
+       struct msgobj_t *obj;
+       int ret, i;
+       int loop_cnt;
+       
+       if(!chip) return 0;
+       
+       
+       if (!(chip->flags & CHIP_CONFIGURED)){
+               if (chip->chipspecops->chip_config(chip))
+                       CANMSG("Error configuring chip.\n");
+               else
+                       chip->flags |= CHIP_CONFIGURED; 
+
+               if((chip->msgobj[0])!=NULL)
+                       if (chip->chipspecops->pre_read_config(chip,chip->msgobj[0])<0)
+                               CANMSG("Error initializing chip for receiving\n");
+                               
+       } /* End of chip configuration */
+       set_bit(MSGOBJ_IRQ_REQUEST_b,&chip->pend_flags);
+       
+
+       while (1) {
+               DEBUGMSG("Worker thread for chip %d active\n",chip->chip_idx);
+               if(test_and_clear_bit(MSGOBJ_IRQ_REQUEST_b,&chip->pend_flags)){
+                       DEBUGMSG("IRQ_REQUEST processing ...\n");
+                       loop_cnt = 100;
+                       if(chip->chipspecops->irq_handler) do{
+                               ret=chip->chipspecops->irq_handler(chip->chip_irq,chip,NULL);
+                       }while(ret && --loop_cnt);
+                       continue;
+               }
+               if(test_and_clear_bit(MSGOBJ_TX_REQUEST_b,&chip->pend_flags)){
+                       DEBUGMSG("TX_REQUEST processing ...\n");
+                       for(i=0;i<chip->max_objects;i++){
+                               if((obj=chip->msgobj[i])==NULL)
+                                       continue;
+                               if(!can_msgobj_test_and_clear_fl(obj,TX_REQUEST))
+                                       continue;
+                               DEBUGMSG("Calling wakeup_tx\n");
+                               chip->chipspecops->wakeup_tx(chip, obj);
+                       }
+                       continue;
+               }
+
+               /*re-enable chip IRQ, I am not sure, if this is required,
+                 but it seems to not work without that */
+               if(chip->chip_irq>=0)
+                       can_enable_irq(chip->chip_irq);
+
+               RTL_MARK_SUSPENDED(pthread_self());
+               if(test_and_clear_bit(MSGOBJ_WORKER_WAKE_b,&chip->pend_flags)){
+                       RTL_MARK_READY(pthread_self());
+                       continue;
+               }
+               rtl_schedule();
+
+       }
+       return 0;
+}
+
+
+int can_chip_setup_irq(struct chip_t *chip)
+{
+       int ret;
+       
+       if(chip==NULL)
+               return -1;
+       if(chip->chipspecops->irq_handler){
+               if (rtl_request_irq(chip->chip_irq,can_rtl_isr))
+                       return -1;
+               else {
+                       DEBUGMSG("Registered interrupt %d\n",chip->chip_irq);
+                       chip->flags |= CHIP_IRQ_SETUP;
+               }
+       }
+        ret=pthread_create(&chip->worker_thread, NULL, can_chip_worker_thread, chip);
+       if(ret<0) chip->worker_thread=NULL;
+       
+       return ret;
+}
+
+
+void can_chip_free_irq(struct chip_t *chip)
+{
+       if(chip->worker_thread)
+               pthread_delete_np(chip->worker_thread);
+       if((chip->flags & CHIP_IRQ_SETUP) && (chip->chip_irq>=0)) {
+               rtl_free_irq(chip->chip_irq);
+               chip->flags &= ~CHIP_IRQ_SETUP;
+       }
+}
+
+
+#endif /*CAN_WITH_RTL*/
index 8725f645cd94deefbc7308d2a70eccafc08677aa..39c033070fa5b042f03d967af53c2db4d944554f 100644 (file)
 extern atomic_t edge_num_cnt;
 
 #ifdef CAN_DEBUG
-       #define DEBUGQUE(fmt,args...) printk(KERN_ERR "can_queue (debug): " fmt,\
+       #define DEBUGQUE(fmt,args...) can_printk(KERN_ERR "can_queue (debug): " fmt,\
        ##args)
 
 #else
        #define DEBUGQUE(fmt,args...)
 #endif
 
-#define ERRMSGQUE(fmt,args...) printk(KERN_ERR "can_queue: " fmt,\
+#define ERRMSGQUE(fmt,args...) can_printk(KERN_ERR "can_queue: " fmt,\
        ##args)
 
 
@@ -71,6 +71,13 @@ void canque_dead_func(unsigned long data)
 
        while((qedge=canque_dead_edges_cut_first())){
                DEBUGQUE("edge %d disposed\n",qedge->edge_num);
+           #ifdef CAN_WITH_RTL
+               if(canque_fifo_test_fl(&qedge->fifo,RTL_MEM)){
+                       canque_dispose_edge_rtl(qedge);
+                       continue;
+               }
+           #endif /*CAN_WITH_RTL*/
+               canque_fifo_done_kern(&qedge->fifo);
                kfree(qedge);
        }
        
@@ -88,6 +95,12 @@ void canque_dead_func(unsigned long data)
                list_del(&qends->dead_peers);
                can_spin_unlock_irqrestore(&canque_dead_func_lock,flags);
                DEBUGQUE("ends structure disposed\n");
+           #ifdef CAN_WITH_RTL
+               if(qends->ends_flags&CAN_ENDSF_MEM_RTL){
+                       canque_ends_free_rtl(qends);
+                       continue;
+               }
+           #endif /*CAN_WITH_RTL*/
                kfree(qends);
        }
 
@@ -132,6 +145,13 @@ void canqueue_notify_kern(struct canque_ends_t *qends, struct canque_edge_t *qed
 {
        DEBUGQUE("canqueue_notify_kern for edge %d, use %d and event %d\n",
                        qedge->edge_num,(int)atomic_read(&qedge->edge_used),what);
+
+       /* delay event delivery for RT-Linux -> kernel notifications */
+       if(canqueue_rtl2lin_check_and_pend(qends,qedge,what)){
+               DEBUGQUE("canqueue_notify_kern postponed\n");
+               return;
+       }
+       
        switch(what){
                case CANQUEUE_NOTIFY_EMPTY:
                        wake_up(&qends->endinfo.fileinfo.emptyq);
@@ -253,6 +273,38 @@ int canque_sync_wait_kern(struct canque_ends_t *qends, struct canque_edge_t *qed
 }
 
 
+/**
+ * canque_fifo_init_kern - initialize one CAN FIFO
+ * @fifo: pointer to the FIFO structure
+ * @slotsnr: number of requested slots
+ *
+ * Return Value: The negative value indicates, that there is no memory
+ *     to allocate space for the requested number of the slots.
+ */
+int canque_fifo_init_kern(struct canque_fifo_t *fifo, int slotsnr)
+{
+       int size;
+       if(!slotsnr) slotsnr=MAX_BUF_LENGTH;
+       size=sizeof(struct canque_slot_t)*slotsnr;
+       fifo->entry=kmalloc(size,GFP_KERNEL);
+       if(!fifo->entry) return -1;
+       fifo->slotsnr=slotsnr;
+       return canque_fifo_init_slots(fifo);
+}
+
+/**
+ * canque_fifo_done_kern - frees slots allocated for CAN FIFO
+ * @fifo: pointer to the FIFO structure
+ */
+int canque_fifo_done_kern(struct canque_fifo_t *fifo)
+{
+       if(fifo->entry)
+               kfree(fifo->entry);
+       fifo->entry=NULL;
+       return 1;
+}
+
+
 /**
  * canque_new_edge_kern - allocate new edge structure in the Linux kernel context
  * @slotsnr: required number of slots in the newly allocated edge structure
@@ -268,7 +320,7 @@ struct canque_edge_t *canque_new_edge_kern(int slotsnr)
 
        memset(qedge,0,sizeof(struct canque_edge_t));
        can_spin_lock_init(&qedge->fifo.fifo_lock);
-       if(canque_fifo_init_slots(&qedge->fifo, slotsnr)<0){
+       if(canque_fifo_init_kern(&qedge->fifo, slotsnr)<0){
                kfree(qedge);
                DEBUGQUE("canque_new_edge_kern failed\n");
                return NULL;
@@ -340,7 +392,7 @@ int canqueue_disconnect_list_kern(struct canque_ends_t *qends, struct list_head
                can_spin_unlock_irqrestore(&qends->ends_lock,flags);
                if(canqueue_disconnect_edge_kern(qends, edge)>=0) {
                        /* Free edge memory */
-                       canque_fifo_done(&edge->fifo);
+                       canque_fifo_done_kern(&edge->fifo);
                        kfree(edge);
                }else{
                        canque_notify_bothends(edge, CANQUEUE_NOTIFY_DEAD_WANTED);
@@ -366,6 +418,19 @@ int canqueue_ends_sync_all_kern(struct canque_ends_t *qends)
        return 0;
 }
 
+
+void canqueue_ends_dispose_postpone(struct canque_ends_t *qends)
+{
+       can_spin_irqflags_t flags;
+
+       can_spin_lock_irqsave(&canque_dead_func_lock, flags);
+       qends->ends_flags |= CAN_ENDSF_DEAD;
+       list_add(&qends->dead_peers,&canque_dead_ends);
+       can_spin_unlock_irqrestore(&canque_dead_func_lock, flags);
+       tasklet_schedule(&canque_dead_tl);
+}
+
+
 /**
  * canqueue_ends_dispose_kern - finalizing of the ends structure for Linux kernel clients
  * @qends: pointer to ends structure
@@ -376,7 +441,6 @@ int canqueue_ends_sync_all_kern(struct canque_ends_t *qends)
  */
 int canqueue_ends_dispose_kern(struct canque_ends_t *qends, int sync)
 {
-       can_spin_irqflags_t flags;
        int delayed;
 
        DEBUGQUE("canqueue_ends_dispose_kern\n");
@@ -397,11 +461,7 @@ int canqueue_ends_dispose_kern(struct canque_ends_t *qends, int sync)
        wake_up(&qends->endinfo.fileinfo.emptyq);
 
        if(delayed){
-               can_spin_lock_irqsave(&canque_dead_func_lock, flags);
-               qends->ends_flags |= CAN_ENDSF_DEAD;
-               list_add(&qends->dead_peers,&canque_dead_ends);
-               can_spin_unlock_irqrestore(&canque_dead_func_lock, flags);
-               tasklet_schedule(&canque_dead_tl);
+               canqueue_ends_dispose_postpone(qends);
 
                DEBUGQUE("canqueue_ends_dispose_kern delayed\n");
                return 1;
diff --git a/lincan/src/can_quertl.c b/lincan/src/can_quertl.c
new file mode 100644 (file)
index 0000000..45129b4
--- /dev/null
@@ -0,0 +1,319 @@
+/* can_quertl.c - CAN message queues functions for the RT-Linux
+ * Linux CAN-bus device driver.
+ * New CAN queues by Pavel Pisa - OCERA team member
+ * email:pisa@cmp.felk.cvut.cz
+ * This software is released under the GPL-License.
+ * Version lincan-0.2  9 Jul 2003
+ */
+
+#ifdef CAN_WITH_RTL
+
+#include "../include/can.h"
+#include "../include/can_sysdep.h"
+#include "../include/can_queue.h"
+
+#include <rtl_malloc.h>
+
+/* 
+ * Modifies Tx message processing 
+ *  0 .. local message processing disabled
+ *  1 .. local messages disabled by default but can be enabled by canque_set_filt
+ *  2 .. local messages enabled by default, can be disabled by canque_set_filt
+ */
+extern int processlocal;
+
+
+#define CANQUE_PENDOPS_LIMIT 15
+#define CANQUE_PENDOPS_MASK  ((1<<CANQUE_PENDOPS_LIMIT)-1)
+
+struct list_head canque_pending_edges_list;
+can_spinlock_t canque_pending_edges_lock;
+
+static int canqueue_rtl_irq = 0;
+
+void
+canqueue_rtl2lin_handler(int irq, void *ignore, struct pt_regs *ignoreregs)
+{
+       can_spin_irqflags_t flags;
+       struct canque_edge_t *qedge;
+       unsigned pending_inops;
+       unsigned pending_outops;
+       int i;
+       
+       can_spin_lock_irqsave (&canque_pending_edges_lock, flags);
+
+       while(!list_empty(&canque_pending_edges_list)){
+               qedge=list_entry(canque_pending_edges_list.next,struct canque_edge_t,pending_peers);
+               list_del(&qedge->pending_peers);
+               canque_fifo_clear_fl(&qedge->fifo, NOTIFYPEND);
+               pending_inops=qedge->pending_inops;
+               qedge->pending_inops=0;
+               pending_outops=qedge->pending_outops;
+               qedge->pending_outops=0;
+               can_spin_unlock_irqrestore (&canque_pending_edges_lock, flags);
+
+               if(pending_outops & ~CANQUE_PENDOPS_MASK){
+                       pending_outops &= CANQUE_PENDOPS_MASK;
+                       canque_notify_outends(qedge,CANQUEUE_NOTIFY_ERROR | qedge->fifo.error_code);
+               }
+               for(i=0;pending_outops;i++,pending_outops>>=1){
+                       if(pending_outops&1)
+                               canque_notify_outends(qedge,i);
+               }
+               if(pending_inops & ~CANQUE_PENDOPS_MASK){
+                       pending_inops &= CANQUE_PENDOPS_MASK;
+                       canque_notify_inends(qedge,CANQUEUE_NOTIFY_ERROR | qedge->fifo.error_code);
+               }
+               for(i=0;pending_inops;i++,pending_inops>>=1){
+                       if(pending_inops&1)
+                               canque_notify_inends(qedge,i);
+               }
+               
+               canque_edge_decref(qedge);
+               can_spin_lock_irqsave (&canque_pending_edges_lock, flags);
+       }
+
+       can_spin_unlock_irqrestore (&canque_pending_edges_lock, flags);
+
+       return;
+}
+
+
+/**
+ * canqueue_rtl2lin_check_and_pend - postpones edge notification if called from RT-Linux 
+ * @qends: notification target ends
+ * @qedge: edge delivering notification
+ * @what:  notification type
+ *
+ * Return Value: if called from Linux context, returns 0 and lefts notification processing
+ *             on caller responsibility. If called from RT-Linux contexts, schedules postponed
+ *             event delivery and returns 1
+ */
+int canqueue_rtl2lin_check_and_pend(struct canque_ends_t *qends,
+                        struct canque_edge_t *qedge, int what)
+{
+       can_spin_irqflags_t flags;
+
+       if(rtl_rt_system_is_idle()) return 0;
+
+       can_spin_lock_irqsave (&canque_pending_edges_lock, flags);
+       
+       if(what>CANQUE_PENDOPS_LIMIT) what=CANQUE_PENDOPS_LIMIT;
+
+       if(qends == qedge->inends) {
+               set_bit(what,&qedge->pending_inops);
+       } else if(qends == qedge->outends) {
+               set_bit(what,&qedge->pending_outops);
+       }
+
+       if(!canque_fifo_test_and_set_fl(&qedge->fifo, NOTIFYPEND)){
+               canque_edge_incref(qedge);
+               list_add_tail(&qedge->pending_peers,&canque_pending_edges_list);
+               rtl_global_pend_irq (canqueue_rtl_irq);
+       }
+
+       can_spin_unlock_irqrestore (&canque_pending_edges_lock, flags);
+       
+       return 1;
+
+}
+
+
+/**
+ * canque_fifo_init_rtl - initialize one CAN FIFO
+ * @fifo: pointer to the FIFO structure
+ * @slotsnr: number of requested slots
+ *
+ * Return Value: The negative value indicates, that there is no memory
+ *     to allocate space for the requested number of the slots.
+ */
+int canque_fifo_init_rtl(struct canque_fifo_t *fifo, int slotsnr)
+{
+       int size;
+       if(!slotsnr) slotsnr=MAX_BUF_LENGTH;
+       size=sizeof(struct canque_slot_t)*slotsnr;
+       fifo->entry=rt_malloc(size);
+       if(!fifo->entry) return -1;
+       fifo->slotsnr=slotsnr;
+       return canque_fifo_init_slots(fifo);
+}
+
+/**
+ * canque_fifo_done_rtl - frees slots allocated for CAN FIFO
+ * @fifo: pointer to the FIFO structure
+ */
+int canque_fifo_done_rtl(struct canque_fifo_t *fifo)
+{
+       if(fifo->entry)
+               rt_free(fifo->entry);
+       fifo->entry=NULL;
+       return 1;
+}
+
+void canque_dispose_edge_rtl(struct canque_edge_t *qedge)
+{
+       canque_fifo_done_rtl(&qedge->fifo);
+       rt_free(qedge);
+}
+
+/**
+ * canque_new_edge_rtl - allocate new edge structure in the RT-Linux context
+ * @slotsnr: required number of slots in the newly allocated edge structure
+ *
+ * Return Value: Returns pointer to allocated slot structure or %NULL if
+ *     there is not enough memory to process operation.
+ */
+struct canque_edge_t *canque_new_edge_rtl(int slotsnr)
+{
+       struct canque_edge_t *qedge;
+       qedge = (struct canque_edge_t *)rt_malloc(sizeof(struct canque_edge_t));
+       if(qedge == NULL) return NULL;
+
+       memset(qedge,0,sizeof(struct canque_edge_t));
+       can_spin_lock_init(&qedge->fifo.fifo_lock);
+       canque_fifo_set_fl(&qedge->fifo,RTL_MEM);
+       if(canque_fifo_init_rtl(&qedge->fifo, slotsnr)<0){
+               rt_free(qedge);
+               return NULL;
+       }
+       atomic_set(&qedge->edge_used,1);
+       qedge->filtid = 0;
+       qedge->filtmask = canque_filtid2internal(0l, (processlocal<2)? MSG_LOCAL:0);
+       qedge->edge_prio = 0;
+    #if defined(CAN_DEBUG) && 0
+       /* not exactly clean, but enough for debugging */
+       atomic_inc(&edge_num_cnt);
+       qedge->edge_num=atomic_read(&edge_num_cnt);
+    #endif /* CAN_DEBUG */
+       return qedge;
+}
+
+void canque_ends_free_rtl(struct canque_ends_t *qends)
+{
+       rt_free(qends);
+}
+
+
+/**
+ * canqueue_notify_rtl - notification callback handler for Linux userspace clients
+ * @qends: pointer to the callback side ends structure
+ * @qedge: edge which invoked notification 
+ * @what: notification type
+ */
+void canqueue_notify_rtl(struct canque_ends_t *qends, struct canque_edge_t *qedge, int what)
+{
+       rtl_irqstate_t flags;
+       
+       switch(what){
+               case CANQUEUE_NOTIFY_EMPTY:
+                       rtl_spin_lock_irqsave(&qends->endinfo.rtlinfo.rtl_lock, flags);
+                       rtl_wait_wakeup(&qends->endinfo.rtlinfo.rtl_emptyq);
+                       rtl_spin_unlock_irqrestore(&qends->endinfo.rtlinfo.rtl_lock, flags);
+                       if(canque_fifo_test_and_clear_fl(&qedge->fifo, FREEONEMPTY))
+                               canque_edge_decref(qedge);
+                       break;
+               case CANQUEUE_NOTIFY_SPACE:
+                       rtl_spin_lock_irqsave(&qends->endinfo.rtlinfo.rtl_lock, flags);
+                       rtl_wait_wakeup(&qends->endinfo.rtlinfo.rtl_writeq);
+                       rtl_spin_unlock_irqrestore(&qends->endinfo.rtlinfo.rtl_lock, flags);
+                       break;
+               case CANQUEUE_NOTIFY_PROC:
+                       rtl_spin_lock_irqsave(&qends->endinfo.rtlinfo.rtl_lock, flags);
+                       rtl_wait_wakeup(&qends->endinfo.rtlinfo.rtl_readq);
+                       rtl_spin_unlock_irqrestore(&qends->endinfo.rtlinfo.rtl_lock, flags);
+                       break;
+               case CANQUEUE_NOTIFY_NOUSR:
+                       rtl_spin_lock_irqsave(&qends->endinfo.rtlinfo.rtl_lock, flags);
+                       rtl_wait_wakeup(&qends->endinfo.rtlinfo.rtl_readq);
+                       rtl_wait_wakeup(&qends->endinfo.rtlinfo.rtl_writeq);
+                       rtl_wait_wakeup(&qends->endinfo.rtlinfo.rtl_emptyq);
+                       rtl_spin_unlock_irqrestore(&qends->endinfo.rtlinfo.rtl_lock, flags);
+                       break;
+               case CANQUEUE_NOTIFY_DEAD_WANTED:
+               case CANQUEUE_NOTIFY_DEAD:
+                       if(canque_fifo_test_and_clear_fl(&qedge->fifo, READY))
+                               canque_edge_decref(qedge);
+                       break;
+               case CANQUEUE_NOTIFY_ATTACH:
+                       break;
+       }
+}
+
+
+/**
+ * canqueue_ends_init_rtl - RT-Linux clients specific ends initialization
+ * @qends: pointer to the callback side ends structure
+ */
+int canqueue_ends_init_rtl(struct canque_ends_t *qends)
+{
+       canqueue_ends_init_gen(qends);
+       qends->context=NULL;
+       rtl_spin_lock_init(&(qends->endinfo.rtlinfo.rtl_lock));
+       rtl_wait_init(&(qends->endinfo.rtlinfo.rtl_readq));
+       rtl_wait_init(&(qends->endinfo.rtlinfo.rtl_writeq));
+       rtl_wait_init(&(qends->endinfo.rtlinfo.rtl_emptyq));
+       
+       qends->notify=canqueue_notify_rtl;
+       return 0;
+}
+
+/**
+ * canqueue_ends_dispose_rtl - finalizing of the ends structure for Linux kernel clients
+ * @qends: pointer to ends structure
+ * @sync: flag indicating, that user wants to wait for processing of all remaining
+ *     messages
+ *
+ * Return Value: Function should be designed such way to not fail.
+ */
+int canqueue_ends_dispose_rtl(struct canque_ends_t *qends, int sync)
+{
+       rtl_irqstate_t flags;
+       int delayed;
+
+       canqueue_block_inlist(qends);
+       canqueue_block_outlist(qends);
+
+       /*Wait for sending of all pending messages in the output FIFOs*/
+       /*if(sync)
+               canqueue_ends_sync_all_rtl(qends);*/
+       
+       /* Finish or kill all outgoing edges listed in inends */
+       delayed=canqueue_ends_kill_inlist(qends, 1);
+       /* Kill all incoming edges listed in outends */
+       delayed|=canqueue_ends_kill_outlist(qends);
+
+       rtl_spin_lock_irqsave(&qends->endinfo.rtlinfo.rtl_lock, flags);
+       rtl_wait_wakeup(&qends->endinfo.rtlinfo.rtl_readq);
+       rtl_wait_wakeup(&qends->endinfo.rtlinfo.rtl_writeq);
+       rtl_wait_wakeup(&qends->endinfo.rtlinfo.rtl_emptyq);
+       rtl_spin_unlock_irqrestore(&qends->endinfo.rtlinfo.rtl_lock, flags);
+
+       if(delayed || !(qends->ends_flags&CAN_ENDSF_MEM_RTL)){
+               canqueue_ends_dispose_postpone(qends);
+
+               return 1;
+       }
+
+       canque_ends_free_rtl(qends);
+       return 0;
+}
+
+
+
+void canqueue_rtl_initialize(void)
+{
+       INIT_LIST_HEAD(&canque_pending_edges_list);
+       can_spin_lock_init(&canque_pending_edges_lock);
+
+       canqueue_rtl_irq = rtl_get_soft_irq (canqueue_rtl2lin_handler, "rtl_canqueue_irq");
+}
+
+
+void canqueue_rtl_done(void)
+{
+       rtl_free_soft_irq (canqueue_rtl_irq);
+
+}
+
+
+#endif /*CAN_WITH_RTL*/
index c0f1a6dc7e0a8926c5670dd6103115f5c99e7fe2..96c37a4acb9a3d44581f2269908ed20b8a56dc9f 100644 (file)
@@ -21,9 +21,10 @@ extern int processlocal;
 atomic_t edge_num_cnt;
 
 //#define CAN_DEBUG
+#undef CAN_DEBUG
 
 #ifdef CAN_DEBUG
-       #define DEBUGQUE(fmt,args...) printk(KERN_ERR "can_queue (debug): " fmt,\
+       #define DEBUGQUE(fmt,args...) can_printk(KERN_ERR "can_queue (debug): " fmt,\
        ##args)
 
 #else
@@ -65,21 +66,17 @@ int canque_fifo_flush_slots(struct canque_fifo_t *fifo)
 
 
 /**
- * canque_fifo_init_slots - initialize one CAN FIFO
+ * canque_fifo_init_slots - initializes slot chain of one CAN FIFO
  * @fifo: pointer to the FIFO structure
- * @slotsnr: number of requested slots
  *
  * Return Value: The negative value indicates, that there is no memory
  *     to allocate space for the requested number of the slots.
  */
-int canque_fifo_init_slots(struct canque_fifo_t *fifo, int slotsnr)
+int canque_fifo_init_slots(struct canque_fifo_t *fifo)
 {
-       int size;
        struct canque_slot_t *slot;
-       if(!slotsnr) slotsnr=MAX_BUF_LENGTH;
-       size=sizeof(struct canque_slot_t)*slotsnr;
-       fifo->entry=kmalloc(size,GFP_KERNEL);
-       if(!fifo->entry) return -1;
+       int slotsnr=fifo->slotsnr;
+       if(!fifo->entry || !slotsnr) return -1;
        slot=fifo->entry;
        fifo->flist=slot;
        while(--slotsnr){
@@ -93,18 +90,6 @@ int canque_fifo_init_slots(struct canque_fifo_t *fifo, int slotsnr)
        return 1;
 }
 
-/**
- * canque_fifo_done - frees slots allocated for CAN FIFO
- * @fifo: pointer to the FIFO structure
- */
-int canque_fifo_done(struct canque_fifo_t *fifo)
-{
-       if(fifo->entry)
-               kfree(fifo->entry);
-       fifo->entry=NULL;
-       return 1;
-}
-
 /* atomic_dec_and_test(&qedge->edge_used);
  void atomic_inc(&qedge->edge_used);
  list_add_tail(struct list_head *new, struct list_head *head)
index 9b8dd261fe325a9aba98897280a52372a9d699f4..1197bcfb48a81a4e1438850f458b2b82ce643493 100644 (file)
@@ -172,7 +172,6 @@ int cc104_init_chip_data(struct candevice_t *candev, int chipnr)
 int cc104_init_obj_data(struct chip_t *chip, int objnr)
 {
        chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr;
-       chip->msgobj[objnr]->flags=0;
        
        return 0;
 }
index 4df1533e9fa283dba8228f71a35c4a4d47c2eea3..73d4764d6662664bd06eec67255035b24875c0ea 100644 (file)
@@ -45,7 +45,7 @@ int can_close(struct inode *inode, struct file *file)
        kfree(canuser);
 
        if(atomic_dec_and_test(&obj->obj_used)){
-               obj->flags &= ~OBJ_OPENED;
+               can_msgobj_clear_fl(obj,OPENED);
                /* FIXME: what about clearing chip HW status, stopping sending messages etc? */
        };
        
index c26a36f0231fab67c8cb420628e888bc98b6a15e..c0b602886f49a8a64abf7552aae9ad73262732c2 100644 (file)
@@ -25,8 +25,25 @@ void canqueue_notify_chip(struct canque_ends_t *qends, struct canque_edge_t *qed
                        wake_up(&qends->endinfo.chipinfo.daemonq);
                        break;*/
                case CANQUEUE_NOTIFY_PROC:
+                   #ifndef CAN_WITH_RTL
                        /*wake_up(&qends->endinfo.chipinfo.daemonq);*/
                        chip->chipspecops->wakeup_tx(chip, obj);
+                   #else /*CAN_WITH_RTL*/
+                       can_msgobj_set_fl(obj,TX_REQUEST);
+                       if(qends->endinfo.chipinfo.worker_thread){
+                               can_msgobj_set_fl(obj,WORKER_WAKE);
+                               pthread_kill(qends->endinfo.chipinfo.worker_thread,RTL_SIGNAL_WAKEUP);
+                               rtl_schedule();
+                       } else {
+                               set_bit(MSGOBJ_TX_REQUEST_b,&chip->pend_flags);
+
+                               if(chip->worker_thread) {
+                                       set_bit(MSGOBJ_WORKER_WAKE_b,&chip->pend_flags);
+                                       pthread_kill(chip->worker_thread,RTL_SIGNAL_WAKEUP);
+                                       rtl_schedule();
+                               }
+                       }
+                   #endif /*CAN_WITH_RTL*/
                        break;
                case CANQUEUE_NOTIFY_DEAD_WANTED:
                case CANQUEUE_NOTIFY_DEAD:
@@ -46,7 +63,9 @@ int canqueue_ends_init_chip(struct canque_ends_t *qends, struct chip_t *chip, st
        if(ret<0) return ret;
        
        qends->context=NULL;
+    #ifndef CAN_WITH_RTL
        init_waitqueue_head(&qends->endinfo.chipinfo.daemonq);
+    #endif /*CAN_WITH_RTL*/
        qends->endinfo.chipinfo.chip=chip;
        qends->endinfo.chipinfo.msgobj=obj;
        qends->notify=canqueue_notify_chip;
index fdca959e807692ceddeaba8a2996e4d67d8b9076..922b4d3608077fe03dfda6a78142707b7e2566b7 100644 (file)
@@ -57,10 +57,7 @@ void canchip_done(struct chip_t *chip)
                        CANMSG("canchip_done: not registered in hostdevice\n");
        }
 
-       if((chip->flags & CHIP_IRQ_SETUP) && (chip->chip_irq>=0)) {
-               free_irq(chip->chip_irq, chip);
-               chip->flags &= ~CHIP_IRQ_SETUP;
-       }
+       can_chip_free_irq(chip);
                
        can_synchronize_irq(chip->chip_irq);
        
index 7a57f45c7e7601753cd0b11b35e7a5db5f01ebde..7b9602f90db47546c0eeb867259b50705ae06db8 100644 (file)
@@ -463,7 +463,7 @@ inline void i82527_irq_read_handler(struct chip_t *chip, struct msgobj_t *obj,
        }
 }
 
-irqreturn_t i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+can_irqreturn_t i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
        int id0=0, id1=0, id2=0, id3=0;
 
@@ -483,7 +483,7 @@ irqreturn_t i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 
                if (irq_register == 0x01) {
                        DEBUGMSG("Status register: 0x%x\n",can_read_reg(chip, iSTAT));
-                       return IRQ_NONE;
+                       return CAN_IRQ_NONE;
                }
                
                if (irq_register == 0x02)
@@ -494,15 +494,15 @@ irqreturn_t i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
                obj=chip->msgobj[object];
 
                if (canobj_read_reg(chip,obj,iMSGCFG) & MCFG_DIR) {
-                       set_bit(OBJ_TX_REQUEST,&obj->flags);
-                       while(!test_and_set_bit(OBJ_TX_LOCK,&obj->flags)){
-                               clear_bit(OBJ_TX_REQUEST,&obj->flags);
+                       can_msgobj_set_fl(obj,TX_REQUEST);
+                       while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
+                               can_msgobj_clear_fl(obj,TX_REQUEST);
 
                                if(canobj_read_reg(chip,obj,iMSGCTL1)&TXRQ_RES)
                                        i82527_irq_write_handler(chip, obj); 
 
-                               clear_bit(OBJ_TX_LOCK,&obj->flags);
-                               if(!test_bit(OBJ_TX_REQUEST,&obj->flags)) break;
+                               can_msgobj_clear_fl(obj,TX_LOCK);
+                               if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
                        }
                }
                else { 
@@ -536,7 +536,7 @@ irqreturn_t i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 
                irq_register=i82527_seg_read_reg(chip, iIRQ);
        }
-       return IRQ_HANDLED;
+       return CAN_IRQ_HANDLED;
 }
 
 void i82527_irq_rtr_handler(struct chip_t *chip, struct msgobj_t *obj,
@@ -562,26 +562,20 @@ void i82527_irq_rtr_handler(struct chip_t *chip, struct msgobj_t *obj,
 
 int i82527_wakeup_tx(struct chip_t *chip, struct msgobj_t *obj)
 {
-        /* dummy lock to prevent preemption fully portable way */
-       can_spinlock_t dummy_lock;
+       can_preempt_disable();
        
-       /*  preempt_disable() */
-       can_spin_lock_init(&dummy_lock);
-       can_spin_lock(&dummy_lock);
-       
-       set_bit(OBJ_TX_REQUEST,&obj->flags);
-       while(!test_and_set_bit(OBJ_TX_LOCK,&obj->flags)){
-               clear_bit(OBJ_TX_REQUEST,&obj->flags);
+       can_msgobj_set_fl(obj,TX_REQUEST);
+       while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
+               can_msgobj_clear_fl(obj,TX_REQUEST);
 
                if(canobj_read_reg(chip,obj,iMSGCTL1)&TXRQ_RES)
                        i82527_irq_write_handler(chip, obj);
        
-               clear_bit(OBJ_TX_LOCK,&obj->flags);
-               if(!test_bit(OBJ_TX_REQUEST,&obj->flags)) break;
+               can_msgobj_clear_fl(obj,TX_LOCK);
+               if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
        }
 
-       /* preempt_enable(); */
-       can_spin_unlock(&dummy_lock);
+       can_preempt_enable();
        return 0;
 }
 
index e48db31691f1452c63a84b4ac21324fd9f5be6c2..26d0cf7db4493299959cdf19935bec57126e0361 100644 (file)
@@ -13,7 +13,7 @@
 #include "../include/irq.h"
 
 
-irqreturn_t dummy_irq_handler(int irq, void *dev_id, struct pt_regs *regs) {
+can_irqreturn_t dummy_irq_handler(int irq, void *dev_id, struct pt_regs *regs) {
        CANMSG("dummy_irq_handler called irq %d \n", irq);
-       return IRQ_NONE;
+       return CAN_IRQ_NONE;
 }
index 6fa87e7f540a5656b4a741499eedd0bb514de4e0..37308b2019fe1028cdc31dea384fc9d996a5961c 100644 (file)
@@ -229,7 +229,6 @@ int m437_init_chip_data(struct candevice_t *candev, int chipnr)
 int m437_init_obj_data(struct chip_t *chip, int objnr)
 {
        chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr+(objnr+1)*0x10;
-       chip->msgobj[objnr]->flags=0;
        
        return 0;
 }
index 918c2f76ecb30a07ac7e4fc38e4dfaf40fe4fd8d..c40310dbde3cc2738d6189ce1488e27246056ec5 100644 (file)
@@ -154,6 +154,10 @@ int init_module(void)
                return -ENODEV;
        }
 
+       #ifdef CAN_WITH_RTL
+       canqueue_rtl_initialize();
+       #endif /*CAN_WITH_RTL*/
+
        for (i=0; i<hardware_p->nr_boards; i++) {
                candev=hardware_p->candevice[i];
                if (candev->hwspecops->request_io(candev)) 
@@ -175,14 +179,9 @@ int init_module(void)
                for(j=0; j<candev->nr_all_chips; j++) {
                        if((chip=candev->chip[j])==NULL)
                                continue;
-                       if(!chip->chipspecops->irq_handler)
-                               continue;
-                       
-                       if (request_irq(chip->chip_irq,chip->chipspecops->irq_handler,SA_SHIRQ,DEVICE_NAME,chip))
+                       if(can_chip_setup_irq(chip)<0) {
+                               CANMSG("IRQ setup failed\n");
                                goto interrupt_error;
-                       else {
-                               DEBUGMSG("Registered interrupt %d\n",chip->chip_irq);
-                               chip->flags |= CHIP_IRQ_SETUP;
                        }
                }
                
@@ -233,6 +232,10 @@ int init_module(void)
        memory_error: ;
                canhardware_done(hardware_p);
 
+               #ifdef CAN_WITH_RTL
+               canqueue_rtl_done();
+               #endif /*CAN_WITH_RTL*/
+
                res=unregister_chrdev(major,DEVICE_NAME);
                if (res<0)
                        CANMSG("Error unloading CAN driver, error: %d\n",res);
@@ -268,6 +271,10 @@ void cleanup_module(void)
 
        canhardware_done(hardware_p);
 
+       #ifdef CAN_WITH_RTL
+       canqueue_rtl_done();
+       #endif /*CAN_WITH_RTL*/
+
        if ( can_del_mem_list() ) 
                CANMSG("Error deallocating memory\n");
 
index aeef3925f94edadd86046965193ec81841a73929..9f6bdefd46b61caea13c6804e278c098106fd8af 100644 (file)
@@ -149,7 +149,6 @@ int nsi_init_obj_data(struct chip_t *chip, int objnr)
 
        chip->msgobj[objnr]->obj_base_addr=
            chip->chip_base_addr+(objnr+1)*0x10;
-       chip->msgobj[objnr]->flags=0;
        
        return 0;
 }
@@ -193,10 +192,10 @@ unsigned nsi_read_register(unsigned long address)
        data */
     unsigned char ret;
     
-    disable_irq(nsican_irq); 
+    can_disable_irq(nsican_irq); 
     outb(address-nsican_base, nsican_base);
     ret=inb(nsican_base+1);
-    enable_irq(nsican_irq); 
+    can_enable_irq(nsican_irq); 
     return ret;
 }
 
index 38ee4d4c8d91ba4b16044379bf024b8ba020f1e8..015b52107130b5c691f5a874d3be3720dc79ebd3 100644 (file)
@@ -33,7 +33,7 @@ int can_open(struct inode *inode, struct file *file)
 
        atomic_inc(&obj->obj_used);
        DEBUGMSG("Device %d opened %d times.\n", MINOR_NR, atomic_read(&obj->obj_used));
-       obj->flags |= OBJ_OPENED;
+       can_msgobj_set_fl(obj,OPENED);
 
        if (chip->flags & CHIP_CONFIGURED) 
                DEBUGMSG("Device is already configured.\n");
@@ -46,8 +46,6 @@ int can_open(struct inode *inode, struct file *file)
                if (chip->chipspecops->pre_read_config(chip,obj)<0)
                        CANMSG("Error initializing chip for receiving\n");
 
-               /* chip->flags |= OBJ_BUFFERS_ALLOCATED; */
-               
        } /* End of chip configuration */
 
        canuser = (struct canuser_t *)kmalloc(sizeof(struct canuser_t), GFP_KERNEL);
index 1e2c93388031ed5807aa26c47f9055febbccd54a..d926e33b283ef0eed08b3054db13d32a6f179b92 100644 (file)
@@ -199,7 +199,6 @@ int pci03_init_chip_data(struct candevice_t *candev, int chipnr)
 int pci03_init_obj_data(struct chip_t *chip, int objnr)
 {
        chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr;
-       chip->msgobj[objnr]->flags=0;
        
        return 0;
 }
index 8745404147e7fd5ed733519ff5d73d949a60554c..6e32610f2eea474b1ca1bb284a97ffdb13df3823 100644 (file)
@@ -169,7 +169,7 @@ int pccanq_reset(struct candevice_t *candev)
        int i=0,chip_nr=0;
 
        for (i=0; i<4; i++)
-               disable_irq(candev->chip[i]->chip_irq);
+               can_disable_irq(candev->chip[i]->chip_irq);
 
        DEBUGMSG("Resetting pccan-q hardware ...\n");
        while (i < 100000) {
@@ -214,7 +214,7 @@ int pccanq_reset(struct candevice_t *candev)
        }
 
        for (i=0; i<4; i++)
-               enable_irq(candev->chip[i]->chip_irq);
+               can_enable_irq(candev->chip[i]->chip_irq);
 
        return 0;
 }      
@@ -290,12 +290,10 @@ int pccan_init_obj_data(struct chip_t *chip, int objnr)
 {
        if (!strcmp(chip->chip_type,"sja1000")) {
                chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr;
-               chip->msgobj[objnr]->flags=0;
-       }
+               }
        else {  /* The spacing for this card is 0x3c0 */
                chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr+(objnr+1)*0x10+(int)((objnr+1)/4)*0x3c0;
-               chip->msgobj[objnr]->flags=0;
-       }
+               }
 
        return 0;
 }
index 6f7b5766fbd47ad0963973c17c119110f3034ebc..64e6b700a9fd55c4cc9831d4222d0fbce5c9f1ed 100644 (file)
@@ -219,7 +219,6 @@ int pcccan_init_chip_data(struct candevice_t *candev, int chipnr)
 int pcccan_init_obj_data(struct chip_t *chip, int objnr)
 {
        chip->msgobj[objnr]->obj_base_addr=(objnr+1)*0x10;
-       chip->msgobj[objnr]->flags=0;
        
        return 0;
 }
@@ -254,10 +253,10 @@ int pcccan_program_irq(struct candevice_t *candev)
  */
 void pcccan_write_register(unsigned char data, unsigned long address)
 {
-       disable_irq(pcccan_irq);
+       can_disable_irq(pcccan_irq);
        outb(address - pcccan_base, pcccan_base+1);
        outb(data, pcccan_base+6);
-       enable_irq(pcccan_irq);
+       can_enable_irq(pcccan_irq);
 }
 
 /**
@@ -273,10 +272,10 @@ void pcccan_write_register(unsigned char data, unsigned long address)
 unsigned pcccan_read_register(unsigned long address)
 {
        unsigned ret;
-       disable_irq(pcccan_irq);
+       can_disable_irq(pcccan_irq);
        outb(address - pcccan_base, pcccan_base+1);
        ret=inb(pcccan_base+2);
-       enable_irq(pcccan_irq);
+       can_enable_irq(pcccan_irq);
        return ret;
 
 }
index 4be3dd2515ca69a199e34f608e6a579ffe0139b1..cfe5856e67cd69acf748bde6c0efe2191410db74 100644 (file)
@@ -205,7 +205,6 @@ int pcm3680_init_chip_data(struct candevice_t *candev, int chipnr)
 int pcm3680_init_obj_data(struct chip_t *chip, int objnr)
 {
        chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr;
-       chip->msgobj[objnr]->flags=0;
        
        return 0;
 }
index 117560c96abeedc16d5e343add136f744712b8c6..57788758b4f64a13d2879b165392c8a7a4056666 100644 (file)
@@ -212,7 +212,6 @@ int pikronisa_init_chip_data(struct candevice_t *candev, int chipnr)
 int pikronisa_init_obj_data(struct chip_t *chip, int objnr)
 {
        chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr;
-       chip->msgobj[objnr]->flags=0;
        return 0;
 }
 
index 3e1984c67d3898e56f26cbddaa1e329175296f7c..16c009823f469419357b5f71bd30bd2fddb7e3eb 100644 (file)
@@ -144,7 +144,6 @@ int pip_init_chip_data(struct candevice_t *candev, int chipnr)
 int pip_init_obj_data(struct chip_t *chip, int objnr)
 {
        chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr+(objnr+1)*0x10;
-       chip->msgobj[objnr]->flags=0;
        
        return 0;
 }
index 57883ce39533747aa3c0876a63c922dd456dd057..acc7cacf3ccb6fa0bdbf64e3c2b102a7ae825eec 100644 (file)
@@ -207,14 +207,15 @@ int init_device_struct(int card)
        if (candev->hwspecops->init_hw_data(candev))
                goto error_nodev;
 
-       if (init_chip_struct(candev))
-               goto error_nodev;
+       if ((ret=init_chip_struct(candev)))
+               goto error_chip;
 
        return 0;
 
     error_nodev:
-       candevice_done(candev);
        ret=-ENODEV;
+    error_chip:
+       candevice_done(candev);
        goto error_both;
 
     error_nomem:
@@ -232,39 +233,40 @@ int init_device_struct(int card)
  */
 int init_chip_struct(struct candevice_t *candev)
 {
+       struct chip_t *chip;
        static int irq_count=0;
        int i=0;
 
        /* Alocate and initialize the chip structures */
        for (i=0; i < candev->nr_all_chips; i++) {
                candev->chip[i]=(struct chip_t *)can_checked_malloc(sizeof(struct chip_t));
-               if (candev->chip[i]==NULL)
+               if ((chip=candev->chip[i])==NULL)
                        return -ENOMEM;
 
-               memset(candev->chip[i], 0, sizeof(struct chip_t));
+               memset(chip, 0, sizeof(struct chip_t));
                
-               candev->chip[i]->write_register=candev->hwspecops->write_register;
-               candev->chip[i]->read_register=candev->hwspecops->read_register;
+               chip->write_register=candev->hwspecops->write_register;
+               chip->read_register=candev->hwspecops->read_register;
 
-               candev->chip[i]->chipspecops=can_checked_malloc(sizeof(struct chipspecops_t));
-               if (candev->chip[i]->chipspecops==NULL)
+               chip->chipspecops=can_checked_malloc(sizeof(struct chipspecops_t));
+               if (chip->chipspecops==NULL)
                        return -ENOMEM;
-
-                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]->baudrate=baudrate[irq_count]*1000;
-               if(!candev->chip[i]->baudrate)
-                       candev->chip[i]->baudrate=baudrate[0]*1000;
-               candev->chip[i]->flags=0x0;
+               
+                chips_p[irq_count]=chip;
+               chip->chip_idx=i;
+               chip->hostdevice=candev;
+               chip->chip_irq=irq[irq_count];
+               chip->baudrate=baudrate[irq_count]*1000;
+               if(!chip->baudrate)
+                       chip->baudrate=baudrate[0]*1000;
+               chip->flags=0x0;
 
                candev->hwspecops->init_chip_data(candev,i);
 
                if (init_chipspecops(candev,i))
                        return -ENODEV;
-
-               init_obj_struct(candev, candev->chip[i], minor[irq_count]);
+               
+               init_obj_struct(candev, chip, minor[irq_count]);
 
                irq_count++;
        } 
@@ -300,7 +302,7 @@ int init_obj_struct(struct candevice_t *candev, struct chip_t *hostchip, int min
                obj->qends=qends;
                obj->tx_qedge=NULL;
                obj->tx_slot=NULL;
-               obj->flags = 0x0;
+               obj->obj_flags = 0x0;
 
                canqueue_ends_init_chip(qends, hostchip, obj);
                
@@ -351,3 +353,32 @@ int init_chipspecops(struct candevice_t *candev, int chipnr)
 
        return 0;
 }
+
+#ifndef CAN_WITH_RTL
+
+int can_chip_setup_irq(struct chip_t *chip)
+{
+       if(chip==NULL)
+               return -1;
+       if(!chip->chipspecops->irq_handler)
+               return 0;
+                       
+       if (request_irq(chip->chip_irq,chip->chipspecops->irq_handler,SA_SHIRQ,DEVICE_NAME,chip))
+               return -1;
+       else {
+               DEBUGMSG("Registered interrupt %d\n",chip->chip_irq);
+               chip->flags |= CHIP_IRQ_SETUP;
+       }
+       return 1;
+}
+
+
+void can_chip_free_irq(struct chip_t *chip)
+{
+       if((chip->flags & CHIP_IRQ_SETUP) && (chip->chip_irq>=0)) {
+               free_irq(chip->chip_irq, chip);
+               chip->flags &= ~CHIP_IRQ_SETUP;
+       }
+}
+
+#endif /*CAN_WITH_RTL*/
index 7b1f88d8f6b9a1e11c09a206a991edcc242b09e3..8e41ae0ddf510c214a322adbd2e154d044ce1fc8 100644 (file)
@@ -20,7 +20,7 @@ int sja1000_enable_configuration(struct chip_t *chip)
        int i=0;
        unsigned flags;
 
-       disable_irq(chip->chip_irq);
+       can_disable_irq(chip->chip_irq);
 
        flags=can_read_reg(chip,SJACR);
 
@@ -32,7 +32,7 @@ int sja1000_enable_configuration(struct chip_t *chip)
        }
        if (i>=10) {
                CANMSG("Reset error\n");
-               enable_irq(chip->chip_irq);
+               can_enable_irq(chip->chip_irq);
                return -ENODEV;
        }
 
@@ -57,7 +57,7 @@ int sja1000_disable_configuration(struct chip_t *chip)
                return -ENODEV;
        }
 
-       enable_irq(chip->chip_irq);
+       can_enable_irq(chip->chip_irq);
 
        return 0;
 }
@@ -331,7 +331,7 @@ int sja1000_config_irqs(struct chip_t *chip, short irqs)
 }
 
 
-irqreturn_t sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+can_irqreturn_t sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
        unsigned irq_register;
        struct chip_t *chip=(struct chip_t *)dev_id;
@@ -343,21 +343,21 @@ irqreturn_t sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 //                                     can_read_reg(chip, SJASR));
 
        if ((irq_register & (IR_WUI|IR_DOI|IR_EI|IR_TI|IR_RI)) == 0)
-               return IRQ_NONE;
+               return CAN_IRQ_NONE;
 
        if ((irq_register & IR_RI) != 0) 
                sja1000_irq_read_handler(chip, obj);
 
        if ((irq_register & IR_TI) != 0) { 
-               set_bit(OBJ_TX_REQUEST,&obj->flags);
-               while(!test_and_set_bit(OBJ_TX_LOCK,&obj->flags)){
-                       clear_bit(OBJ_TX_REQUEST,&obj->flags);
+               can_msgobj_set_fl(obj,TX_REQUEST);
+               while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
+                       can_msgobj_clear_fl(obj,TX_REQUEST);
 
                        if (can_read_reg(chip, SJASR) & SR_TBS)
                                sja1000_irq_write_handler(chip, obj);
 
-                       clear_bit(OBJ_TX_LOCK,&obj->flags);
-                       if(!test_bit(OBJ_TX_REQUEST,&obj->flags)) break;
+                       can_msgobj_clear_fl(obj,TX_LOCK);
+                       if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
                }
        }
 
@@ -376,7 +376,7 @@ irqreturn_t sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
                }
        }
 
-       return IRQ_HANDLED;
+       return CAN_IRQ_HANDLED;
 }
 
 void sja1000_irq_read_handler(struct chip_t *chip, struct msgobj_t *obj)
@@ -446,26 +446,20 @@ void sja1000_irq_write_handler(struct chip_t *chip, struct msgobj_t *obj)
  */
 int sja1000_wakeup_tx(struct chip_t *chip, struct msgobj_t *obj)
 {
-        /* dummy lock to prevent preemption fully portable way */
-       can_spinlock_t dummy_lock;
+       can_preempt_disable();
        
-       /*  preempt_disable() */
-       can_spin_lock_init(&dummy_lock);
-       can_spin_lock(&dummy_lock);
-       
-       set_bit(OBJ_TX_REQUEST,&obj->flags);
-       while(!test_and_set_bit(OBJ_TX_LOCK,&obj->flags)){
-               clear_bit(OBJ_TX_REQUEST,&obj->flags);
+       can_msgobj_set_fl(obj,TX_REQUEST);
+       while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
+               can_msgobj_clear_fl(obj,TX_REQUEST);
 
                if (can_read_reg(chip, SJASR) & SR_TBS)
                        sja1000_irq_write_handler(chip, obj);
        
-               clear_bit(OBJ_TX_LOCK,&obj->flags);
-               if(!test_bit(OBJ_TX_REQUEST,&obj->flags)) break;
+               can_msgobj_clear_fl(obj,TX_LOCK);
+               if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
        }
 
-       /* preempt_enable(); */
-       can_spin_unlock(&dummy_lock);
+       can_preempt_enable();
        return 0;
 }
 
index b34e984d84c5affa3e08d3e5ed2aaff7aeb4b924..eafed8a83912b32872ec9eacc27c659fc3b26018 100644 (file)
@@ -23,7 +23,7 @@ int sja1000p_enable_configuration(struct chip_t *chip)
        int i=0;
        enum sja1000_PeliCAN_MOD flags;
 
-       disable_irq(chip->chip_irq);
+       can_disable_irq(chip->chip_irq);
 
        flags=can_read_reg(chip,SJAMOD);
 
@@ -37,7 +37,7 @@ int sja1000p_enable_configuration(struct chip_t *chip)
        }
        if (i>=10) {
                CANMSG("Reset error\n");
-               enable_irq(chip->chip_irq);
+               can_enable_irq(chip->chip_irq);
                return -ENODEV;
        }
 
@@ -69,7 +69,7 @@ int sja1000p_disable_configuration(struct chip_t *chip)
                return -ENODEV;
        }
 
-       enable_irq(chip->chip_irq);
+       can_enable_irq(chip->chip_irq);
 
        return 0;
 }
@@ -605,7 +605,7 @@ void sja1000p_irq_write_handler(struct chip_t *chip, struct msgobj_t *obj)
  * message queues.
  * File: src/sja1000p.c
  */
-irqreturn_t sja1000p_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+can_irqreturn_t sja1000p_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
        int irq_register, status, error_code;
        struct chip_t *chip=(struct chip_t *)dev_id;
@@ -617,11 +617,11 @@ irqreturn_t sja1000p_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 //                                     can_read_reg(chip,SJASR));
 
        if ((irq_register & (IR_BEI|IR_EPI|IR_DOI|IR_EI|IR_TI|IR_RI)) == 0)
-               return IRQ_NONE;
+               return CAN_IRQ_NONE;
 
-       if(!obj->flags & OBJ_BUFFERS_ALLOCATED) {
-               CANMSG("sja1000p_irq_handler: called with device closed, irq_register 0x%02x\n", irq_register);
-               return IRQ_NONE;
+       if(!(chip->flags&CHIP_CONFIGURED)) {
+               CANMSG("sja1000p_irq_handler: called for non-configured device, irq_register 0x%02x\n", irq_register);
+               return CAN_IRQ_NONE;
        }
 
        if ((irq_register & IR_RI) != 0) {
@@ -632,15 +632,15 @@ irqreturn_t sja1000p_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
        if ((irq_register & IR_TI) != 0) {
                DEBUGMSG("sja1000_irq_handler: TI\n");
                obj->ret = 0;
-               set_bit(OBJ_TX_REQUEST,&obj->flags);
-               while(!test_and_set_bit(OBJ_TX_LOCK,&obj->flags)){
-                       clear_bit(OBJ_TX_REQUEST,&obj->flags);
+               can_msgobj_set_fl(obj,TX_REQUEST);
+               while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
+                       can_msgobj_clear_fl(obj,TX_REQUEST);
 
                        if (can_read_reg(chip, SJASR) & SR_TBS)
                                sja1000p_irq_write_handler(chip, obj);
 
-                       clear_bit(OBJ_TX_LOCK,&obj->flags);
-                       if(!test_bit(OBJ_TX_REQUEST,&obj->flags)) break;
+                       can_msgobj_clear_fl(obj,TX_LOCK);
+                       if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
                        DEBUGMSG("TX looping in sja1000_irq_handler\n");
                }
        }
@@ -677,7 +677,7 @@ irqreturn_t sja1000p_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
                obj->tx_retry_cnt=0;
        }
 
-       return IRQ_HANDLED;
+       return CAN_IRQ_HANDLED;
 }
 
 /**
@@ -690,29 +690,24 @@ irqreturn_t sja1000p_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
  */
 int sja1000p_wakeup_tx(struct chip_t *chip, struct msgobj_t *obj)
 {
-        /* dummy lock to prevent preemption fully portable way */
-       can_spinlock_t dummy_lock;
        
-       /*  preempt_disable() */
-       can_spin_lock_init(&dummy_lock);
-       can_spin_lock(&dummy_lock);
+       can_preempt_disable();
        
-       set_bit(OBJ_TX_REQUEST,&obj->flags);
-       while(!test_and_set_bit(OBJ_TX_LOCK,&obj->flags)){
-               clear_bit(OBJ_TX_REQUEST,&obj->flags);
+       can_msgobj_set_fl(obj,TX_REQUEST);
+       while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
+               can_msgobj_clear_fl(obj,TX_REQUEST);
 
                if (can_read_reg(chip, SJASR) & SR_TBS){
                        obj->tx_retry_cnt=0;
                        sja1000p_irq_write_handler(chip, obj);
                }
        
-               clear_bit(OBJ_TX_LOCK,&obj->flags);
-               if(!test_bit(OBJ_TX_REQUEST,&obj->flags)) break;
+               can_msgobj_clear_fl(obj,TX_LOCK);
+               if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
                DEBUGMSG("TX looping in sja1000p_wakeup_tx\n");
        }
 
-       /* preempt_enable(); */
-       can_spin_unlock(&dummy_lock);
+       can_preempt_enable();
        return 0;
 }
 
index 7f11d5c1b51ead9426c394d3f74baa8245d774d6..abbbe1a663194ed7f7e841125a787b68a5392381 100644 (file)
@@ -93,7 +93,6 @@ int smartcan_init_chip_data(struct candevice_t *candev, int chipnr)
 int smartcan_init_obj_data(struct chip_t *chip, int objnr)
 {
        chip->msgobj[objnr]->obj_base_addr=(objnr+1)*0x10;
-       chip->msgobj[objnr]->flags=0;
 
        return 0;
 }
@@ -101,19 +100,19 @@ int smartcan_init_obj_data(struct chip_t *chip, int objnr)
 
 void smartcan_write_register(unsigned char data, unsigned long address)
 {
-       disable_irq(smartcan_irq);
+       can_disable_irq(smartcan_irq);
        outb(address-smartcan_base,smartcan_base);
        outb(data,smartcan_base+1);
-       enable_irq(smartcan_irq);
+       can_enable_irq(smartcan_irq);
 }
 
 unsigned smartcan_read_register(unsigned long address)
 {
        unsigned ret;
-       disable_irq(smartcan_irq);
+       can_disable_irq(smartcan_irq);
        outb(address-smartcan_base,smartcan_base);
        ret=inb(smartcan_base+1);
-       enable_irq(smartcan_irq);
+       can_enable_irq(smartcan_irq);
        return ret;
 }
 
index 793c67c7d460042f9cea112dbb07172533211255..83fbba3115fc19409fdfb61b21807e18b3825f30 100644 (file)
@@ -164,7 +164,6 @@ int ssv_init_obj_data(struct chip_t *chip, int objnr)
 
     chip->msgobj[objnr]->obj_base_addr=
         chip->chip_base_addr+(objnr+1)*0x10;
-    chip->msgobj[objnr]->flags=0;
        
     return 0;
 }
@@ -214,17 +213,17 @@ unsigned ssv_read_register(unsigned long address)
 
     if((address-ssvcan_base)<0x100)
     {
-       disable_irq(ssvcan_irq[0]);
+       can_disable_irq(ssvcan_irq[0]);
        outb(address-ssvcan_base, ssvcan_base);
        ret=inb(ssvcan_base+1);
-       enable_irq(ssvcan_irq[0]);
+       can_enable_irq(ssvcan_irq[0]);
     }
     else
     {
-       disable_irq(ssvcan_irq[1]);
+       can_disable_irq(ssvcan_irq[1]);
        outb(address-ssvcan_base-0x100, ssvcan_base+0x02);
        ret=inb(ssvcan_base+1+0x02);
-       enable_irq(ssvcan_irq[1]);
+       can_enable_irq(ssvcan_irq[1]);
     }
 
     return ret;
index 9b72902614bc18857fe8eb330dcddbc67566fb42..f53022855fe1897ce08e7e7015fdc7b7cba2f45f 100644 (file)
@@ -182,7 +182,6 @@ int template_init_chip_data(struct candevice_t *candev, int chipnr)
 int template_init_obj_data(struct chip_t *chip, int objnr)
 {
        chip->msgobj[objnr]->obj_base_addr=chip->chip_base_addr+(objnr+1)*0x10;
-       chip->msgobj[objnr]->flags=0;
        
        return 0;
 }
index e4b9c17cccc9487b44806210ef1608e80d4eaf68..80ce0fbd5f07df20f61c442eaf63e97e545bfd48 100644 (file)
@@ -280,27 +280,23 @@ void virtual_irq_write_handler(struct chip_t *chip, struct msgobj_t *obj)
  * message queues.
  * File: src/virtual.c
  */
-irqreturn_t virtual_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+can_irqreturn_t virtual_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
-       return IRQ_HANDLED;
+       return CAN_IRQ_HANDLED;
 }
 
 
 void virtual_schedule_next(struct msgobj_t *obj)
 {
        int cmd;
-        /* dummy lock to prevent preemption fully portable way */
-       can_spinlock_t dummy_lock;
 
-       /*  preempt_disable() */
-       can_spin_lock_init(&dummy_lock);
-       can_spin_lock(&dummy_lock);
+       can_preempt_disable();
 
-       set_bit(OBJ_TX_REQUEST,&obj->flags);
+       can_msgobj_set_fl(obj,TX_REQUEST);
        
-       while(!test_and_set_bit(OBJ_TX_LOCK,&obj->flags)){
+       while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
 
-               clear_bit(OBJ_TX_REQUEST,&obj->flags);
+               can_msgobj_clear_fl(obj,TX_REQUEST);
                
                cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
                if(cmd>=0) {
@@ -309,14 +305,13 @@ void virtual_schedule_next(struct msgobj_t *obj)
                        CANMSG("virtual: scheduled delivery\n");
 
                } else          
-                       clear_bit(OBJ_TX_LOCK,&obj->flags);
+                       can_msgobj_clear_fl(obj,TX_LOCK);
                
-               if(!test_bit(OBJ_TX_REQUEST,&obj->flags)) break;
+               if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
                DEBUGMSG("TX looping in virtual_schedule_next\n");
        }
 
-       /* preempt_enable(); */
-       can_spin_unlock(&dummy_lock);
+       can_preempt_enable();
 }
 
 
@@ -332,7 +327,7 @@ void virtual_do_tx_timeout(unsigned long data)
                obj->tx_slot=NULL;
                CANMSG("virtual: delayed delivery\n");
        }
-       clear_bit(OBJ_TX_LOCK,&obj->flags);
+       can_msgobj_clear_fl(obj,TX_LOCK);
 
        virtual_schedule_next(obj);
 }
@@ -347,13 +342,15 @@ void virtual_do_tx_timeout(unsigned long data)
  */
 int virtual_wakeup_tx(struct chip_t *chip, struct msgobj_t *obj)
 {
-       /* set_bit(OBJ_TX_REQUEST,&obj->flags); */
+       /* can_msgobj_set_fl(obj,TX_REQUEST); */
        
        struct canque_edge_t *qedge;
        struct canque_slot_t *slot;
        int cmd;
-       
+
+    #ifndef CAN_WITH_RTL
        if(!virtual_bus_latency(obj)) {
+    #endif /*CAN_WITH_RTL*/
                /* Ensure delivery of all ready slots */
                while((cmd=canque_test_outslot(obj->qends, &qedge, &slot)) >= 0){
                        if(cmd==0) {
@@ -362,9 +359,11 @@ int virtual_wakeup_tx(struct chip_t *chip, struct msgobj_t *obj)
                        }
                        canque_free_outslot(obj->qends, qedge, slot);
                }
+    #ifndef CAN_WITH_RTL
        } else {
                virtual_schedule_next(obj);
        }
+    #endif /*CAN_WITH_RTL*/
 
        return 0;
 }
@@ -483,7 +482,6 @@ int virtual_init_obj_data(struct chip_t *chip, int objnr)
 {
        struct msgobj_t *obj=chip->msgobj[objnr];
        obj->obj_base_addr=chip->chip_base_addr;
-       obj->flags=0;
        obj->tx_timeout.function=virtual_do_tx_timeout;
        obj->tx_timeout.data=(unsigned long)obj;
        return 0;