]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/unican.c
Merge: Changes, which should enable to handle more VME Unican cards under RT-Linux.
[lincan.git] / lincan / src / unican.c
1 /* unican.c
2  * Linux CAN-bus device driver.
3  * Written for new CAN driver version by Pavel Pisa - OCERA team member
4  * email:pisa@cmp.felk.cvut.cz
5  * This software is released under the GPL-License.
6  * Version lincan-0.3  17 Jun 2004
7  */ 
8
9 #include "../include/can.h"
10 #include "../include/can_sysdep.h"
11 #include "../include/main.h"
12 #include "../include/unican_cl2.h"
13 #include "../include/setup.h"
14
15 #define UNICAN_PCI_VENDOR  0xFA3C
16 #define UNICAN_PCI_ID      0x0101
17
18 static void unican_delay(long msdelay)
19 {
20     #ifdef CAN_WITH_RTL
21         if(!rtl_rt_system_is_idle()) {
22                 rtl_delay(1000000l*msdelay);
23         }else
24     #endif /*CAN_WITH_RTL*/
25         {
26                 set_current_state(TASK_UNINTERRUPTIBLE);
27                 schedule_timeout((msdelay*HZ)/1000+1);
28         }
29
30 }
31
32
33 long unican_bus_latency(struct msgobj_t *obj)
34 {
35         long latency;
36         latency=obj->hostchip->baudrate;
37         if(latency){
38                 latency=(long)HZ*1000/latency;
39         }
40         return latency;
41 }
42
43
44 /* * * unican Chip Functionality * * */
45
46 int unican_enable_configuration(struct canchip_t *chip)
47 {
48         return 0;
49 }
50
51 int unican_disable_configuration(struct canchip_t *chip)
52 {
53         return 0;
54 }
55
56 /**
57  * unican_chip_config: - can chip configuration
58  * @chip: pointer to chip state structure
59  *
60  * Return Value: negative value reports error.
61  * File: src/unican.c
62  */
63 int unican_chip_config(struct canchip_t *chip)
64 {
65         int ret;
66         sCAN_CARD *chipext = (sCAN_CARD *)chip->chip_data;
67
68         unican_delay(10);
69         
70         /* disable all card interrupts */
71         ret = cl2_int_mode(chipext, INT_MODE_ALL*0);
72         if(ret != CL2_OK) {
73                 CANMSG("disable interrupts by cl2_iit_mode returned %d\n",ret);
74                 return -ENODEV;
75         }
76         unican_delay(1);
77
78         if (chip->baudrate == 0)
79                 chip->baudrate=1000000;
80                 
81         ret = chip->chipspecops->baud_rate(chip,chip->baudrate,chip->clock,0,75,0);
82         if(ret < 0){
83                 CANMSG("can not set baudrate\n");
84                 return ret;
85         }
86         
87         unican_delay(2);
88         /* set interrupt inhibit time to 1 ms */
89         ret = cl2_set_iit(chipext, 10);
90         if(ret != CL2_OK) {
91                 CANMSG("cl2_set_iit returned %d\n",ret);
92                 return -ENODEV;
93         }
94         unican_delay(1);
95
96         /* enable start interrupt inhibit time command */
97         ret = cl2_iit_mode(chipext, 1);
98         if(ret != CL2_OK) {
99                 CANMSG("cl2_iit_mode returned %d\n",ret);
100                 return -ENODEV;
101         }
102         unican_delay(1);
103         
104         /* enable all card interrupts */
105         ret = cl2_int_mode(chipext, INT_MODE_ALL);
106         if(ret != CL2_OK) {
107                 CANMSG("cl2_iit_mode returned %d\n",ret);
108                 return -ENODEV;
109         }
110         unican_delay(1);
111
112         /* generate interrupt command */
113         cl2_gen_interrupt(chipext);
114
115
116         return 0;
117 }
118
119 /**
120  * unican_extended_mask: - setup of extended mask for message filtering
121  * @chip: pointer to chip state structure
122  * @code: can message acceptance code
123  * @mask: can message acceptance mask
124  *
125  * Return Value: negative value reports error.
126  * File: src/unican.c
127  */
128 int unican_extended_mask(struct canchip_t *chip, unsigned long code, unsigned  long mask)
129 {
130         return 0;
131 }
132
133 /**
134  * unican_baud_rate: - set communication parameters.
135  * @chip: pointer to chip state structure
136  * @rate: baud rate in Hz
137  * @clock: frequency of sja1000 clock in Hz (ISA osc is 14318000)
138  * @sjw: synchronization jump width (0-3) prescaled clock cycles
139  * @sampl_pt: sample point in % (0-100) sets (TSEG1+1)/(TSEG1+TSEG2+2) ratio
140  * @flags: fields %BTR1_SAM, %OCMODE, %OCPOL, %OCTP, %OCTN, %CLK_OFF, %CBP
141  *
142  * Return Value: negative value reports error.
143  * File: src/unican.c
144  */
145 int unican_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
146                                                         int sampl_pt, int flags)
147 {
148         int ret;
149         sCAN_CARD *chipext = (sCAN_CARD *)chip->chip_data;
150         int bt_val;
151
152         switch (rate) {
153                 case 5000:   bt_val = CL2_BITRATE_5K; break;
154                 case 10000:  bt_val = CL2_BITRATE_10K; break;
155                 case 20000:  bt_val = CL2_BITRATE_20K; break;
156                 case 50000:  bt_val = CL2_BITRATE_50K; break;
157                 case 100000: bt_val = CL2_BITRATE_100K; break;
158                 case 125000: bt_val = CL2_BITRATE_125K; break;
159                 case 200000: bt_val = CL2_BITRATE_200K; break;
160                 case 250000: bt_val = CL2_BITRATE_250K; break;
161                 case 500000: bt_val = CL2_BITRATE_500K; break;
162                 case 800000: bt_val = CL2_BITRATE_800K; break;
163                 case 1000000:bt_val = CL2_BITRATE_1M; break;
164                 default: return -EINVAL;
165         }
166         
167         ret=cl2_set_bitrate(chipext,bt_val);
168         if(ret == CL2_COMMAND_BUSY) return -EBUSY;
169         if(ret != CL2_OK) return -EINVAL;
170         unican_delay(2);
171         
172         return 0;
173 }
174
175 /**
176  * unican_read: - reads and distributes one or more received messages
177  * @chip: pointer to chip state structure
178  * @obj: pinter to CAN message queue information
179  *
180  * This is rewritten cl2_receive_data function. The direct use of CL2
181  * function would require one more message data copy to reformat message
182  * data into different structure layout. Other way is to rewrite CL2 sources.
183  * No of these solutions is perfect.
184  *
185  * File: src/unican.c
186  */
187 void unican_read(struct canchip_t *chip, struct msgobj_t *obj) {
188         sCAN_CARD *chipext = (sCAN_CARD *)chip->chip_data;
189         __u16 *ptr16;
190         __u16 u;
191         unsigned long timestamp;
192         int i;
193
194         do {
195                 ptr16 = (__u16*)chipext->rxBufPtr;
196                 u = unican_readw(ptr16++);
197                 if ( !(u & CL2_MESSAGE_VALID) ) break; /* No more messages in the queue */
198
199                 obj->rx_msg.id = ((__u32)(u & 0xFF00 )) << 16;
200                 u = unican_readw(ptr16++);
201                 obj->rx_msg.id |= ((__u32)( u & 0x00FF )) << 16;
202                 obj->rx_msg.id |= (__u32)( u & 0xFF00 );
203                 u = unican_readw(ptr16++);
204                 obj->rx_msg.id |= (__u32)( u & 0x00FF );
205
206
207                 u >>= 8;
208
209                 if ( u & CL2_EXT_FRAME ) {      /* 2.0B frame */
210                         obj->rx_msg.id >>= 3;
211                         obj->rx_msg.flags = MSG_EXT;
212                 } else {                        /* 2.0A frame */
213                         obj->rx_msg.id >>= 21;
214                         obj->rx_msg.flags = 0;
215                 }
216
217                 /*if ( !(u & (CL2_REMOTE_FRAME<<8)) ) 
218                         obj->rx_msg.flags |= MSG_RTR;*/
219
220                 obj->rx_msg.length = ( (u >> 4) & 0x000F );
221                 if(obj->rx_msg.length > CAN_MSG_LENGTH) obj->rx_msg.length = CAN_MSG_LENGTH;
222
223                 for ( i = 0; i < obj->rx_msg.length; ) {
224                         u = unican_readw(ptr16++);
225                         obj->rx_msg.data[i++] = (__u8)( u );
226                         obj->rx_msg.data[i++] = (__u8)( u >> 8 );
227                 }
228                 if ( obj->rx_msg.length & 0x01 ) {      /* odd */
229                         timestamp = ( (unican_readw(ptr16++) & 0x00FF) | (u & 0xFF00) );
230                 } else {                                /* even */
231                         u = unican_readw(ptr16++);
232                         timestamp = (u << 8) | (u >> 8);
233                 }
234                 unican_writew(0x000,(__u16*)chipext->rxBufPtr);
235
236                #ifdef CAN_MSG_VERSION_2
237                 obj->rx_msg.timestamp.tv_sec = 0;
238                 obj->rx_msg.timestamp.tv_usec = timestamp;
239                #else /* CAN_MSG_VERSION_2 */
240                 obj->rx_msg.timestamp = timestamp;
241                #endif /* CAN_MSG_VERSION_2 */
242                
243                 /* increment rx-buffer pointer */
244                 if ( (chipext->rxBufBase + chipext->rxBufSize*16 ) <= (chipext->rxBufPtr += 16) ) {
245                         chipext->rxBufPtr = chipext->rxBufBase;
246                 }
247
248                 canque_filter_msg2edges(obj->qends, &obj->rx_msg);
249
250         } while (1);
251 }
252
253 /**
254  * unican_pre_read_config: - prepares message object for message reception
255  * @chip: pointer to chip state structure
256  * @obj: pointer to message object state structure
257  *
258  * Return Value: negative value reports error.
259  *      Positive value indicates immediate reception of message.
260  * File: src/unican.c
261  */
262 int unican_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj)
263 {
264         return 0;
265 }
266
267 #define MAX_TRANSMIT_WAIT_LOOPS 10
268 /**
269  * unican_pre_write_config: - prepares message object for message transmission
270  * @chip: pointer to chip state structure
271  * @obj: pointer to message object state structure
272  * @msg: pointer to CAN message
273  *
274  * Return Value: negative value reports error.
275  * File: src/unican.c
276  */
277 int unican_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, 
278                                                         struct canmsg_t *msg)
279 {
280         return 0;
281 }
282
283 /**
284  * unican_send_msg: - initiate message transmission
285  * @chip: pointer to chip state structure
286  * @obj: pointer to message object state structure
287  * @msg: pointer to CAN message
288  *
289  * This function is called after unican_pre_write_config() function,
290  * which prepares data in chip buffer.
291  * Return Value: negative value reports error.
292  * File: src/unican.c
293  */
294 int unican_send_msg(struct canchip_t *chip, struct msgobj_t *obj, 
295                                                         struct canmsg_t *msg)
296 {
297         return 0;
298 }
299
300 /**
301  * unican_check_tx_stat: - checks state of transmission engine
302  * @chip: pointer to chip state structure
303  *
304  * Return Value: negative value reports error.
305  *      Positive return value indicates transmission under way status.
306  *      Zero value indicates finishing of all issued transmission requests.
307  * File: src/unican.c
308  */
309 int unican_check_tx_stat(struct canchip_t *chip)
310 {
311         return 0;
312 }
313
314 /**
315  * unican_set_btregs: -  configures bitrate registers
316  * @chip: pointer to chip state structure
317  * @btr0: bitrate register 0
318  * @btr1: bitrate register 1
319  *
320  * Return Value: negative value reports error.
321  * File: src/unican.c
322  */
323 int unican_set_btregs(struct canchip_t *chip, unsigned short btr0, 
324                                                         unsigned short btr1)
325 {
326         int ret;
327         sCAN_CARD *chipext = (sCAN_CARD *)chip->chip_data;
328         int bt_val;
329
330         bt_val=btr0 | (btr1<<8);
331         ret=cl2_set_bitrate(chipext,bt_val);
332         if(ret == CL2_COMMAND_BUSY) return -EBUSY;
333         if(ret != CL2_OK) return -EINVAL;
334
335         return 0;
336 }
337
338 /**
339  * unican_stop_chip: -  starts chip message processing
340  * @chip: pointer to chip state structure
341  *
342  * Return Value: negative value reports error.
343  * File: src/unican.c
344  */
345 int unican_start_chip(struct canchip_t *chip)
346 {
347         return 0;
348 }
349
350 /**
351  * unican_stop_chip: -  stops chip message processing
352  * @chip: pointer to chip state structure
353  *
354  * Return Value: negative value reports error.
355  * File: src/unican.c
356  */
357 int unican_stop_chip(struct canchip_t *chip)
358 {
359         return 0;
360 }
361
362
363 /**
364  * unican_remote_request: - configures message object and asks for RTR message
365  * @chip: pointer to chip state structure
366  * @obj: pointer to message object structure
367  *
368  * Return Value: negative value reports error.
369  * File: src/unican.c
370  */
371 int unican_remote_request(struct canchip_t *chip, struct msgobj_t *obj)
372 {
373         CANMSG("unican_remote_request not implemented\n");
374         return -ENOSYS;
375 }
376
377 /**
378  * unican_standard_mask: - setup of mask for message filtering
379  * @chip: pointer to chip state structure
380  * @code: can message acceptance code
381  * @mask: can message acceptance mask
382  *
383  * Return Value: negative value reports error.
384  * File: src/unican.c
385  */
386 int unican_standard_mask(struct canchip_t *chip, unsigned short code,
387                 unsigned short mask)
388 {
389         CANMSG("unican_standard_mask not implemented\n");
390         return -ENOSYS;
391 }
392
393 /**
394  * unican_clear_objects: - clears state of all message object residing in chip
395  * @chip: pointer to chip state structure
396  *
397  * Return Value: negative value reports error.
398  * File: src/unican.c
399  */
400 int unican_clear_objects(struct canchip_t *chip)
401 {
402         CANMSG("unican_clear_objects not implemented\n");
403         return -ENOSYS;
404 }
405
406 /**
407  * unican_config_irqs: - tunes chip hardware interrupt delivery
408  * @chip: pointer to chip state structure
409  * @irqs: requested chip IRQ configuration
410  *
411  * Return Value: negative value reports error.
412  * File: src/unican.c
413  */
414 int unican_config_irqs(struct canchip_t *chip, short irqs)
415 {
416
417         CANMSG("unican_config_irqs not implemented\n");
418         return -ENOSYS;
419 }
420
421 /**
422  * unican_irq_write_handler: - part of ISR code responsible for transmit events
423  * @chip: pointer to chip state structure
424  * @obj: pointer to attached queue description
425  *
426  * The main purpose of this function is to read message from attached queues
427  * and transfer message contents into CAN controller chip.
428  * This subroutine is called by
429  * unican_irq_write_handler() for transmit events.
430  * File: src/unican.c
431  */
432 void unican_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
433 {
434         int cmd;
435         sCAN_CARD *chipext = (sCAN_CARD *)chip->chip_data;
436         __u16 *ptr16 = (__u16*)chipext->rxBufPtr;
437         __u16 u;
438         unsigned long timestamp=0;
439         unsigned long cobid;
440         int i;
441         int len;
442
443        #if 0
444         if(obj->tx_slot){
445                 /* Do local transmitted message distribution if enabled */
446                 if (processlocal){
447                         obj->tx_slot->msg.flags |= MSG_LOCAL;
448                         canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
449                 }
450                 /* Free transmitted slot */
451                 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
452                 obj->tx_slot=NULL;
453         }
454        #endif
455
456         if ( chipext->asyncTxBufSize==0 ) {
457                 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_PREP);
458                 return; /* No asynchronous queue configured */
459         }
460
461         do {
462                 ptr16 = (__u16*)chipext->asyncTxBufPtr;
463                 if(unican_readw(ptr16) & CL2_MESSAGE_VALID)
464                         return;         /* No free space in asynchronous Tx queue */
465
466                 cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
467                 if(cmd<0)
468                         return;         /* No more messages to send */
469                 
470
471                 cobid = obj->tx_slot->msg.id;
472                 
473                 if ( (obj->tx_slot->msg.flags & MSG_EXT) ) {    /* 2.0B frame */
474                         cobid <<= 3;
475                 } else {                                        /* 2.0A frame */
476                         cobid <<= 5+16;
477                 }
478                 ptr16++;
479                 u = ((cobid>>16) & 0x00FF ) + (cobid & 0xFF00);
480                 unican_writew(u,ptr16++);
481
482                 len = obj->tx_slot->msg.length;
483                 if(len > CAN_MSG_LENGTH)
484                         len = CAN_MSG_LENGTH;
485                 u = (len << 12) | (cobid & 0x00FF);
486                 
487                 if ( !(obj->tx_slot->msg.flags & MSG_RTR) ) 
488                         u |= CL2_REMOTE_FRAME<<8;
489                 if ( obj->tx_slot->msg.flags & MSG_EXT ) 
490                         u |= CL2_EXT_FRAME<<8;
491
492                 unican_writew(u,ptr16++);
493
494                 for ( i = 0; i < len-1; )       {
495                         u = obj->tx_slot->msg.data[i++];
496                         u |= ((__u16)obj->tx_slot->msg.data[i]<<8); i++;
497                         unican_writew(u,ptr16++);
498                 }
499                 if(i == len) {
500                         unican_writew(timestamp,ptr16);
501                 } else {
502                         u = obj->tx_slot->msg.data[i++];
503                         u |= ((timestamp & 0x00FF)<<8);
504                         unican_writew(u,ptr16++);
505                         unican_writew(timestamp & 0x00FF, ptr16);
506                 }
507
508                 u = ((cobid>>16) & 0xFF00) | CL2_MESSAGE_VALID;
509                 unican_writew(u,(__u16*)chipext->asyncTxBufPtr);
510
511                 if ( (chipext->asyncTxBufBase + chipext->asyncTxBufSize*16) <= 
512                                                 (chipext->asyncTxBufPtr += 16) ) {
513                         chipext->asyncTxBufPtr = chipext->asyncTxBufBase;
514                 }
515
516
517                 /* Do local transmitted message distribution if enabled. */
518                 /* This code should not be called directly there, because it breaks strict
519                    behavior of queues if O_SYNC is set. */
520                 if (processlocal){
521                         obj->tx_slot->msg.flags |= MSG_LOCAL;
522                         canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
523                 }
524                 /* Free transmitted slot */
525                 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
526                 obj->tx_slot=NULL;
527         
528         }while(1);
529         
530         return;
531
532 }
533
534 void unican_irq_sync_activities(struct canchip_t *chip, struct msgobj_t *obj)
535 {
536         while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)) {
537
538                 if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST)) {
539                         unican_irq_write_handler(chip, obj);
540                 }
541
542                 /*if(can_msgobj_test_and_clear_fl(obj,FILTCH_REQUEST)) {
543                         unican_irq_update_filter(chip, obj);
544                 }*/
545
546                 can_msgobj_clear_fl(obj,TX_LOCK);
547                 if(can_msgobj_test_fl(obj,TX_REQUEST))
548                         continue;
549                 if(can_msgobj_test_fl(obj,FILTCH_REQUEST) && !obj->tx_slot)
550                         continue;
551                 break;
552         }
553 }
554
555
556 #define MAX_RETR 10
557
558 /**
559  * unican_irq_handler: - interrupt service routine
560  * @irq: interrupt vector number, this value is system specific
561  * @chip: pointer to chip state structure
562  * 
563  * Interrupt handler is activated when state of CAN controller chip changes,
564  * there is message to be read or there is more space for new messages or
565  * error occurs. The receive events results in reading of the message from
566  * CAN controller chip and distribution of message through attached
567  * message queues.
568  * File: src/unican.c
569  */
570 int unican_irq_handler(int irq, struct canchip_t *chip)
571 {
572         sCAN_CARD *chipext = (sCAN_CARD *)chip->chip_data;
573         struct msgobj_t *obj=chip->msgobj[0];
574         __u16 status;
575         __u16 error;
576
577         if(!(chip->flags&CHIP_CONFIGURED)) {
578                 CANMSG("unican_irq_handler: called for non-configured device\n");
579                 return CANCHIP_IRQ_NONE;
580         }
581
582         if (cl2_get_status(chipext, &status) == CL2_NO_REQUEST) {
583                 /* Reenable interrupts generation, this has to be even there, 
584                  * because irq_accept disables interrupts
585                  */
586                 cl2_gen_interrupt(chipext);
587                 return CANCHIP_IRQ_NONE;
588         }
589
590         cl2_clear_interrupt(chipext);
591
592
593         if(status & CL2_CARD_ERROR) {
594                 cl2_get_error(chipext, &error);
595                 CANMSG("unican_irq_handler: card status=0x%04x error=0x%04x \n",status,error);
596         }
597         if(status & CL2_ASYNC_QUEUE_EMPTY) {
598
599         }
600         if(status & CL2_SYNC_QUEUE_EMPTY) {
601                 can_msgobj_set_fl(obj,TX_REQUEST);
602
603                 /* calls unican_irq_write_handler synchronized with other invocations */
604                 unican_irq_sync_activities(chip, obj);
605
606         }
607         if(status & CL2_DATA_IN_RBUF) {
608                 unican_read(chip, obj);
609         }
610
611         /* Reenable interrupts generation */
612         cl2_gen_interrupt(chipext);
613
614         return CANCHIP_IRQ_HANDLED;
615 }
616
617
618 /**
619  * unican_irq_accept: - fast irq accept routine, blocks further interrupts
620  * @irq: interrupt vector number, this value is system specific
621  * @chip: pointer to chip state structure
622  * 
623  * This routine only accepts interrupt reception and stops further
624  * incoming interrupts, but does not handle situation causing interrupt.
625  * File: src/unican.c
626  */
627 int unican_irq_accept(int irq, struct canchip_t *chip)
628 {
629         sCAN_CARD *chipext = (sCAN_CARD *)chip->chip_data;
630
631         cl2_clear_interrupt(chipext);
632
633         return CANCHIP_IRQ_ACCEPTED;
634 }
635
636 /*void unican_do_tx_timeout(unsigned long data)
637 {
638         struct msgobj_t *obj=(struct msgobj_t *)data;
639         
640 }*/
641
642 /**
643  * unican_wakeup_tx: - wakeups TX processing
644  * @chip: pointer to chip state structure
645  * @obj: pointer to message object structure
646  *
647  * Return Value: negative value reports error.
648  * File: src/unican.c
649  */
650 int unican_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
651 {
652         can_preempt_disable();
653
654         can_msgobj_set_fl(obj,TX_REQUEST);
655
656         /* calls unican_irq_write_handler synchronized with other invocations
657           from kernel and IRQ context */
658         unican_irq_sync_activities(chip, obj);
659
660         can_preempt_enable();
661
662         return 0;
663 }
664
665
666 /* * * unican Board Functionality * * */
667
668 #define IO_RANGE 0x1000
669
670 /**
671  * unican_request_io: - reserve io or memory range for can board
672  * @candev: pointer to candevice/board which asks for io. Field @io_addr
673  *      of @candev is used in most cases to define start of the range
674  *
675  * Return Value: The function returns zero on success or %-ENODEV on failure
676  * File: src/unican.c
677  */
678 int unican_request_io(struct candevice_t *candev)
679 {
680         unsigned long remap_addr;
681         if (!can_request_mem_region(candev->io_addr,IO_RANGE,DEVICE_NAME " - unican")) {
682                 CANMSG("Unable to request IO-memory: 0x%lx\n",candev->io_addr);
683                 return -ENODEV;
684         }
685         if ( !( remap_addr = (long) ioremap( candev->io_addr, IO_RANGE ) ) ) {
686                 CANMSG("Unable to access I/O memory at: 0x%lx\n", candev->io_addr);
687                 can_release_mem_region(candev->io_addr,IO_RANGE);
688                 return -ENODEV;
689         
690         }
691         can_base_addr_fixup(candev, remap_addr);
692         DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", candev->io_addr, candev->io_addr + IO_RANGE - 1);
693         return 0;
694 }
695
696 /**
697  * unican_elease_io - free reserved io memory range
698  * @candev: pointer to candevice/board which releases io
699  *
700  * Return Value: The function always returns zero
701  * File: src/unican.c
702  */
703 int unican_release_io(struct candevice_t *candev)
704 {
705         iounmap((void*)candev->dev_base_addr);
706         can_release_mem_region(candev->io_addr,IO_RANGE);
707         return 0;
708 }
709
710 /**
711  * unican_reset - hardware reset routine
712  * @candev: Pointer to candevice/board structure
713  *
714  * Return Value: The function returns zero on success or %-ENODEV on failure
715  * File: src/unican.c
716  */
717 int unican_reset(struct candevice_t *candev)
718 {
719         int ret;
720         int i;
721         struct canchip_t *chip = candev->chip[0];
722         sCAN_CARD *chipext;
723         
724
725         if(chip->chip_data == NULL) {
726                 chip->chip_data = can_checked_malloc(sizeof(sCAN_CARD));
727                 if(!chip->chip_data) return -ENOMEM;
728                 memset(chip->chip_data,0,sizeof(sCAN_CARD));
729                 ret = cl2_init_card(chip->chip_data,(void*)chip->chip_base_addr,chip->chip_irq);
730                 if(ret != CL2_OK){
731                         CANMSG("cl2_init_card returned %d\n",ret);
732                         return -ENODEV;
733                 }
734         }
735         
736         chipext = (sCAN_CARD *)chip->chip_data;
737                 
738         i = 0;
739         /* reset and test whether the card is present */
740         do {
741                 cl2_reset_card(chipext);
742                 unican_delay(10);
743                 i++;
744                 ret = cl2_test_card(chipext);
745         } while((ret != CL2_OK)&&(i<10));
746
747         if(ret != CL2_OK) {
748                 CANMSG("card check failed %d\n",ret);
749                 return -ENODEV;
750         }
751         
752         /* start card firmware */
753         ret = cl2_start_firmware(chipext);
754         if(ret != CL2_OK){
755                 CANMSG("cl2_start_firmware returned %d\n",ret);
756                 return -ENODEV;
757         }
758         
759         unican_delay(100);
760
761         return 0;
762 }
763
764 /**
765  * unican_init_hw_data - Initialize hardware cards
766  * @candev: Pointer to candevice/board structure
767  *
768  * Return Value: The function always returns zero
769  * File: src/unican.c
770  */
771 int unican_init_hw_data(struct candevice_t *candev) 
772 {
773         candev->res_addr=0;
774         candev->nr_82527_chips=0;
775         candev->nr_sja1000_chips=0;
776         candev->nr_all_chips=1;
777         candev->flags |= CANDEV_PROGRAMMABLE_IRQ*0;
778
779         return 0;
780 }
781
782 /**
783  * unican_init_chip_data - Initialize chips
784  * @candev: Pointer to candevice/board structure
785  * @chipnr: Number of the CAN chip on the hardware card
786  *
787  * Return Value: The function always returns zero
788  * File: src/unican.c
789  */
790 int unican_init_chip_data(struct candevice_t *candev, int chipnr)
791 {
792         struct canchip_t *chip = candev->chip[chipnr];
793         chip->chip_type = "unican";
794         chip->chip_base_addr = 0;
795         chip->clock = 10000000;
796         chip->int_clk_reg = 0x0;
797         chip->int_bus_reg = 0x0;
798         chip->max_objects = 1;
799         chip->chip_base_addr=candev->io_addr;
800                         
801         CANMSG("initializing unican chip operations\n");
802         chip->chipspecops->chip_config=unican_chip_config;
803         chip->chipspecops->baud_rate=unican_baud_rate;
804         chip->chipspecops->standard_mask=unican_standard_mask;
805         chip->chipspecops->extended_mask=unican_extended_mask;
806         chip->chipspecops->message15_mask=unican_extended_mask;
807         chip->chipspecops->clear_objects=unican_clear_objects;
808         chip->chipspecops->config_irqs=unican_config_irqs;
809         chip->chipspecops->pre_read_config=unican_pre_read_config;
810         chip->chipspecops->pre_write_config=unican_pre_write_config;
811         chip->chipspecops->send_msg=unican_send_msg;
812         chip->chipspecops->check_tx_stat=unican_check_tx_stat;
813         chip->chipspecops->wakeup_tx=unican_wakeup_tx;
814         chip->chipspecops->remote_request=unican_remote_request;
815         chip->chipspecops->enable_configuration=unican_enable_configuration;
816         chip->chipspecops->disable_configuration=unican_disable_configuration;
817         chip->chipspecops->set_btregs=unican_set_btregs;
818         chip->chipspecops->start_chip=unican_start_chip;
819         chip->chipspecops->stop_chip=unican_stop_chip;
820         chip->chipspecops->irq_handler=unican_irq_handler;
821         chip->chipspecops->irq_accept=unican_irq_accept;
822
823         return 0;
824 }
825
826 /**
827  * unican_init_obj_data - Initialize message buffers
828  * @chip: Pointer to chip specific structure
829  * @objnr: Number of the message buffer
830  *
831  * Return Value: The function always returns zero
832  * File: src/unican.c
833  */
834 int unican_init_obj_data(struct canchip_t *chip, int objnr)
835 {
836         struct msgobj_t *obj=chip->msgobj[objnr];
837         obj->obj_base_addr=chip->chip_base_addr;
838         /*obj->tx_timeout.function=unican_do_tx_timeout;
839         obj->tx_timeout.data=(unsigned long)obj;*/
840         return 0;
841 }
842
843 /**
844  * unican_program_irq - program interrupts
845  * @candev: Pointer to candevice/board structure
846  *
847  * Return value: The function returns zero on success or %-ENODEV on failure
848  * File: src/unican.c
849  */
850 int unican_program_irq(struct candevice_t *candev)
851 {
852         return 0;
853 }
854
855 int unican_register(struct hwspecops_t *hwspecops)
856 {
857         hwspecops->request_io = unican_request_io;
858         hwspecops->release_io = unican_release_io;
859         hwspecops->reset = unican_reset;
860         hwspecops->init_hw_data = unican_init_hw_data;
861         hwspecops->init_chip_data = unican_init_chip_data;
862         hwspecops->init_obj_data = unican_init_obj_data;
863         hwspecops->write_register = NULL;
864         hwspecops->read_register = NULL;
865         hwspecops->program_irq = unican_program_irq;
866         return 0;
867 }
868
869
870 /* Unicontrols PCI board specific functions */
871
872 #ifdef CAN_ENABLE_PCI_SUPPORT
873
874 int unican_pci_request_io(struct candevice_t *candev)
875 {
876         unsigned long remap_addr;
877
878     #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
879         if(pci_request_region(candev->sysdevptr.pcidev, 0, "unican_pci") != 0){
880                 CANMSG("Request of Unican PCI range failed\n");
881                 return -ENODEV;
882         }
883     #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
884         if(pci_request_regions(candev->sysdevptr.pcidev, "kv_pcican") != 0){
885                 CANMSG("Request of Unican PCI range failed\n");
886                 return -ENODEV;
887         }
888     #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
889
890         candev->dev_base_addr=pci_resource_start(candev->sysdevptr.pcidev,0);
891         candev->io_addr=candev->dev_base_addr;
892         candev->res_addr=candev->dev_base_addr;
893
894         if ( !( remap_addr = (long) ioremap( candev->io_addr, IO_RANGE ) ) ) {
895                 CANMSG("Unable to access I/O memory at: 0x%lx\n", candev->io_addr);
896             #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
897                 pci_release_region(candev->sysdevptr.pcidev, 0);
898             #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
899                 pci_release_regions(candev->sysdevptr.pcidev);
900             #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
901                 return -ENODEV;
902         
903         }
904         can_base_addr_fixup(candev, remap_addr);
905         DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", candev->io_addr, candev->io_addr + IO_RANGE - 1);
906         DEBUGMSG("VMA: dev_base_addr: 0x%lx chip_base_addr: 0x%lx\n", 
907                 candev->dev_base_addr, candev->chip[0]->chip_base_addr);
908
909         return 0;
910 }
911
912
913 int unican_pci_release_io(struct candevice_t *candev)
914 {
915         iounmap((void*)candev->dev_base_addr);
916     #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
917         pci_release_region(candev->sysdevptr.pcidev, 0);
918     #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
919         pci_release_regions(candev->sysdevptr.pcidev);
920     #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
921         return 0;
922 }
923
924
925 int unican_pci_init_hw_data(struct candevice_t *candev)
926 {
927         struct pci_dev *pcidev = NULL;
928
929         do {
930                 pcidev = pci_find_device(UNICAN_PCI_VENDOR, UNICAN_PCI_ID, pcidev);
931                 if(pcidev == NULL) return -ENODEV;
932         } while(can_check_dev_taken(pcidev));
933         
934         if (pci_enable_device (pcidev)){
935                 printk(KERN_CRIT "Setup of Unican PCI failed\n");
936                 return -EIO;
937         }
938         candev->sysdevptr.pcidev=pcidev;
939         
940         if(!(pci_resource_flags(pcidev,0)&IORESOURCE_MEM)){
941                 printk(KERN_CRIT "Unican PCI region 0 is not MEM\n");
942                 return -EIO;
943         }
944         candev->dev_base_addr=pci_resource_start(pcidev,0);
945         candev->io_addr=candev->dev_base_addr;
946         candev->res_addr=candev->dev_base_addr;
947         
948         /*candev->flags |= CANDEV_PROGRAMMABLE_IRQ;*/
949
950         candev->nr_82527_chips=0;
951         candev->nr_sja1000_chips=0;
952         candev->nr_all_chips=1;
953
954         return 0;
955 }
956
957
958 int unican_pci_init_chip_data(struct candevice_t *candev, int chipnr)
959 {
960         int ret;
961         candev->chip[chipnr]->chip_irq=candev->sysdevptr.pcidev->irq;
962         ret = unican_init_chip_data(candev, chipnr);
963         candev->chip[chipnr]->flags |= CHIP_IRQ_PCI;
964         return ret;
965 }
966
967 int unican_pci_register(struct hwspecops_t *hwspecops)
968 {
969         hwspecops->request_io = unican_pci_request_io;
970         hwspecops->release_io = unican_pci_release_io;
971         hwspecops->reset = unican_reset;
972         hwspecops->init_hw_data = unican_pci_init_hw_data;
973         hwspecops->init_chip_data = unican_pci_init_chip_data;
974         hwspecops->init_obj_data = unican_init_obj_data;
975         hwspecops->write_register = NULL;
976         hwspecops->read_register = NULL;
977         hwspecops->program_irq = unican_program_irq;
978         return 0;
979 }
980
981 #endif /*CAN_ENABLE_PCI_SUPPORT*/
982
983 #ifdef CAN_ENABLE_VME_SUPPORT
984
985 #include "unican_vme.c"
986
987 #endif /*CAN_ENABLE_VME_SUPPORT*/