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
8 #include <linux/autoconf.h>
9 #if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS)
13 #if defined (MODVERSIONS)
14 #include <linux/modversions.h>
17 #include <linux/malloc.h>
20 #include "../.support"
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"
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);
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);
59 int add_mem_to_list(void *address_p)
61 struct mem_addr *mem_new;
64 DEBUGMSG("add_mem_to_list %p, mem_head=%p\n",address_p, mem_head);
68 mem_new=(struct mem_addr *)kmalloc(sizeof(struct mem_addr),GFP_KERNEL);
69 if (mem_new == NULL) {
70 CANMSG("Memory list error.\n");
73 mem_new->next=mem_head;
74 mem_new->address=address_p;
80 int del_mem_from_list(void *address_p)
82 struct mem_addr *mem_search=NULL;
83 struct mem_addr *mem_delete=NULL;
86 DEBUGMSG("del_mem_from_list %p, mem_head=%p\n", address_p, mem_head);
90 mem_search = mem_head;
92 if (mem_head->address == address_p) {
93 kfree(mem_head->address);
94 mem_head=mem_head->next;
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;
109 int del_mem_list(void)
111 struct mem_addr *mem_old;
114 DEBUGMSG("del_mem_list, mem_head=%p\n", mem_head);
118 while (mem_head->next != NULL) {
120 kfree(mem_old->address);
121 mem_head=mem_old->next;
128 /* The function init_hw_struct is used to initialize the hardware structure. */
129 int init_hw_struct(void)
133 hardware_p->nr_boards=0;
134 while ( (hw[i] != NULL) & (i < MAX_HW_CARDS) ) {
135 hardware_p->nr_boards++;
137 if (init_device_struct(i)) {
138 CANMSG("Error initializing candevice_t structures.\n");
147 /* The function init_device_struct is used to initialize a single device
150 int init_device_struct(int card)
152 hardware_p->candevice[card]=(struct candevice_t *)kmalloc(sizeof(struct candevice_t),GFP_KERNEL);
153 if (hardware_p->candevice[card]==NULL)
156 if ( add_mem_to_list(hardware_p->candevice[card]) )
159 candevices_p[card]=hardware_p->candevice[card];
161 hardware_p->candevice[card]->hwname=hw[card];
162 hardware_p->candevice[card]->io_addr=io[card];
164 hardware_p->candevice[card]->hwspecops=(struct hwspecops_t *)kmalloc(sizeof(struct hwspecops_t),GFP_KERNEL);
165 if (hardware_p->candevice[card]->hwspecops==NULL)
168 if ( add_mem_to_list(hardware_p->candevice[card]->hwspecops) )
171 if (init_hwspecops(card))
174 if (candevices_p[card]->hwspecops->init_hw_data(card))
177 if (init_chip_struct(card))
183 /* The function init_chip_struct is used to initialize all chip_t structures
184 * on one hardware board.
186 int init_chip_struct(int card)
188 static int irq_count=0;
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)
197 if ( add_mem_to_list(candevices_p[card]->chip[i]) )
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)
204 if ( add_mem_to_list(candevices_p[card]->chip[i]->chipspecops) )
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;
212 candevices_p[card]->hwspecops->init_chip_data(card,i);
214 if (init_chipspecops(card,i))
217 init_obj_struct(card, irq_count);
225 int init_obj_struct(int card, int chip)
227 static int obj_count=0;
228 int i=0,max_objects=0;
230 if (!strcmp(chips_p[chip]->chip_type,"i82527"))
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)
239 if ( add_mem_to_list(chips_p[chip]->msgobj[i]) )
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)
246 if ( add_mem_to_list(chips_p[chip]->msgobj[i]->fifo) )
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;
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;
262 chips_p[chip]->msgobj[i]->flags = 0x0;
264 candevices_p[card]->hwspecops->init_obj_data(chip,i);
272 int init_hwspecops(int card)
275 if (!strcmp(candevices_p[card]->hwname,"template")) {
276 template_register(candevices_p[card]->hwspecops);
280 if (!strcmp(candevices_p[card]->hwname,"pip5")) {
281 pip5_register(candevices_p[card]->hwspecops);
283 else if (!strcmp(candevices_p[card]->hwname,"pip6")) {
284 pip6_register(candevices_p[card]->hwspecops);
288 if (!strcmp(candevices_p[card]->hwname,"smartcan")) {
289 smartcan_register(candevices_p[card]->hwspecops);
293 if (!strcmp(candevices_p[card]->hwname,"nsican")) {
294 nsi_register(candevices_p[card]->hwspecops);
298 if (!strcmp(candevices_p[card]->hwname,"cc104")) {
299 cc104_register(candevices_p[card]->hwspecops);
303 if (!strcmp(candevices_p[card]->hwname,"aim104")) {
304 aim104_register(candevices_p[card]->hwspecops);
308 if (!strcmp(candevices_p[card]->hwname,"pc-i03")) {
309 pci03_register(candevices_p[card]->hwspecops);
313 if (!strcmp(candevices_p[card]->hwname,"pcm3680")) {
314 pcm3680_register(candevices_p[card]->hwspecops);
318 if (!strcmp(candevices_p[card]->hwname,"pccan-f") |
319 !strcmp(candevices_p[card]->hwname,"pccan-s") ) {
320 pccanf_register(candevices_p[card]->hwspecops);
322 if (!strcmp(candevices_p[card]->hwname,"pccan-d")) {
323 pccand_register(candevices_p[card]->hwspecops);
325 if (!strcmp(candevices_p[card]->hwname,"pccan-q")) {
326 pccanq_register(candevices_p[card]->hwspecops);
330 if (!strcmp(candevices_p[card]->hwname,"m437")) {
331 m437_register(candevices_p[card]->hwspecops);
335 if (!strcmp(candevices_p[card]->hwname,"pcccan")) {
336 pcccan_register(candevices_p[card]->hwspecops);
340 if (!strcmp(candevices_p[card]->hwname,"ssv")) {
341 ssv_register(candevices_p[card]->hwspecops);
347 int init_chipspecops(int card, int chipnr)
349 if (!strcmp(candevices_p[card]->chip[chipnr]->chip_type,"i82527")) {
350 i82527_register(candevices_p[card]->chip[chipnr]->chipspecops);
352 if (!strcmp(candevices_p[card]->chip[chipnr]->chip_type,"sja1000")) {
353 sja1000_register(candevices_p[card]->chip[chipnr]->chipspecops);
355 if (!strcmp(candevices_p[card]->chip[chipnr]->chip_type,"sja1000p")) {
356 sja1000p_register(candevices_p[card]->chip[chipnr]->chipspecops);