2 * Linux CAN-bus device driver.
3 * Written by Arnaud Westenberg email:arnaud@wanadoo.nl
4 * Rewritten for new CAN queues by Pavel Pisa - OCERA team member
5 * email:pisa@cmp.felk.cvut.cz
6 * This software is released under the GPL-License.
7 * Version lincan-0.2 9 Jul 2003
10 #include "../include/can.h"
11 #include "../include/can_sysdep.h"
12 #include "../include/main.h"
13 #include "../include/devcommon.h"
14 #include "../include/setup.h"
15 #include "../include/finish.h"
17 extern int sja1000_register(struct chipspecops_t *chipspecops);
18 extern int sja1000p_register(struct chipspecops_t *chipspecops);
19 extern int i82527_register(struct chipspecops_t *chipspecops);
21 int init_device_struct(int card);
22 int init_hwspecops(struct candevice_t *candev);
23 int init_chip_struct(struct candevice_t *candev);
24 int init_obj_struct(struct candevice_t *candev, struct chip_t *hostchip, int minorbase);
25 int init_chipspecops(struct candevice_t *candev, int chipnr);
27 void *can_checked_malloc(size_t size)
29 struct mem_addr *mem_new;
32 address_p=kmalloc(size,GFP_KERNEL);
33 if(address_p == NULL) {
34 CANMSG("can_checked_malloc: out of the memory\n");
39 DEBUGMSG("can_checked_malloc: allocated %d bytes at %p, mem_head=%p\n",
40 (int)size, address_p, mem_head);
43 mem_new=(struct mem_addr *)kmalloc(sizeof(struct mem_addr),GFP_KERNEL);
44 if (mem_new == NULL) {
45 CANMSG("can_checked_malloc: memory list allocation error.\n");
49 mem_new->next=mem_head;
50 mem_new->address=address_p;
57 int can_checked_free(void *address_p)
59 struct mem_addr **mem_pptr;
60 struct mem_addr *mem_del=NULL;
63 DEBUGMSG("can_checked_free %p, mem_head=%p\n", address_p, mem_head);
66 for(mem_pptr = &mem_head; (mem_del = *mem_pptr); mem_pptr = &mem_del->next) {
67 if (mem_del->address != address_p)
69 *mem_pptr=mem_del->next;
75 CANMSG("can_checked_free: address %p not found on the mem list\n", address_p);
82 int can_del_mem_list(void)
87 DEBUGMSG("can_del_mem_list, mem_head=%p\n", mem_head);
89 if(mem_head == NULL) {
90 CANMSG("can_del_mem_list: no entries on the list - OK\n");
94 while((mem=mem_head) != NULL) {
96 CANMSG("can_del_mem_list: deleting %p with size %d\n",
97 mem->address, (int)mem->size);
105 int can_request_io_region(unsigned long start, unsigned long n, const char *name)
107 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
108 if(check_region(start,n)) return 0;
109 request_region(start,n,name);
112 return (request_region(start,n,name))?1:0;
116 void can_release_io_region(unsigned long start, unsigned long n)
118 release_region(start,n);
121 int can_request_mem_region(unsigned long start, unsigned long n, const char *name)
123 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
126 return (request_mem_region(start,n,name))?1:0;
130 void can_release_mem_region(unsigned long start, unsigned long n)
132 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
135 release_mem_region(start,n);
139 /* This function shifts all base address structures acording to address
140 translation between physical and virtual address mappings */
141 int can_base_addr_fixup(struct candevice_t *candev, unsigned long new_base)
146 offs=new_base-candev->dev_base_addr;
147 candev->dev_base_addr=new_base;
148 for(i=0;i<candev->nr_all_chips;i++){
149 candev->chip[i]->chip_base_addr += offs;
150 for(j=0;j<candev->chip[i]->max_objects;j++)
151 candev->chip[i]->msgobj[j]->obj_base_addr += offs;
156 /* The function init_hw_struct is used to initialize the hardware structure. */
157 int init_hw_struct(void)
161 hardware_p->nr_boards=0;
162 while ( (hw[i] != NULL) & (i < MAX_HW_CARDS) ) {
163 hardware_p->nr_boards++;
165 if (init_device_struct(i)) {
166 CANMSG("Error initializing candevice_t structures.\n");
175 /* The function init_device_struct is used to initialize a single device
178 int init_device_struct(int card)
180 struct candevice_t *candev;
183 candev=(struct candevice_t *)can_checked_malloc(sizeof(struct candevice_t));
187 memset(candev, 0, sizeof(struct candevice_t));
189 hardware_p->candevice[card]=candev;
190 candev->candev_idx=card;
194 candev->hwname=hw[card];
195 candev->io_addr=io[card];
196 candev->dev_base_addr=io[card];
198 candev->hwspecops=(struct hwspecops_t *)can_checked_malloc(sizeof(struct hwspecops_t));
199 if (candev->hwspecops==NULL)
202 memset(candev->hwspecops, 0, sizeof(struct hwspecops_t));
204 if (init_hwspecops(candev))
207 if (candev->hwspecops->init_hw_data(candev))
210 if (init_chip_struct(candev))
216 candevice_done(candev);
224 hardware_p->candevice[card]=NULL;
225 can_checked_free(candev);
230 /* The function init_chip_struct is used to initialize all chip_t structures
231 * on one hardware board.
233 int init_chip_struct(struct candevice_t *candev)
235 static int irq_count=0;
238 /* Alocate and initialize the chip structures */
239 for (i=0; i < candev->nr_all_chips; i++) {
240 candev->chip[i]=(struct chip_t *)can_checked_malloc(sizeof(struct chip_t));
241 if (candev->chip[i]==NULL)
244 memset(candev->chip[i], 0, sizeof(struct chip_t));
246 candev->chip[i]->write_register=candev->hwspecops->write_register;
247 candev->chip[i]->read_register=candev->hwspecops->read_register;
249 candev->chip[i]->chipspecops=can_checked_malloc(sizeof(struct chipspecops_t));
250 if (candev->chip[i]->chipspecops==NULL)
253 chips_p[irq_count]=candev->chip[i];
254 candev->chip[i]->chip_idx=i;
255 candev->chip[i]->hostdevice=candev;
256 candev->chip[i]->chip_irq=irq[irq_count];
257 candev->chip[i]->baudrate=baudrate[irq_count]*1000;
258 if(!candev->chip[i]->baudrate)
259 candev->chip[i]->baudrate=baudrate[0]*1000;
260 candev->chip[i]->flags=0x0;
262 candev->hwspecops->init_chip_data(candev,i);
264 if (init_chipspecops(candev,i))
267 init_obj_struct(candev, candev->chip[i], minor[irq_count]);
275 int init_obj_struct(struct candevice_t *candev, struct chip_t *hostchip, int minorbase)
277 struct canque_ends_t *qends;
278 static int obj_count=0;
280 struct msgobj_t *obj;
282 max_objects=hostchip->max_objects;
283 for (i=0; i<max_objects; i++) {
284 obj=(struct msgobj_t *)can_checked_malloc(sizeof(struct msgobj_t));
285 hostchip->msgobj[i]=obj;
289 memset(obj, 0, sizeof(struct msgobj_t));
291 atomic_set(&obj->obj_used,0);
292 INIT_LIST_HEAD(&obj->obj_users);
293 init_timer(&obj->tx_timeout);
295 qends = (struct canque_ends_t *)can_checked_malloc(sizeof(struct canque_ends_t));
296 if(qends == NULL) return -ENOMEM;
297 memset(qends, 0, sizeof(struct canque_ends_t));
298 obj->hostchip=hostchip;
305 canqueue_ends_init_chip(qends, hostchip, obj);
307 if (minorbase == -1) minorbase=obj_count;
308 if ((minorbase >= 0) && (minorbase+i<MAX_TOT_MSGOBJS)){
309 objects_p[minorbase+i]=obj;
310 obj->minor=minorbase+i;
311 } else obj->minor=-1;
313 candev->hwspecops->init_obj_data(hostchip,i);
321 int init_hwspecops(struct candevice_t *candev)
323 const struct boardtype_t *brp;
325 brp = boardtype_find(candev->hwname);
328 CANMSG("Sorry, hardware \"%s\" is currently not supported.\n",candev->hwname);
332 brp->board_register(candev->hwspecops);
337 int init_chipspecops(struct candevice_t *candev, int chipnr)
339 if (!strcmp(candev->chip[chipnr]->chip_type,"i82527")) {
340 candev->chip[chipnr]->max_objects=15;
341 i82527_register(candev->chip[chipnr]->chipspecops);
343 if (!strcmp(candev->chip[chipnr]->chip_type,"sja1000")) {
344 candev->chip[chipnr]->max_objects=1;
345 sja1000_register(candev->chip[chipnr]->chipspecops);
347 if (!strcmp(candev->chip[chipnr]->chip_type,"sja1000p")) {
348 candev->chip[chipnr]->max_objects=1;
349 sja1000p_register(candev->chip[chipnr]->chipspecops);