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_hwspecops(struct candevice_t *candev, int *irqnum_p);
22 int init_device_struct(int card, int *chan_param_idx_p, int *irq_param_idx_p);
23 int init_chip_struct(struct candevice_t *candev, int chipnr, int irq, long baudrate);
24 int init_obj_struct(struct candevice_t *candev, struct chip_t *hostchip, int objnr);
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;
157 int register_obj_struct(struct msgobj_t *obj, int minorbase)
159 static int next_minor=0;
163 next_minor=minorbase;
164 if(next_minor>=MAX_TOT_MSGOBJS)
168 if(objects_p[i]==NULL){
174 if(++i >= MAX_TOT_MSGOBJS) i=0;
175 }while(i!=next_minor);
181 int register_chip_struct(struct chip_t *chip, int minorbase)
183 static int next_chip_slot=0;
186 if(next_chip_slot>=MAX_TOT_CHIPS)
190 if(chips_p[i]==NULL){
196 if(++i >= MAX_TOT_CHIPS) i=0;
197 }while(i!=next_chip_slot);
202 /* The function init_hw_struct is used to initialize the hardware structure. */
203 int init_hw_struct(void)
207 int chan_param_idx=0;
209 hardware_p->nr_boards=0;
210 while ( (hw[i] != NULL) & (i < MAX_HW_CARDS) ) {
211 hardware_p->nr_boards++;
213 if (init_device_struct(i, &chan_param_idx, &irq_param_idx)) {
214 CANMSG("Error initializing candevice_t structures.\n");
223 /* The function init_device_struct is used to initialize a single device
226 int init_device_struct(int card, int *chan_param_idx_p, int *irq_param_idx_p)
228 struct candevice_t *candev;
235 candev=(struct candevice_t *)can_checked_malloc(sizeof(struct candevice_t));
239 memset(candev, 0, sizeof(struct candevice_t));
241 hardware_p->candevice[card]=candev;
242 candev->candev_idx=card;
246 candev->hwname=hw[card];
247 candev->io_addr=io[card];
248 candev->dev_base_addr=io[card];
250 candev->hwspecops=(struct hwspecops_t *)can_checked_malloc(sizeof(struct hwspecops_t));
251 if (candev->hwspecops==NULL)
254 memset(candev->hwspecops, 0, sizeof(struct hwspecops_t));
256 if (init_hwspecops(candev, &irqnum))
259 if (candev->hwspecops->init_hw_data(candev))
262 /* Alocate and initialize the chip structures */
263 for (chipnr=0; chipnr < candev->nr_all_chips; chipnr++) {
266 irqsig=irq[*irq_param_idx_p+chipnr];
268 bd=baudrate[*chan_param_idx_p+chipnr];
269 if(!bd) bd=baudrate[0];
271 if ((ret=init_chip_struct(candev, chipnr, irqsig, bd*1000)))
277 for (chipnr=0; chipnr < candev->nr_all_chips; chipnr++) {
278 int m=minor[*chan_param_idx_p+chipnr];
279 struct chip_t *chip=candev->chip[chipnr];
282 register_chip_struct(chip, m);
284 for (objnr=0; objnr<chip->max_objects; objnr++) {
285 register_obj_struct(chip->msgobj[objnr], m);
290 *irq_param_idx_p += irqnum;
291 *chan_param_idx_p += candev->nr_all_chips;
298 candevice_done(candev);
305 hardware_p->candevice[card]=NULL;
306 can_checked_free(candev);
311 /* The function init_chip_struct is used to initialize all chip_t structures
312 * on one hardware board.
314 int init_chip_struct(struct candevice_t *candev, int chipnr, int irq, long baudrate)
320 candev->chip[chipnr]=(struct chip_t *)can_checked_malloc(sizeof(struct chip_t));
321 if ((chip=candev->chip[chipnr])==NULL)
324 memset(chip, 0, sizeof(struct chip_t));
326 chip->write_register=candev->hwspecops->write_register;
327 chip->read_register=candev->hwspecops->read_register;
329 chip->chipspecops=can_checked_malloc(sizeof(struct chipspecops_t));
330 if (chip->chipspecops==NULL)
333 chip->chip_idx=chipnr;
334 chip->hostdevice=candev;
336 chip->baudrate=baudrate;
339 candev->hwspecops->init_chip_data(candev,chipnr);
341 if (init_chipspecops(candev,chipnr))
344 for (objnr=0; objnr<chip->max_objects; objnr++) {
345 ret=init_obj_struct(candev, chip, objnr);
346 if(ret<0) return ret;
353 int init_obj_struct(struct candevice_t *candev, struct chip_t *hostchip, int objnr)
355 struct canque_ends_t *qends;
356 struct msgobj_t *obj;
359 obj=(struct msgobj_t *)can_checked_malloc(sizeof(struct msgobj_t));
360 hostchip->msgobj[objnr]=obj;
364 memset(obj, 0, sizeof(struct msgobj_t));
367 atomic_set(&obj->obj_used,0);
368 INIT_LIST_HEAD(&obj->obj_users);
369 init_timer(&obj->tx_timeout);
371 qends = (struct canque_ends_t *)can_checked_malloc(sizeof(struct canque_ends_t));
372 if(qends == NULL) return -ENOMEM;
373 memset(qends, 0, sizeof(struct canque_ends_t));
374 obj->hostchip=hostchip;
379 obj->obj_flags = 0x0;
381 ret=canqueue_ends_init_chip(qends, hostchip, obj);
382 if(ret<0) return ret;
384 ret=candev->hwspecops->init_obj_data(hostchip,objnr);
385 if(ret<0) return ret;
391 int init_hwspecops(struct candevice_t *candev, int *irqnum_p)
393 const struct boardtype_t *brp;
395 brp = boardtype_find(candev->hwname);
398 CANMSG("Sorry, hardware \"%s\" is currently not supported.\n",candev->hwname);
403 *irqnum_p=brp->irqnum;
404 brp->board_register(candev->hwspecops);
410 int init_chipspecops(struct candevice_t *candev, int chipnr)
412 if (!strcmp(candev->chip[chipnr]->chip_type,"i82527")) {
413 candev->chip[chipnr]->max_objects=15;
414 i82527_register(candev->chip[chipnr]->chipspecops);
416 if (!strcmp(candev->chip[chipnr]->chip_type,"sja1000")) {
417 candev->chip[chipnr]->max_objects=1;
418 sja1000_register(candev->chip[chipnr]->chipspecops);
420 if (!strcmp(candev->chip[chipnr]->chip_type,"sja1000p")) {
421 candev->chip[chipnr]->max_objects=1;
422 sja1000p_register(candev->chip[chipnr]->chipspecops);
430 int can_chip_setup_irq(struct chip_t *chip)
434 if(!chip->chipspecops->irq_handler)
437 if (request_irq(chip->chip_irq,chip->chipspecops->irq_handler,SA_SHIRQ,DEVICE_NAME,chip))
440 DEBUGMSG("Registered interrupt %d\n",chip->chip_irq);
441 chip->flags |= CHIP_IRQ_SETUP;
447 void can_chip_free_irq(struct chip_t *chip)
449 if((chip->flags & CHIP_IRQ_SETUP) && (chip->chip_irq>=0)) {
450 free_irq(chip->chip_irq, chip);
451 chip->flags &= ~CHIP_IRQ_SETUP;
455 #endif /*CAN_WITH_RTL*/