]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/include/can_queue.h
LinCAN sources go through big white-space cleanup.
[lincan.git] / lincan / include / can_queue.h
1 /**************************************************************************/
2 /* File: can_queue.h - CAN queues and message passing infrastructure      */
3 /*                                                                        */
4 /* LinCAN - (Not only) Linux CAN bus driver                               */
5 /* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz>   */
6 /* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz>             */
7 /* Funded by OCERA and FRESCOR IST projects                               */
8 /*                                                                        */
9 /* LinCAN is free software; you can redistribute it and/or modify it      */
10 /* under terms of the GNU General Public License as published by the      */
11 /* Free Software Foundation; either version 2, or (at your option) any    */
12 /* later version.  LinCAN is distributed in the hope that it will be      */
13 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty    */
14 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU    */
15 /* General Public License for more details. You should have received a    */
16 /* copy of the GNU General Public License along with LinCAN; see file     */
17 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,  */
18 /* Cambridge, MA 02139, USA.                                              */
19 /*                                                                        */
20 /* To allow use of LinCAN in the compact embedded systems firmware        */
21 /* and RT-executives (RTEMS for example), main authors agree with next    */
22 /* special exception:                                                     */
23 /*                                                                        */
24 /* Including LinCAN header files in a file, instantiating LinCAN generics */
25 /* or templates, or linking other files with LinCAN objects to produce    */
26 /* an application image/executable, does not by itself cause the          */
27 /* resulting application image/executable to be covered by                */
28 /* the GNU General Public License.                                        */
29 /* This exception does not however invalidate any other reasons           */
30 /* why the executable file might be covered by the GNU Public License.    */
31 /* Publication of enhanced or derived LinCAN files is required although.  */
32 /**************************************************************************/
33
34 #ifndef _CAN_QUEUE_H
35 #define _CAN_QUEUE_H
36
37 #include "./canmsg.h"
38 #include "./constants.h"
39 #include "./can_sysdep.h"
40
41 /**
42  * struct canque_slot_t - one CAN message slot in the CAN FIFO queue
43  * @next: pointer to the next/younger slot
44  * @slot_flags: space for flags and optional command describing action
45  *      associated with slot data
46  * @msg: space for one CAN message
47  *
48  * This structure is used to store CAN messages in the CAN FIFO queue.
49  */
50  struct canque_slot_t {
51         struct canque_slot_t *next;
52         unsigned long slot_flags;
53         struct canmsg_t msg;
54 };
55
56 #define CAN_SLOTF_CMD   0x00ff  /*  */
57
58 /**
59  * struct canque_fifo_t - CAN FIFO queue representation
60  * @fifo_flags: this field holds global flags describing state of the FIFO.
61  *      %CAN_FIFOF_ERROR is set when some error condition occurs.
62  *      %CAN_FIFOF_ERR2BLOCK defines, that error should lead to the FIFO block state.
63  *      %CAN_FIFOF_BLOCK state blocks insertion of the next messages.
64  *      %CAN_FIFOF_OVERRUN attempt to acquire new slot, when FIFO is full.
65  *      %CAN_FIFOF_FULL indicates FIFO full state.
66  *      %CAN_FIFOF_EMPTY indicates no allocated slot in the FIFO.
67  *      %CAN_FIFOF_DEAD condition indication. Used when FIFO is beeing destroyed.
68  * @error_code: futher description of error condition
69  * @head: pointer to the FIFO head, oldest slot
70  * @tail: pointer to the location, where pointer to newly inserted slot
71  *      should be added
72  * @flist: pointer to list of the free slots associated with queue
73  * @entry: pointer to the memory allocated for the list slots.
74  * @fifo_lock: the lock to ensure atomicity of slot manipulation operations.
75  * @slotsnr:  number of allocated slots
76  *
77  * This structure represents CAN FIFO queue. It is implemented as
78  * a single linked list of slots prepared for processing. The empty slots
79  * are stored in single linked list (@flist).
80  */
81 struct canque_fifo_t {
82         unsigned long fifo_flags;
83         unsigned long error_code;
84         struct canque_slot_t *head;     /* points to the oldest entry */
85         struct canque_slot_t **tail;    /* points to NULL pointer for chaining */
86         struct canque_slot_t *flist;    /* points the first entry in the free list */
87         struct canque_slot_t *entry;    /* points to first allocated entry */
88         can_spinlock_t fifo_lock;       /* can_spin_lock_irqsave / can_spin_unlock_irqrestore */
89         int    slotsnr;
90 };
91
92 #define CAN_FIFOF_DESTROY_b     15
93 #define CAN_FIFOF_ERROR_b       14
94 #define CAN_FIFOF_ERR2BLOCK_b   13
95 #define CAN_FIFOF_BLOCK_b       12
96 #define CAN_FIFOF_OVERRUN_b     11
97 #define CAN_FIFOF_FULL_b        10
98 #define CAN_FIFOF_EMPTY_b       9
99 #define CAN_FIFOF_DEAD_b        8
100 #define CAN_FIFOF_INACTIVE_b    7
101 #define CAN_FIFOF_FREEONEMPTY_b 6
102 #define CAN_FIFOF_READY_b       5
103 #define CAN_FIFOF_NOTIFYPEND_b  4
104 #define CAN_FIFOF_RTL_MEM_b     3
105
106 #define CAN_FIFOF_DESTROY       (1<<CAN_FIFOF_DESTROY_b)
107 #define CAN_FIFOF_ERROR         (1<<CAN_FIFOF_ERROR_b)
108 #define CAN_FIFOF_ERR2BLOCK     (1<<CAN_FIFOF_ERR2BLOCK_b)
109 #define CAN_FIFOF_BLOCK         (1<<CAN_FIFOF_BLOCK_b)
110 #define CAN_FIFOF_OVERRUN       (1<<CAN_FIFOF_OVERRUN_b)
111 #define CAN_FIFOF_FULL          (1<<CAN_FIFOF_FULL_b)
112 #define CAN_FIFOF_EMPTY         (1<<CAN_FIFOF_EMPTY_b)
113 #define CAN_FIFOF_DEAD          (1<<CAN_FIFOF_DEAD_b)
114 #define CAN_FIFOF_INACTIVE      (1<<CAN_FIFOF_INACTIVE_b)
115 #define CAN_FIFOF_FREEONEMPTY   (1<<CAN_FIFOF_FREEONEMPTY_b)
116 #define CAN_FIFOF_READY         (1<<CAN_FIFOF_READY_b)
117 #define CAN_FIFOF_NOTIFYPEND    (1<<CAN_FIFOF_NOTIFYPEND_b)
118 #define CAN_FIFOF_RTL_MEM       (1<<CAN_FIFOF_RTL_MEM_b)
119
120 #define canque_fifo_test_fl(fifo,fifo_fl) \
121   test_bit(CAN_FIFOF_##fifo_fl##_b,&(fifo)->fifo_flags)
122 #define canque_fifo_set_fl(fifo,fifo_fl) \
123   set_bit(CAN_FIFOF_##fifo_fl##_b,&(fifo)->fifo_flags)
124 #define canque_fifo_clear_fl(fifo,fifo_fl) \
125   clear_bit(CAN_FIFOF_##fifo_fl##_b,&(fifo)->fifo_flags)
126 #define canque_fifo_test_and_set_fl(fifo,fifo_fl) \
127   test_and_set_bit(CAN_FIFOF_##fifo_fl##_b,&(fifo)->fifo_flags)
128 #define canque_fifo_test_and_clear_fl(fifo,fifo_fl) \
129   test_and_clear_bit(CAN_FIFOF_##fifo_fl##_b,&(fifo)->fifo_flags)
130
131
132 /**
133  * canque_fifo_get_inslot - allocate slot for the input of one CAN message
134  * @fifo: pointer to the FIFO structure
135  * @slotp: pointer to location to store pointer to the allocated slot.
136  * @cmd: optional command associated with allocated slot.
137  *
138  * Return Value: The function returns negative value if there is no
139  *      free slot in the FIFO queue.
140  */
141 static inline
142 int canque_fifo_get_inslot(struct canque_fifo_t *fifo, struct canque_slot_t **slotp, int cmd)
143 {
144         can_spin_irqflags_t flags;
145         struct canque_slot_t *slot;
146         can_spin_lock_irqsave(&fifo->fifo_lock, flags);
147         /* get the first free slot slot from flist */
148         if(!(slot=fifo->flist)) {
149                 canque_fifo_set_fl(fifo,OVERRUN);
150                 canque_fifo_set_fl(fifo,FULL);
151                 can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
152                 *slotp=NULL;
153                 return -1;
154         }
155         /* adjust free slot list */
156         if(!(fifo->flist=slot->next))
157                 canque_fifo_set_fl(fifo,FULL);
158         can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
159         *slotp=slot;
160         slot->slot_flags=cmd&CAN_SLOTF_CMD;
161         return 1;
162 }
163
164 /**
165  * canque_fifo_put_inslot - releases slot to further processing
166  * @fifo: pointer to the FIFO structure
167  * @slot: pointer to the slot previously acquired by canque_fifo_get_inslot().
168  *
169  * Return Value: The nonzero return value indicates, that the queue was empty
170  *      before call to the function. The caller should wake-up output side of the queue.
171  */
172 static inline
173 int canque_fifo_put_inslot(struct canque_fifo_t *fifo, struct canque_slot_t *slot)
174 {
175         int ret;
176         can_spin_irqflags_t flags;
177         slot->next=NULL;
178         can_spin_lock_irqsave(&fifo->fifo_lock, flags);
179         if(*fifo->tail) can_printk(KERN_CRIT "canque_fifo_put_inslot: fifo->tail != NULL\n");
180         *fifo->tail=slot;
181         fifo->tail=&slot->next;
182         ret=0;
183         if(canque_fifo_test_and_clear_fl(fifo,EMPTY))
184           ret=CAN_FIFOF_EMPTY;  /* Fifo has been empty before put */
185         if(canque_fifo_test_and_clear_fl(fifo,INACTIVE))
186           ret=CAN_FIFOF_INACTIVE; /* Fifo has been empty before put */
187         can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
188         return ret;
189 }
190
191 /**
192  * canque_fifo_abort_inslot - release and abort slot
193  * @fifo: pointer to the FIFO structure
194  * @slot: pointer to the slot previously acquired by canque_fifo_get_inslot().
195  *
196  * Return Value: The nonzero value indicates, that fifo was full
197  */
198 static inline
199 int canque_fifo_abort_inslot(struct canque_fifo_t *fifo, struct canque_slot_t *slot)
200 {
201         int ret=0;
202         can_spin_irqflags_t flags;
203         can_spin_lock_irqsave(&fifo->fifo_lock, flags);
204         slot->next=fifo->flist;
205         fifo->flist=slot;
206         if(canque_fifo_test_and_clear_fl(fifo,FULL))
207                 ret=CAN_FIFOF_FULL;
208         can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
209         return ret;
210 }
211
212 /**
213  * canque_fifo_test_outslot - test and get ready slot from the FIFO
214  * @fifo: pointer to the FIFO structure
215  * @slotp: pointer to location to store pointer to the oldest slot from the FIFO.
216  *
217  * Return Value: The negative value indicates, that queue is empty.
218  *      The positive or zero value represents command stored into slot by
219  *      the call to the function canque_fifo_get_inslot().
220  *      The successfully acquired FIFO output slot has to be released by
221  *      the call canque_fifo_free_outslot() or canque_fifo_again_outslot().
222  */
223 static inline
224 int canque_fifo_test_outslot(struct canque_fifo_t *fifo, struct canque_slot_t **slotp)
225 {
226         can_spin_irqflags_t flags;
227         int cmd;
228         struct canque_slot_t *slot;
229         can_spin_lock_irqsave(&fifo->fifo_lock, flags);
230         if(!(slot=fifo->head)){;
231                 canque_fifo_set_fl(fifo,EMPTY);
232                 can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
233                 *slotp=NULL;
234                 return -1;
235         }
236         if(!(fifo->head=slot->next))
237                 fifo->tail=&fifo->head;
238         can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
239
240         *slotp=slot;
241         cmd=slot->slot_flags;
242         return cmd&CAN_SLOTF_CMD;
243 }
244
245
246 /**
247  * canque_fifo_free_outslot - free processed FIFO slot
248  * @fifo: pointer to the FIFO structure
249  * @slot: pointer to the slot previously acquired by canque_fifo_test_outslot().
250  *
251  * Return Value: The returned value informs about FIFO state change.
252  *      The mask %CAN_FIFOF_FULL indicates, that the FIFO was full before
253  *      the function call. The mask %CAN_FIFOF_EMPTY informs, that last ready slot
254  *      has been processed.
255  */
256 static inline
257 int canque_fifo_free_outslot(struct canque_fifo_t *fifo, struct canque_slot_t *slot)
258 {
259         int ret=0;
260         can_spin_irqflags_t flags;
261         can_spin_lock_irqsave(&fifo->fifo_lock, flags);
262         slot->next=fifo->flist;
263         fifo->flist=slot;
264         if(canque_fifo_test_and_clear_fl(fifo,FULL))
265                 ret=CAN_FIFOF_FULL;
266         if(!(fifo->head)){
267                 canque_fifo_set_fl(fifo,EMPTY);
268                 ret|=CAN_FIFOF_EMPTY;
269         }
270         can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
271         return ret;
272 }
273
274 /**
275  * canque_fifo_again_outslot - interrupt and postpone processing of the slot
276  * @fifo: pointer to the FIFO structure
277  * @slot: pointer to the slot previously acquired by canque_fifo_test_outslot().
278  *
279  * Return Value: The function cannot fail..
280  */
281 static inline
282 int canque_fifo_again_outslot(struct canque_fifo_t *fifo, struct canque_slot_t *slot)
283 {
284         can_spin_irqflags_t flags;
285         can_spin_lock_irqsave(&fifo->fifo_lock, flags);
286         if(!(slot->next=fifo->head))
287                 fifo->tail=&slot->next;
288         fifo->head=slot;
289         can_spin_unlock_irqrestore(&fifo->fifo_lock, flags);
290         return 1;
291 }
292
293 int canque_fifo_flush_slots(struct canque_fifo_t *fifo);
294
295 int canque_fifo_init_slots(struct canque_fifo_t *fifo);
296
297 #define CANQUEUE_PRIO_NR  3
298
299 /* Forward declarations for external types */
300 struct msgobj_t;
301 struct canchip_t;
302
303 /**
304  * struct canque_edge_t - CAN message delivery subsystem graph edge
305  * @fifo: place where primitive @struct canque_fifo_t FIFO is located.
306  * @filtid: the possible CAN message identifiers filter.
307  * @filtmask: the filter mask, the comparison considers only
308  *      @filtid bits corresponding to set bits in the @filtmask field.
309  * @inpeers: the lists of all peers FIFOs connected by their
310  *      input side (@inends) to the same terminal (@struct canque_ends_t).
311  * @outpeers: the lists of all peers FIFOs connected by their
312  *      output side (@outends) to the same terminal (@struct canque_ends_t).
313  * @activepeers: the lists of peers FIFOs connected by their
314  *      output side (@outends) to the same terminal (@struct canque_ends_t)
315  *      with same priority and active state.
316  * @inends: the pointer to the FIFO input side terminal (@struct canque_ends_t).
317  * @outends: the pointer to the FIFO output side terminal (@struct canque_ends_t).
318  * @edge_used: the atomic usage counter, mainly used for safe destruction of the edge.
319  * @edge_prio: the assigned queue priority from the range 0 to %CANQUEUE_PRIO_NR-1
320  * @edge_num: edge sequential number intended for debugging purposes only
321  * @pending_peers: edges with pending delayed events (RTL->Linux calls)
322  * @pending_inops: bitmask of pending operations
323  * @pending_outops: bitmask of pending operations
324  *
325  * This structure represents one direction connection from messages source
326  * (@inends) to message consumer (@outends) fifo ends hub. The edge contains
327  * &struct canque_fifo_t for message fifo implementation.
328  */
329 struct canque_edge_t {
330         struct canque_fifo_t fifo;
331         unsigned long filtid;
332         unsigned long filtmask;
333         struct list_head inpeers;
334         struct list_head outpeers;
335         struct list_head activepeers;
336         struct canque_ends_t *inends;
337         struct canque_ends_t *outends;
338         atomic_t edge_used;
339         int edge_prio;
340         int edge_num;
341     #ifdef CAN_WITH_RTL
342         struct list_head pending_peers;
343         unsigned long pending_inops;
344         unsigned long pending_outops;
345     #endif /*CAN_WITH_RTL*/
346 };
347
348 /**
349  * struct canque_ends_t - CAN message delivery subsystem graph vertex (FIFO ends)
350  * @ends_flags: this field holds flags describing state of the ENDS structure.
351  * @active: the array of the lists of active edges directed to the ends structure
352  *      with ready messages. The array is indexed by the edges priorities.
353  * @idle: the list of the edges directed to the ends structure with empty FIFOs.
354  * @inlist: the list of outgoing edges input sides.
355  * @outlist: the list of all incoming edges output sides. Each of there edges
356  *      is listed on one of @active or @idle lists.
357  * @ends_lock: the lock synchronizing operations between threads accessing
358  *      same ends structure.
359  * @notify: pointer to notify procedure. The next state changes are notified.
360  *      %CANQUEUE_NOTIFY_EMPTY (out->in call) - all slots are processed by FIFO out side.
361  *      %CANQUEUE_NOTIFY_SPACE (out->in call) - full state negated => there is space for new message.
362  *      %CANQUEUE_NOTIFY_PROC  (in->out call) - empty state negated => out side is requested to process slots.
363  *      %CANQUEUE_NOTIFY_NOUSR (both) - notify, that the last user has released the edge usage
364  *              called with some lock to prevent edge disappear.
365  *      %CANQUEUE_NOTIFY_DEAD  (both) - edge is in progress of deletion.
366  *      %CANQUEUE_NOTIFY_ATACH (both) - new edge has been attached to end.
367  *      %CANQUEUE_NOTIFY_FILTCH (out->in call) - edge filter rules changed
368  *      %CANQUEUE_NOTIFY_ERROR  (out->in call) - error in messages processing.
369  * @context: space to store ends user specific information
370  * @endinfo: space to store some other ends usage specific informations
371  *      mainly for waking-up by the notify calls.
372  * @dead_peers: used to chain ends wanting for postponed destruction
373  *
374  * Structure represents place to connect edges to for CAN communication entity.
375  * The zero, one or more incoming and outgoing edges can be connected to
376  * this structure.
377  */
378 struct canque_ends_t {
379         unsigned long ends_flags;
380         struct list_head active[CANQUEUE_PRIO_NR];
381         struct list_head idle;
382         struct list_head inlist;
383         struct list_head outlist;
384         can_spinlock_t ends_lock;       /* can_spin_lock_irqsave / can_spin_unlock_irqrestore */
385         void (*notify)(struct canque_ends_t *qends, struct canque_edge_t *qedge, int what);
386         void *context;
387         union {
388                 struct {
389                         wait_queue_head_t readq;
390                         wait_queue_head_t writeq;
391                         wait_queue_head_t emptyq;
392                     #ifdef CAN_ENABLE_KERN_FASYNC
393                         struct fasync_struct *fasync;
394                     #endif /*CAN_ENABLE_KERN_FASYNC*/
395                 } fileinfo;
396             #ifdef CAN_WITH_RTL
397                 struct {
398                         rtl_spinlock_t rtl_lock;
399                         rtl_wait_t rtl_readq;
400                         atomic_t   rtl_readq_age;
401                         rtl_wait_t rtl_writeq;
402                         atomic_t   rtl_writeq_age;
403                         rtl_wait_t rtl_emptyq;
404                         atomic_t   rtl_emptyq_age;
405                         unsigned long pend_flags;
406                 } rtlinfo;
407             #endif /*CAN_WITH_RTL*/
408                 struct {
409                         struct msgobj_t *msgobj;
410                         struct canchip_t *chip;
411                     #ifndef CAN_WITH_RTL
412                         wait_queue_head_t daemonq;
413                     #else /*CAN_WITH_RTL*/
414                         pthread_t worker_thread;
415                     #endif /*CAN_WITH_RTL*/
416                 } chipinfo;
417         } endinfo;
418         struct list_head dead_peers;
419 };
420
421 #define CANQUEUE_NOTIFY_EMPTY  1 /* out -> in - all slots are processed by FIFO out side */
422 #define CANQUEUE_NOTIFY_SPACE  2 /* out -> in - full state negated => there is space for new message */
423 #define CANQUEUE_NOTIFY_PROC   3 /* in -> out - empty state negated => out side is requested to process slots */
424 #define CANQUEUE_NOTIFY_NOUSR  4 /* called with some lock to prevent edge disappear */
425 #define CANQUEUE_NOTIFY_DEAD   5 /*  */
426 #define CANQUEUE_NOTIFY_DEAD_WANTED 6 /*  */
427 #define CANQUEUE_NOTIFY_ATTACH 7 /*  */
428 #define CANQUEUE_NOTIFY_FILTCH 8 /* filter changed */
429 #define CANQUEUE_NOTIFY_ERROR      0x10000 /* error notifiers */
430 #define CANQUEUE_NOTIFY_ERRTX_PREP 0x11001 /* tx preparation error */
431 #define CANQUEUE_NOTIFY_ERRTX_SEND 0x11002 /* tx send error */
432 #define CANQUEUE_NOTIFY_ERRTX_BUS  0x11003 /* tx bus error */
433
434 #define CAN_ENDSF_DEAD    (1<<0)
435 #define CAN_ENDSF_MEM_RTL (1<<1)
436
437 /**
438  * canque_notify_inends - request to send notification to the input ends
439  * @qedge: pointer to the edge structure
440  * @what: notification type
441  */
442 static inline
443 void canque_notify_inends(struct canque_edge_t *qedge, int what)
444 {
445         if(qedge->inends)
446                 if(qedge->inends->notify)
447                         qedge->inends->notify(qedge->inends,qedge,what);
448 }
449
450 /**
451  * canque_notify_outends - request to send notification to the output ends
452  * @qedge: pointer to the edge structure
453  * @what: notification type
454  */
455 static inline
456 void canque_notify_outends(struct canque_edge_t *qedge, int what)
457 {
458         if(qedge->outends)
459                 if(qedge->outends->notify)
460                         qedge->outends->notify(qedge->outends,qedge,what);
461 }
462
463 /**
464  * canque_notify_bothends - request to send notification to the both ends
465  * @qedge: pointer to the edge structure
466  * @what: notification type
467  */
468 static inline
469 void canque_notify_bothends(struct canque_edge_t *qedge, int what)
470 {
471         canque_notify_inends(qedge, what);
472         canque_notify_outends(qedge, what);
473 }
474
475 /**
476  * canque_activate_edge - mark output end of the edge as active
477  * @qedge: pointer to the edge structure
478  * @inends: input side of the edge
479  *
480  * Function call moves output side of the edge from idle onto active edges
481  * list. This function has to be called with edge reference count held.
482  * that is same as for most of other edge functions.
483  */
484 static inline
485 void canque_activate_edge(struct canque_ends_t *inends, struct canque_edge_t *qedge)
486 {
487         can_spin_irqflags_t flags;
488         struct canque_ends_t *outends;
489         if(qedge->edge_prio>=CANQUEUE_PRIO_NR)
490                 qedge->edge_prio=CANQUEUE_PRIO_NR-1;
491         if((outends=qedge->outends)){
492                 can_spin_lock_irqsave(&outends->ends_lock, flags);
493                 can_spin_lock(&qedge->fifo.fifo_lock);
494                 if(!canque_fifo_test_fl(&qedge->fifo,EMPTY)){
495                         list_del(&qedge->activepeers);
496                         list_add_tail(&qedge->activepeers,&outends->active[qedge->edge_prio]);
497                 }
498                 can_spin_unlock(&qedge->fifo.fifo_lock);
499                 can_spin_unlock_irqrestore(&outends->ends_lock, flags);
500         }
501 }
502
503 /**
504  * canque_filtid2internal - converts message ID and filter flags into internal format
505  * @id: CAN message 11 or 29 bit identifier
506  * @filtflags: CAN message flags
507  *
508  * This function maps message ID and %MSG_RTR, %MSG_EXT and %MSG_LOCAL into one 32 bit number
509  */
510 static inline
511 unsigned int canque_filtid2internal(unsigned long id, int filtflags)
512 {
513         filtflags &= MSG_RTR|MSG_EXT|MSG_LOCAL;
514         filtflags += filtflags&MSG_RTR;
515         return (id&MSG_ID_MASK) | (filtflags<<28);
516 }
517
518 int canque_get_inslot(struct canque_ends_t *qends,
519         struct canque_edge_t **qedgep, struct canque_slot_t **slotp, int cmd);
520
521 int canque_get_inslot4id(struct canque_ends_t *qends,
522         struct canque_edge_t **qedgep, struct canque_slot_t **slotp,
523         int cmd, unsigned long id, int prio);
524
525 int canque_put_inslot(struct canque_ends_t *qends,
526         struct canque_edge_t *qedge, struct canque_slot_t *slot);
527
528 int canque_abort_inslot(struct canque_ends_t *qends,
529         struct canque_edge_t *qedge, struct canque_slot_t *slot);
530
531 int canque_filter_msg2edges(struct canque_ends_t *qends, struct canmsg_t *msg);
532
533 int canque_test_outslot(struct canque_ends_t *qends,
534         struct canque_edge_t **qedgep, struct canque_slot_t **slotp);
535
536 int canque_free_outslot(struct canque_ends_t *qends,
537         struct canque_edge_t *qedge, struct canque_slot_t *slot);
538
539 int canque_again_outslot(struct canque_ends_t *qends,
540         struct canque_edge_t *qedge, struct canque_slot_t *slot);
541
542 int canque_set_filt(struct canque_edge_t *qedge,
543         unsigned long filtid, unsigned long filtmask, int flags);
544
545 int canque_flush(struct canque_edge_t *qedge);
546
547 int canqueue_disconnect_edge(struct canque_edge_t *qedge);
548
549 int canqueue_connect_edge(struct canque_edge_t *qedge, struct canque_ends_t *inends, struct canque_ends_t *outends);
550
551 int canqueue_ends_init_gen(struct canque_ends_t *qends);
552
553 void canqueue_block_inlist(struct canque_ends_t *qends);
554
555 void canqueue_block_outlist(struct canque_ends_t *qends);
556
557 int canqueue_ends_kill_inlist(struct canque_ends_t *qends, int send_rest);
558
559 int canqueue_ends_kill_outlist(struct canque_ends_t *qends);
560
561 int canqueue_ends_filt_conjuction(struct canque_ends_t *qends, struct canfilt_t *filt);
562
563 int canqueue_ends_flush_inlist(struct canque_ends_t *qends);
564
565 int canqueue_ends_flush_outlist(struct canque_ends_t *qends);
566
567 /* edge reference and traversal functions */
568
569 void canque_edge_do_dead(struct canque_edge_t *edge);
570
571 /**
572  * canque_edge_incref - increments edge reference count
573  * @edge: pointer to the edge structure
574  */
575 static inline
576 void canque_edge_incref(struct canque_edge_t *edge)
577 {
578         atomic_inc(&edge->edge_used);
579 }
580
581 static inline
582 can_spin_irqflags_t canque_edge_lock_both_ends(struct canque_ends_t *inends, struct canque_ends_t *outends)
583 {
584         can_spin_irqflags_t  flags;
585         if(inends<outends) {
586                 can_spin_lock_irqsave(&inends->ends_lock, flags);
587                 can_spin_lock(&outends->ends_lock);
588         }else{
589                 can_spin_lock_irqsave(&outends->ends_lock, flags);
590                 if(outends!=inends) can_spin_lock(&inends->ends_lock);
591         }
592         return flags;
593 }
594
595 static inline
596 void canque_edge_unlock_both_ends(struct canque_ends_t *inends, struct canque_ends_t *outends, can_spin_irqflags_t flags)
597 {
598         if(outends!=inends) can_spin_unlock(&outends->ends_lock);
599         can_spin_unlock_irqrestore(&inends->ends_lock, flags);
600 }
601
602 /* Non-inlined version of edge reference decrement */
603 void __canque_edge_decref(struct canque_edge_t *edge);
604
605 static inline
606 void __canque_edge_decref_body(struct canque_edge_t *edge)
607 {
608         can_spin_irqflags_t flags;
609         int dead_fl=0;
610         struct canque_ends_t *inends=edge->inends;
611         struct canque_ends_t *outends=edge->outends;
612
613         flags=canque_edge_lock_both_ends(inends, outends);
614         if(atomic_dec_and_test(&edge->edge_used)) {
615                 dead_fl=!canque_fifo_test_and_set_fl(&edge->fifo,DEAD);
616                 /* Because of former evolution of edge references
617                    management notify of CANQUEUE_NOTIFY_NOUSR could
618                    be moved to canque_edge_do_dead :-) */
619         }
620         canque_edge_unlock_both_ends(inends, outends, flags);
621         if(dead_fl) canque_edge_do_dead(edge);
622 }
623
624 #ifndef CAN_HAVE_ARCH_CMPXCHG
625 /**
626  * canque_edge_decref - decrements edge reference count
627  * @edge: pointer to the edge structure
628  *
629  * This function has to be called without lock held for both ends of edge.
630  * If reference count drops to 0, function canque_edge_do_dead()
631  * is called.
632  */
633 static inline
634 void canque_edge_decref(struct canque_edge_t *edge)
635 {
636         __canque_edge_decref_body(edge);
637 }
638 #else
639 static inline
640 void canque_edge_decref(struct canque_edge_t *edge)
641 {
642         int x, y;
643
644         x = atomic_read(&edge->edge_used);
645         do{
646                 if(x<=1)
647                         return __canque_edge_decref(edge);
648                 y=x;
649             #ifdef CAN_HAVE_ATOMIC_CMPXCHG
650                 atomic_cmpxchg(&edge->edge_used, x, x-1);
651             #else /* workaround for case that atomic_cmpxchg is not defined */
652                 /* This code strongly depends on the definition of atomic_t !!!! */
653                 x=__cmpxchg(&edge->edge_used, x, x-1, sizeof(atomic_t));
654                 /* If even this does not help, comment out CAN_HAVE_ARCH_CMPXCHG in can_sysdep.h */
655             #endif
656         } while(x!=y);
657 }
658 #endif
659
660 static inline
661 struct canque_edge_t *canque_first_inedge(struct canque_ends_t *qends)
662 {
663         can_spin_irqflags_t flags;
664         struct list_head *entry;
665         struct canque_edge_t *edge;
666
667         can_spin_lock_irqsave(&qends->ends_lock, flags);
668         entry=qends->inlist.next;
669     skip_dead:
670         if(entry != &qends->inlist) {
671                 edge=list_entry(entry,struct canque_edge_t,inpeers);
672                 if(canque_fifo_test_fl(&edge->fifo,DEAD)) {
673                         entry=entry->next;
674                         goto skip_dead;
675                 }
676                 canque_edge_incref(edge);
677         } else {
678                 edge=NULL;
679         }
680         can_spin_unlock_irqrestore(&qends->ends_lock, flags);
681         return edge;
682 }
683
684
685 static inline
686 struct canque_edge_t *canque_next_inedge(struct canque_ends_t *qends, struct canque_edge_t *edge)
687 {
688         can_spin_irqflags_t flags;
689         struct list_head *entry;
690         struct canque_edge_t *next;
691
692         can_spin_lock_irqsave(&qends->ends_lock, flags);
693         entry=edge->inpeers.next;
694     skip_dead:
695         if(entry != &qends->inlist) {
696                 next=list_entry(entry,struct canque_edge_t,inpeers);
697                 if(canque_fifo_test_fl(&edge->fifo,DEAD)) {
698                         entry=entry->next;
699                         goto skip_dead;
700                 }
701                 canque_edge_incref(next);
702         } else {
703                 next=NULL;
704         }
705         can_spin_unlock_irqrestore(&qends->ends_lock, flags);
706         canque_edge_decref(edge);
707         return next;
708 }
709
710 #define canque_for_each_inedge(qends, edge) \
711             for(edge=canque_first_inedge(qends);edge;edge=canque_next_inedge(qends, edge))
712
713 static inline
714 struct canque_edge_t *canque_first_outedge(struct canque_ends_t *qends)
715 {
716         can_spin_irqflags_t flags;
717         struct list_head *entry;
718         struct canque_edge_t *edge;
719
720         can_spin_lock_irqsave(&qends->ends_lock, flags);
721         entry=qends->outlist.next;
722     skip_dead:
723         if(entry != &qends->outlist) {
724                 edge=list_entry(entry,struct canque_edge_t,outpeers);
725                 if(canque_fifo_test_fl(&edge->fifo,DEAD)) {
726                         entry=entry->next;
727                         goto skip_dead;
728                 }
729                 canque_edge_incref(edge);
730         } else {
731                 edge=NULL;
732         }
733         can_spin_unlock_irqrestore(&qends->ends_lock, flags);
734         return edge;
735 }
736
737
738 static inline
739 struct canque_edge_t *canque_next_outedge(struct canque_ends_t *qends, struct canque_edge_t *edge)
740 {
741         can_spin_irqflags_t flags;
742         struct list_head *entry;
743         struct canque_edge_t *next;
744
745         can_spin_lock_irqsave(&qends->ends_lock, flags);
746         entry=edge->outpeers.next;
747     skip_dead:
748         if(entry != &qends->outlist) {
749                 next=list_entry(entry,struct canque_edge_t,outpeers);
750                 if(canque_fifo_test_fl(&edge->fifo,DEAD)) {
751                         entry=entry->next;
752                         goto skip_dead;
753                 }
754                 canque_edge_incref(next);
755         } else {
756                 next=NULL;
757         }
758         can_spin_unlock_irqrestore(&qends->ends_lock, flags);
759         canque_edge_decref(edge);
760         return next;
761 }
762
763 #define canque_for_each_outedge(qends, edge) \
764             for(edge=canque_first_outedge(qends);edge;edge=canque_next_outedge(qends, edge))
765
766 /* Linux kernel specific functions */
767
768 int canque_fifo_init_kern(struct canque_fifo_t *fifo, int slotsnr);
769
770 int canque_fifo_done_kern(struct canque_fifo_t *fifo);
771
772 struct canque_edge_t *canque_new_edge_kern(int slotsnr);
773
774 int canque_get_inslot4id_wait_kern(struct canque_ends_t *qends,
775         struct canque_edge_t **qedgep, struct canque_slot_t **slotp,
776         int cmd, unsigned long id, int prio);
777
778 int canque_get_outslot_wait_kern(struct canque_ends_t *qends,
779         struct canque_edge_t **qedgep, struct canque_slot_t **slotp);
780
781 int canque_sync_wait_kern(struct canque_ends_t *qends, struct canque_edge_t *qedge);
782
783 int canqueue_ends_init_kern(struct canque_ends_t *qends);
784
785 int canqueue_ends_dispose_kern(struct canque_ends_t *qends, int sync);
786
787 void canqueue_ends_dispose_postpone(struct canque_ends_t *qends);
788
789 void canqueue_kern_initialize(void);
790
791 #ifdef CAN_WITH_RTL
792
793 extern struct tasklet_struct canque_dead_tl;    /*publication required only for RTL*/
794
795 /* RT-Linux specific functions and variables */
796
797 extern int canqueue_rtl_irq;
798
799 extern unsigned long canqueue_rtl2lin_pend;
800
801 #define CAN_RTL2LIN_PEND_DEAD_b 0
802
803 void canqueue_rtl_initialize(void);
804 void canqueue_rtl_done(void);
805
806 int canqueue_rtl2lin_check_and_pend(struct canque_ends_t *qends,
807                          struct canque_edge_t *qedge, int what);
808
809 struct canque_edge_t *canque_new_edge_rtl(int slotsnr);
810
811 void canque_dispose_edge_rtl(struct canque_edge_t *qedge);
812
813 int canque_get_inslot4id_wait_rtl(struct canque_ends_t *qends,
814         struct canque_edge_t **qedgep, struct canque_slot_t **slotp,
815         int cmd, unsigned long id, int prio);
816
817 int canque_get_outslot_wait_rtl(struct canque_ends_t *qends,
818         struct canque_edge_t **qedgep, struct canque_slot_t **slotp);
819
820 int canque_sync_wait_rtl(struct canque_ends_t *qends, struct canque_edge_t *qedge);
821
822 void canque_ends_free_rtl(struct canque_ends_t *qends);
823
824 int canqueue_ends_init_rtl(struct canque_ends_t *qends);
825
826 int canqueue_ends_dispose_rtl(struct canque_ends_t *qends, int sync);
827
828 #else /*CAN_WITH_RTL*/
829
830 static inline int canqueue_rtl2lin_check_and_pend(struct canque_ends_t *qends,
831                         struct canque_edge_t *qedge, int what) { return 0; }
832
833 #endif /*CAN_WITH_RTL*/
834
835
836 #endif /*_CAN_QUEUE_H*/