]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/app/usbcan/devcommon.c
embedded: reintroduce missing emulated bus initialization for UL_USB1 board.
[lincan.git] / embedded / app / usbcan / devcommon.c
1 /**************************************************************************/
2 /* File: devcommon.c - common device code                                 */
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 #include "./can/can.h"
35 #include "./can/can_sysdep.h"
36 #include "./can/can_queue.h"
37 #include "./can/main.h"
38 #include "./can/devcommon.h"
39
40 #ifdef CAN_WITH_RTL
41 static inline
42 void canqueue_wake_chip_worker(struct canque_ends_t *qends, struct canchip_t *chip, struct msgobj_t *obj)
43 {
44         if(qends->endinfo.chipinfo.worker_thread){
45                 can_msgobj_set_fl(obj,WORKER_WAKE);
46                 pthread_kill(qends->endinfo.chipinfo.worker_thread,RTL_SIGNAL_WAKEUP);
47                 rtl_schedule();
48         } else {
49                 set_bit(MSGOBJ_TX_REQUEST_b,&chip->pend_flags);
50                 if(chip->worker_thread) {
51                         set_bit(MSGOBJ_WORKER_WAKE_b,&chip->pend_flags);
52                         pthread_kill(chip->worker_thread,RTL_SIGNAL_WAKEUP);
53                         rtl_schedule();
54                 }
55         }
56 }
57
58 #endif /*CAN_WITH_RTL*/
59
60
61 /**
62  * canqueue_notify_chip - notification callback handler for CAN chips ends of queues
63  * @qends: pointer to the callback side ends structure
64  * @qedge: edge which invoked notification
65  * @what: notification type
66  *
67  * This function has to deal with more possible cases. It can be called from
68  * the kernel or interrupt context for Linux only compilation of driver.
69  * The function can be called from kernel context or RT-Linux thread context
70  * for mixed mode Linux/RT-Linux compilation.
71  */
72 void canqueue_notify_chip(struct canque_ends_t *qends, struct canque_edge_t *qedge, int what)
73 {
74         struct canchip_t *chip=qends->endinfo.chipinfo.chip;
75         struct msgobj_t *obj=qends->endinfo.chipinfo.msgobj;
76
77         DEBUGMSG("canqueue_notify_chip for edge %d and event %d\n",qedge->edge_num,what);
78         switch(what){
79                 /*case CANQUEUE_NOTIFY_EMPTY:*/
80                 /*case CANQUEUE_NOTIFY_SPACE:*/
81                 /*case CANQUEUE_NOTIFY_NOUSR:
82                         wake_up(&qends->endinfo.chipinfo.daemonq);
83                         break;*/
84                 case CANQUEUE_NOTIFY_PROC:
85                     #ifndef CAN_WITH_RTL
86                         /*wake_up(&qends->endinfo.chipinfo.daemonq);*/
87                         if(canque_fifo_test_fl(&qedge->fifo, READY)){
88                                 if ((chip) && (chip->flags & CHIP_ATTACHED))
89                                         chip->chipspecops->wakeup_tx(chip, obj);
90                         }
91                     #else /*CAN_WITH_RTL*/
92                         can_msgobj_set_fl(obj,TX_REQUEST);
93                         canqueue_wake_chip_worker(qends, chip, obj);
94                     #endif /*CAN_WITH_RTL*/
95                         break;
96                 case CANQUEUE_NOTIFY_DEAD_WANTED:
97                 case CANQUEUE_NOTIFY_DEAD:
98                         if(canque_fifo_test_and_clear_fl(&qedge->fifo, READY))
99                                 canque_edge_decref(qedge);
100                         break;
101                 case CANQUEUE_NOTIFY_ATTACH:
102                         break;
103                 case CANQUEUE_NOTIFY_FILTCH:
104                         if(!chip->chipspecops->filtch_rq)
105                                 break;
106                     #ifndef CAN_WITH_RTL
107                         chip->chipspecops->filtch_rq(chip, obj);
108                     #else /*CAN_WITH_RTL*/
109                         can_msgobj_set_fl(obj,FILTCH_REQUEST);
110                         canqueue_wake_chip_worker(qends, chip, obj);
111                     #endif /*CAN_WITH_RTL*/
112
113                         break;
114         }
115 }
116
117
118 /**
119  * canqueue_ends_init_chip - CAN chip specific ends initialization
120  * @qends: pointer to the ends structure
121  * @chip: pointer to the corresponding CAN chip structure
122  * @obj: pointer to the corresponding message object structure
123  */
124 int canqueue_ends_init_chip(struct canque_ends_t *qends, struct canchip_t *chip, struct msgobj_t *obj)
125 {
126         int ret;
127         ret=canqueue_ends_init_gen(qends);
128         if(ret<0) return ret;
129
130         qends->context=NULL;
131     #ifndef CAN_WITH_RTL
132         init_waitqueue_head(&qends->endinfo.chipinfo.daemonq);
133     #endif /*CAN_WITH_RTL*/
134         qends->endinfo.chipinfo.chip=chip;
135         qends->endinfo.chipinfo.msgobj=obj;
136         qends->notify=canqueue_notify_chip;
137
138         DEBUGMSG("canqueue_ends_init_chip\n");
139         return 0;
140 }
141
142
143 /**
144  * canqueue_ends_done_chip - finalizing of the ends structure for CAN chips
145  * @qends: pointer to ends structure
146  *
147  * Return Value: Function should be designed such way to not fail.
148  */
149 int canqueue_ends_done_chip(struct canque_ends_t *qends)
150 {
151         int delayed;
152
153         /* Finish or kill all outgoing edges listed in inends */
154         delayed=canqueue_ends_kill_inlist(qends, 1);
155         /* Kill all incoming edges listed in outends */
156         delayed|=canqueue_ends_kill_outlist(qends);
157
158         return delayed;
159 }