]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/ipci165.c
2a1f7c43845707dd063cff4a571c98054eb9445c
[lincan.git] / lincan / src / ipci165.c
1 /* ipci165.c
2  * Linux CAN-bus device driver for IXXAT iPC-I 165 (PCI) compatible HW.
3  * Written for new CAN driver version by Radim Kalas
4  * email:kalas@unicontrols.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/setup.h"
13 #include "../include/finish.h"
14 #include "../include/ipci165.h"
15 #include "../include/ipci165_fw.h"
16 #include "../include/kthread.h"
17
18 #include <ctype.h>
19
20 #ifndef IRQF_SHARED
21 #define IRQF_SHARED SA_SHIRQ
22 #endif  /*IRQF_SHARED*/
23
24 can_irqreturn_t ipci165_irq_handler(CAN_IRQ_HANDLER_ARGS(irq_number, dev_id));
25 int ipci165_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
26                       int sampl_pt, int flags);
27 int ipci165_set_btregs(struct canchip_t *chip, unsigned short btr0,
28                        unsigned short btr1);
29 int ipci165_start_chip(struct canchip_t *chip);
30
31 #ifdef CAN_DEBUG
32   void dump_mem(char *ptr, int size);
33 #else
34 #define dump_mem(a,b)
35 #endif
36
37 #define ipci165_load_btr(btr,btr0,btr1) {*btr = btr0; *(btr+1) = btr1;}
38
39 /**
40  * ipci165_delay - Delay the execution
41  * @msdelay: milliseconds to wait
42  *
43  * Return value: no return value
44  * File: src/ipci165.c
45  */
46 static void ipci165_delay(long msdelay)
47 {
48 #ifdef CAN_WITH_RTL
49   if(!rtl_rt_system_is_idle())
50   {
51     rtl_delay(1000000l*msdelay);
52   } else
53 #endif /*CAN_WITH_RTL*/
54   {
55     set_current_state(TASK_UNINTERRUPTIBLE);
56     schedule_timeout((msdelay*HZ)/1000+1);
57   }
58 }
59
60 /**
61  * ipci165_generate_irq - Generate irq for HW
62  * @candev: Pointer to hardware/board specific functions
63  *
64  * Return value: The function returns zero on success or non zero on failure
65  * File: src/ipci165.c
66  */
67 void ipci165_generate_irq(struct candevice_t *candev)
68 {
69   can_ioptr_t crm_addr = candev->aux_base_addr;
70   can_writeb(can_readb(crm_addr + CRM_UCR) & 0xFB, crm_addr + CRM_UCR);
71   can_writeb(can_readb(crm_addr + CRM_UCR) | 0x04, crm_addr + CRM_UCR);
72 }
73
74 /**
75  * bci_command - Send command to controller
76  * @candev: Pointer to hardware/board specific functions
77  * @cmd: Command to be performed
78  * @size: Command data size
79  * @data: Command data
80  *
81  * Return value: The function returns zero on success or non zero on failure
82  * File: src/ipci165.c
83  */
84 int bci_command(struct candevice_t *candev, char cmd, int size, char *data)
85 {
86   can_ioptr_t dpram_addr = candev->dev_base_addr;
87
88   DEBUGMSG ("ipci165_bci_command\n");
89
90   if (size > BCI_CMD_MAX_LEN)
91   {
92     DEBUGMSG ("ipci165_bci_command: parameter error\n");
93     return -EINVAL;
94   }
95
96   /* grant access to the command buffer */
97   can_spin_lock(&candev->device_lock);
98
99   // check command buffer status
100   if (can_readb(dpram_addr + OF_BCI_SYNC) != 0)
101   {
102     /* something went wrong ... */
103     can_spin_unlock(&candev->device_lock);
104     DEBUGMSG ("ipci165_bci_command: command buffer is busy\n");
105     return (-EBUSY);
106   }
107
108   // prepare command
109   can_writeb(cmd, dpram_addr + OF_BCI_CMD);
110   can_writeb(size + 1, dpram_addr + OF_BCI_NUM);
111   memcpy_toio(dpram_addr + OF_BCI_DATA, data, size);
112
113   // set flag for firmware
114   can_writeb(1, dpram_addr + OF_BCI_SYNC);
115
116   // generate interrupt to microcontroller
117   ipci165_generate_irq (candev);
118
119   return 0;
120 }
121
122 /**
123  * bci_response - Get response from controller
124  * @candev: Pointer to hardware/board specific functions
125  * @cmd: Command to get response for
126  * @size: Command data size
127  * @data: Command data
128  *
129  * Return value: The function returns zero on success or non zero on failure
130  * File: src/ipci165.c
131  */
132 int bci_response(struct candevice_t *candev, char cmd, int *size, char *data)
133 {
134   can_ioptr_t dpram_addr = candev->dev_base_addr;
135   char tmp;
136   int delay;
137
138   DEBUGMSG ("ipci165_bci_response\n");
139
140   delay = 1000;
141   while (can_readb(dpram_addr + OF_BCI_SYNC) != 2)
142   {
143     /* wait 1 ms */
144     /*    ipci165_delay(1); */
145     udelay(100);
146     if (--delay == 0)
147     {
148       /* timeout occured */
149       /* release the lock */
150       can_spin_unlock(&candev->device_lock);
151       CANMSG ("BCI timeout!\n");
152       return -EBUSY;
153     }
154   }
155
156   /* we will not copy the command filed, so decrement the size by 1 */
157   tmp = can_readb(dpram_addr + OF_BCI_NUM) - 1;
158   if (*size > tmp) *size = tmp;
159
160   if (can_readb(dpram_addr + OF_BCI_CMD) != cmd)
161   {
162     /* release the buffer */
163     can_writeb(0, dpram_addr + OF_BCI_SYNC);
164     /* unlock the access */
165     can_spin_unlock(&candev->device_lock);
166
167     DEBUGMSG ("ipci165_bci_command: invalid answer\n");
168     return -EIO;
169   }
170   memcpy_fromio(data, dpram_addr + OF_BCI_DATA, *size);
171
172   /* release the buffer */
173   can_writeb(0, dpram_addr + OF_BCI_SYNC);
174   /* unlock the access */
175   can_spin_unlock(&candev->device_lock);
176   return 0;
177 }
178
179 /**
180  * ipci165_restart_can - Flush queues and sestart can controller
181  * @candev: Pointer to hardware/board specific functions
182  * @chip_idx: chip number
183  *
184  * Return value: The function returns zero on success or non zero on failure
185  * File: src/ipci165.c
186  */
187 int ipci165_restart_can(struct canchip_t *chip)
188 {
189   char data[3];
190   int size;
191   int i;
192
193   struct ipci165_chip_t *chip_data;
194   unsigned long msg_ofs;
195
196   /* reset CAN */
197   data[0] = chip->chip_idx;
198   size = 1;
199   if (bci_command(chip->hostdevice, CMD_RESET_CAN, 1, data) ||
200       bci_response(chip->hostdevice, CMD_RESET_CAN, &size, data) ||
201       (data[0] == 0))
202   {
203     CANMSG ("CAN reset failed!\n");
204     return -ENODEV;
205   }
206
207   /* flush TX/RX queues in DP-RAM */
208   chip_data = (struct ipci165_chip_t *)chip->chip_data;
209   msg_ofs = BCI_MSG_STATUS;
210
211   for (i = 0; i< BCI_QUEUE_SIZE; i++)
212   {
213     can_writeb(BCI_MSG_STATUS_FREE, chip_data->rx_queue.addr + msg_ofs);
214     can_writeb(BCI_MSG_STATUS_FREE, chip_data->tx_queue.addr + msg_ofs);
215     msg_ofs += BCI_MSG_SIZE;
216   }
217
218   /* In- and output buffer re-initialization */
219   canqueue_ends_flush_inlist(chip->msgobj[0]->qends);
220   canqueue_ends_flush_outlist(chip->msgobj[0]->qends);
221
222   /* start CAN */
223   data[0] = chip->chip_idx;
224   size = 1;
225   if (bci_command(chip->hostdevice, CMD_START_CAN, 1, data) ||
226       bci_response(chip->hostdevice, CMD_START_CAN, &size, data) ||
227       (data[0] == 0))
228   {
229     CANMSG ("start chip failed!\n");
230     return -ENODEV;
231   }
232   return 0;
233 }
234
235 /* this is the thread function that we are executing */
236 /**
237  * ipci165_kthread - Thread restarting can controller after bus-off.
238  * @kthread: pointer to kernel thread descriptor
239  * @chip_idx: chip number
240  *
241  * Return value: no return value
242  * File: src/ipci165.c
243  */
244 void ipci165_kthread(kthread_t *kthread)
245 {
246   struct canchip_t *chip = (struct canchip_t *)kthread->arg;
247   struct ipci165_chip_t *chip_data = (struct ipci165_chip_t *)chip->chip_data;
248
249   /* setup the thread environment */
250   init_kthread(kthread, "ipci165");
251
252   /* this is normal work to do */
253   CANMSG ("kernel thread started!\n");
254
255   /* an endless loop in which we are doing our work */
256   for(;;)
257   {
258     /* fall asleep */
259     wait_event_interruptible(kthread->queue,test_bit(CHIP_FLAG_BUS_OFF,&chip_data->flags));
260
261     /* We need to do a memory barrier here to be sure that
262     the flags are visible on all CPUs. */
263     mb();
264
265     /* here we are back from sleep because we caught a signal. */
266     if (kthread->terminate)
267     {
268       /* we received a request to terminate ourself */
269       break;
270     }
271
272     {
273       clear_bit(CHIP_FLAG_BUS_OFF,&chip_data->flags);
274       set_bit(CHIP_FLAG_RESET,&chip_data->flags);
275       /* this is normal work to do */
276       ipci165_restart_can(chip);
277
278       clear_bit(CHIP_FLAG_RESET,&chip_data->flags);
279
280       /* wait at least 100ms for next reset */
281       ipci165_delay(100);
282     }
283   }
284   /* here we go only in case of termination of the thread */
285
286   /* cleanup the thread, leave */
287   CANMSG ("kernel thread terminated!\n");
288   exit_kthread(kthread);
289
290   /* returning from the thread here calls the exit functions */
291 }
292
293 /**
294  * ipci165_qfull_latency - Compute delay to send out full tx queue
295  * @candev: Pointer to candevice/board structure
296  * @obj: pointer to message object state structure
297  *
298  * Return Value: The function returns computed delay in jiffies
299  * File: src/ipci165.c
300  */
301 long ipci165_qfull_latency(struct msgobj_t *obj)
302 {
303   long latency;
304   latency = obj->hostchip->baudrate;
305   if(latency){
306     latency=(long)HZ*(CAN_FRAME_MIN_BIT_LEN * BCI_QUEUE_SIZE)/latency + 1;
307   }
308
309   return latency;
310 }
311
312 /**
313  * ipci165_connect_irq: Installs interrupt routine and enable irq on HW
314  * @candev: Pointer to candevice/board structure
315  *
316  * Return Value: The function returns zero on success or %-ENODEV on failure
317  * File: src/ipci165.c
318  */
319 int ipci165_connect_irq(struct candevice_t *candev)
320 {
321   can_ioptr_t crm_addr = candev->aux_base_addr;
322   unsigned char icr;
323   DEBUGMSG ("ipci165_connect_irq\n");
324
325   /* install interrupt routine */
326   if (request_irq(candev->sysdevptr.pcidev->irq,
327                   ipci165_irq_handler,
328                   IRQF_SHARED,
329                   DEVICE_NAME,
330                   candev))
331     return -ENODEV;
332
333   // Enable interrupt to PC
334   can_writeb(can_readb(crm_addr + CRM_ICR) | 0x40, crm_addr + CRM_ICR);
335   udelay (100);
336   icr = can_readb(crm_addr + CRM_ICR);
337   return 0;
338 }
339
340 /**
341  * ipci165_disconnect_irq - Disable irq on HW
342  * @candev: Pointer to candevice/board structure
343  *
344  * Return Value: The function returns zero on success or %-ENODEV on failure
345  * File: src/ipci165.c
346  */
347 void ipci165_disconnect_irq(struct candevice_t *candev)
348 {
349   can_ioptr_t crm_addr = candev->aux_base_addr;
350   unsigned char icr;
351   DEBUGMSG ("ipci165_disconnect_irq\n");
352
353   // Enable interrupt to PC
354   can_writeb(can_readb(crm_addr + CRM_ICR) & ~0x40, crm_addr + CRM_ICR);
355   udelay (100);
356   icr = can_readb(crm_addr + CRM_ICR);
357   /* deinstall interrupt routine */
358   free_irq(candev->sysdevptr.pcidev->irq, candev);
359 }
360
361 /* * * CAN Functionality * * */
362
363 /**
364  * ipci165_chip_config - Can chip configuration
365  * @chip: pointer to chip state structure
366  *
367  * Return Value: negative value reports error.
368  * File: src/ipci165.c
369  */
370 int ipci165_chip_config(struct canchip_t *chip)
371 {
372   struct ipci165_chip_t *chip_data = chip->chip_data;
373   char data[3];
374   int ret, size;
375
376   DEBUGMSG ("ipci165_chip_config[%i]\n",chip->chip_idx);
377
378   /* comupte the base address of tx and rx queue for the channel */
379   chip_data->tx_queue.addr = chip->chip_base_addr + OF_CH1_TX_QUEUE +
380       chip->chip_idx * (OF_CH2_TX_QUEUE-OF_CH1_TX_QUEUE);
381   chip_data->rx_queue.addr = chip->chip_base_addr + OF_CH1_RX_QUEUE +
382       chip->chip_idx * (OF_CH2_RX_QUEUE-OF_CH1_RX_QUEUE);
383
384   /* reset CAN */
385   data[0] = chip->chip_idx;
386
387   size = 1;
388   if (bci_command(chip->hostdevice, CMD_RESET_CAN, 1, data) ||
389       bci_response(chip->hostdevice, CMD_RESET_CAN, &size, data) ||
390       (data[0] == 0))
391   {
392     CANMSG ("CAN reset failed!\n");
393     return -ENODEV;
394   }
395
396   /* configure rx queue */
397   data[0] = chip->chip_idx;
398   data[1] = BCI_LATENCY_MODE;
399   data[2] = 0; /* dummy */
400
401   size = 1;
402   if (bci_command(chip->hostdevice, CMD_CONFIG_RX_QUEUE, 3, data) ||
403       bci_response(chip->hostdevice, CMD_CONFIG_RX_QUEUE, &size, data) ||
404       (data[0] == 0))
405   {
406     CANMSG ("config RX queue failed!\n");
407     return -ENODEV;
408   }
409   /* setup baud rate */
410   if (!chip->baudrate) chip->baudrate = 1000000;
411   if ((ret = ipci165_baud_rate(chip, chip->baudrate, chip->clock, 0, 0, 0))) return ret;
412
413   /* start can communication */
414   if ((ret = ipci165_start_chip(chip))) return ret;
415
416   return 0;
417 }
418
419 /**
420  * ipci165_baud_rate - Set communication parameters
421  * @chip: pointer to chip state structure
422  * @rate: baud rate in Hz
423  * @clock: not used
424  * @sjw: not used
425  * @sampl_pt: not used
426  * @flags: not used
427  *
428  * Return Value: negative value reports error.
429  * File: src/ipci165.c
430  */
431 int ipci165_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
432                       int sampl_pt, int flags)
433 {
434   DEBUGMSG ("ipci165_baud_rate[%i]\n",chip->chip_idx);
435
436   switch (rate) {
437     case 10000:  return ipci165_set_btregs(chip, BCI_10KB);
438     case 20000:  return ipci165_set_btregs(chip, BCI_20KB);
439     case 50000:  return ipci165_set_btregs(chip, BCI_50KB);
440     case 100000: return ipci165_set_btregs(chip, BCI_100KB);
441     case 125000: return ipci165_set_btregs(chip, BCI_125KB);
442     case 250000: return ipci165_set_btregs(chip, BCI_250KB);
443     case 500000: return ipci165_set_btregs(chip, BCI_500KB);
444     case 1000000:return ipci165_set_btregs(chip, BCI_1000KB);
445     default: return -EINVAL;
446   }
447
448   return 0;
449 }
450
451 /**
452  * ipci165_set_btregs - Configure bitrate registers
453  * @chip: pointer to chip state structure
454  * @btr0: bitrate register 0
455  * @btr1: bitrate register 1
456  *
457  * Return Value: negative value reports error.
458  * File: src/ipci165.c
459  */
460 int ipci165_set_btregs(struct canchip_t *chip, unsigned short btr0,
461                        unsigned short btr1)
462 {
463   unsigned char data[3];
464   int size;
465
466   DEBUGMSG ("ipci165_set_btregs[%i]: btr0=%02x, btr1=%02x\n",chip->chip_idx,
467             (unsigned)btr0,(unsigned)btr1);
468   
469   /* configure the chip */
470   data[0] = chip->chip_idx;
471   data[1] = btr0;
472   data[2] = btr1;
473   
474   size = 1;
475   if (bci_command(chip->hostdevice, CMD_INIT_CAN, 3, data) ||
476       bci_response(chip->hostdevice, CMD_INIT_CAN, &size, data) ||
477       (data[0] == 0))
478   {
479     CANMSG ("baud rate setup failed!\n");
480     return -ENODEV;
481   }
482   return 0;
483 }
484
485 /**
486  * ipci165_stop_chip - Start chip message processing
487  * @chip: pointer to chip state structure
488  *
489  * Return Value: negative value reports error.
490  * File: src/ipci165.c
491  */
492 int ipci165_start_chip(struct canchip_t *chip)
493 {
494   char data[1];
495   int size;
496
497   DEBUGMSG ("ipci165_start_chip[%i]\n",chip->chip_idx);
498   
499   /* start CAN */
500   data[0] = chip->chip_idx;
501   
502   size = 1;
503   if (bci_command(chip->hostdevice, CMD_START_CAN, 1, data) ||
504       bci_response(chip->hostdevice, CMD_START_CAN, &size, data) ||
505       (data[0] == 0))
506   {
507     CANMSG ("start chip failed!\n");
508     return -ENODEV;
509   }
510   return 0;
511 }
512
513 /**
514  * ipci165_stop_chip -  Stop chip message processing
515  * @chip: pointer to chip state structure
516  *
517  * Return Value: negative value reports error.
518  * File: src/ipci165.c
519  */
520 int ipci165_stop_chip(struct canchip_t *chip)
521 {
522   char data[1];
523   int size;
524
525   DEBUGMSG ("ipci165_stop_chip[%i]\n",chip->chip_idx);
526   
527   /* configure the chip */
528   data[0] = chip->chip_idx;
529   
530   size = 1;
531   if (bci_command(chip->hostdevice, CMD_STOP_CAN, 1, data) ||
532       bci_response(chip->hostdevice, CMD_STOP_CAN, &size, data) ||
533       (data[0] == 0))
534   {
535     CANMSG ("stop chip failed!\n");
536     return -ENODEV;
537   }
538   return 0;
539 }
540
541 /**
542  * ipci165_pre_read_config - Prepare message object for message reception
543  * @chip: pointer to chip state structure
544  * @obj: pointer to message object state structure
545  *
546  * Return Value: negative value reports error.
547  *      Positive value indicates immediate reception of message.
548  * File: src/ipci165.c
549  */
550 int ipci165_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj)
551 {
552   return 0;
553 }
554
555 /**
556  * ipci165_pre_write_config - Prepare message object for message transmission
557  * @chip: pointer to chip state structure
558  * @obj: pointer to message object state structure
559  * @msg: pointer to CAN message
560  *
561  * Return Value: negative value reports error.
562  * File: src/ipci165.c
563  */
564 int ipci165_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
565                              struct canmsg_t *msg)
566 {
567   return 0;
568 }
569
570 /**
571  * ipci165_send_msg - Initiate message transmission
572  * @chip: pointer to chip state structure
573  * @obj: pointer to message object state structure
574  * @msg: pointer to CAN message
575  *
576  * This function is called after ipci165_pre_write_config() function,
577  * which prepares data in chip buffer.
578  * Return Value: negative value reports error.
579  * File: src/ipci165.c
580  */
581 int ipci165_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
582                      struct canmsg_t *msg)
583 {
584   return 0;
585 }
586
587 /**
588  * ipci165_check_tx_stat - Checks state of transmission engine
589  * @chip: pointer to chip state structure
590  *
591  * Return Value: negative value reports error.
592  *      Positive return value indicates transmission under way status.
593  *      Zero value indicates finishing of all issued transmission requests.
594  * File: src/ipci165.c
595  */
596 int ipci165_check_tx_stat(struct canchip_t *chip)
597 {
598   return 0;
599 }
600
601 /**
602  * ipci165_irq_read_handler - ISR code responsible for receiving
603  * @chip: pointer to chip state structure
604  * @obj: pointer to attached queue description
605  *
606  * The main purpose of this function is to read message from CAN controller and
607  * transfer them to attached queues
608  * File: src/ipci165.c
609  */
610 void ipci165_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj)
611 {
612   struct ipci165_chip_t *chip_data = (struct ipci165_chip_t *)chip->chip_data;
613   struct bci_queue_t *queue = &(chip_data)->rx_queue;
614   can_ioptr_t         queue_addr = queue->addr;
615   can_ioptr_t         msg_addr   = queue_addr + queue->idx * BCI_MSG_SIZE;
616
617   int len;
618   unsigned char frame_info;
619   unsigned status;
620   unsigned short tmp16;
621   unsigned long  tmp32;
622
623   DEBUGMSG ("ipci165_irq_read_handler[%i]\n",chip->chip_idx);
624
625   do {
626     dump_mem(msg_addr, BCI_MSG_SIZE);
627     if (can_readb(msg_addr + BCI_MSG_TYPE) == BCI_MSG_TYPE_CAN)
628     {
629 #if 0
630       printk("ST(0)=%x, ST(1)=%x\n",can_readw(chip->chip_base_addr+OF_CAN1_STATUS),
631              can_readw(chip->chip_base_addr+OF_CAN2_STATUS));
632       for (tmp16 = 0 ; tmp16 < BCI_QUEUE_SIZE ; tmp16 ++)
633         printk ("MSG_ST(%i)=%x\n",tmp16,can_readb(chip->chip_base_addr + OF_CH2_TX_QUEUE + tmp16*BCI_MSG_SIZE + BCI_MSG_STATUS));
634       /* this is a can message */
635       DEBUGMSG ("ipci165_irq_read_handler[%i]: message in buffer\n",chip->chip_idx);
636 #endif
637
638       frame_info = can_readb(msg_addr + BCI_MSG_FRAME);
639       len =  frame_info & 0x0f;
640       if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
641       obj->rx_msg.length = len;
642       obj->rx_msg.flags  = (frame_info & BCI_MSG_FRAME_RTR ? MSG_RTR : 0);
643       obj->rx_msg.cob    = 0;
644       obj->rx_msg.timestamp.tv_sec = 0;
645       obj->rx_msg.timestamp.tv_usec = 
646           BCI_TIMESTAMP_RES * can_readl(msg_addr + BCI_MSG_TIMESTAMP);
647       /*  BCI_TIMESTAMP_RES * le32_to_cpu(can_readl(msg_addr + BCI_MSG_TIMESTAMP)); */
648
649       /* fill CAN message timestamp */
650       /* can_filltimestamp(&obj->rx_msg.timestamp); */
651
652       if (frame_info & BCI_MSG_FRAME_EXT)
653       {
654         /* extended frame - 29 bit identifier */
655         obj->rx_msg.flags |= MSG_EXT;
656         /* the ID is stored in motorola format (big endian), left justified  */
657         /* obj->rx_msg.id = be32_to_cpu(can_readl(msg_addr + BCI_MSG_ID) >> 3); */
658         memcpy_fromio(&tmp32, msg_addr + BCI_MSG_ID, 4);
659         obj->rx_msg.id = be32_to_cpu(tmp32 >> 3);
660         if (len > 0)
661           memcpy_fromio(obj->rx_msg.data, msg_addr + BCI_MSG_EXT_DATA, len);
662       } else
663       {
664         /* standard frame - 11 bit identifier */
665         /* the ID is stored in motorola format (big endian), left justified */
666         /* obj->rx_msg.id = be16_to_cpu(can_readw(msg_addr + BCI_MSG_ID) >> 5); */
667         memcpy_fromio(&tmp16, msg_addr + BCI_MSG_ID, 2);
668         obj->rx_msg.id = be16_to_cpu(tmp16 >> 5);
669         if (len > 0)
670           memcpy_fromio(obj->rx_msg.data, msg_addr + BCI_MSG_STD_DATA, len);
671       }
672       canque_filter_msg2edges(obj->qends, &obj->rx_msg);
673     }
674     else
675     {
676       /* this is a status message */
677       status = can_readw(msg_addr + BCI_MSG_CAN_STATUS);
678       DEBUGMSG ("ipci165_irq_read_handler[%i]: CAN status=%04x\n",chip->chip_idx, status);
679
680       /* wake up the reset thread if the CAN is in bus off */
681       if (status & BCI_CAN_STATUS_BUS_OFF) 
682       {
683         CANMSG ("BUS-OFF detected! Restarting\n");
684         set_bit(CHIP_FLAG_BUS_OFF,&chip_data->flags);
685         wake_up(&chip_data->kthread.queue);
686       }
687
688       if(obj->tx_slot)
689       {
690         canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_BUS);
691       }
692
693     }
694     DEBUGMSG ("ipci165_irq_read_handler[%i]: device status\n", chip->chip_idx);
695     dump_mem(chip->chip_base_addr + OF_STATUS_BUFFER, 12);
696
697     /* update pointer */
698     queue->idx = (queue->idx + 1) % BCI_QUEUE_SIZE;
699     /* release the buffer */
700     can_writeb(BCI_MSG_STATUS_FREE, msg_addr + BCI_MSG_STATUS);
701     msg_addr = queue_addr + queue->idx * BCI_MSG_SIZE;
702
703   } while (can_readb(msg_addr + BCI_MSG_STATUS) == BCI_MSG_STATUS_FULL);
704
705 }
706
707 /**
708  * ipci165_irq_write_handler - ISR code responsible for transmitting
709  * @chip: pointer to chip state structure
710  * @obj: pointer to attached queue description
711  *
712  * The main purpose of this function is to read message from attached queues
713  * and transfer message contents into CAN controller chip.
714  * File: src/ipci165.c
715  */
716 void ipci165_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
717 {
718   struct ipci165_chip_t *chip_data = ((struct ipci165_chip_t *)chip->chip_data);
719   struct bci_queue_t *queue      = &chip_data->tx_queue;
720   can_ioptr_t         queue_addr = queue->addr;
721   can_ioptr_t         msg_addr   = queue_addr + queue->idx * BCI_MSG_SIZE;
722   struct canque_slot_t *tx_slot;
723
724   int len;
725   unsigned char frame_info, ext;
726   unsigned short tmp16;
727   unsigned long  tmp32;
728
729   DEBUGMSG ("ipci165_irq_write_handler[%i]\n",chip->chip_idx);
730
731   while ((canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot) >=0))
732   {
733     if (test_bit(CHIP_FLAG_RESET,&chip_data->flags) ||
734         (can_readb(msg_addr + BCI_MSG_STATUS) == BCI_MSG_STATUS_FULL))
735     {
736       canque_again_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
737
738       /* lost interrupt work around */
739       ipci165_generate_irq(obj->hostchip->hostdevice);
740
741       mod_timer(&obj->tx_timeout, jiffies + ipci165_qfull_latency(obj));
742       DEBUGMSG("ipci165_irq_write_handler[%i]: scheduled retry\n", chip->chip_idx);
743
744       return;
745     }
746
747     tx_slot = obj->tx_slot;
748     DEBUGMSG ("msg[%i] : id=%lx dlc=%x flg=%02x\n",
749               chip->chip_idx,
750               (unsigned long)tx_slot->msg.id,
751               (unsigned int)tx_slot->msg.length,
752               (unsigned int)tx_slot->msg.flags);
753     dump_mem(tx_slot->msg.data, tx_slot->msg.length);
754
755     len = tx_slot->msg.length;
756     if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
757
758     ext = tx_slot->msg.flags;
759     frame_info =
760         len |
761         ((tx_slot->msg.flags & MSG_RTR) ? BCI_MSG_FRAME_RTR : 0) |
762         ((tx_slot->msg.flags & MSG_EXT) ? BCI_MSG_FRAME_EXT : 0);
763
764     can_writeb(BCI_MSG_SIZE - 2, msg_addr + BCI_MSG_NUM);
765     can_writeb(BCI_MSG_TYPE_CAN, msg_addr + BCI_MSG_TYPE);
766     can_writeb(frame_info, msg_addr + BCI_MSG_FRAME);
767     if (frame_info & BCI_MSG_FRAME_EXT)
768     {
769       /* extended frame - 29 bit identifier */
770       /* the ID is stored in motorola format (big endian), left justified  */
771       tmp32 = be32_to_cpu(tx_slot->msg.id) << 3;
772       memcpy_toio(msg_addr + BCI_MSG_ID, &tmp32, 4);
773       if (len > 0)
774         memcpy_toio(msg_addr + BCI_MSG_EXT_DATA, tx_slot->msg.data, len);
775     } else
776     {
777       /* standard frame - 11 bit identifier */
778       /* the ID is stored in motorola format (big endian), left justified */
779       tmp16 = be16_to_cpu(tx_slot->msg.id) << 5;
780       memcpy_toio(msg_addr + BCI_MSG_ID, &tmp16, 2);
781       if (len > 0)
782         memcpy_toio(msg_addr + BCI_MSG_STD_DATA, tx_slot->msg.data, len);
783     }
784
785     dump_mem(msg_addr, BCI_MSG_SIZE);
786
787     /* update pointer */
788     queue->idx = (queue->idx + 1) % BCI_QUEUE_SIZE;
789     /* mark the buffer as full */
790     can_writeb(BCI_MSG_STATUS_FULL, msg_addr + BCI_MSG_STATUS);
791     /* wake up the controller */
792     ipci165_generate_irq(chip->hostdevice);
793
794     /* next message address */
795     msg_addr = queue_addr + queue->idx * BCI_MSG_SIZE;
796
797     /* Do local transmitted message distribution if enabled. */
798     /* This code should not be called directly there, because it breaks strict
799     behavior of queues if O_SYNC is set. */
800     if (processlocal){
801       obj->tx_slot->msg.flags |= MSG_LOCAL;
802       canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
803     }
804     /* Free transmitted slot */
805     canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
806     obj->tx_slot = NULL;
807   }
808   return;
809 }
810
811 /**
812  * ipci165_irq_sync_activities - Synchronized access to write handler
813  * @chip: pointer to chip state structure
814  * @obj: pointer to attached queue description
815  *
816  * Return Value: The function always returns zero
817  * File: src/ipci165.c
818  */
819 void ipci165_irq_sync_activities(struct canchip_t *chip, struct msgobj_t *obj)
820 {
821   while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)) 
822   {
823     if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST)) 
824     {
825       ipci165_irq_write_handler(chip, obj);
826     }
827
828     can_msgobj_clear_fl(obj,TX_LOCK);
829     if(can_msgobj_test_fl(obj,TX_REQUEST))
830       continue;
831 /*    if(can_msgobj_test_fl(obj,FILTCH_REQUEST) && !obj->tx_slot)
832     continue; */
833     break;
834   }
835 }
836
837 /**
838  * ipci165_irq_chip_handler - ISR for dedicated chip
839  * @chip: pointer to chip state structure
840  *
841  * The main purpose of this function is to perform all necessary channel
842  * operations as a reaction on signalled interrupt. 
843  * File: src/ipci165.c
844  */
845 void ipci165_irq_chip_handler(struct canchip_t *chip)
846 {
847   struct msgobj_t       *obj = chip->msgobj[0];
848   struct ipci165_chip_t *chip_data = chip->chip_data;
849   struct bci_queue_t    *queue; 
850
851   DEBUGMSG ("ipci165_irq_chip_handler[%i]\n",chip->chip_idx);
852
853   /* check receive queue for messages */
854   queue = &chip_data->rx_queue;
855   if (can_readb(queue->addr + queue->idx * BCI_MSG_SIZE + BCI_MSG_STATUS)
856       == BCI_MSG_STATUS_FULL)
857     ipci165_irq_read_handler(chip, obj);
858
859   queue = &chip_data->tx_queue;
860 /*  if (can_readb(queue->addr + queue->idx * BCI_MSG_SIZE + BCI_MSG_STATUS)
861   == BCI_MSG_STATUS_FREE) */
862   {
863     can_msgobj_set_fl(obj,TX_REQUEST);
864
865     /* calls unican_irq_write_handler synchronized with other invocations */
866     ipci165_irq_sync_activities(chip, obj);
867   }
868
869 }
870
871 #define MAX_RETR 10
872
873 /**
874  * ipci165_irq_handler - Interrupt service routine
875  * @irq: interrupt vector number, this value is system specific
876  * @dev_id: driver private pointer registered at time of request_irq() call.
877  *      The CAN driver uses this pointer to store relationship of interrupt
878  *      to chip state structure - @struct canchip_t
879  * @regs: system dependent value pointing to registers stored in exception frame
880  * 
881  * The interrupt handler is activated when the ipci165 controller generates
882  * an interrupt as a reaction an internal state change. The interrupt is
883  * acknowledged and ipci165_irq_chip_handler is called for every channel.
884  * File: src/ipci165.c
885  */
886 can_irqreturn_t ipci165_irq_handler(CAN_IRQ_HANDLER_ARGS(irq_number, dev_id))
887 {
888   int retval;
889   struct candevice_t *candev = (struct candevice_t *)dev_id;
890
891   can_ioptr_t crm_addr   = candev->aux_base_addr;
892   can_ioptr_t ucr1_addr  = crm_addr + CRM_UCR + 1;
893   struct canchip_t *chip;
894   unsigned char icr;
895   int i;
896
897   /* DEBUGMSG ("ipci165_irq_handler\n"); */
898
899   /* read interrupt control register (byte 0) */
900   icr = can_readb(crm_addr + CRM_ICR);
901
902   if ((icr & 0x44) == 0x44)
903   {
904     DEBUGMSG ("ipci165_irq_handler: pending interrupt\n");
905
906     /* confirm pending interrupt */
907     can_writeb(can_readb(ucr1_addr) | 0x01,  ucr1_addr);
908     can_writeb(can_readb(ucr1_addr) & ~0x01, ucr1_addr);
909
910     /* call interrupt handler for every channel */
911     for (i=0 ; i < candev->nr_all_chips ; i++)
912     {
913       chip = candev->chip[i];
914       if (chip->flags & CHIP_CONFIGURED)
915         ipci165_irq_chip_handler(candev->chip[i]);
916     }
917     DEBUGMSG ("ipci165_irq_handler: interrupt handled\n");
918
919     retval = CANCHIP_IRQ_HANDLED;
920   } else {
921     DEBUGMSG ("ipci165_irq_handler: not our interrupt\n");
922     retval = CANCHIP_IRQ_NONE;
923   }
924
925   return CAN_IRQ_RETVAL(retval);
926 }
927
928 /**
929  * ipci165_wakeup_tx - Wakeup TX processing
930  * @chip: pointer to chip state structure
931  * @obj: pointer to message object structure
932  *
933  * Function is responsible for initiating message transmition.
934  * It is responsible for clearing of object TX_REQUEST flag
935  *
936  * Return Value: negative value reports error.
937  * File: src/ipci165.c
938  */
939 int ipci165_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
940 {
941   DEBUGMSG ("ipci165_wakeup_tx\n");
942   can_preempt_disable();
943
944   can_msgobj_set_fl(obj,TX_REQUEST);
945
946   /* calls ipci165_irq_write_handler synchronized with other invocations
947   from kernel and IRQ context */
948   ipci165_irq_sync_activities(chip, obj);
949
950   can_preempt_enable();
951   DEBUGMSG ("ipci165_wakeup_tx: finished\n");
952
953   return 0;
954 }
955
956 void ipci165_do_tx_timeout(unsigned long data)
957 {
958   struct msgobj_t *obj=(struct msgobj_t *)data;
959
960   DEBUGMSG ("ipci165_do_tx_timeout\n");
961
962   can_preempt_disable();
963
964   can_msgobj_set_fl(obj,TX_REQUEST);
965
966   /* calls ipci165_irq_write_handler synchronized with other invocations
967   from kernel and IRQ context */
968   ipci165_irq_sync_activities(obj->hostchip, obj);
969
970   can_preempt_enable();
971   DEBUGMSG ("ipci165_do_tx_timeout: finished\n");
972 }
973
974 /**
975  * ipci165_attach_to_chip: - attaches to the chip, setups registers and state
976  * @chip: pointer to chip state structure
977  *
978  * Return Value: negative value reports error.
979  * File: src/ipci165.c
980  */
981 int ipci165_attach_to_chip(struct canchip_t *chip)
982 {
983   return 0;
984 }
985
986 /**
987  * ipci165_release_chip: - called before chip structure removal if %CHIP_ATTACHED is set
988  * @chip: pointer to chip state structure
989  *
990  * Return Value: negative value reports error.
991  * File: src/ipci165.c
992  */
993 int ipci165_release_chip(struct canchip_t *chip)
994 {
995   ipci165_stop_chip(chip);
996   /* disable interrupts in the hardware, etc. */
997   return 0;
998 }
999
1000 /* * * iPC-I 165/PCI Board Functionality * * */
1001
1002 /**
1003  * ipci165_request_io - Reserve io or memory range for can board
1004  * @candev: pointer to candevice/board which asks for io. Field @io_addr
1005  *      of @candev is used in most cases to define start of the range
1006  *
1007  * Return Value: The function returns zero on success or %-ENODEV on failure
1008  * File: src/ipci165.c
1009  */
1010 int ipci165_request_io(struct candevice_t *candev)
1011 {
1012   unsigned long dpram_addr; /* physical address before remap for this function */
1013   unsigned long crm_addr;   /* physical address before remap for this function */
1014   unsigned long fix_addr;   /* physical address before remap for this function */
1015   int i,j;
1016
1017   DEBUGMSG ("ipci165_request_io\n");
1018
1019   crm_addr   = pci_resource_start(candev->sysdevptr.pcidev,0);
1020   dpram_addr = pci_resource_start(candev->sysdevptr.pcidev,2);
1021
1022   DEBUGMSG ("ipci165_request_io: crm = 0x%lx, dpram = 0x%lx\n",crm_addr, dpram_addr);
1023
1024   /* verify, if our HW is buggy, and try to fix it */
1025 #if 0
1026   if (test_bit (7, &crm_addr))
1027   {
1028     CANMSG ("Wrong PCI base address [0x%lx](PLX PCI9050 bug)!\n", dpram_addr);
1029
1030     fix_addr = pci_resource_start(candev->sysdevptr.pcidev,3);
1031
1032     if (fix_addr == 0)
1033     {
1034       CANMSG ("This card was not fixed!\n");
1035
1036       if (candev->aux_base_addr == NULL)
1037       {
1038         CANMSG ("You have to specify IO address parameter!\n");
1039         return -EINVAL;
1040       }
1041       CANMSG ("Using specified IO address value for the memory [0x%lx]\n",
1042               can_ioptr2ulong(candev->aux_base_addr));
1043     }
1044     else
1045     {
1046       CANMSG ("Fixed card. Using of 3 region [0x%lx]\n", fix_addr);
1047       candev->aux_base_addr = fix_addr;
1048     }
1049
1050     pci_write_config_dword (candev->sysdevptr.pcidev,
1051                             PCI_BASE_ADDRESS_0, fix_addr);
1052   }
1053 #endif
1054
1055 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
1056   if(pci_request_region(candev->sysdevptr.pcidev, 2, "kv_ipci165_dpram") == 0)
1057   {
1058     if(pci_request_region(candev->sysdevptr.pcidev, 0, "kv_ipci165_reg") == 0)
1059     {
1060 #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1061   if(pci_request_regions(candev->sysdevptr.pcidev, "kv_ipci165") == 0)
1062   {
1063 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1064
1065       if ((candev->dev_base_addr = ioremap(dpram_addr, 
1066            pci_resource_len(candev->sysdevptr.pcidev,2))))
1067       {
1068         DEBUGMSG ("ipci165_request_io: dpram remapped to 0x%lx\n", candev->dev_base_addr);
1069
1070         if ((candev->aux_base_addr = ioremap(crm_addr, 
1071              pci_resource_len(candev->sysdevptr.pcidev,0))))
1072         {
1073           DEBUGMSG ("ipci165_request_io: crm remapped to 0x%lx\n", can_ioptr2ulong(candev->aux_base_addr));
1074           /* all resources has been allocated */
1075
1076           /* Because of my mapping, I cannot use the
1077              can_base_addr_fixup(candev, remap_addr) to remap the addresses */
1078           for(i=0;i<candev->nr_all_chips;i++)
1079           {
1080             candev->chip[i]->chip_base_addr = candev->dev_base_addr;
1081             for(j=0;j<candev->chip[i]->max_objects;j++)
1082               candev->chip[i]->msgobj[j]->obj_base_addr = candev->dev_base_addr;
1083           }
1084
1085           return 0;
1086
1087         } else CANMSG("Unable to remap memory at: 0x%lx\n", crm_addr);
1088         iounmap(candev->aux_base_addr);
1089
1090       } else CANMSG("Unable to remap memory at: 0x%lx\n", dpram_addr);
1091       iounmap(candev->dev_base_addr);
1092
1093 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
1094       pci_release_region(candev->sysdevptr.pcidev, 0);
1095     } else CANMSG("Request of kv_ipci165_reg range failed\n");
1096
1097     pci_release_region(candev->sysdevptr.pcidev, 2);
1098   } else CANMSG("Request of kv_ipci165_dpram range failed\n");
1099
1100 #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1101     pci_release_regions(candev->sysdevptr.pcidev);
1102   } else CANMSG("Request of kv_ipci165 regions failed\n");
1103 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1104
1105   return -ENODEV;
1106 }
1107
1108 /**
1109  * ipci165_release_io - Free reserved io memory range
1110  * @candev: pointer to candevice/board which releases io
1111  *
1112  * Return Value: The function always returns zero
1113  * File: src/ipci165.c
1114  */
1115 int ipci165_release_io(struct candevice_t *candev)
1116 {
1117   struct ipci165_chip_t *chip_data;
1118   int i;
1119   
1120   /* disable irq on HW */
1121   ipci165_disconnect_irq(candev);
1122
1123 #if 0
1124   /* terminate the kernel threads */
1125   for (i = 0 ; i < candev->nr_all_chips ; i++)
1126   {
1127     chip_data = (struct ipci165_chip_t *)candev->chip[i]->chip_data;
1128     stop_kthread(&chip_data->restart_thread);
1129   }
1130 #endif
1131
1132   iounmap(candev->aux_base_addr);
1133   iounmap(candev->dev_base_addr);
1134
1135 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
1136   pci_release_region(candev->sysdevptr.pcidev, 2);
1137   pci_release_region(candev->sysdevptr.pcidev, 0);
1138 #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1139   pci_release_regions(candev->sysdevptr.pcidev);
1140 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1141
1142   return 0;
1143 }
1144
1145 /**
1146  * ipci165_download_fw - Download FW into CAN hardware
1147  * @candev: Pointer to candevice/board structure
1148  *
1149  * Return Value: returns zero on success
1150  * File: src/ipci165.c
1151  */
1152 int ipci165_download_fw(struct candevice_t *candev)
1153 {
1154   can_ioptr_t dpram_addr = candev->dev_base_addr;
1155   char board_name[BOARD_NAME_LEN+1];
1156   char hw_version[HW_VERSION_LEN+1];
1157   char mode[MODE_LEN+1];
1158
1159   struct ipci165_fw_t *fwArray = ipci165_fw;
1160   int attempt;
1161
1162   DEBUGMSG ("ipci165_download_fw\n");
1163
1164   /* read name and version */  
1165   memcpy_fromio (board_name, dpram_addr + BOARD_NAME_OFS, BOARD_NAME_LEN);
1166   board_name[BOARD_NAME_LEN] = 0;
1167
1168   memcpy_fromio (hw_version, dpram_addr + HW_VERSION_OFS, HW_VERSION_LEN);
1169   hw_version[HW_VERSION_LEN] = 0;
1170
1171   CANMSG ("Board Name: %s\n", board_name);
1172   CANMSG ("HW Version: %s\n", hw_version);
1173
1174 /*
1175   if ((hw_version[0] != 'V') && (hw_version[0] != 'v'))
1176 {
1177   CANMSG ("This board is too old and not supported by the BCI !\n");
1178   return -ENODEV;
1179 }
1180 */
1181
1182   /* detect & test mode */
1183   memcpy_fromio (mode, dpram_addr + MODE_OFS, MODE_LEN);
1184   mode[MODE_LEN] = 0;
1185
1186   if (strncmp (mode, "PC-Loader V", 11))
1187   {
1188     CANMSG ("Unknown mode [%s], can't download firmware!\n",mode);
1189     return -ENODEV;
1190   }
1191
1192   while (fwArray->len)
1193   {
1194     /* fill buffer */
1195     can_writeb(LD_CMD_DOWNLOAD, dpram_addr + OF_LD_CMD);
1196     can_writeb(fwArray->len, dpram_addr + OF_LD_NUM);
1197     can_writeb(0, dpram_addr + OF_LD_NUM + 1);
1198
1199     can_writel(fwArray->addr, dpram_addr + OF_LD_ADDRESS);
1200     /*    can_writel already performes the cpu_to_le32 conversion by itself   */
1201     /*    can_writel(cpu_to_le32(fwArray->addr), dpram_addr + OF_LD_ADDRESS); */
1202
1203     memcpy_toio(dpram_addr + OF_LD_DATA, fwArray->a_data, fwArray->len);
1204
1205 #if 0
1206     dump_mem((void *)(dpram_addr + OF_LD_SYNC), fwArray->len + 8);
1207 #endif
1208     /* buffer is prepared, set flag for loader */
1209     can_writeb(1, dpram_addr + OF_LD_SYNC);
1210
1211     /* update pointer */
1212     fwArray++;
1213
1214     /* wait for the loader */
1215     attempt = 1000;
1216     while (can_readb(dpram_addr + OF_LD_SYNC) != 0)
1217     {
1218       udelay(100);
1219       if (--attempt == 0)
1220       {
1221         /* timeout occured */
1222         CANMSG ("Firmware download failed!\n");
1223         return -ENODEV;
1224       }
1225     }
1226   }
1227   CANMSG ("Firmware downladed successfully\n");
1228
1229   /* start the FW */
1230   can_writeb(LD_CMD_START_FW, dpram_addr + OF_LD_CMD);
1231   can_writeb(1, dpram_addr + OF_LD_SYNC);
1232   ipci165_delay (500);
1233
1234   return 0;
1235 }
1236
1237 /**
1238  * ipci165_reset - Hardware reset routine
1239  * @candev: Pointer to candevice/board structure
1240  *
1241  * Return Value: The function returns zero on success or %-ENODEV on failure
1242  * File: src/ipci165.c
1243  */
1244 int ipci165_reset(struct candevice_t *candev)
1245 {
1246   can_ioptr_t crm_addr = candev->aux_base_addr;
1247   unsigned long test_data;
1248   char buffer[BCI_CMD_MAX_LEN];
1249   int i, size, chips;
1250   unsigned char ucr;
1251   struct canchip_t *chip;
1252   struct ipci165_chip_t *chip_data;
1253
1254   DEBUGMSG ("ipci165_reset: hardware reset\n");
1255
1256   /* reset the HW */
1257   ucr = can_readb(crm_addr + CRM_UCR + 3);
1258   can_writeb(ucr | 0x40, crm_addr + CRM_UCR + 3);
1259   udelay(100);
1260   can_writeb(ucr & ~0x40, crm_addr + CRM_UCR + 3);
1261
1262   /* wait a little bit */
1263   ipci165_delay(200);
1264
1265   /* download FW */
1266   if (ipci165_download_fw(candev)) return -ENODEV;
1267
1268   /* enable irq on HW */
1269   if (ipci165_connect_irq(candev))
1270     {
1271     CANMSG ("Interrupt routine installation for IRQ %i failed!\n",
1272             candev->sysdevptr.pcidev->irq);
1273     return -ENODEV;
1274     }
1275
1276   /* test BCI interface */
1277   test_data = 0x12345678;
1278   size = sizeof(test_data);
1279   if (bci_command(candev, CMD_TEST, size, (char *)&test_data) ||
1280       bci_response(candev, CMD_TEST, &size, (char *)&test_data) ||
1281       (test_data != ~0x12345678))
1282   {
1283     CANMSG ("BCI test failed! Test pattern is %lx\n", test_data);
1284     return -ENODEV;
1285   }
1286
1287   /* get Firmware identification */
1288   /* send command, fw requests 1 dummy byte */
1289   size = BCI_CMD_MAX_LEN;
1290   if (bci_command(candev, CMD_ID, 1, (char *)&test_data) ||
1291       bci_response(candev, CMD_ID, &size, buffer))
1292   {
1293     CANMSG ("Firmware Identification reading failed!\n");
1294     return -ENODEV;
1295   }
1296   CANMSG ("Firmware: %s\n",buffer);
1297
1298   /* get Firmware version */
1299   /* send command, fw requests 1 dummy byte */
1300   size = BCI_CMD_MAX_LEN;
1301   if (bci_command(candev, CMD_VERSION, 1, (char *)&test_data) ||
1302       bci_response(candev, CMD_VERSION, &size, buffer))
1303   {
1304     CANMSG ("Firmware Version reading failed!\n");
1305     return -ENODEV;
1306   }
1307   CANMSG ("Version: %s\n",buffer);
1308
1309   /* get Board Info */
1310   /* send command, fw requests 1 dummy byte */
1311   size = BOARD_INFO_SIZE;
1312   if (bci_command(candev, CMD_GET_BOARD_INFO, 1, (char *)&test_data) ||
1313       bci_response(candev, CMD_GET_BOARD_INFO, &size, (char *) buffer))
1314   {
1315     CANMSG ("Get Board Info failed!\n");
1316     return -ENODEV;
1317   }
1318
1319   chips = le16_to_cpu(*(unsigned short*)(buffer+OF_BOARD_INFO_CHIPS));
1320   /* shouldn't be, but who knows ... */
1321   if (chips > 2) chips = 2;
1322
1323   CANMSG ("Chips: %i\n",chips);
1324   CANMSG ("Chip 1 Type: %s\n",buffer+OF_BOARD_INFO_CHIP1_TYPE);
1325
1326   /* update board info */
1327   if (chips == 1)
1328   {
1329     /* we have to correct the number in candev and release allocated
1330        structures */
1331     candev->nr_all_chips = chips;
1332     canchip_done(candev->chip[1]);
1333
1334   } else CANMSG ("Chip 2 Type: %s\n",buffer+OF_BOARD_INFO_CHIP2_TYPE); 
1335
1336   /* start kernel threads */
1337   for (i = 0 ; i < chips ; i++)
1338   {
1339     chip = candev->chip[i];
1340     chip_data = (struct ipci165_chip_t *)chip->chip_data;
1341     chip_data->kthread.arg = chip;
1342     start_kthread(ipci165_kthread, &chip_data->kthread);
1343   }
1344
1345   CANMSG ("HW is up and working.\n");
1346   return 0;
1347 }
1348
1349 /**
1350  * ipci165_init_hw_data - Initialize hardware cards
1351  * @candev: Pointer to candevice/board structure
1352  *
1353  * Return Value: The function always returns zero
1354  * File: src/ipci165.c
1355  */
1356 int ipci165_init_hw_data(struct candevice_t *candev)
1357 {
1358   struct pci_dev *pcidev = NULL;
1359   unsigned short SubsystemID;
1360
1361   DEBUGMSG ("ipci165_init_hw_data\n");
1362
1363   /* find iPC-I 165 on PCI bus */
1364   do
1365   {
1366     pcidev = pci_find_device(IPCI165_VENDOR_ID, IPCI165_DEVICE_ID, pcidev);
1367     if(pcidev == NULL) return -ENODEV;
1368
1369     /* check subvendor ID */
1370     pci_read_config_word (pcidev, PCI_SUBSYSTEM_ID, &SubsystemID);
1371     if ((SubsystemID != IPCI165_SUBSYSTEM_ID) &&
1372         (SubsystemID != CP350_SUBSYSTEM_ID))
1373       break;
1374   }
1375   while(can_check_dev_taken(pcidev));
1376
1377   /* enable it */
1378   if (pci_enable_device (pcidev))
1379   {
1380     CANMSG ("Cannot enable PCI device\n");
1381     return -EIO;
1382   }
1383
1384   candev->sysdevptr.pcidev = pcidev;
1385   candev->res_addr=0;
1386   candev->nr_82527_chips=0;
1387   candev->nr_sja1000_chips=0;
1388   /* we do not know yet, whether our HW has one or two chan chips. Let's
1389      prepare configuration for maximal configuration = 2. This will be
1390      corrected later on */
1391   candev->nr_all_chips=2; 
1392   candev->flags |= CANDEV_PROGRAMMABLE_IRQ*0;
1393   /* initialize device spinlock */
1394   can_spin_lock_init(&candev->device_lock);
1395
1396   return 0;
1397 }
1398
1399 #define CHIP_TYPE "ipci165"
1400
1401 /**
1402  * ipci165_init_chip_data - Initialize chips
1403  * @candev: Pointer to candevice/board structure)
1404  * @chipnr: Number of the CAN chip on the hardware card
1405  *
1406  * Return Value: The function always returns zero
1407  * File: src/ipci165.c
1408  */
1409 int ipci165_init_chip_data(struct candevice_t *candev, int chipnr)
1410 {
1411   struct canchip_t      *chip = candev->chip[chipnr];
1412   struct ipci165_chip_t *chip_data;
1413
1414   DEBUGMSG ("ipci165_init_chip_data\n");
1415
1416   chip->chip_type = CHIP_TYPE;
1417   chip->chip_base_addr = 0; /* mapping not known yet */
1418   chip->clock = 10000000;
1419   chip->int_clk_reg = 0x0;
1420   chip->int_bus_reg = 0x0;
1421   chip->max_objects = 1;
1422
1423 #if 0
1424   /* initialize interrupt handling only for channel 0. The interrupt
1425      is shared between the channels so we have to work it out in one
1426      interrupt routine. */
1427   if (chipnr == 0)
1428   {
1429     chip->chipspecops->irq_handler=ipci165_irq_handler;
1430     chip->chip_irq=candev->sysdevptr.pcidev->irq;
1431     chip->flags |= CHIP_IRQ_PCI;
1432   } else
1433   {
1434     chip->chipspecops->irq_handler=NULL;
1435   }
1436 #else
1437   chip->chipspecops->irq_handler = NULL;
1438   chip->chip_irq = 0;
1439   chip->flags |= CHIP_IRQ_CUSTOM;
1440 #endif
1441
1442   chip_data = can_checked_malloc(sizeof(struct ipci165_chip_t));
1443   if(!chip_data) return -ENOMEM;
1444   chip_data->rx_queue.idx = 0;
1445   chip_data->rx_queue.addr = 0;
1446   chip_data->tx_queue.idx = 0;
1447   chip_data->tx_queue.addr = 0;
1448   chip->chip_data = chip_data;
1449
1450   CANMSG("initializing ipci165 chip operations\n");
1451   chip->chipspecops->attach_to_chip=ipci165_attach_to_chip;
1452   chip->chipspecops->release_chip=ipci165_release_chip;
1453   chip->chipspecops->chip_config=ipci165_chip_config;
1454   chip->chipspecops->baud_rate=ipci165_baud_rate;
1455   chip->chipspecops->set_btregs=ipci165_set_btregs;
1456   chip->chipspecops->start_chip=ipci165_start_chip;
1457   chip->chipspecops->stop_chip=ipci165_stop_chip;
1458   chip->chipspecops->pre_read_config=ipci165_pre_read_config;
1459   chip->chipspecops->wakeup_tx=ipci165_wakeup_tx;
1460   chip->chipspecops->filtch_rq=NULL;
1461   chip->chipspecops->irq_accept=NULL;
1462
1463   chip->chipspecops->standard_mask=NULL;
1464   chip->chipspecops->extended_mask=NULL;
1465   chip->chipspecops->message15_mask=NULL;
1466   chip->chipspecops->clear_objects=NULL;
1467   chip->chipspecops->config_irqs=NULL;
1468   chip->chipspecops->pre_write_config=NULL;
1469   chip->chipspecops->send_msg=NULL;
1470   chip->chipspecops->check_tx_stat=NULL;
1471   chip->chipspecops->remote_request=NULL;
1472   chip->chipspecops->enable_configuration=NULL;
1473   chip->chipspecops->disable_configuration=NULL;
1474
1475   return 0;
1476 }
1477
1478 /**
1479  * ipci165_init_obj_data - Initialize message buffers
1480  * @chip: Pointer to chip specific structure
1481  * @objnr: Number of the message buffer
1482  *
1483  * Return Value: The function always returns zero
1484  * File: src/ipci165.c
1485  */
1486 int ipci165_init_obj_data(struct canchip_t *chip, int objnr)
1487 {
1488   struct msgobj_t *obj=chip->msgobj[objnr];
1489   
1490   DEBUGMSG ("ipci165_init_obj_data\n");
1491   
1492   obj->obj_base_addr = 0; /* not known yet */
1493   obj->tx_timeout.function = ipci165_do_tx_timeout;
1494   obj->tx_timeout.data = (unsigned long)obj;
1495   return 0;
1496 }
1497
1498 /**
1499  * ipci165_program_irq - Program interrupts
1500  * @candev: Pointer to candevice/board structure
1501  *
1502  * Return value: The function returns zero on success or %-ENODEV on failure
1503  * File: src/ipci165.c
1504  */
1505 int ipci165_program_irq(struct candevice_t *candev)
1506 {
1507   return 0;
1508 }
1509
1510 /**
1511  * ipci165_register - Register Board Support Functions
1512  * @candev: Pointer to hardware/board specific functions
1513  *
1514  * Return value: The function returns zero on success or %-ENODEV on failure
1515  * File: src/ipci165.c
1516  */
1517 int ipci165_register(struct hwspecops_t *hwspecops)
1518 {
1519   hwspecops->request_io = ipci165_request_io;
1520   hwspecops->release_io = ipci165_release_io;
1521   hwspecops->reset = ipci165_reset;
1522   hwspecops->init_hw_data = ipci165_init_hw_data;
1523   hwspecops->init_chip_data = ipci165_init_chip_data;
1524   hwspecops->init_obj_data = ipci165_init_obj_data;
1525   hwspecops->write_register = NULL;
1526   hwspecops->read_register = NULL;
1527   hwspecops->program_irq = ipci165_program_irq;
1528   return 0;
1529 }
1530
1531 #ifdef CAN_DEBUG
1532 void dump_mem(char *ptr, int size)
1533 {
1534   int to, j;
1535   unsigned char str[80], buf[16];
1536   char *strp;
1537
1538   for (; size > 0; size -= 16)
1539   {
1540     to = size > 16 ? 16 : size;
1541     memcpy (buf,ptr, to);
1542     strp = str;
1543     for (j = 0; j < to ; j++)
1544       strp += sprintf(strp, "%02x ",buf[j]);
1545     for (; j < 16 ; j++) 
1546       strp += sprintf(strp, "   ");
1547     for (j = 0; j < to ; j++)
1548       *strp++= isprint(buf[j]) ? buf[j] : '.';
1549
1550     DEBUGMSG ("[%lx] %s\n", (long unsigned)ptr, str);
1551     ptr += to;
1552   }
1553 }
1554 #endif