1 /* devcommon.c - common device code
2 * Linux CAN-bus device driver.
3 * New CAN queues by Pavel Pisa - OCERA team member
4 * email:pisa@cmp.felk.cvut.cz
5 * This software is released under the GPL-License.
6 * Version lincan-0.3 17 Jun 2004
9 #include "../include/can.h"
10 #include "../include/can_sysdep.h"
11 #include "../include/can_queue.h"
12 #include "../include/main.h"
13 #include "../include/devcommon.h"
17 void canqueue_wake_chip_worker(struct canque_ends_t *qends, struct canchip_t *chip, struct msgobj_t *obj)
19 if(qends->endinfo.chipinfo.worker_thread){
20 can_msgobj_set_fl(obj,WORKER_WAKE);
21 pthread_kill(qends->endinfo.chipinfo.worker_thread,RTL_SIGNAL_WAKEUP);
24 set_bit(MSGOBJ_TX_REQUEST_b,&chip->pend_flags);
25 if(chip->worker_thread) {
26 set_bit(MSGOBJ_WORKER_WAKE_b,&chip->pend_flags);
27 pthread_kill(chip->worker_thread,RTL_SIGNAL_WAKEUP);
33 #endif /*CAN_WITH_RTL*/
37 * canqueue_notify_chip - notification callback handler for CAN chips ends of queues
38 * @qends: pointer to the callback side ends structure
39 * @qedge: edge which invoked notification
40 * @what: notification type
42 * This function has to deal with more possible cases. It can be called from
43 * the kernel or interrupt context for Linux only compilation of driver.
44 * The function can be called from kernel context or RT-Linux thread context
45 * for mixed mode Linux/RT-Linux compilation.
47 void canqueue_notify_chip(struct canque_ends_t *qends, struct canque_edge_t *qedge, int what)
49 struct canchip_t *chip=qends->endinfo.chipinfo.chip;
50 struct msgobj_t *obj=qends->endinfo.chipinfo.msgobj;
52 DEBUGMSG("canqueue_notify_chip for edge %d and event %d\n",qedge->edge_num,what);
54 /*case CANQUEUE_NOTIFY_EMPTY:*/
55 /*case CANQUEUE_NOTIFY_SPACE:*/
56 /*case CANQUEUE_NOTIFY_NOUSR:
57 wake_up(&qends->endinfo.chipinfo.daemonq);
59 case CANQUEUE_NOTIFY_PROC:
61 /*wake_up(&qends->endinfo.chipinfo.daemonq);*/
62 if(canque_fifo_test_fl(&qedge->fifo, READY)){
63 if ((chip) && (chip->flags & CHIP_ATTACHED))
64 chip->chipspecops->wakeup_tx(chip, obj);
66 #else /*CAN_WITH_RTL*/
67 can_msgobj_set_fl(obj,TX_REQUEST);
68 canqueue_wake_chip_worker(qends, chip, obj);
69 #endif /*CAN_WITH_RTL*/
71 case CANQUEUE_NOTIFY_DEAD_WANTED:
72 case CANQUEUE_NOTIFY_DEAD:
73 if(canque_fifo_test_and_clear_fl(&qedge->fifo, READY))
74 canque_edge_decref(qedge);
76 case CANQUEUE_NOTIFY_ATTACH:
78 case CANQUEUE_NOTIFY_FILTCH:
79 if(!chip->chipspecops->filtch_rq)
82 chip->chipspecops->filtch_rq(chip, obj);
83 #else /*CAN_WITH_RTL*/
84 can_msgobj_set_fl(obj,FILTCH_REQUEST);
85 canqueue_wake_chip_worker(qends, chip, obj);
86 #endif /*CAN_WITH_RTL*/
94 * canqueue_ends_init_chip - CAN chip specific ends initialization
95 * @qends: pointer to the ends structure
96 * @chip: pointer to the corresponding CAN chip structure
97 * @obj: pointer to the corresponding message object structure
99 int canqueue_ends_init_chip(struct canque_ends_t *qends, struct canchip_t *chip, struct msgobj_t *obj)
102 ret=canqueue_ends_init_gen(qends);
103 if(ret<0) return ret;
107 init_waitqueue_head(&qends->endinfo.chipinfo.daemonq);
108 #endif /*CAN_WITH_RTL*/
109 qends->endinfo.chipinfo.chip=chip;
110 qends->endinfo.chipinfo.msgobj=obj;
111 qends->notify=canqueue_notify_chip;
113 DEBUGMSG("canqueue_ends_init_chip\n");
119 * canqueue_ends_done_chip - finalizing of the ends structure for CAN chips
120 * @qends: pointer to ends structure
122 * Return Value: Function should be designed such way to not fail.
124 int canqueue_ends_done_chip(struct canque_ends_t *qends)
128 /* Finish or kill all outgoing edges listed in inends */
129 delayed=canqueue_ends_kill_inlist(qends, 1);
130 /* Kill all incoming edges listed in outends */
131 delayed|=canqueue_ends_kill_outlist(qends);