]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/src/can_quekern.c
LinCAN driver structured comments updated.
[lincan.git] / lincan / src / can_quekern.c
index 093886c2c41e01e9dfb0cdd5727a8aba993e626d..3eea5a36b4d462c14f9cf1d01e778e5fd9a5976b 100644 (file)
 extern atomic_t edge_num_cnt;
 
 #ifdef CAN_DEBUG
-       #define DEBUGQUE(fmt,args...) can_printk(KERN_ERR "can_queue (debug): " fmt,\
+       #define DEBUGQUE(fmt,args...) can_printk(KERN_ERR "can_quekern (debug): " fmt,\
        ##args)
 
 #else
        #define DEBUGQUE(fmt,args...)
 #endif
 
-#define ERRMSGQUE(fmt,args...) can_printk(KERN_ERR "can_queue: " fmt,\
+#define ERRMSGQUE(fmt,args...) can_printk(KERN_ERR "can_quekern: " fmt,\
        ##args)
 
 
@@ -128,6 +128,27 @@ void canque_edge_do_dead(struct canque_edge_t *edge, int dead_fl)
        
        if(dead_fl) return;
        
+       canque_notify_bothends(edge,CANQUEUE_NOTIFY_NOUSR);
+    #ifdef CAN_WITH_RTL
+       /* The problem of the above call is, that in RT-Linux to Linux notify
+          case is edge scheduled for delayed notify delivery, this needs
+          to be reflected there */
+       if(atomic_read(&edge->edge_used)>0){
+               can_spin_lock_irqsave(&edge->inends->ends_lock, flags);
+               can_spin_lock(&edge->outends->ends_lock);
+               if(atomic_read(&edge->edge_used)>0){
+                       /* left edge to live for a while, banshee comes again in a while */
+                       canque_fifo_clear_fl(&edge->fifo,DEAD);
+                       can_spin_unlock(&edge->outends->ends_lock);
+                       can_spin_unlock_irqrestore(&edge->inends->ends_lock, flags);
+                       can_printk(KERN_ERR "can_quertl (debug): canque_edge_do_dead postponed\n");
+                       return;
+               }
+               can_spin_unlock(&edge->outends->ends_lock);
+               can_spin_unlock_irqrestore(&edge->inends->ends_lock, flags);
+       }
+    #endif /*CAN_WITH_RTL*/
+       
        if(canqueue_disconnect_edge(edge)<0){
                ERRMSGQUE("canque_edge_do_dead: canqueue_disconnect_edge failed !!!\n");
                return;
@@ -155,6 +176,13 @@ void canque_edge_do_dead(struct canque_edge_t *edge, int dead_fl)
  * @qends: pointer to the callback side ends structure
  * @qedge: edge which invoked notification 
  * @what: notification type
+ *
+ * The notification event is handled directly by call of this function except case,
+ * when called from RT-Linux context in mixed mode Linux/RT-Linux compilation.
+ * It is not possible to directly call Linux kernel synchronization primitives
+ * in such case. The notification request is postponed and signaled by @pending_inops flags
+ * by call canqueue_rtl2lin_check_and_pend() function. 
+ * The edge reference count is increased until until all pending notifications are processed.
  */
 void canqueue_notify_kern(struct canque_ends_t *qends, struct canque_edge_t *qedge, int what)
 {
@@ -355,7 +383,7 @@ struct canque_edge_t *canque_new_edge_kern(int slotsnr)
 
 #ifdef USE_SYNC_DISCONNECT_EDGE_KERN
 
-/**
+/*not included in doc
  * canqueue_disconnect_edge_kern - disconnect edge from communicating entities with wait
  * @qends: ends structure belonging to calling communication object
  * @qedge: pointer to edge