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"
20 can_irqreturn_t ipci165_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
21 int ipci165_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
22 int sampl_pt, int flags);
23 int ipci165_set_btregs(struct canchip_t *chip, unsigned short btr0,
25 int ipci165_start_chip(struct canchip_t *chip);
28 void dump_mem(char *ptr, int size);
33 #define ipci165_load_btr(btr,btr0,btr1) {*btr = btr0; *(btr+1) = btr1;}
36 * ipci165_delay - Delay the execution
37 * @msdelay: milliseconds to wait
39 * Return value: no return value
42 static void ipci165_delay(long msdelay)
45 if(!rtl_rt_system_is_idle())
47 rtl_delay(1000000l*msdelay);
49 #endif /*CAN_WITH_RTL*/
51 set_current_state(TASK_UNINTERRUPTIBLE);
52 schedule_timeout((msdelay*HZ)/1000+1);
57 * ipci165_generate_irq - Generate irq for HW
58 * @candev: Pointer to hardware/board specific functions
60 * Return value: The function returns zero on success or non zero on failure
63 void ipci165_generate_irq(struct candevice_t *candev)
65 unsigned long crm_addr = candev->io_addr;
66 writeb(readb(crm_addr + CRM_UCR) & 0xFB, crm_addr + CRM_UCR);
67 writeb(readb(crm_addr + CRM_UCR) | 0x04, crm_addr + CRM_UCR);
71 * bci_command - Send command to controller
72 * @candev: Pointer to hardware/board specific functions
73 * @cmd: Command to be performed
74 * @size: Command data size
77 * Return value: The function returns zero on success or non zero on failure
80 int bci_command(struct candevice_t *candev, char cmd, int size, char *data)
82 unsigned long dpram_addr = candev->dev_base_addr;
84 DEBUGMSG ("ipci165_bci_command\n");
86 if (size > BCI_CMD_MAX_LEN)
88 DEBUGMSG ("ipci165_bci_command: parameter error\n");
92 /* grant access to the command buffer */
93 can_spin_lock(&candev->device_lock);
95 // check command buffer status
96 if (readb(dpram_addr + OF_BCI_SYNC) != 0)
98 /* something went wrong ... */
99 can_spin_unlock(&candev->device_lock);
100 DEBUGMSG ("ipci165_bci_command: command buffer is busy\n");
105 writeb(cmd, dpram_addr + OF_BCI_CMD);
106 writeb(size + 1, dpram_addr + OF_BCI_NUM);
107 memcpy_toio(dpram_addr + OF_BCI_DATA, data, size);
109 // set flag for firmware
110 writeb(1, dpram_addr + OF_BCI_SYNC);
112 // generate interrupt to microcontroller
113 ipci165_generate_irq (candev);
119 * bci_response - Get response from controller
120 * @candev: Pointer to hardware/board specific functions
121 * @cmd: Command to get response for
122 * @size: Command data size
123 * @data: Command data
125 * Return value: The function returns zero on success or non zero on failure
126 * File: src/ipci165.c
128 int bci_response(struct candevice_t *candev, char cmd, int *size, char *data)
130 unsigned long dpram_addr = candev->dev_base_addr;
134 DEBUGMSG ("ipci165_bci_response\n");
137 while (readb(dpram_addr + OF_BCI_SYNC) != 2)
140 /* ipci165_delay(1); */
144 /* timeout occured */
145 /* release the lock */
146 can_spin_unlock(&candev->device_lock);
147 CANMSG ("BCI timeout!\n");
152 /* we will not copy the command filed, so decrement the size by 1 */
153 tmp = readb(dpram_addr + OF_BCI_NUM) - 1;
154 if (*size > tmp) *size = tmp;
156 if (readb(dpram_addr + OF_BCI_CMD) != cmd)
158 /* release the buffer */
159 writeb(0, dpram_addr + OF_BCI_SYNC);
160 /* unlock the access */
161 can_spin_unlock(&candev->device_lock);
163 DEBUGMSG ("ipci165_bci_command: invalid answer\n");
166 memcpy_fromio(data, dpram_addr + OF_BCI_DATA, *size);
168 /* release the buffer */
169 writeb(0, dpram_addr + OF_BCI_SYNC);
170 /* unlock the access */
171 can_spin_unlock(&candev->device_lock);
176 * ipci165_restart_can - Flush queues and sestart can controller
177 * @candev: Pointer to hardware/board specific functions
178 * @chip_idx: chip number
180 * Return value: The function returns zero on success or non zero on failure
181 * File: src/ipci165.c
183 int ipci165_restart_can(struct canchip_t *chip)
189 struct ipci165_chip_t *chip_data;
190 unsigned long msg_ofs;
193 data[0] = chip->chip_idx;
195 if (bci_command(chip->hostdevice, CMD_RESET_CAN, 1, data) ||
196 bci_response(chip->hostdevice, CMD_RESET_CAN, &size, data) ||
199 CANMSG ("CAN reset failed!\n");
203 /* flush TX/RX queues in DP-RAM */
204 chip_data = (struct ipci165_chip_t *)chip->chip_data;
205 msg_ofs = BCI_MSG_STATUS;
207 for (i = 0; i< BCI_QUEUE_SIZE; i++)
209 writeb(BCI_MSG_STATUS_FREE, chip_data->rx_queue.addr + msg_ofs);
210 writeb(BCI_MSG_STATUS_FREE, chip_data->tx_queue.addr + msg_ofs);
211 msg_ofs += BCI_MSG_SIZE;
214 /* In- and output buffer re-initialization */
215 canqueue_ends_flush_inlist(chip->msgobj[0]->qends);
216 canqueue_ends_flush_outlist(chip->msgobj[0]->qends);
219 data[0] = chip->chip_idx;
221 if (bci_command(chip->hostdevice, CMD_START_CAN, 1, data) ||
222 bci_response(chip->hostdevice, CMD_START_CAN, &size, data) ||
225 CANMSG ("start chip failed!\n");
231 /* this is the thread function that we are executing */
233 * ipci165_kthread - Thread restarting can controller after bus-off.
234 * @kthread: pointer to kernel thread descriptor
235 * @chip_idx: chip number
237 * Return value: no return value
238 * File: src/ipci165.c
240 void ipci165_kthread(kthread_t *kthread)
242 struct canchip_t *chip = (struct canchip_t *)kthread->arg;
243 struct ipci165_chip_t *chip_data = (struct ipci165_chip_t *)chip->chip_data;
245 /* setup the thread environment */
246 init_kthread(kthread, "ipci165");
248 /* this is normal work to do */
249 CANMSG ("kernel thread started!\n");
251 /* an endless loop in which we are doing our work */
255 wait_event_interruptible(kthread->queue,test_bit(CHIP_FLAG_BUS_OFF,&chip_data->flags));
257 /* We need to do a memory barrier here to be sure that
258 the flags are visible on all CPUs. */
261 /* here we are back from sleep because we caught a signal. */
262 if (kthread->terminate)
264 /* we received a request to terminate ourself */
269 clear_bit(CHIP_FLAG_BUS_OFF,&chip_data->flags);
270 set_bit(CHIP_FLAG_RESET,&chip_data->flags);
271 /* this is normal work to do */
272 ipci165_restart_can(chip);
274 clear_bit(CHIP_FLAG_RESET,&chip_data->flags);
276 /* wait at least 100ms for next reset */
280 /* here we go only in case of termination of the thread */
282 /* cleanup the thread, leave */
283 CANMSG ("kernel thread terminated!\n");
284 exit_kthread(kthread);
286 /* returning from the thread here calls the exit functions */
290 * ipci165_qfull_latency - Compute delay to send out full tx queue
291 * @candev: Pointer to candevice/board structure
292 * @obj: pointer to message object state structure
294 * Return Value: The function returns computed delay in jiffies
295 * File: src/ipci165.c
297 long ipci165_qfull_latency(struct msgobj_t *obj)
300 latency = obj->hostchip->baudrate;
302 latency=(long)HZ*(CAN_FRAME_MIN_BIT_LEN * BCI_QUEUE_SIZE)/latency + 1;
309 * ipci165_connect_irq: Installs interrupt routine and enable irq on HW
310 * @candev: Pointer to candevice/board structure
312 * Return Value: The function returns zero on success or %-ENODEV on failure
313 * File: src/ipci165.c
315 int ipci165_connect_irq(struct candevice_t *candev)
317 unsigned long crm_addr = candev->io_addr;
319 DEBUGMSG ("ipci165_connect_irq\n");
321 /* install interrupt routine */
322 if (request_irq(candev->sysdevptr.pcidev->irq,
329 // Enable interrupt to PC
330 writeb(readb(crm_addr + CRM_ICR) | 0x40, crm_addr + CRM_ICR);
332 icr = readb(crm_addr + CRM_ICR);
337 * ipci165_disconnect_irq - Disable irq on HW
338 * @candev: Pointer to candevice/board structure
340 * Return Value: The function returns zero on success or %-ENODEV on failure
341 * File: src/ipci165.c
343 void ipci165_disconnect_irq(struct candevice_t *candev)
345 unsigned long crm_addr = candev->io_addr;
347 DEBUGMSG ("ipci165_disconnect_irq\n");
349 // Enable interrupt to PC
350 writeb(readb(crm_addr + CRM_ICR) & ~0x40, crm_addr + CRM_ICR);
352 icr = readb(crm_addr + CRM_ICR);
353 /* deinstall interrupt routine */
354 free_irq(candev->sysdevptr.pcidev->irq, candev);
357 /* * * CAN Functionality * * */
360 * ipci165_chip_config - Can chip configuration
361 * @chip: pointer to chip state structure
363 * Return Value: negative value reports error.
364 * File: src/ipci165.c
366 int ipci165_chip_config(struct canchip_t *chip)
368 struct ipci165_chip_t *chip_data = chip->chip_data;
372 DEBUGMSG ("ipci165_chip_config[%i]\n",chip->chip_idx);
374 /* comupte the base address of tx and rx queue for the channel */
375 chip_data->tx_queue.addr = chip->chip_base_addr + OF_CH1_TX_QUEUE +
376 chip->chip_idx * (OF_CH2_TX_QUEUE-OF_CH1_TX_QUEUE);
377 chip_data->rx_queue.addr = chip->chip_base_addr + OF_CH1_RX_QUEUE +
378 chip->chip_idx * (OF_CH2_RX_QUEUE-OF_CH1_RX_QUEUE);
381 data[0] = chip->chip_idx;
384 if (bci_command(chip->hostdevice, CMD_RESET_CAN, 1, data) ||
385 bci_response(chip->hostdevice, CMD_RESET_CAN, &size, data) ||
388 CANMSG ("CAN reset failed!\n");
392 /* configure rx queue */
393 data[0] = chip->chip_idx;
394 data[1] = BCI_LATENCY_MODE;
395 data[2] = 0; /* dummy */
398 if (bci_command(chip->hostdevice, CMD_CONFIG_RX_QUEUE, 3, data) ||
399 bci_response(chip->hostdevice, CMD_CONFIG_RX_QUEUE, &size, data) ||
402 CANMSG ("config RX queue failed!\n");
405 /* setup baud rate */
406 if (!chip->baudrate) chip->baudrate = 1000000;
407 if ((ret = ipci165_baud_rate(chip, chip->baudrate, chip->clock, 0, 0, 0))) return ret;
409 /* start can communication */
410 if ((ret = ipci165_start_chip(chip))) return ret;
416 * ipci165_baud_rate - Set communication parameters
417 * @chip: pointer to chip state structure
418 * @rate: baud rate in Hz
421 * @sampl_pt: not used
424 * Return Value: negative value reports error.
425 * File: src/ipci165.c
427 int ipci165_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
428 int sampl_pt, int flags)
430 DEBUGMSG ("ipci165_baud_rate[%i]\n",chip->chip_idx);
433 case 10000: return ipci165_set_btregs(chip, BCI_10KB);
434 case 20000: return ipci165_set_btregs(chip, BCI_20KB);
435 case 50000: return ipci165_set_btregs(chip, BCI_50KB);
436 case 100000: return ipci165_set_btregs(chip, BCI_100KB);
437 case 125000: return ipci165_set_btregs(chip, BCI_125KB);
438 case 250000: return ipci165_set_btregs(chip, BCI_250KB);
439 case 500000: return ipci165_set_btregs(chip, BCI_500KB);
440 case 1000000:return ipci165_set_btregs(chip, BCI_1000KB);
441 default: return -EINVAL;
448 * ipci165_set_btregs - Configure bitrate registers
449 * @chip: pointer to chip state structure
450 * @btr0: bitrate register 0
451 * @btr1: bitrate register 1
453 * Return Value: negative value reports error.
454 * File: src/ipci165.c
456 int ipci165_set_btregs(struct canchip_t *chip, unsigned short btr0,
459 unsigned char data[3];
462 DEBUGMSG ("ipci165_set_btregs[%i]: btr0=%02x, btr1=%02x\n",chip->chip_idx,
463 (unsigned)btr0,(unsigned)btr1);
465 /* configure the chip */
466 data[0] = chip->chip_idx;
471 if (bci_command(chip->hostdevice, CMD_INIT_CAN, 3, data) ||
472 bci_response(chip->hostdevice, CMD_INIT_CAN, &size, data) ||
475 CANMSG ("baud rate setup failed!\n");
482 * ipci165_stop_chip - Start chip message processing
483 * @chip: pointer to chip state structure
485 * Return Value: negative value reports error.
486 * File: src/ipci165.c
488 int ipci165_start_chip(struct canchip_t *chip)
493 DEBUGMSG ("ipci165_start_chip[%i]\n",chip->chip_idx);
496 data[0] = chip->chip_idx;
499 if (bci_command(chip->hostdevice, CMD_START_CAN, 1, data) ||
500 bci_response(chip->hostdevice, CMD_START_CAN, &size, data) ||
503 CANMSG ("start chip failed!\n");
510 * ipci165_stop_chip - Stop chip message processing
511 * @chip: pointer to chip state structure
513 * Return Value: negative value reports error.
514 * File: src/ipci165.c
516 int ipci165_stop_chip(struct canchip_t *chip)
521 DEBUGMSG ("ipci165_stop_chip[%i]\n",chip->chip_idx);
523 /* configure the chip */
524 data[0] = chip->chip_idx;
527 if (bci_command(chip->hostdevice, CMD_STOP_CAN, 1, data) ||
528 bci_response(chip->hostdevice, CMD_STOP_CAN, &size, data) ||
531 CANMSG ("stop chip failed!\n");
538 * ipci165_pre_read_config - Prepare message object for message reception
539 * @chip: pointer to chip state structure
540 * @obj: pointer to message object state structure
542 * Return Value: negative value reports error.
543 * Positive value indicates immediate reception of message.
544 * File: src/ipci165.c
546 int ipci165_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj)
552 * ipci165_pre_write_config - Prepare message object for message transmission
553 * @chip: pointer to chip state structure
554 * @obj: pointer to message object state structure
555 * @msg: pointer to CAN message
557 * Return Value: negative value reports error.
558 * File: src/ipci165.c
560 int ipci165_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
561 struct canmsg_t *msg)
567 * ipci165_send_msg - Initiate message transmission
568 * @chip: pointer to chip state structure
569 * @obj: pointer to message object state structure
570 * @msg: pointer to CAN message
572 * This function is called after ipci165_pre_write_config() function,
573 * which prepares data in chip buffer.
574 * Return Value: negative value reports error.
575 * File: src/ipci165.c
577 int ipci165_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
578 struct canmsg_t *msg)
584 * ipci165_check_tx_stat - Checks state of transmission engine
585 * @chip: pointer to chip state structure
587 * Return Value: negative value reports error.
588 * Positive return value indicates transmission under way status.
589 * Zero value indicates finishing of all issued transmission requests.
590 * File: src/ipci165.c
592 int ipci165_check_tx_stat(struct canchip_t *chip)
598 * ipci165_irq_read_handler - ISR code responsible for receiving
599 * @chip: pointer to chip state structure
600 * @obj: pointer to attached queue description
602 * The main purpose of this function is to read message from CAN controller and
603 * transfer them to attached queues
604 * File: src/ipci165.c
606 void ipci165_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj)
608 struct ipci165_chip_t *chip_data = (struct ipci165_chip_t *)chip->chip_data;
609 struct bci_queue_t *queue = &(chip_data)->rx_queue;
610 unsigned long queue_addr = queue->addr;
611 unsigned long msg_addr = queue_addr + queue->idx * BCI_MSG_SIZE;
614 unsigned char frame_info;
616 unsigned short tmp16;
619 DEBUGMSG ("ipci165_irq_read_handler[%i]\n",chip->chip_idx);
622 dump_mem(msg_addr, BCI_MSG_SIZE);
623 if (readb(msg_addr + BCI_MSG_TYPE) == BCI_MSG_TYPE_CAN)
626 printk("ST(0)=%x, ST(1)=%x\n",readw(chip->chip_base_addr+OF_CAN1_STATUS),
627 readw(chip->chip_base_addr+OF_CAN2_STATUS));
628 for (tmp16 = 0 ; tmp16 < BCI_QUEUE_SIZE ; tmp16 ++)
629 printk ("MSG_ST(%i)=%x\n",tmp16,readb(chip->chip_base_addr + OF_CH2_TX_QUEUE + tmp16*BCI_MSG_SIZE + BCI_MSG_STATUS));
630 /* this is a can message */
631 DEBUGMSG ("ipci165_irq_read_handler[%i]: message in buffer\n",chip->chip_idx);
634 frame_info = readb(msg_addr + BCI_MSG_FRAME);
635 len = frame_info & 0x0f;
636 if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
637 obj->rx_msg.length = len;
638 obj->rx_msg.flags = (frame_info & BCI_MSG_FRAME_RTR ? MSG_RTR : 0);
640 obj->rx_msg.timestamp.tv_sec = 0;
641 obj->rx_msg.timestamp.tv_usec =
642 BCI_TIMESTAMP_RES * readl(msg_addr + BCI_MSG_TIMESTAMP);
643 /* BCI_TIMESTAMP_RES * le32_to_cpu(readl(msg_addr + BCI_MSG_TIMESTAMP)); */
645 /* fill CAN message timestamp */
646 /* can_filltimestamp(&obj->rx_msg.timestamp); */
648 if (frame_info & BCI_MSG_FRAME_EXT)
650 /* extended frame - 29 bit identifier */
651 obj->rx_msg.flags |= MSG_EXT;
652 /* the ID is stored in motorola format (big endian), left justified */
653 /* obj->rx_msg.id = be32_to_cpu(readl(msg_addr + BCI_MSG_ID) >> 3); */
654 memcpy_fromio(&tmp32, msg_addr + BCI_MSG_ID, 4);
655 obj->rx_msg.id = be32_to_cpu(tmp32 >> 3);
657 memcpy_fromio(obj->rx_msg.data, msg_addr + BCI_MSG_EXT_DATA, len);
660 /* standard frame - 11 bit identifier */
661 /* the ID is stored in motorola format (big endian), left justified */
662 /* obj->rx_msg.id = be16_to_cpu(readw(msg_addr + BCI_MSG_ID) >> 5); */
663 memcpy_fromio(&tmp16, msg_addr + BCI_MSG_ID, 2);
664 obj->rx_msg.id = be16_to_cpu(tmp16 >> 5);
666 memcpy_fromio(obj->rx_msg.data, msg_addr + BCI_MSG_STD_DATA, len);
668 canque_filter_msg2edges(obj->qends, &obj->rx_msg);
672 /* this is a status message */
673 status = readw(msg_addr + BCI_MSG_CAN_STATUS);
674 DEBUGMSG ("ipci165_irq_read_handler[%i]: CAN status=%04x\n",chip->chip_idx, status);
676 /* wake up the reset thread if the CAN is in bus off */
677 if (status & BCI_CAN_STATUS_BUS_OFF)
679 CANMSG ("BUS-OFF detected! Restarting\n");
680 set_bit(CHIP_FLAG_BUS_OFF,&chip_data->flags);
681 wake_up(&chip_data->kthread.queue);
686 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_BUS);
690 DEBUGMSG ("ipci165_irq_read_handler[%i]: device status\n", chip->chip_idx);
691 dump_mem(chip->chip_base_addr + OF_STATUS_BUFFER, 12);
694 queue->idx = (queue->idx + 1) % BCI_QUEUE_SIZE;
695 /* release the buffer */
696 writeb(BCI_MSG_STATUS_FREE, msg_addr + BCI_MSG_STATUS);
697 msg_addr = queue_addr + queue->idx * BCI_MSG_SIZE;
699 } while (readb(msg_addr + BCI_MSG_STATUS) == BCI_MSG_STATUS_FULL);
704 * ipci165_irq_write_handler - ISR code responsible for transmitting
705 * @chip: pointer to chip state structure
706 * @obj: pointer to attached queue description
708 * The main purpose of this function is to read message from attached queues
709 * and transfer message contents into CAN controller chip.
710 * File: src/ipci165.c
712 void ipci165_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
714 struct ipci165_chip_t *chip_data = ((struct ipci165_chip_t *)chip->chip_data);
715 struct bci_queue_t *queue = &chip_data->tx_queue;
716 unsigned long queue_addr = queue->addr;
717 unsigned long msg_addr = queue_addr + queue->idx * BCI_MSG_SIZE;
718 struct canque_slot_t *tx_slot;
721 unsigned char frame_info, ext;
722 unsigned short tmp16;
725 DEBUGMSG ("ipci165_irq_write_handler[%i]\n",chip->chip_idx);
727 while ((canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot) >=0))
729 if (test_bit(CHIP_FLAG_RESET,&chip_data->flags) ||
730 (readb(msg_addr + BCI_MSG_STATUS) == BCI_MSG_STATUS_FULL))
732 canque_again_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
734 /* lost interrupt work around */
735 ipci165_generate_irq(obj->hostchip->hostdevice);
737 mod_timer(&obj->tx_timeout, jiffies + ipci165_qfull_latency(obj));
738 DEBUGMSG("ipci165_irq_write_handler[%i]: scheduled retry\n", chip->chip_idx);
743 tx_slot = obj->tx_slot;
744 DEBUGMSG ("msg[%i] : id=%lx dlc=%x flg=%02x\n",
746 (unsigned long)tx_slot->msg.id,
747 (unsigned int)tx_slot->msg.length,
748 (unsigned int)tx_slot->msg.flags);
749 dump_mem(tx_slot->msg.data, tx_slot->msg.length);
751 len = tx_slot->msg.length;
752 if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
754 ext = tx_slot->msg.flags;
757 ((tx_slot->msg.flags & MSG_RTR) ? BCI_MSG_FRAME_RTR : 0) |
758 ((tx_slot->msg.flags & MSG_EXT) ? BCI_MSG_FRAME_EXT : 0);
760 writeb(BCI_MSG_SIZE - 2, msg_addr + BCI_MSG_NUM);
761 writeb(BCI_MSG_TYPE_CAN, msg_addr + BCI_MSG_TYPE);
762 writeb(frame_info, msg_addr + BCI_MSG_FRAME);
763 if (frame_info & BCI_MSG_FRAME_EXT)
765 /* extended frame - 29 bit identifier */
766 /* the ID is stored in motorola format (big endian), left justified */
767 tmp32 = be32_to_cpu(tx_slot->msg.id) << 3;
768 memcpy_toio(msg_addr + BCI_MSG_ID, &tmp32, 4);
770 memcpy_toio(msg_addr + BCI_MSG_EXT_DATA, tx_slot->msg.data, len);
773 /* standard frame - 11 bit identifier */
774 /* the ID is stored in motorola format (big endian), left justified */
775 tmp16 = be16_to_cpu(tx_slot->msg.id) << 5;
776 memcpy_toio(msg_addr + BCI_MSG_ID, &tmp16, 2);
778 memcpy_toio(msg_addr + BCI_MSG_STD_DATA, tx_slot->msg.data, len);
781 dump_mem(msg_addr, BCI_MSG_SIZE);
784 queue->idx = (queue->idx + 1) % BCI_QUEUE_SIZE;
785 /* mark the buffer as full */
786 writeb(BCI_MSG_STATUS_FULL, msg_addr + BCI_MSG_STATUS);
787 /* wake up the controller */
788 ipci165_generate_irq(chip->hostdevice);
790 /* next message address */
791 msg_addr = queue_addr + queue->idx * BCI_MSG_SIZE;
793 /* Do local transmitted message distribution if enabled. */
794 /* This code should not be called directly there, because it breaks strict
795 behavior of queues if O_SYNC is set. */
797 obj->tx_slot->msg.flags |= MSG_LOCAL;
798 canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
800 /* Free transmitted slot */
801 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
808 * ipci165_irq_sync_activities - Synchronized access to write handler
809 * @chip: pointer to chip state structure
810 * @obj: pointer to attached queue description
812 * Return Value: The function always returns zero
813 * File: src/ipci165.c
815 void ipci165_irq_sync_activities(struct canchip_t *chip, struct msgobj_t *obj)
817 while(!can_msgobj_test_and_set_fl(obj,TX_LOCK))
819 if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST))
821 ipci165_irq_write_handler(chip, obj);
824 can_msgobj_clear_fl(obj,TX_LOCK);
825 if(can_msgobj_test_fl(obj,TX_REQUEST))
827 /* if(can_msgobj_test_fl(obj,FILTCH_REQUEST) && !obj->tx_slot)
834 * ipci165_irq_chip_handler - ISR for dedicated chip
835 * @chip: pointer to chip state structure
837 * The main purpose of this function is to perform all necessary channel
838 * operations as a reaction on signalled interrupt.
839 * File: src/ipci165.c
841 void ipci165_irq_chip_handler(struct canchip_t *chip)
843 struct msgobj_t *obj = chip->msgobj[0];
844 struct ipci165_chip_t *chip_data = chip->chip_data;
845 struct bci_queue_t *queue;
847 DEBUGMSG ("ipci165_irq_chip_handler[%i]\n",chip->chip_idx);
849 /* check receive queue for messages */
850 queue = &chip_data->rx_queue;
851 if (readb(queue->addr + queue->idx * BCI_MSG_SIZE + BCI_MSG_STATUS)
852 == BCI_MSG_STATUS_FULL)
853 ipci165_irq_read_handler(chip, obj);
855 queue = &chip_data->tx_queue;
856 /* if (readb(queue->addr + queue->idx * BCI_MSG_SIZE + BCI_MSG_STATUS)
857 == BCI_MSG_STATUS_FREE) */
859 can_msgobj_set_fl(obj,TX_REQUEST);
861 /* calls unican_irq_write_handler synchronized with other invocations */
862 ipci165_irq_sync_activities(chip, obj);
870 * ipci165_irq_handler - Interrupt service routine
871 * @irq: interrupt vector number, this value is system specific
872 * @dev_id: driver private pointer registered at time of request_irq() call.
873 * The CAN driver uses this pointer to store relationship of interrupt
874 * to chip state structure - @struct canchip_t
875 * @regs: system dependent value pointing to registers stored in exception frame
877 * The interrupt handler is activated when the ipci165 controller generates
878 * an interrupt as a reaction an internal state change. The interrupt is
879 * acknowledged and ipci165_irq_chip_handler is called for every channel.
880 * File: src/ipci165.c
882 can_irqreturn_t ipci165_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
885 struct candevice_t *candev = (struct candevice_t *)dev_id;
887 unsigned long crm_addr = candev->io_addr;
888 unsigned long ucr1_addr = crm_addr + CRM_UCR + 1;
889 struct canchip_t *chip;
893 /* DEBUGMSG ("ipci165_irq_handler\n"); */
895 /* read interrupt control register (byte 0) */
896 icr = readb(crm_addr + CRM_ICR);
898 if ((icr & 0x44) == 0x44)
900 DEBUGMSG ("ipci165_irq_handler: pending interrupt\n");
902 /* confirm pending interrupt */
903 writeb(readb(ucr1_addr) | 0x01, ucr1_addr);
904 writeb(readb(ucr1_addr) & ~0x01, ucr1_addr);
906 /* call interrupt handler for every channel */
907 for (i=0 ; i < candev->nr_all_chips ; i++)
909 chip = candev->chip[i];
910 if (chip->flags & CHIP_CONFIGURED)
911 ipci165_irq_chip_handler(candev->chip[i]);
913 DEBUGMSG ("ipci165_irq_handler: interrupt handled\n");
915 retval = CANCHIP_IRQ_HANDLED;
917 DEBUGMSG ("ipci165_irq_handler: not our interrupt\n");
918 retval = CANCHIP_IRQ_NONE;
921 return CAN_IRQ_RETVAL(retval);
925 * ipci165_wakeup_tx - Wakeup TX processing
926 * @chip: pointer to chip state structure
927 * @obj: pointer to message object structure
929 * Function is responsible for initiating message transmition.
930 * It is responsible for clearing of object TX_REQUEST flag
932 * Return Value: negative value reports error.
933 * File: src/ipci165.c
935 int ipci165_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
937 DEBUGMSG ("ipci165_wakeup_tx\n");
938 can_preempt_disable();
940 can_msgobj_set_fl(obj,TX_REQUEST);
942 /* calls ipci165_irq_write_handler synchronized with other invocations
943 from kernel and IRQ context */
944 ipci165_irq_sync_activities(chip, obj);
946 can_preempt_enable();
947 DEBUGMSG ("ipci165_wakeup_tx: finished\n");
952 void ipci165_do_tx_timeout(unsigned long data)
954 struct msgobj_t *obj=(struct msgobj_t *)data;
956 DEBUGMSG ("ipci165_do_tx_timeout\n");
958 can_preempt_disable();
960 can_msgobj_set_fl(obj,TX_REQUEST);
962 /* calls ipci165_irq_write_handler synchronized with other invocations
963 from kernel and IRQ context */
964 ipci165_irq_sync_activities(obj->hostchip, obj);
966 can_preempt_enable();
967 DEBUGMSG ("ipci165_do_tx_timeout: finished\n");
971 * ipci165_attach_to_chip: - attaches to the chip, setups registers and state
972 * @chip: pointer to chip state structure
974 * Return Value: negative value reports error.
975 * File: src/ipci165.c
977 int ipci165_attach_to_chip(struct canchip_t *chip)
983 * ipci165_release_chip: - called before chip structure removal if %CHIP_ATTACHED is set
984 * @chip: pointer to chip state structure
986 * Return Value: negative value reports error.
987 * File: src/ipci165.c
989 int ipci165_release_chip(struct canchip_t *chip)
991 ipci165_stop_chip(chip);
992 /* disable interrupts in the hardware, etc. */
996 /* * * iPC-I 165/PCI Board Functionality * * */
999 * ipci165_request_io - Reserve io or memory range for can board
1000 * @candev: pointer to candevice/board which asks for io. Field @io_addr
1001 * of @candev is used in most cases to define start of the range
1003 * Return Value: The function returns zero on success or %-ENODEV on failure
1004 * File: src/ipci165.c
1006 int ipci165_request_io(struct candevice_t *candev)
1008 unsigned long dpram_addr;
1009 unsigned long crm_addr;
1010 unsigned long fix_addr;
1013 DEBUGMSG ("ipci165_request_io\n");
1015 crm_addr = pci_resource_start(candev->sysdevptr.pcidev,0);
1016 dpram_addr = pci_resource_start(candev->sysdevptr.pcidev,2);
1018 DEBUGMSG ("ipci165_request_io: crm = 0x%lx, dpram = 0x%lx\n",crm_addr, dpram_addr);
1020 /* verify, if our HW is buggy, and try to fix it */
1022 if (test_bit (7, &crm_addr))
1024 CANMSG ("Wrong PCI base address [0x%lx](PLX PCI9050 bug)!\n", dpram_addr);
1026 fix_addr = pci_resource_start(candev->sysdevptr.pcidev,3);
1030 CANMSG ("This card was not fixed!\n");
1032 if (candev->io_addr == 0)
1034 CANMSG ("You have to specify IO address parameter!\n");
1037 CANMSG ("Using specified IO address value for the memory [0x%lx]\n",
1042 CANMSG ("Fixed card. Using of 3 region [0x%lx]\n", fix_addr);
1043 candev->io_addr = fix_addr;
1046 pci_write_config_dword (candev->sysdevptr.pcidev,
1047 PCI_BASE_ADDRESS_0, fix_addr);
1051 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
1052 if(pci_request_region(candev->sysdevptr.pcidev, 2, "kv_ipci165_dpram") == 0)
1054 if(pci_request_region(candev->sysdevptr.pcidev, 0, "kv_ipci165_reg") == 0)
1056 #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1057 if(pci_request_regions(candev->sysdevptr.pcidev, "kv_ipci165") == 0)
1059 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1061 if ((candev->dev_base_addr = (long) ioremap(dpram_addr,
1062 pci_resource_len(candev->sysdevptr.pcidev,2))))
1064 DEBUGMSG ("ipci165_request_io: dpram remapped to 0x%lx\n", candev->dev_base_addr);
1066 if ((candev->io_addr = (long) ioremap(crm_addr,
1067 pci_resource_len(candev->sysdevptr.pcidev,0))))
1069 DEBUGMSG ("ipci165_request_io: crm remapped to 0x%lx\n", candev->io_addr);
1070 /* all resources has been allocated */
1071 candev->res_addr=candev->io_addr;
1073 /* Because of my mapping, I cannot use the
1074 can_base_addr_fixup(candev, remap_addr) to remap the addresses */
1075 for(i=0;i<candev->nr_all_chips;i++)
1077 candev->chip[i]->chip_base_addr = candev->dev_base_addr;
1078 for(j=0;j<candev->chip[i]->max_objects;j++)
1079 candev->chip[i]->msgobj[j]->obj_base_addr = candev->dev_base_addr;
1084 } else CANMSG("Unable to remap memory at: 0x%lx\n", crm_addr);
1085 iounmap((void*)candev->io_addr);
1087 } else CANMSG("Unable to remap memory at: 0x%lx\n", dpram_addr);
1088 iounmap((void*)candev->dev_base_addr);
1090 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
1091 pci_release_region(candev->sysdevptr.pcidev, 0);
1092 } else CANMSG("Request of kv_ipci165_reg range failed\n");
1094 pci_release_region(candev->sysdevptr.pcidev, 2);
1095 } else CANMSG("Request of kv_ipci165_dpram range failed\n");
1097 #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1098 pci_release_regions(candev->sysdevptr.pcidev);
1099 } else CANMSG("Request of kv_ipci165 regions failed\n");
1100 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1106 * ipci165_release_io - Free reserved io memory range
1107 * @candev: pointer to candevice/board which releases io
1109 * Return Value: The function always returns zero
1110 * File: src/ipci165.c
1112 int ipci165_release_io(struct candevice_t *candev)
1114 struct ipci165_chip_t *chip_data;
1117 /* disable irq on HW */
1118 ipci165_disconnect_irq(candev);
1121 /* terminate the kernel threads */
1122 for (i = 0 ; i < candev->nr_all_chips ; i++)
1124 chip_data = (struct ipci165_chip_t *)candev->chip[i]->chip_data;
1125 stop_kthread(&chip_data->restart_thread);
1129 iounmap((void*)candev->io_addr);
1130 iounmap((void*)candev->dev_base_addr);
1132 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
1133 pci_release_region(candev->sysdevptr.pcidev, 2);
1134 pci_release_region(candev->sysdevptr.pcidev, 0);
1135 #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1136 pci_release_regions(candev->sysdevptr.pcidev);
1137 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1143 * ipci165_download_fw - Download FW into CAN hardware
1144 * @candev: Pointer to candevice/board structure
1146 * Return Value: returns zero on success
1147 * File: src/ipci165.c
1149 int ipci165_download_fw(struct candevice_t *candev)
1151 unsigned long dpram_addr = candev->dev_base_addr;
1152 char board_name[BOARD_NAME_LEN+1];
1153 char hw_version[HW_VERSION_LEN+1];
1154 char mode[MODE_LEN+1];
1156 struct ipci165_fw_t *fwArray = ipci165_fw;
1159 DEBUGMSG ("ipci165_download_fw\n");
1161 /* read name and version */
1162 memcpy_fromio (board_name, dpram_addr + BOARD_NAME_OFS, BOARD_NAME_LEN);
1163 board_name[BOARD_NAME_LEN] = 0;
1165 memcpy_fromio (hw_version, dpram_addr + HW_VERSION_OFS, HW_VERSION_LEN);
1166 hw_version[HW_VERSION_LEN] = 0;
1168 CANMSG ("Board Name: %s\n", board_name);
1169 CANMSG ("HW Version: %s\n", hw_version);
1172 if ((hw_version[0] != 'V') && (hw_version[0] != 'v'))
1174 CANMSG ("This board is too old and not supported by the BCI !\n");
1179 /* detect & test mode */
1180 memcpy_fromio (mode, dpram_addr + MODE_OFS, MODE_LEN);
1183 if (strncmp (mode, "PC-Loader V", 11))
1185 CANMSG ("Unknown mode [%s], can't download firmware!\n",mode);
1189 while (fwArray->len)
1192 writeb(LD_CMD_DOWNLOAD, dpram_addr + OF_LD_CMD);
1193 writeb(fwArray->len, dpram_addr + OF_LD_NUM);
1194 writeb(0, dpram_addr + OF_LD_NUM + 1);
1196 writel(fwArray->addr, dpram_addr + OF_LD_ADDRESS);
1197 /* writel already performes the cpu_to_le32 conversion by itself */
1198 /* writel(cpu_to_le32(fwArray->addr), dpram_addr + OF_LD_ADDRESS); */
1200 memcpy_toio(dpram_addr + OF_LD_DATA, fwArray->a_data, fwArray->len);
1203 dump_mem((void *)(dpram_addr + OF_LD_SYNC), fwArray->len + 8);
1205 /* buffer is prepared, set flag for loader */
1206 writeb(1, dpram_addr + OF_LD_SYNC);
1208 /* update pointer */
1211 /* wait for the loader */
1213 while (readb(dpram_addr + OF_LD_SYNC) != 0)
1218 /* timeout occured */
1219 CANMSG ("Firmware download failed!\n");
1224 CANMSG ("Firmware downladed successfully\n");
1227 writeb(LD_CMD_START_FW, dpram_addr + OF_LD_CMD);
1228 writeb(1, dpram_addr + OF_LD_SYNC);
1229 ipci165_delay (500);
1235 * ipci165_reset - Hardware reset routine
1236 * @candev: Pointer to candevice/board structure
1238 * Return Value: The function returns zero on success or %-ENODEV on failure
1239 * File: src/ipci165.c
1241 int ipci165_reset(struct candevice_t *candev)
1243 unsigned long crm_addr = candev->io_addr;
1244 unsigned long test_data;
1245 char buffer[BCI_CMD_MAX_LEN];
1248 struct canchip_t *chip;
1249 struct ipci165_chip_t *chip_data;
1251 DEBUGMSG ("ipci165_reset: hardware reset\n");
1254 ucr = readb(crm_addr + CRM_UCR + 3);
1255 writeb(ucr | 0x40, crm_addr + CRM_UCR + 3);
1257 writeb(ucr & ~0x40, crm_addr + CRM_UCR + 3);
1259 /* wait a little bit */
1263 if (ipci165_download_fw(candev)) return -ENODEV;
1265 /* enable irq on HW */
1266 if (ipci165_connect_irq(candev))
1268 CANMSG ("Interrupt routine installation for IRQ %i failed!\n",
1269 candev->sysdevptr.pcidev->irq);
1273 /* test BCI interface */
1274 test_data = 0x12345678;
1275 size = sizeof(test_data);
1276 if (bci_command(candev, CMD_TEST, size, (char *)&test_data) ||
1277 bci_response(candev, CMD_TEST, &size, (char *)&test_data) ||
1278 (test_data != ~0x12345678))
1280 CANMSG ("BCI test failed! Test pattern is %lx\n", test_data);
1284 /* get Firmware identification */
1285 /* send command, fw requests 1 dummy byte */
1286 size = BCI_CMD_MAX_LEN;
1287 if (bci_command(candev, CMD_ID, 1, (char *)&test_data) ||
1288 bci_response(candev, CMD_ID, &size, buffer))
1290 CANMSG ("Firmware Identification reading failed!\n");
1293 CANMSG ("Firmware: %s\n",buffer);
1295 /* get Firmware version */
1296 /* send command, fw requests 1 dummy byte */
1297 size = BCI_CMD_MAX_LEN;
1298 if (bci_command(candev, CMD_VERSION, 1, (char *)&test_data) ||
1299 bci_response(candev, CMD_VERSION, &size, buffer))
1301 CANMSG ("Firmware Version reading failed!\n");
1304 CANMSG ("Version: %s\n",buffer);
1306 /* get Board Info */
1307 /* send command, fw requests 1 dummy byte */
1308 size = BOARD_INFO_SIZE;
1309 if (bci_command(candev, CMD_GET_BOARD_INFO, 1, (char *)&test_data) ||
1310 bci_response(candev, CMD_GET_BOARD_INFO, &size, (char *) buffer))
1312 CANMSG ("Get Board Info failed!\n");
1316 chips = le16_to_cpu(*(unsigned short*)(buffer+OF_BOARD_INFO_CHIPS));
1317 /* shouldn't be, but who knows ... */
1318 if (chips > 2) chips = 2;
1320 CANMSG ("Chips: %i\n",chips);
1321 CANMSG ("Chip 1 Type: %s\n",buffer+OF_BOARD_INFO_CHIP1_TYPE);
1323 /* update board info */
1326 /* we have to correct the number in candev and release allocated
1328 candev->nr_all_chips = chips;
1329 canchip_done(candev->chip[1]);
1331 } else CANMSG ("Chip 2 Type: %s\n",buffer+OF_BOARD_INFO_CHIP2_TYPE);
1333 /* start kernel threads */
1334 for (i = 0 ; i < chips ; i++)
1336 chip = candev->chip[i];
1337 chip_data = (struct ipci165_chip_t *)chip->chip_data;
1338 chip_data->kthread.arg = chip;
1339 start_kthread(ipci165_kthread, &chip_data->kthread);
1342 CANMSG ("HW is up and working.\n");
1347 * ipci165_init_hw_data - Initialize hardware cards
1348 * @candev: Pointer to candevice/board structure
1350 * Return Value: The function always returns zero
1351 * File: src/ipci165.c
1353 int ipci165_init_hw_data(struct candevice_t *candev)
1355 struct pci_dev *pcidev = NULL;
1356 unsigned short SubsystemID;
1358 DEBUGMSG ("ipci165_init_hw_data\n");
1360 /* find iPC-I 165 on PCI bus */
1363 pcidev = pci_find_device(IPCI165_VENDOR_ID, IPCI165_DEVICE_ID, pcidev);
1364 if(pcidev == NULL) return -ENODEV;
1366 /* check subvendor ID */
1367 pci_read_config_word (pcidev, PCI_SUBSYSTEM_ID, &SubsystemID);
1368 if ((SubsystemID != IPCI165_SUBSYSTEM_ID) &&
1369 (SubsystemID != CP350_SUBSYSTEM_ID))
1372 while(can_check_dev_taken(pcidev));
1375 if (pci_enable_device (pcidev))
1377 CANMSG ("Cannot enable PCI device\n");
1381 candev->sysdevptr.pcidev = pcidev;
1383 candev->nr_82527_chips=0;
1384 candev->nr_sja1000_chips=0;
1385 /* we do not know yet, whether our HW has one or two chan chips. Let's
1386 prepare configuration for maximal configuration = 2. This will be
1387 corrected later on */
1388 candev->nr_all_chips=2;
1389 candev->flags |= CANDEV_PROGRAMMABLE_IRQ*0;
1390 /* initialize device spinlock */
1391 can_spin_lock_init(&candev->device_lock);
1396 #define CHIP_TYPE "ipci165"
1399 * ipci165_init_chip_data - Initialize chips
1400 * @candev: Pointer to candevice/board structure)
1401 * @chipnr: Number of the CAN chip on the hardware card
1403 * Return Value: The function always returns zero
1404 * File: src/ipci165.c
1406 int ipci165_init_chip_data(struct candevice_t *candev, int chipnr)
1408 struct canchip_t *chip = candev->chip[chipnr];
1409 struct ipci165_chip_t *chip_data;
1411 DEBUGMSG ("ipci165_init_chip_data\n");
1413 chip->chip_type = CHIP_TYPE;
1414 chip->chip_base_addr = 0; /* mapping not known yet */
1415 chip->clock = 10000000;
1416 chip->int_clk_reg = 0x0;
1417 chip->int_bus_reg = 0x0;
1418 chip->max_objects = 1;
1421 /* initialize interrupt handling only for channel 0. The interrupt
1422 is shared between the channels so we have to work it out in one
1423 interrupt routine. */
1426 chip->chipspecops->irq_handler=ipci165_irq_handler;
1427 chip->chip_irq=candev->sysdevptr.pcidev->irq;
1428 chip->flags |= CHIP_IRQ_PCI;
1431 chip->chipspecops->irq_handler=NULL;
1434 chip->chipspecops->irq_handler = NULL;
1436 chip->flags |= CHIP_IRQ_CUSTOM;
1439 chip_data = can_checked_malloc(sizeof(struct ipci165_chip_t));
1440 if(!chip_data) return -ENOMEM;
1441 chip_data->rx_queue.idx = 0;
1442 chip_data->rx_queue.addr = 0;
1443 chip_data->tx_queue.idx = 0;
1444 chip_data->tx_queue.addr = 0;
1445 chip->chip_data = chip_data;
1447 CANMSG("initializing ipci165 chip operations\n");
1448 chip->chipspecops->attach_to_chip=ipci165_attach_to_chip;
1449 chip->chipspecops->release_chip=ipci165_release_chip;
1450 chip->chipspecops->chip_config=ipci165_chip_config;
1451 chip->chipspecops->baud_rate=ipci165_baud_rate;
1452 chip->chipspecops->set_btregs=ipci165_set_btregs;
1453 chip->chipspecops->start_chip=ipci165_start_chip;
1454 chip->chipspecops->stop_chip=ipci165_stop_chip;
1455 chip->chipspecops->pre_read_config=ipci165_pre_read_config;
1456 chip->chipspecops->wakeup_tx=ipci165_wakeup_tx;
1457 chip->chipspecops->filtch_rq=NULL;
1458 chip->chipspecops->irq_accept=NULL;
1460 chip->chipspecops->standard_mask=NULL;
1461 chip->chipspecops->extended_mask=NULL;
1462 chip->chipspecops->message15_mask=NULL;
1463 chip->chipspecops->clear_objects=NULL;
1464 chip->chipspecops->config_irqs=NULL;
1465 chip->chipspecops->pre_write_config=NULL;
1466 chip->chipspecops->send_msg=NULL;
1467 chip->chipspecops->check_tx_stat=NULL;
1468 chip->chipspecops->remote_request=NULL;
1469 chip->chipspecops->enable_configuration=NULL;
1470 chip->chipspecops->disable_configuration=NULL;
1476 * ipci165_init_obj_data - Initialize message buffers
1477 * @chip: Pointer to chip specific structure
1478 * @objnr: Number of the message buffer
1480 * Return Value: The function always returns zero
1481 * File: src/ipci165.c
1483 int ipci165_init_obj_data(struct canchip_t *chip, int objnr)
1485 struct msgobj_t *obj=chip->msgobj[objnr];
1487 DEBUGMSG ("ipci165_init_obj_data\n");
1489 obj->obj_base_addr = 0; /* not known yet */
1490 obj->tx_timeout.function = ipci165_do_tx_timeout;
1491 obj->tx_timeout.data = (unsigned long)obj;
1496 * ipci165_program_irq - Program interrupts
1497 * @candev: Pointer to candevice/board structure
1499 * Return value: The function returns zero on success or %-ENODEV on failure
1500 * File: src/ipci165.c
1502 int ipci165_program_irq(struct candevice_t *candev)
1508 * ipci165_register - Register Board Support Functions
1509 * @candev: Pointer to hardware/board specific functions
1511 * Return value: The function returns zero on success or %-ENODEV on failure
1512 * File: src/ipci165.c
1514 int ipci165_register(struct hwspecops_t *hwspecops)
1516 hwspecops->request_io = ipci165_request_io;
1517 hwspecops->release_io = ipci165_release_io;
1518 hwspecops->reset = ipci165_reset;
1519 hwspecops->init_hw_data = ipci165_init_hw_data;
1520 hwspecops->init_chip_data = ipci165_init_chip_data;
1521 hwspecops->init_obj_data = ipci165_init_obj_data;
1522 hwspecops->write_register = NULL;
1523 hwspecops->read_register = NULL;
1524 hwspecops->program_irq = ipci165_program_irq;
1529 void dump_mem(char *ptr, int size)
1532 unsigned char str[80], buf[16];
1535 for (; size > 0; size -= 16)
1537 to = size > 16 ? 16 : size;
1538 memcpy (buf,ptr, to);
1540 for (j = 0; j < to ; j++)
1541 strp += sprintf(strp, "%02x ",buf[j]);
1542 for (; j < 16 ; j++)
1543 strp += sprintf(strp, " ");
1544 for (j = 0; j < to ; j++)
1545 *strp++= isprint(buf[j]) ? buf[j] : '.';
1547 DEBUGMSG ("[%lx] %s\n", (long unsigned)ptr, str);