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
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"
21 #define IRQF_SHARED SA_SHIRQ
22 #endif /*IRQF_SHARED*/
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,
29 int ipci165_start_chip(struct canchip_t *chip);
32 void dump_mem(char *ptr, int size);
37 #define ipci165_load_btr(btr,btr0,btr1) {*btr = btr0; *(btr+1) = btr1;}
40 * ipci165_delay - Delay the execution
41 * @msdelay: milliseconds to wait
43 * Return value: no return value
46 static void ipci165_delay(long msdelay)
49 if(!rtl_rt_system_is_idle())
51 rtl_delay(1000000l*msdelay);
53 #endif /*CAN_WITH_RTL*/
55 set_current_state(TASK_UNINTERRUPTIBLE);
56 schedule_timeout((msdelay*HZ)/1000+1);
61 * ipci165_generate_irq - Generate irq for HW
62 * @candev: Pointer to hardware/board specific functions
64 * Return value: The function returns zero on success or non zero on failure
67 void ipci165_generate_irq(struct candevice_t *candev)
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);
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
81 * Return value: The function returns zero on success or non zero on failure
84 int bci_command(struct candevice_t *candev, char cmd, int size, char *data)
86 can_ioptr_t dpram_addr = candev->dev_base_addr;
88 DEBUGMSG ("ipci165_bci_command\n");
90 if (size > BCI_CMD_MAX_LEN)
92 DEBUGMSG ("ipci165_bci_command: parameter error\n");
96 /* grant access to the command buffer */
97 can_spin_lock(&candev->device_lock);
99 // check command buffer status
100 if (can_readb(dpram_addr + OF_BCI_SYNC) != 0)
102 /* something went wrong ... */
103 can_spin_unlock(&candev->device_lock);
104 DEBUGMSG ("ipci165_bci_command: command buffer is busy\n");
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);
113 // set flag for firmware
114 can_writeb(1, dpram_addr + OF_BCI_SYNC);
116 // generate interrupt to microcontroller
117 ipci165_generate_irq (candev);
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
129 * Return value: The function returns zero on success or non zero on failure
130 * File: src/ipci165.c
132 int bci_response(struct candevice_t *candev, char cmd, int *size, char *data)
134 can_ioptr_t dpram_addr = candev->dev_base_addr;
138 DEBUGMSG ("ipci165_bci_response\n");
141 while (can_readb(dpram_addr + OF_BCI_SYNC) != 2)
144 /* ipci165_delay(1); */
148 /* timeout occured */
149 /* release the lock */
150 can_spin_unlock(&candev->device_lock);
151 CANMSG ("BCI timeout!\n");
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;
160 if (can_readb(dpram_addr + OF_BCI_CMD) != cmd)
162 /* release the buffer */
163 can_writeb(0, dpram_addr + OF_BCI_SYNC);
164 /* unlock the access */
165 can_spin_unlock(&candev->device_lock);
167 DEBUGMSG ("ipci165_bci_command: invalid answer\n");
170 memcpy_fromio(data, dpram_addr + OF_BCI_DATA, *size);
172 /* release the buffer */
173 can_writeb(0, dpram_addr + OF_BCI_SYNC);
174 /* unlock the access */
175 can_spin_unlock(&candev->device_lock);
180 * ipci165_restart_can - Flush queues and sestart can controller
181 * @candev: Pointer to hardware/board specific functions
182 * @chip_idx: chip number
184 * Return value: The function returns zero on success or non zero on failure
185 * File: src/ipci165.c
187 int ipci165_restart_can(struct canchip_t *chip)
193 struct ipci165_chip_t *chip_data;
194 unsigned long msg_ofs;
197 data[0] = chip->chip_idx;
199 if (bci_command(chip->hostdevice, CMD_RESET_CAN, 1, data) ||
200 bci_response(chip->hostdevice, CMD_RESET_CAN, &size, data) ||
203 CANMSG ("CAN reset failed!\n");
207 /* flush TX/RX queues in DP-RAM */
208 chip_data = (struct ipci165_chip_t *)chip->chip_data;
209 msg_ofs = BCI_MSG_STATUS;
211 for (i = 0; i< BCI_QUEUE_SIZE; i++)
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;
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);
223 data[0] = chip->chip_idx;
225 if (bci_command(chip->hostdevice, CMD_START_CAN, 1, data) ||
226 bci_response(chip->hostdevice, CMD_START_CAN, &size, data) ||
229 CANMSG ("start chip failed!\n");
235 /* this is the thread function that we are executing */
237 * ipci165_kthread - Thread restarting can controller after bus-off.
238 * @kthread: pointer to kernel thread descriptor
239 * @chip_idx: chip number
241 * Return value: no return value
242 * File: src/ipci165.c
244 void ipci165_kthread(kthread_t *kthread)
246 struct canchip_t *chip = (struct canchip_t *)kthread->arg;
247 struct ipci165_chip_t *chip_data = (struct ipci165_chip_t *)chip->chip_data;
249 /* setup the thread environment */
250 init_kthread(kthread, "ipci165");
252 /* this is normal work to do */
253 CANMSG ("kernel thread started!\n");
255 /* an endless loop in which we are doing our work */
259 wait_event_interruptible(kthread->queue,test_bit(CHIP_FLAG_BUS_OFF,&chip_data->flags));
261 /* We need to do a memory barrier here to be sure that
262 the flags are visible on all CPUs. */
265 /* here we are back from sleep because we caught a signal. */
266 if (kthread->terminate)
268 /* we received a request to terminate ourself */
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);
278 clear_bit(CHIP_FLAG_RESET,&chip_data->flags);
280 /* wait at least 100ms for next reset */
284 /* here we go only in case of termination of the thread */
286 /* cleanup the thread, leave */
287 CANMSG ("kernel thread terminated!\n");
288 exit_kthread(kthread);
290 /* returning from the thread here calls the exit functions */
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
298 * Return Value: The function returns computed delay in jiffies
299 * File: src/ipci165.c
301 long ipci165_qfull_latency(struct msgobj_t *obj)
304 latency = obj->hostchip->baudrate;
306 latency=(long)HZ*(CAN_FRAME_MIN_BIT_LEN * BCI_QUEUE_SIZE)/latency + 1;
313 * ipci165_connect_irq: Installs interrupt routine and enable irq on HW
314 * @candev: Pointer to candevice/board structure
316 * Return Value: The function returns zero on success or %-ENODEV on failure
317 * File: src/ipci165.c
319 int ipci165_connect_irq(struct candevice_t *candev)
321 can_ioptr_t crm_addr = candev->aux_base_addr;
323 DEBUGMSG ("ipci165_connect_irq\n");
325 /* install interrupt routine */
326 if (request_irq(candev->sysdevptr.pcidev->irq,
333 // Enable interrupt to PC
334 can_writeb(can_readb(crm_addr + CRM_ICR) | 0x40, crm_addr + CRM_ICR);
336 icr = can_readb(crm_addr + CRM_ICR);
341 * ipci165_disconnect_irq - Disable irq on HW
342 * @candev: Pointer to candevice/board structure
344 * Return Value: The function returns zero on success or %-ENODEV on failure
345 * File: src/ipci165.c
347 void ipci165_disconnect_irq(struct candevice_t *candev)
349 can_ioptr_t crm_addr = candev->aux_base_addr;
351 DEBUGMSG ("ipci165_disconnect_irq\n");
353 // Enable interrupt to PC
354 can_writeb(can_readb(crm_addr + CRM_ICR) & ~0x40, crm_addr + CRM_ICR);
356 icr = can_readb(crm_addr + CRM_ICR);
357 /* deinstall interrupt routine */
358 free_irq(candev->sysdevptr.pcidev->irq, candev);
361 /* * * CAN Functionality * * */
364 * ipci165_chip_config - Can chip configuration
365 * @chip: pointer to chip state structure
367 * Return Value: negative value reports error.
368 * File: src/ipci165.c
370 int ipci165_chip_config(struct canchip_t *chip)
372 struct ipci165_chip_t *chip_data = chip->chip_data;
376 DEBUGMSG ("ipci165_chip_config[%i]\n",chip->chip_idx);
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);
385 data[0] = chip->chip_idx;
388 if (bci_command(chip->hostdevice, CMD_RESET_CAN, 1, data) ||
389 bci_response(chip->hostdevice, CMD_RESET_CAN, &size, data) ||
392 CANMSG ("CAN reset failed!\n");
396 /* configure rx queue */
397 data[0] = chip->chip_idx;
398 data[1] = BCI_LATENCY_MODE;
399 data[2] = 0; /* dummy */
402 if (bci_command(chip->hostdevice, CMD_CONFIG_RX_QUEUE, 3, data) ||
403 bci_response(chip->hostdevice, CMD_CONFIG_RX_QUEUE, &size, data) ||
406 CANMSG ("config RX queue failed!\n");
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;
413 /* start can communication */
414 if ((ret = ipci165_start_chip(chip))) return ret;
420 * ipci165_baud_rate - Set communication parameters
421 * @chip: pointer to chip state structure
422 * @rate: baud rate in Hz
425 * @sampl_pt: not used
428 * Return Value: negative value reports error.
429 * File: src/ipci165.c
431 int ipci165_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
432 int sampl_pt, int flags)
434 DEBUGMSG ("ipci165_baud_rate[%i]\n",chip->chip_idx);
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;
452 * ipci165_set_btregs - Configure bitrate registers
453 * @chip: pointer to chip state structure
454 * @btr0: bitrate register 0
455 * @btr1: bitrate register 1
457 * Return Value: negative value reports error.
458 * File: src/ipci165.c
460 int ipci165_set_btregs(struct canchip_t *chip, unsigned short btr0,
463 unsigned char data[3];
466 DEBUGMSG ("ipci165_set_btregs[%i]: btr0=%02x, btr1=%02x\n",chip->chip_idx,
467 (unsigned)btr0,(unsigned)btr1);
469 /* configure the chip */
470 data[0] = chip->chip_idx;
475 if (bci_command(chip->hostdevice, CMD_INIT_CAN, 3, data) ||
476 bci_response(chip->hostdevice, CMD_INIT_CAN, &size, data) ||
479 CANMSG ("baud rate setup failed!\n");
486 * ipci165_stop_chip - Start chip message processing
487 * @chip: pointer to chip state structure
489 * Return Value: negative value reports error.
490 * File: src/ipci165.c
492 int ipci165_start_chip(struct canchip_t *chip)
497 DEBUGMSG ("ipci165_start_chip[%i]\n",chip->chip_idx);
500 data[0] = chip->chip_idx;
503 if (bci_command(chip->hostdevice, CMD_START_CAN, 1, data) ||
504 bci_response(chip->hostdevice, CMD_START_CAN, &size, data) ||
507 CANMSG ("start chip failed!\n");
514 * ipci165_stop_chip - Stop chip message processing
515 * @chip: pointer to chip state structure
517 * Return Value: negative value reports error.
518 * File: src/ipci165.c
520 int ipci165_stop_chip(struct canchip_t *chip)
525 DEBUGMSG ("ipci165_stop_chip[%i]\n",chip->chip_idx);
527 /* configure the chip */
528 data[0] = chip->chip_idx;
531 if (bci_command(chip->hostdevice, CMD_STOP_CAN, 1, data) ||
532 bci_response(chip->hostdevice, CMD_STOP_CAN, &size, data) ||
535 CANMSG ("stop chip failed!\n");
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
546 * Return Value: negative value reports error.
547 * Positive value indicates immediate reception of message.
548 * File: src/ipci165.c
550 int ipci165_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj)
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
561 * Return Value: negative value reports error.
562 * File: src/ipci165.c
564 int ipci165_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
565 struct canmsg_t *msg)
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
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
581 int ipci165_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
582 struct canmsg_t *msg)
588 * ipci165_check_tx_stat - Checks state of transmission engine
589 * @chip: pointer to chip state structure
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
596 int ipci165_check_tx_stat(struct canchip_t *chip)
602 * ipci165_irq_read_handler - ISR code responsible for receiving
603 * @chip: pointer to chip state structure
604 * @obj: pointer to attached queue description
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
610 void ipci165_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj)
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;
618 unsigned char frame_info;
620 unsigned short tmp16;
623 DEBUGMSG ("ipci165_irq_read_handler[%i]\n",chip->chip_idx);
626 dump_mem(msg_addr, BCI_MSG_SIZE);
627 if (can_readb(msg_addr + BCI_MSG_TYPE) == BCI_MSG_TYPE_CAN)
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);
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);
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)); */
649 /* fill CAN message timestamp */
650 /* can_filltimestamp(&obj->rx_msg.timestamp); */
652 if (frame_info & BCI_MSG_FRAME_EXT)
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);
661 memcpy_fromio(obj->rx_msg.data, msg_addr + BCI_MSG_EXT_DATA, len);
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);
670 memcpy_fromio(obj->rx_msg.data, msg_addr + BCI_MSG_STD_DATA, len);
672 canque_filter_msg2edges(obj->qends, &obj->rx_msg);
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);
680 /* wake up the reset thread if the CAN is in bus off */
681 if (status & BCI_CAN_STATUS_BUS_OFF)
683 CANMSG ("BUS-OFF detected! Restarting\n");
684 set_bit(CHIP_FLAG_BUS_OFF,&chip_data->flags);
685 wake_up(&chip_data->kthread.queue);
690 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_BUS);
694 DEBUGMSG ("ipci165_irq_read_handler[%i]: device status\n", chip->chip_idx);
695 dump_mem(chip->chip_base_addr + OF_STATUS_BUFFER, 12);
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;
703 } while (can_readb(msg_addr + BCI_MSG_STATUS) == BCI_MSG_STATUS_FULL);
708 * ipci165_irq_write_handler - ISR code responsible for transmitting
709 * @chip: pointer to chip state structure
710 * @obj: pointer to attached queue description
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
716 void ipci165_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
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;
725 unsigned char frame_info, ext;
726 unsigned short tmp16;
729 DEBUGMSG ("ipci165_irq_write_handler[%i]\n",chip->chip_idx);
731 while ((canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot) >=0))
733 if (test_bit(CHIP_FLAG_RESET,&chip_data->flags) ||
734 (can_readb(msg_addr + BCI_MSG_STATUS) == BCI_MSG_STATUS_FULL))
736 canque_again_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
738 /* lost interrupt work around */
739 ipci165_generate_irq(obj->hostchip->hostdevice);
741 mod_timer(&obj->tx_timeout, jiffies + ipci165_qfull_latency(obj));
742 DEBUGMSG("ipci165_irq_write_handler[%i]: scheduled retry\n", chip->chip_idx);
747 tx_slot = obj->tx_slot;
748 DEBUGMSG ("msg[%i] : id=%lx dlc=%x flg=%02x\n",
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);
755 len = tx_slot->msg.length;
756 if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
758 ext = tx_slot->msg.flags;
761 ((tx_slot->msg.flags & MSG_RTR) ? BCI_MSG_FRAME_RTR : 0) |
762 ((tx_slot->msg.flags & MSG_EXT) ? BCI_MSG_FRAME_EXT : 0);
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)
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);
774 memcpy_toio(msg_addr + BCI_MSG_EXT_DATA, tx_slot->msg.data, len);
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);
782 memcpy_toio(msg_addr + BCI_MSG_STD_DATA, tx_slot->msg.data, len);
785 dump_mem(msg_addr, BCI_MSG_SIZE);
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);
794 /* next message address */
795 msg_addr = queue_addr + queue->idx * BCI_MSG_SIZE;
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. */
801 obj->tx_slot->msg.flags |= MSG_LOCAL;
802 canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
804 /* Free transmitted slot */
805 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
812 * ipci165_irq_sync_activities - Synchronized access to write handler
813 * @chip: pointer to chip state structure
814 * @obj: pointer to attached queue description
816 * Return Value: The function always returns zero
817 * File: src/ipci165.c
819 void ipci165_irq_sync_activities(struct canchip_t *chip, struct msgobj_t *obj)
821 while(!can_msgobj_test_and_set_fl(obj,TX_LOCK))
823 if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST))
825 ipci165_irq_write_handler(chip, obj);
828 can_msgobj_clear_fl(obj,TX_LOCK);
829 if(can_msgobj_test_fl(obj,TX_REQUEST))
831 /* if(can_msgobj_test_fl(obj,FILTCH_REQUEST) && !obj->tx_slot)
838 * ipci165_irq_chip_handler - ISR for dedicated chip
839 * @chip: pointer to chip state structure
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
845 void ipci165_irq_chip_handler(struct canchip_t *chip)
847 struct msgobj_t *obj = chip->msgobj[0];
848 struct ipci165_chip_t *chip_data = chip->chip_data;
849 struct bci_queue_t *queue;
851 DEBUGMSG ("ipci165_irq_chip_handler[%i]\n",chip->chip_idx);
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);
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) */
863 can_msgobj_set_fl(obj,TX_REQUEST);
865 /* calls unican_irq_write_handler synchronized with other invocations */
866 ipci165_irq_sync_activities(chip, obj);
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
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
886 can_irqreturn_t ipci165_irq_handler(CAN_IRQ_HANDLER_ARGS(irq_number, dev_id))
889 struct candevice_t *candev = (struct candevice_t *)dev_id;
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;
897 /* DEBUGMSG ("ipci165_irq_handler\n"); */
899 /* read interrupt control register (byte 0) */
900 icr = can_readb(crm_addr + CRM_ICR);
902 if ((icr & 0x44) == 0x44)
904 DEBUGMSG ("ipci165_irq_handler: pending interrupt\n");
906 /* confirm pending interrupt */
907 can_writeb(can_readb(ucr1_addr) | 0x01, ucr1_addr);
908 can_writeb(can_readb(ucr1_addr) & ~0x01, ucr1_addr);
910 /* call interrupt handler for every channel */
911 for (i=0 ; i < candev->nr_all_chips ; i++)
913 chip = candev->chip[i];
914 if (chip->flags & CHIP_CONFIGURED)
915 ipci165_irq_chip_handler(candev->chip[i]);
917 DEBUGMSG ("ipci165_irq_handler: interrupt handled\n");
919 retval = CANCHIP_IRQ_HANDLED;
921 DEBUGMSG ("ipci165_irq_handler: not our interrupt\n");
922 retval = CANCHIP_IRQ_NONE;
925 return CAN_IRQ_RETVAL(retval);
929 * ipci165_wakeup_tx - Wakeup TX processing
930 * @chip: pointer to chip state structure
931 * @obj: pointer to message object structure
933 * Function is responsible for initiating message transmition.
934 * It is responsible for clearing of object TX_REQUEST flag
936 * Return Value: negative value reports error.
937 * File: src/ipci165.c
939 int ipci165_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
941 DEBUGMSG ("ipci165_wakeup_tx\n");
942 can_preempt_disable();
944 can_msgobj_set_fl(obj,TX_REQUEST);
946 /* calls ipci165_irq_write_handler synchronized with other invocations
947 from kernel and IRQ context */
948 ipci165_irq_sync_activities(chip, obj);
950 can_preempt_enable();
951 DEBUGMSG ("ipci165_wakeup_tx: finished\n");
956 void ipci165_do_tx_timeout(unsigned long data)
958 struct msgobj_t *obj=(struct msgobj_t *)data;
960 DEBUGMSG ("ipci165_do_tx_timeout\n");
962 can_preempt_disable();
964 can_msgobj_set_fl(obj,TX_REQUEST);
966 /* calls ipci165_irq_write_handler synchronized with other invocations
967 from kernel and IRQ context */
968 ipci165_irq_sync_activities(obj->hostchip, obj);
970 can_preempt_enable();
971 DEBUGMSG ("ipci165_do_tx_timeout: finished\n");
975 * ipci165_attach_to_chip: - attaches to the chip, setups registers and state
976 * @chip: pointer to chip state structure
978 * Return Value: negative value reports error.
979 * File: src/ipci165.c
981 int ipci165_attach_to_chip(struct canchip_t *chip)
987 * ipci165_release_chip: - called before chip structure removal if %CHIP_ATTACHED is set
988 * @chip: pointer to chip state structure
990 * Return Value: negative value reports error.
991 * File: src/ipci165.c
993 int ipci165_release_chip(struct canchip_t *chip)
995 ipci165_stop_chip(chip);
996 /* disable interrupts in the hardware, etc. */
1000 /* * * iPC-I 165/PCI Board Functionality * * */
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
1007 * Return Value: The function returns zero on success or %-ENODEV on failure
1008 * File: src/ipci165.c
1010 int ipci165_request_io(struct candevice_t *candev)
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 */
1017 DEBUGMSG ("ipci165_request_io\n");
1019 crm_addr = pci_resource_start(candev->sysdevptr.pcidev,0);
1020 dpram_addr = pci_resource_start(candev->sysdevptr.pcidev,2);
1022 DEBUGMSG ("ipci165_request_io: crm = 0x%lx, dpram = 0x%lx\n",crm_addr, dpram_addr);
1024 /* verify, if our HW is buggy, and try to fix it */
1026 if (test_bit (7, &crm_addr))
1028 CANMSG ("Wrong PCI base address [0x%lx](PLX PCI9050 bug)!\n", dpram_addr);
1030 fix_addr = pci_resource_start(candev->sysdevptr.pcidev,3);
1034 CANMSG ("This card was not fixed!\n");
1036 if (candev->aux_base_addr == NULL)
1038 CANMSG ("You have to specify IO address parameter!\n");
1041 CANMSG ("Using specified IO address value for the memory [0x%lx]\n",
1042 can_ioptr2ulong(candev->aux_base_addr));
1046 CANMSG ("Fixed card. Using of 3 region [0x%lx]\n", fix_addr);
1047 candev->aux_base_addr = fix_addr;
1050 pci_write_config_dword (candev->sysdevptr.pcidev,
1051 PCI_BASE_ADDRESS_0, fix_addr);
1055 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
1056 if(pci_request_region(candev->sysdevptr.pcidev, 2, "kv_ipci165_dpram") == 0)
1058 if(pci_request_region(candev->sysdevptr.pcidev, 0, "kv_ipci165_reg") == 0)
1060 #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1061 if(pci_request_regions(candev->sysdevptr.pcidev, "kv_ipci165") == 0)
1063 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1065 if ((candev->dev_base_addr = ioremap(dpram_addr,
1066 pci_resource_len(candev->sysdevptr.pcidev,2))))
1068 DEBUGMSG ("ipci165_request_io: dpram remapped to 0x%lx\n", candev->dev_base_addr);
1070 if ((candev->aux_base_addr = ioremap(crm_addr,
1071 pci_resource_len(candev->sysdevptr.pcidev,0))))
1073 DEBUGMSG ("ipci165_request_io: crm remapped to 0x%lx\n", can_ioptr2ulong(candev->aux_base_addr));
1074 /* all resources has been allocated */
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++)
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;
1087 } else CANMSG("Unable to remap memory at: 0x%lx\n", crm_addr);
1088 iounmap(candev->aux_base_addr);
1090 } else CANMSG("Unable to remap memory at: 0x%lx\n", dpram_addr);
1091 iounmap(candev->dev_base_addr);
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");
1097 pci_release_region(candev->sysdevptr.pcidev, 2);
1098 } else CANMSG("Request of kv_ipci165_dpram range failed\n");
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))*/
1109 * ipci165_release_io - Free reserved io memory range
1110 * @candev: pointer to candevice/board which releases io
1112 * Return Value: The function always returns zero
1113 * File: src/ipci165.c
1115 int ipci165_release_io(struct candevice_t *candev)
1117 struct ipci165_chip_t *chip_data;
1120 /* disable irq on HW */
1121 ipci165_disconnect_irq(candev);
1124 /* terminate the kernel threads */
1125 for (i = 0 ; i < candev->nr_all_chips ; i++)
1127 chip_data = (struct ipci165_chip_t *)candev->chip[i]->chip_data;
1128 stop_kthread(&chip_data->restart_thread);
1132 iounmap(candev->aux_base_addr);
1133 iounmap(candev->dev_base_addr);
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))*/
1146 * ipci165_download_fw - Download FW into CAN hardware
1147 * @candev: Pointer to candevice/board structure
1149 * Return Value: returns zero on success
1150 * File: src/ipci165.c
1152 int ipci165_download_fw(struct candevice_t *candev)
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];
1159 struct ipci165_fw_t *fwArray = ipci165_fw;
1162 DEBUGMSG ("ipci165_download_fw\n");
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;
1168 memcpy_fromio (hw_version, dpram_addr + HW_VERSION_OFS, HW_VERSION_LEN);
1169 hw_version[HW_VERSION_LEN] = 0;
1171 CANMSG ("Board Name: %s\n", board_name);
1172 CANMSG ("HW Version: %s\n", hw_version);
1175 if ((hw_version[0] != 'V') && (hw_version[0] != 'v'))
1177 CANMSG ("This board is too old and not supported by the BCI !\n");
1182 /* detect & test mode */
1183 memcpy_fromio (mode, dpram_addr + MODE_OFS, MODE_LEN);
1186 if (strncmp (mode, "PC-Loader V", 11))
1188 CANMSG ("Unknown mode [%s], can't download firmware!\n",mode);
1192 while (fwArray->len)
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);
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); */
1203 memcpy_toio(dpram_addr + OF_LD_DATA, fwArray->a_data, fwArray->len);
1206 dump_mem((void *)(dpram_addr + OF_LD_SYNC), fwArray->len + 8);
1208 /* buffer is prepared, set flag for loader */
1209 can_writeb(1, dpram_addr + OF_LD_SYNC);
1211 /* update pointer */
1214 /* wait for the loader */
1216 while (can_readb(dpram_addr + OF_LD_SYNC) != 0)
1221 /* timeout occured */
1222 CANMSG ("Firmware download failed!\n");
1227 CANMSG ("Firmware downladed successfully\n");
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);
1238 * ipci165_reset - Hardware reset routine
1239 * @candev: Pointer to candevice/board structure
1241 * Return Value: The function returns zero on success or %-ENODEV on failure
1242 * File: src/ipci165.c
1244 int ipci165_reset(struct candevice_t *candev)
1246 can_ioptr_t crm_addr = candev->aux_base_addr;
1247 unsigned long test_data;
1248 char buffer[BCI_CMD_MAX_LEN];
1251 struct canchip_t *chip;
1252 struct ipci165_chip_t *chip_data;
1254 DEBUGMSG ("ipci165_reset: hardware reset\n");
1257 ucr = can_readb(crm_addr + CRM_UCR + 3);
1258 can_writeb(ucr | 0x40, crm_addr + CRM_UCR + 3);
1260 can_writeb(ucr & ~0x40, crm_addr + CRM_UCR + 3);
1262 /* wait a little bit */
1266 if (ipci165_download_fw(candev)) return -ENODEV;
1268 /* enable irq on HW */
1269 if (ipci165_connect_irq(candev))
1271 CANMSG ("Interrupt routine installation for IRQ %i failed!\n",
1272 candev->sysdevptr.pcidev->irq);
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))
1283 CANMSG ("BCI test failed! Test pattern is %lx\n", test_data);
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))
1293 CANMSG ("Firmware Identification reading failed!\n");
1296 CANMSG ("Firmware: %s\n",buffer);
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))
1304 CANMSG ("Firmware Version reading failed!\n");
1307 CANMSG ("Version: %s\n",buffer);
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))
1315 CANMSG ("Get Board Info failed!\n");
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;
1323 CANMSG ("Chips: %i\n",chips);
1324 CANMSG ("Chip 1 Type: %s\n",buffer+OF_BOARD_INFO_CHIP1_TYPE);
1326 /* update board info */
1329 /* we have to correct the number in candev and release allocated
1331 candev->nr_all_chips = chips;
1332 canchip_done(candev->chip[1]);
1334 } else CANMSG ("Chip 2 Type: %s\n",buffer+OF_BOARD_INFO_CHIP2_TYPE);
1336 /* start kernel threads */
1337 for (i = 0 ; i < chips ; i++)
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);
1345 CANMSG ("HW is up and working.\n");
1350 * ipci165_init_hw_data - Initialize hardware cards
1351 * @candev: Pointer to candevice/board structure
1353 * Return Value: The function always returns zero
1354 * File: src/ipci165.c
1356 int ipci165_init_hw_data(struct candevice_t *candev)
1358 struct pci_dev *pcidev = NULL;
1359 unsigned short SubsystemID;
1361 DEBUGMSG ("ipci165_init_hw_data\n");
1363 /* find iPC-I 165 on PCI bus */
1366 pcidev = pci_find_device(IPCI165_VENDOR_ID, IPCI165_DEVICE_ID, pcidev);
1367 if(pcidev == NULL) return -ENODEV;
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))
1375 while(can_check_dev_taken(pcidev));
1378 if (pci_enable_device (pcidev))
1380 CANMSG ("Cannot enable PCI device\n");
1384 candev->sysdevptr.pcidev = pcidev;
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);
1399 #define CHIP_TYPE "ipci165"
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
1406 * Return Value: The function always returns zero
1407 * File: src/ipci165.c
1409 int ipci165_init_chip_data(struct candevice_t *candev, int chipnr)
1411 struct canchip_t *chip = candev->chip[chipnr];
1412 struct ipci165_chip_t *chip_data;
1414 DEBUGMSG ("ipci165_init_chip_data\n");
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;
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. */
1429 chip->chipspecops->irq_handler=ipci165_irq_handler;
1430 chip->chip_irq=candev->sysdevptr.pcidev->irq;
1431 chip->flags |= CHIP_IRQ_PCI;
1434 chip->chipspecops->irq_handler=NULL;
1437 chip->chipspecops->irq_handler = NULL;
1439 chip->flags |= CHIP_IRQ_CUSTOM;
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;
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;
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;
1479 * ipci165_init_obj_data - Initialize message buffers
1480 * @chip: Pointer to chip specific structure
1481 * @objnr: Number of the message buffer
1483 * Return Value: The function always returns zero
1484 * File: src/ipci165.c
1486 int ipci165_init_obj_data(struct canchip_t *chip, int objnr)
1488 struct msgobj_t *obj=chip->msgobj[objnr];
1490 DEBUGMSG ("ipci165_init_obj_data\n");
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;
1499 * ipci165_program_irq - Program interrupts
1500 * @candev: Pointer to candevice/board structure
1502 * Return value: The function returns zero on success or %-ENODEV on failure
1503 * File: src/ipci165.c
1505 int ipci165_program_irq(struct candevice_t *candev)
1511 * ipci165_register - Register Board Support Functions
1512 * @candev: Pointer to hardware/board specific functions
1514 * Return value: The function returns zero on success or %-ENODEV on failure
1515 * File: src/ipci165.c
1517 int ipci165_register(struct hwspecops_t *hwspecops)
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;
1532 void dump_mem(char *ptr, int size)
1535 unsigned char str[80], buf[16];
1538 for (; size > 0; size -= 16)
1540 to = size > 16 ? 16 : size;
1541 memcpy (buf,ptr, to);
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] : '.';
1550 DEBUGMSG ("[%lx] %s\n", (long unsigned)ptr, str);