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