]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/setup.c
The first enhanced version of Linux CAN-bus driver for OCERA project
[lincan.git] / lincan / src / setup.c
1 /* setup.c
2  * Linux CAN-bus device driver.
3  * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
4  * This software is released under the GPL-License.
5  * Version 0.7  6 Aug 2001
6  */ 
7
8 #define __NO_VERSION__
9 #include <linux/module.h>
10
11 #include <linux/autoconf.h>
12 #if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS)
13 #define MODVERSIONS
14 #endif
15
16 #if defined (MODVERSIONS)
17 #include <linux/modversions.h>
18 #endif
19
20 #include <linux/version.h>
21 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
22 #include <linux/malloc.h>
23 #else
24 #include <linux/slab.h>
25 #endif
26 #include <linux/fs.h>
27
28 #include ".supported_cards.h"
29
30 #include "../include/main.h"
31 #include "../include/setup.h"
32 #include "../include/pip.h"
33 #include "../include/pccan.h"
34 #include "../include/smartcan.h"
35 #include "../include/pc-i03.h"
36 #include "../include/pcm3680.h"
37 #include "../include/m437.h"
38 #include "../include/template.h"
39 #include "../include/i82527.h"
40 #include "../include/aim104.h"
41 #include "../include/pcccan.h"
42
43 extern int sja1000_register(struct chipspecops_t *chipspecops);
44 extern int sja1000p_register(struct chipspecops_t *chipspecops);
45 extern int i82527_register(struct chipspecops_t *chipspecops);
46 extern int template_register(struct hwspecops_t *hwspecops);
47 extern int pip5_register(struct hwspecops_t *hwspecops);
48 extern int pip6_register(struct hwspecops_t *hwspecops);
49 extern int smartcan_register(struct hwspecops_t *hwspecops);
50 extern int pccanf_register(struct hwspecops_t *hwspecops);
51 extern int pccand_register(struct hwspecops_t *hwspecops);
52 extern int pccanq_register(struct hwspecops_t *hwspecops);
53 extern int nsi_register(struct hwspecops_t *hwspecops);
54 extern int cc104_register(struct hwspecops_t *hwspecops);
55 extern int pci03_register(struct hwspecops_t *hwspecops);
56 extern int pcm3680_register(struct hwspecops_t *hwspecops);
57 extern int aim104_register(struct hwspecops_t *hwspecops);
58 extern int pcccan_register(struct hwspecops_t *hwspecops);
59 extern int ssv_register(struct hwspecops_t *hwspecops);
60 extern int bfadcan_register(struct hwspecops_t *hwspecops);
61 extern int pikronisa_register(struct hwspecops_t *hwspecops);
62
63 int init_device_struct(int card);
64 int init_hwspecops(int card);
65 int init_chip_struct(int card);
66 int init_obj_struct(int card, int chip);
67 int init_chipspecops(int card, int chipnr);
68
69 int add_mem_to_list(void *address_p)
70 {
71         struct mem_addr *mem_new;
72
73 #ifdef DEBUG_MEM
74         DEBUGMSG("add_mem_to_list %p, mem_head=%p\n",address_p, mem_head);
75         return 0;
76 #endif
77
78         mem_new=(struct mem_addr *)kmalloc(sizeof(struct mem_addr),GFP_KERNEL);
79         if (mem_new == NULL) {
80                 CANMSG("Memory list error.\n");
81                 return -ENOMEM;
82         }
83         mem_new->next=mem_head;
84         mem_new->address=address_p;
85         mem_head=mem_new;
86
87         return 0;
88 }
89
90 int del_mem_from_list(void *address_p)
91 {
92         struct mem_addr *mem_search=NULL;
93         struct mem_addr *mem_delete=NULL;
94
95 #ifdef DEBUG_MEM
96         DEBUGMSG("del_mem_from_list %p, mem_head=%p\n", address_p, mem_head);
97         return 0;
98 #endif
99         if(mem_head == NULL) {
100                 CANMSG("del_mem_from_list: mem_head == NULL address_p=%p!\n",
101                                 address_p);
102                 return 0;
103         }
104
105         mem_search = mem_head;
106
107         if (mem_head->address == address_p) {
108                 kfree(mem_head->address);
109                 mem_head=mem_head->next;
110                 kfree(mem_search);
111         }
112         else {
113                 while (mem_search->next->address != address_p)
114                         mem_search=mem_search->next;
115                 kfree(mem_search->next->address);               
116                 mem_delete=mem_search->next;
117                 mem_search->next=mem_search->next->next;
118                 kfree(mem_delete);
119         }
120         return 0;
121 }
122
123
124 int del_mem_list(void)
125 {
126         struct mem_addr *mem_old;
127
128 #ifdef DEBUG_MEM
129         DEBUGMSG("del_mem_list, mem_head=%p\n", mem_head);
130         return 0;
131 #endif
132         if(mem_head == NULL) {
133                 CANMSG("del_mem_list: mem_head == NULL!\n");
134                 return 0;
135         }
136
137         while (mem_head->next != NULL) {
138                 mem_old=mem_head;
139                 kfree(mem_old->address);
140                 mem_head=mem_old->next;
141                 kfree(mem_old);
142         }
143         
144         return 0;
145 }
146
147 /* The function init_hw_struct is used to initialize the hardware structure. */
148 int init_hw_struct(void)
149 {
150         int i=0;
151
152         hardware_p->nr_boards=0;
153         while ( (hw[i] != NULL) & (i < MAX_HW_CARDS) ) {
154                 hardware_p->nr_boards++;
155
156                 if (init_device_struct(i)) {
157                         CANMSG("Error initializing candevice_t structures.\n");
158                         return -ENODEV;
159                 }
160                 i++;
161         }
162
163         return 0;
164 }
165
166 /* The function init_device_struct is used to initialize a single device 
167  * structure.
168  */
169 int init_device_struct(int card)
170 {
171         hardware_p->candevice[card]=(struct candevice_t *)kmalloc(sizeof(struct candevice_t),GFP_KERNEL);
172         if (hardware_p->candevice[card]==NULL)
173                 return -ENOMEM;
174         else
175                 if ( add_mem_to_list(hardware_p->candevice[card]) )
176                         return -ENOMEM;
177
178         candevices_p[card]=hardware_p->candevice[card];
179
180         hardware_p->candevice[card]->hwname=hw[card];
181         hardware_p->candevice[card]->io_addr=io[card];
182
183         hardware_p->candevice[card]->hwspecops=(struct hwspecops_t *)kmalloc(sizeof(struct hwspecops_t),GFP_KERNEL);
184         if (hardware_p->candevice[card]->hwspecops==NULL)
185                 return -ENOMEM;
186         else
187                 if ( add_mem_to_list(hardware_p->candevice[card]->hwspecops) )
188                         return -ENOMEM;
189
190         if (init_hwspecops(card))
191                 return -ENODEV;
192
193         if (candevices_p[card]->hwspecops->init_hw_data(card))
194                 return -ENODEV;
195
196         if (init_chip_struct(card))
197                 return -ENODEV;
198
199         return 0;
200 }
201
202 /* The function init_chip_struct is used to initialize all chip_t structures
203  * on one hardware board.
204  */
205 int init_chip_struct(int card)
206 {
207         static int irq_count=0;
208         int i=0;
209
210         /* Alocate and initialize the chip structures */
211         for (i=0; i < candevices_p[card]->nr_82527_chips+candevices_p[card]->nr_sja1000_chips; i++) {
212                 candevices_p[card]->chip[i]=(struct chip_t *)kmalloc(sizeof(struct chip_t),GFP_KERNEL);
213                 if (candevices_p[card]->chip[i]==NULL)
214                         return -ENOMEM;
215                 else
216                         if ( add_mem_to_list(candevices_p[card]->chip[i]) )
217                                 return -ENOMEM;
218
219                 candevices_p[card]->chip[i]->chipspecops=(struct chipspecops_t *)kmalloc(sizeof(struct chipspecops_t),GFP_KERNEL);
220                 if (candevices_p[card]->chip[i]->chipspecops==NULL)
221                         return -ENOMEM;
222                 else
223                         if ( add_mem_to_list(candevices_p[card]->chip[i]->chipspecops) )
224                                 return -ENOMEM;
225
226                 chips_p[irq_count]=candevices_p[card]->chip[i];
227                 candevices_p[card]->chip[i]->hostdevice=candevices_p[card];
228                 candevices_p[card]->chip[i]->chip_irq=irq[irq_count];
229                 candevices_p[card]->chip[i]->flags=0x0;
230
231                 candevices_p[card]->hwspecops->init_chip_data(card,i);
232
233                 if (init_chipspecops(card,i))
234                         return -ENODEV;
235
236                 init_obj_struct(card, irq_count);
237
238                 irq_count++;
239         } 
240
241         return 0;
242 }
243
244 int init_obj_struct(int card, int chip)
245 {
246         static int obj_count=0;
247         int i=0,max_objects=0;
248
249         if (!strcmp(chips_p[chip]->chip_type,"i82527")) 
250                 max_objects=15;
251         else
252                 max_objects=1;
253         for (i=0; i<max_objects; i++) {
254                 chips_p[chip]->msgobj[i]=(struct msgobj_t *)kmalloc(sizeof(struct msgobj_t),GFP_KERNEL);
255                 if (chips_p[chip]->msgobj[i] == NULL) 
256                         return -ENOMEM;
257                 else
258                         if ( add_mem_to_list(chips_p[chip]->msgobj[i]) )
259                                 return -ENOMEM;
260
261                 chips_p[chip]->msgobj[i]->fifo=(struct canfifo_t *)kmalloc(sizeof(struct canfifo_t),GFP_KERNEL);
262                 if (chips_p[chip]->msgobj[i]->fifo == NULL)
263                         return -ENOMEM;
264                 else
265                         if ( add_mem_to_list(chips_p[chip]->msgobj[i]->fifo) )
266                                 return -ENOMEM;
267                 
268                 if (minor[0] == -1) {
269                         objects_p[obj_count]=chips_p[chip]->msgobj[i];
270                         objects_p[obj_count]->hostchip=chips_p[chip];
271                         objects_p[obj_count]->object=i+1;
272                         objects_p[obj_count]->minor=obj_count;
273                 }
274                 else {
275                         objects_p[minor[chip]+i]=chips_p[chip]->msgobj[i];
276                         objects_p[minor[chip]+i]->hostchip=chips_p[chip];
277                         objects_p[minor[chip]+i]->object=i+1;
278                         objects_p[minor[chip]+i]->minor=minor[chip]+i;
279                 }
280
281                 chips_p[chip]->msgobj[i]->flags = 0x0;
282         
283                 candevices_p[card]->hwspecops->init_obj_data(chip,i);
284
285                 obj_count++;
286         }
287         return 0;
288 }
289
290
291 int init_hwspecops(int card)
292 {
293         #ifdef ENABLE_CARD_template
294         if (!strcmp(candevices_p[card]->hwname,"template")) {
295                 template_register(candevices_p[card]->hwspecops);
296         }
297         #endif
298         #ifdef ENABLE_CARD_pip
299         if (!strcmp(candevices_p[card]->hwname,"pip5")) {
300                 pip5_register(candevices_p[card]->hwspecops);
301         }
302         else if (!strcmp(candevices_p[card]->hwname,"pip6")) {
303                 pip6_register(candevices_p[card]->hwspecops);
304         }
305         #endif
306         #ifdef ENABLE_CARD_smartcan
307         if (!strcmp(candevices_p[card]->hwname,"smartcan")) {
308                 smartcan_register(candevices_p[card]->hwspecops);
309         }
310         #endif
311         #ifdef ENABLE_CARD_nsi
312         if (!strcmp(candevices_p[card]->hwname,"nsican")) {
313                 nsi_register(candevices_p[card]->hwspecops);
314         }
315         #endif
316         #ifdef ENABLE_CARD_cc_can104
317         if (!strcmp(candevices_p[card]->hwname,"cc104")) {
318                 cc104_register(candevices_p[card]->hwspecops);
319         }
320         #endif
321         #ifdef ENABLE_CARD_aim104
322         if (!strcmp(candevices_p[card]->hwname,"aim104")) {
323                 aim104_register(candevices_p[card]->hwspecops);
324         }
325         #endif
326         #ifdef ENABLE_CARD_pc_i03
327         if (!strcmp(candevices_p[card]->hwname,"pc-i03")) {
328                 pci03_register(candevices_p[card]->hwspecops);
329         }
330         #endif
331         #ifdef ENABLE_CARD_pcm3680
332         if (!strcmp(candevices_p[card]->hwname,"pcm3680")) {
333                 pcm3680_register(candevices_p[card]->hwspecops);
334         }
335         #endif
336         #ifdef ENABLE_CARD_pccan
337         if (!strcmp(candevices_p[card]->hwname,"pccan-f") |
338                  !strcmp(candevices_p[card]->hwname,"pccan-s") ) {
339                 pccanf_register(candevices_p[card]->hwspecops);
340         }
341         if (!strcmp(candevices_p[card]->hwname,"pccan-d")) {
342                 pccand_register(candevices_p[card]->hwspecops);
343         }
344         if (!strcmp(candevices_p[card]->hwname,"pccan-q")) {
345                 pccanq_register(candevices_p[card]->hwspecops);
346         }
347         #endif
348         #ifdef ENABLE_CARD_m437
349         if (!strcmp(candevices_p[card]->hwname,"m437")) {
350                 m437_register(candevices_p[card]->hwspecops);
351         }
352         #endif
353         #ifdef ENABLE_CARD_pcccan
354         if (!strcmp(candevices_p[card]->hwname,"pcccan")) {
355                 pcccan_register(candevices_p[card]->hwspecops);
356         }
357         #endif
358         #ifdef ENABLE_CARD_ssv
359         if (!strcmp(candevices_p[card]->hwname,"ssv")) {
360                 ssv_register(candevices_p[card]->hwspecops);
361         }
362         #endif
363         #ifdef ENABLE_CARD_bfadcan
364         if (!strcmp(candevices_p[card]->hwname,"bfadcan")) {
365                 bfadcan_register(candevices_p[card]->hwspecops);
366         }
367         #endif
368         #ifdef ENABLE_CARD_pikronisa
369         if (!strcmp(candevices_p[card]->hwname,"pikronisa")) {
370                 pikronisa_register(candevices_p[card]->hwspecops);
371         }
372         #endif
373         return 0;
374 }
375
376 int init_chipspecops(int card, int chipnr)
377 {
378         if (!strcmp(candevices_p[card]->chip[chipnr]->chip_type,"i82527")) {
379                 i82527_register(candevices_p[card]->chip[chipnr]->chipspecops);
380         } 
381         if (!strcmp(candevices_p[card]->chip[chipnr]->chip_type,"sja1000")) {
382                 sja1000_register(candevices_p[card]->chip[chipnr]->chipspecops);
383         }
384         if (!strcmp(candevices_p[card]->chip[chipnr]->chip_type,"sja1000p")) {
385                 sja1000p_register(candevices_p[card]->chip[chipnr]->chipspecops);
386         }
387
388         return 0;
389 }