1 /**************************************************************************/
2 /* File: ipci165.c - support for IXXAT iPC-I 165 (PCI) compatible HW */
4 /* LinCAN - (Not only) Linux CAN bus driver */
5 /* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
6 /* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
7 /* Copyright (C) 2004-2005 Radim Kalas <kalas@unicontrols.cz> */
8 /* Funded by OCERA and FRESCOR IST projects */
9 /* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
11 /* LinCAN is free software; you can redistribute it and/or modify it */
12 /* under terms of the GNU General Public License as published by the */
13 /* Free Software Foundation; either version 2, or (at your option) any */
14 /* later version. LinCAN is distributed in the hope that it will be */
15 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
16 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
17 /* General Public License for more details. You should have received a */
18 /* copy of the GNU General Public License along with LinCAN; see file */
19 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
20 /* Cambridge, MA 02139, USA. */
22 /* To allow use of LinCAN in the compact embedded systems firmware */
23 /* and RT-executives (RTEMS for example), main authors agree with next */
24 /* special exception: */
26 /* Including LinCAN header files in a file, instantiating LinCAN generics */
27 /* or templates, or linking other files with LinCAN objects to produce */
28 /* an application image/executable, does not by itself cause the */
29 /* resulting application image/executable to be covered by */
30 /* the GNU General Public License. */
31 /* This exception does not however invalidate any other reasons */
32 /* why the executable file might be covered by the GNU Public License. */
33 /* Publication of enhanced or derived LinCAN files is required although. */
34 /**************************************************************************/
36 #include "../include/can.h"
37 #include "../include/can_sysdep.h"
38 #include "../include/main.h"
39 #include "../include/setup.h"
40 #include "../include/finish.h"
41 #include "../include/ipci165.h"
42 #include "../include/ipci165_fw.h"
43 #include "../include/kthread.h"
48 #define IRQF_SHARED SA_SHIRQ
49 #endif /*IRQF_SHARED*/
51 can_irqreturn_t ipci165_irq_handler(CAN_IRQ_HANDLER_ARGS(irq_number, dev_id));
52 int ipci165_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
53 int sampl_pt, int flags);
54 int ipci165_set_btregs(struct canchip_t *chip, unsigned short btr0,
56 int ipci165_start_chip(struct canchip_t *chip);
59 void dump_mem(char *ptr, int size);
64 #define ipci165_load_btr(btr,btr0,btr1) {*btr = btr0; *(btr+1) = btr1;}
67 * ipci165_delay - Delay the execution
68 * @msdelay: milliseconds to wait
70 * Return value: no return value
73 static void ipci165_delay(long msdelay)
76 if(!rtl_rt_system_is_idle())
78 rtl_delay(1000000l*msdelay);
80 #endif /*CAN_WITH_RTL*/
82 set_current_state(TASK_UNINTERRUPTIBLE);
83 schedule_timeout((msdelay*HZ)/1000+1);
88 * ipci165_generate_irq - Generate irq for HW
89 * @candev: Pointer to hardware/board specific functions
91 * Return value: The function returns zero on success or non zero on failure
94 void ipci165_generate_irq(struct candevice_t *candev)
96 can_ioptr_t crm_addr = candev->aux_base_addr;
97 can_writeb(can_readb(crm_addr + CRM_UCR) & 0xFB, crm_addr + CRM_UCR);
98 can_writeb(can_readb(crm_addr + CRM_UCR) | 0x04, crm_addr + CRM_UCR);
102 * bci_command - Send command to controller
103 * @candev: Pointer to hardware/board specific functions
104 * @cmd: Command to be performed
105 * @size: Command data size
106 * @data: Command data
108 * Return value: The function returns zero on success or non zero on failure
109 * File: src/ipci165.c
111 int bci_command(struct candevice_t *candev, char cmd, int size, char *data)
113 can_ioptr_t dpram_addr = candev->dev_base_addr;
115 DEBUGMSG ("ipci165_bci_command\n");
117 if (size > BCI_CMD_MAX_LEN)
119 DEBUGMSG ("ipci165_bci_command: parameter error\n");
123 /* grant access to the command buffer */
124 can_spin_lock(&candev->device_lock);
126 // check command buffer status
127 if (can_readb(dpram_addr + OF_BCI_SYNC) != 0)
129 /* something went wrong ... */
130 can_spin_unlock(&candev->device_lock);
131 DEBUGMSG ("ipci165_bci_command: command buffer is busy\n");
136 can_writeb(cmd, dpram_addr + OF_BCI_CMD);
137 can_writeb(size + 1, dpram_addr + OF_BCI_NUM);
138 memcpy_toio(dpram_addr + OF_BCI_DATA, data, size);
140 // set flag for firmware
141 can_writeb(1, dpram_addr + OF_BCI_SYNC);
143 // generate interrupt to microcontroller
144 ipci165_generate_irq (candev);
150 * bci_response - Get response from controller
151 * @candev: Pointer to hardware/board specific functions
152 * @cmd: Command to get response for
153 * @size: Command data size
154 * @data: Command data
156 * Return value: The function returns zero on success or non zero on failure
157 * File: src/ipci165.c
159 int bci_response(struct candevice_t *candev, char cmd, int *size, char *data)
161 can_ioptr_t dpram_addr = candev->dev_base_addr;
165 DEBUGMSG ("ipci165_bci_response\n");
168 while (can_readb(dpram_addr + OF_BCI_SYNC) != 2)
171 /* ipci165_delay(1); */
175 /* timeout occured */
176 /* release the lock */
177 can_spin_unlock(&candev->device_lock);
178 CANMSG ("BCI timeout!\n");
183 /* we will not copy the command filed, so decrement the size by 1 */
184 tmp = can_readb(dpram_addr + OF_BCI_NUM) - 1;
185 if (*size > tmp) *size = tmp;
187 if (can_readb(dpram_addr + OF_BCI_CMD) != cmd)
189 /* release the buffer */
190 can_writeb(0, dpram_addr + OF_BCI_SYNC);
191 /* unlock the access */
192 can_spin_unlock(&candev->device_lock);
194 DEBUGMSG ("ipci165_bci_command: invalid answer\n");
197 memcpy_fromio(data, dpram_addr + OF_BCI_DATA, *size);
199 /* release the buffer */
200 can_writeb(0, dpram_addr + OF_BCI_SYNC);
201 /* unlock the access */
202 can_spin_unlock(&candev->device_lock);
207 * ipci165_restart_can - Flush queues and sestart can controller
208 * @candev: Pointer to hardware/board specific functions
209 * @chip_idx: chip number
211 * Return value: The function returns zero on success or non zero on failure
212 * File: src/ipci165.c
214 int ipci165_restart_can(struct canchip_t *chip)
220 struct ipci165_chip_t *chip_data;
221 unsigned long msg_ofs;
224 data[0] = chip->chip_idx;
226 if (bci_command(chip->hostdevice, CMD_RESET_CAN, 1, data) ||
227 bci_response(chip->hostdevice, CMD_RESET_CAN, &size, data) ||
230 CANMSG ("CAN reset failed!\n");
234 /* flush TX/RX queues in DP-RAM */
235 chip_data = (struct ipci165_chip_t *)chip->chip_data;
236 msg_ofs = BCI_MSG_STATUS;
238 for (i = 0; i< BCI_QUEUE_SIZE; i++)
240 can_writeb(BCI_MSG_STATUS_FREE, chip_data->rx_queue.addr + msg_ofs);
241 can_writeb(BCI_MSG_STATUS_FREE, chip_data->tx_queue.addr + msg_ofs);
242 msg_ofs += BCI_MSG_SIZE;
245 /* In- and output buffer re-initialization */
246 canqueue_ends_flush_inlist(chip->msgobj[0]->qends);
247 canqueue_ends_flush_outlist(chip->msgobj[0]->qends);
250 data[0] = chip->chip_idx;
252 if (bci_command(chip->hostdevice, CMD_START_CAN, 1, data) ||
253 bci_response(chip->hostdevice, CMD_START_CAN, &size, data) ||
256 CANMSG ("start chip failed!\n");
262 /* this is the thread function that we are executing */
264 * ipci165_kthread - Thread restarting can controller after bus-off.
265 * @kthread: pointer to kernel thread descriptor
266 * @chip_idx: chip number
268 * Return value: no return value
269 * File: src/ipci165.c
271 void ipci165_kthread(kthread_t *kthread)
273 struct canchip_t *chip = (struct canchip_t *)kthread->arg;
274 struct ipci165_chip_t *chip_data = (struct ipci165_chip_t *)chip->chip_data;
276 /* setup the thread environment */
277 init_kthread(kthread, "ipci165");
279 /* this is normal work to do */
280 CANMSG ("kernel thread started!\n");
282 /* an endless loop in which we are doing our work */
286 wait_event_interruptible(kthread->queue,test_bit(CHIP_FLAG_BUS_OFF,&chip_data->flags));
288 /* We need to do a memory barrier here to be sure that
289 the flags are visible on all CPUs. */
292 /* here we are back from sleep because we caught a signal. */
293 if (kthread->terminate)
295 /* we received a request to terminate ourself */
300 clear_bit(CHIP_FLAG_BUS_OFF,&chip_data->flags);
301 set_bit(CHIP_FLAG_RESET,&chip_data->flags);
302 /* this is normal work to do */
303 ipci165_restart_can(chip);
305 clear_bit(CHIP_FLAG_RESET,&chip_data->flags);
307 /* wait at least 100ms for next reset */
311 /* here we go only in case of termination of the thread */
313 /* cleanup the thread, leave */
314 CANMSG ("kernel thread terminated!\n");
315 exit_kthread(kthread);
317 /* returning from the thread here calls the exit functions */
321 * ipci165_qfull_latency - Compute delay to send out full tx queue
322 * @candev: Pointer to candevice/board structure
323 * @obj: pointer to message object state structure
325 * Return Value: The function returns computed delay in jiffies
326 * File: src/ipci165.c
328 long ipci165_qfull_latency(struct msgobj_t *obj)
331 latency = obj->hostchip->baudrate;
333 latency=(long)HZ*(CAN_FRAME_MIN_BIT_LEN * BCI_QUEUE_SIZE)/latency + 1;
340 * ipci165_connect_irq: Installs interrupt routine and enable irq on HW
341 * @candev: Pointer to candevice/board structure
343 * Return Value: The function returns zero on success or %-ENODEV on failure
344 * File: src/ipci165.c
346 int ipci165_connect_irq(struct candevice_t *candev)
348 can_ioptr_t crm_addr = candev->aux_base_addr;
350 DEBUGMSG ("ipci165_connect_irq\n");
352 /* install interrupt routine */
353 if (request_irq(candev->sysdevptr.pcidev->irq,
360 // Enable interrupt to PC
361 can_writeb(can_readb(crm_addr + CRM_ICR) | 0x40, crm_addr + CRM_ICR);
363 icr = can_readb(crm_addr + CRM_ICR);
368 * ipci165_disconnect_irq - Disable irq on HW
369 * @candev: Pointer to candevice/board structure
371 * Return Value: The function returns zero on success or %-ENODEV on failure
372 * File: src/ipci165.c
374 void ipci165_disconnect_irq(struct candevice_t *candev)
376 can_ioptr_t crm_addr = candev->aux_base_addr;
378 DEBUGMSG ("ipci165_disconnect_irq\n");
380 // Enable interrupt to PC
381 can_writeb(can_readb(crm_addr + CRM_ICR) & ~0x40, crm_addr + CRM_ICR);
383 icr = can_readb(crm_addr + CRM_ICR);
384 /* deinstall interrupt routine */
385 free_irq(candev->sysdevptr.pcidev->irq, candev);
388 /* * * CAN Functionality * * */
391 * ipci165_chip_config - Can chip configuration
392 * @chip: pointer to chip state structure
394 * Return Value: negative value reports error.
395 * File: src/ipci165.c
397 int ipci165_chip_config(struct canchip_t *chip)
399 struct ipci165_chip_t *chip_data = chip->chip_data;
403 DEBUGMSG ("ipci165_chip_config[%i]\n",chip->chip_idx);
405 /* comupte the base address of tx and rx queue for the channel */
406 chip_data->tx_queue.addr = chip->chip_base_addr + OF_CH1_TX_QUEUE +
407 chip->chip_idx * (OF_CH2_TX_QUEUE-OF_CH1_TX_QUEUE);
408 chip_data->rx_queue.addr = chip->chip_base_addr + OF_CH1_RX_QUEUE +
409 chip->chip_idx * (OF_CH2_RX_QUEUE-OF_CH1_RX_QUEUE);
412 data[0] = chip->chip_idx;
415 if (bci_command(chip->hostdevice, CMD_RESET_CAN, 1, data) ||
416 bci_response(chip->hostdevice, CMD_RESET_CAN, &size, data) ||
419 CANMSG ("CAN reset failed!\n");
423 /* configure rx queue */
424 data[0] = chip->chip_idx;
425 data[1] = BCI_LATENCY_MODE;
426 data[2] = 0; /* dummy */
429 if (bci_command(chip->hostdevice, CMD_CONFIG_RX_QUEUE, 3, data) ||
430 bci_response(chip->hostdevice, CMD_CONFIG_RX_QUEUE, &size, data) ||
433 CANMSG ("config RX queue failed!\n");
436 /* setup baud rate */
437 if (!chip->baudrate) chip->baudrate = 1000000;
438 if ((ret = ipci165_baud_rate(chip, chip->baudrate, chip->clock, 0, 0, 0))) return ret;
440 /* start can communication */
441 if ((ret = ipci165_start_chip(chip))) return ret;
447 * ipci165_baud_rate - Set communication parameters
448 * @chip: pointer to chip state structure
449 * @rate: baud rate in Hz
452 * @sampl_pt: not used
455 * Return Value: negative value reports error.
456 * File: src/ipci165.c
458 int ipci165_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
459 int sampl_pt, int flags)
461 DEBUGMSG ("ipci165_baud_rate[%i]\n",chip->chip_idx);
464 case 10000: return ipci165_set_btregs(chip, BCI_10KB);
465 case 20000: return ipci165_set_btregs(chip, BCI_20KB);
466 case 50000: return ipci165_set_btregs(chip, BCI_50KB);
467 case 100000: return ipci165_set_btregs(chip, BCI_100KB);
468 case 125000: return ipci165_set_btregs(chip, BCI_125KB);
469 case 250000: return ipci165_set_btregs(chip, BCI_250KB);
470 case 500000: return ipci165_set_btregs(chip, BCI_500KB);
471 case 1000000:return ipci165_set_btregs(chip, BCI_1000KB);
472 default: return -EINVAL;
479 * ipci165_set_btregs - Configure bitrate registers
480 * @chip: pointer to chip state structure
481 * @btr0: bitrate register 0
482 * @btr1: bitrate register 1
484 * Return Value: negative value reports error.
485 * File: src/ipci165.c
487 int ipci165_set_btregs(struct canchip_t *chip, unsigned short btr0,
490 unsigned char data[3];
493 DEBUGMSG ("ipci165_set_btregs[%i]: btr0=%02x, btr1=%02x\n",chip->chip_idx,
494 (unsigned)btr0,(unsigned)btr1);
496 /* configure the chip */
497 data[0] = chip->chip_idx;
502 if (bci_command(chip->hostdevice, CMD_INIT_CAN, 3, data) ||
503 bci_response(chip->hostdevice, CMD_INIT_CAN, &size, data) ||
506 CANMSG ("baud rate setup failed!\n");
513 * ipci165_stop_chip - Start chip message processing
514 * @chip: pointer to chip state structure
516 * Return Value: negative value reports error.
517 * File: src/ipci165.c
519 int ipci165_start_chip(struct canchip_t *chip)
524 DEBUGMSG ("ipci165_start_chip[%i]\n",chip->chip_idx);
527 data[0] = chip->chip_idx;
530 if (bci_command(chip->hostdevice, CMD_START_CAN, 1, data) ||
531 bci_response(chip->hostdevice, CMD_START_CAN, &size, data) ||
534 CANMSG ("start chip failed!\n");
541 * ipci165_stop_chip - Stop chip message processing
542 * @chip: pointer to chip state structure
544 * Return Value: negative value reports error.
545 * File: src/ipci165.c
547 int ipci165_stop_chip(struct canchip_t *chip)
552 DEBUGMSG ("ipci165_stop_chip[%i]\n",chip->chip_idx);
554 /* configure the chip */
555 data[0] = chip->chip_idx;
558 if (bci_command(chip->hostdevice, CMD_STOP_CAN, 1, data) ||
559 bci_response(chip->hostdevice, CMD_STOP_CAN, &size, data) ||
562 CANMSG ("stop chip failed!\n");
569 * ipci165_pre_read_config - Prepare message object for message reception
570 * @chip: pointer to chip state structure
571 * @obj: pointer to message object state structure
573 * Return Value: negative value reports error.
574 * Positive value indicates immediate reception of message.
575 * File: src/ipci165.c
577 int ipci165_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj)
583 * ipci165_pre_write_config - Prepare message object for message transmission
584 * @chip: pointer to chip state structure
585 * @obj: pointer to message object state structure
586 * @msg: pointer to CAN message
588 * Return Value: negative value reports error.
589 * File: src/ipci165.c
591 int ipci165_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
592 struct canmsg_t *msg)
598 * ipci165_send_msg - Initiate message transmission
599 * @chip: pointer to chip state structure
600 * @obj: pointer to message object state structure
601 * @msg: pointer to CAN message
603 * This function is called after ipci165_pre_write_config() function,
604 * which prepares data in chip buffer.
605 * Return Value: negative value reports error.
606 * File: src/ipci165.c
608 int ipci165_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
609 struct canmsg_t *msg)
615 * ipci165_check_tx_stat - Checks state of transmission engine
616 * @chip: pointer to chip state structure
618 * Return Value: negative value reports error.
619 * Positive return value indicates transmission under way status.
620 * Zero value indicates finishing of all issued transmission requests.
621 * File: src/ipci165.c
623 int ipci165_check_tx_stat(struct canchip_t *chip)
629 * ipci165_irq_read_handler - ISR code responsible for receiving
630 * @chip: pointer to chip state structure
631 * @obj: pointer to attached queue description
633 * The main purpose of this function is to read message from CAN controller and
634 * transfer them to attached queues
635 * File: src/ipci165.c
637 void ipci165_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj)
639 struct ipci165_chip_t *chip_data = (struct ipci165_chip_t *)chip->chip_data;
640 struct bci_queue_t *queue = &(chip_data)->rx_queue;
641 can_ioptr_t queue_addr = queue->addr;
642 can_ioptr_t msg_addr = queue_addr + queue->idx * BCI_MSG_SIZE;
645 unsigned char frame_info;
647 unsigned short tmp16;
650 DEBUGMSG ("ipci165_irq_read_handler[%i]\n",chip->chip_idx);
653 dump_mem(msg_addr, BCI_MSG_SIZE);
654 if (can_readb(msg_addr + BCI_MSG_TYPE) == BCI_MSG_TYPE_CAN)
657 printk("ST(0)=%x, ST(1)=%x\n",can_readw(chip->chip_base_addr+OF_CAN1_STATUS),
658 can_readw(chip->chip_base_addr+OF_CAN2_STATUS));
659 for (tmp16 = 0 ; tmp16 < BCI_QUEUE_SIZE ; tmp16 ++)
660 printk ("MSG_ST(%i)=%x\n",tmp16,can_readb(chip->chip_base_addr + OF_CH2_TX_QUEUE + tmp16*BCI_MSG_SIZE + BCI_MSG_STATUS));
661 /* this is a can message */
662 DEBUGMSG ("ipci165_irq_read_handler[%i]: message in buffer\n",chip->chip_idx);
665 frame_info = can_readb(msg_addr + BCI_MSG_FRAME);
666 len = frame_info & 0x0f;
667 if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
668 obj->rx_msg.length = len;
669 obj->rx_msg.flags = (frame_info & BCI_MSG_FRAME_RTR ? MSG_RTR : 0);
671 obj->rx_msg.timestamp.tv_sec = 0;
672 obj->rx_msg.timestamp.tv_usec =
673 BCI_TIMESTAMP_RES * can_readl(msg_addr + BCI_MSG_TIMESTAMP);
674 /* BCI_TIMESTAMP_RES * le32_to_cpu(can_readl(msg_addr + BCI_MSG_TIMESTAMP)); */
676 /* fill CAN message timestamp */
677 /* can_filltimestamp(&obj->rx_msg.timestamp); */
679 if (frame_info & BCI_MSG_FRAME_EXT)
681 /* extended frame - 29 bit identifier */
682 obj->rx_msg.flags |= MSG_EXT;
683 /* the ID is stored in motorola format (big endian), left justified */
684 /* obj->rx_msg.id = be32_to_cpu(can_readl(msg_addr + BCI_MSG_ID) >> 3); */
685 memcpy_fromio(&tmp32, msg_addr + BCI_MSG_ID, 4);
686 obj->rx_msg.id = be32_to_cpu(tmp32 >> 3);
688 memcpy_fromio(obj->rx_msg.data, msg_addr + BCI_MSG_EXT_DATA, len);
691 /* standard frame - 11 bit identifier */
692 /* the ID is stored in motorola format (big endian), left justified */
693 /* obj->rx_msg.id = be16_to_cpu(can_readw(msg_addr + BCI_MSG_ID) >> 5); */
694 memcpy_fromio(&tmp16, msg_addr + BCI_MSG_ID, 2);
695 obj->rx_msg.id = be16_to_cpu(tmp16 >> 5);
697 memcpy_fromio(obj->rx_msg.data, msg_addr + BCI_MSG_STD_DATA, len);
699 canque_filter_msg2edges(obj->qends, &obj->rx_msg);
703 /* this is a status message */
704 status = can_readw(msg_addr + BCI_MSG_CAN_STATUS);
705 DEBUGMSG ("ipci165_irq_read_handler[%i]: CAN status=%04x\n",chip->chip_idx, status);
707 /* wake up the reset thread if the CAN is in bus off */
708 if (status & BCI_CAN_STATUS_BUS_OFF)
710 CANMSG ("BUS-OFF detected! Restarting\n");
711 set_bit(CHIP_FLAG_BUS_OFF,&chip_data->flags);
712 wake_up(&chip_data->kthread.queue);
717 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_BUS);
721 DEBUGMSG ("ipci165_irq_read_handler[%i]: device status\n", chip->chip_idx);
722 dump_mem(chip->chip_base_addr + OF_STATUS_BUFFER, 12);
725 queue->idx = (queue->idx + 1) % BCI_QUEUE_SIZE;
726 /* release the buffer */
727 can_writeb(BCI_MSG_STATUS_FREE, msg_addr + BCI_MSG_STATUS);
728 msg_addr = queue_addr + queue->idx * BCI_MSG_SIZE;
730 } while (can_readb(msg_addr + BCI_MSG_STATUS) == BCI_MSG_STATUS_FULL);
735 * ipci165_irq_write_handler - ISR code responsible for transmitting
736 * @chip: pointer to chip state structure
737 * @obj: pointer to attached queue description
739 * The main purpose of this function is to read message from attached queues
740 * and transfer message contents into CAN controller chip.
741 * File: src/ipci165.c
743 void ipci165_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
745 struct ipci165_chip_t *chip_data = ((struct ipci165_chip_t *)chip->chip_data);
746 struct bci_queue_t *queue = &chip_data->tx_queue;
747 can_ioptr_t queue_addr = queue->addr;
748 can_ioptr_t msg_addr = queue_addr + queue->idx * BCI_MSG_SIZE;
749 struct canque_slot_t *tx_slot;
752 unsigned char frame_info, ext;
753 unsigned short tmp16;
756 DEBUGMSG ("ipci165_irq_write_handler[%i]\n",chip->chip_idx);
758 while ((canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot) >=0))
760 if (test_bit(CHIP_FLAG_RESET,&chip_data->flags) ||
761 (can_readb(msg_addr + BCI_MSG_STATUS) == BCI_MSG_STATUS_FULL))
763 canque_again_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
765 /* lost interrupt work around */
766 ipci165_generate_irq(obj->hostchip->hostdevice);
768 mod_timer(&obj->tx_timeout, jiffies + ipci165_qfull_latency(obj));
769 DEBUGMSG("ipci165_irq_write_handler[%i]: scheduled retry\n", chip->chip_idx);
774 tx_slot = obj->tx_slot;
775 DEBUGMSG ("msg[%i] : id=%lx dlc=%x flg=%02x\n",
777 (unsigned long)tx_slot->msg.id,
778 (unsigned int)tx_slot->msg.length,
779 (unsigned int)tx_slot->msg.flags);
780 dump_mem(tx_slot->msg.data, tx_slot->msg.length);
782 len = tx_slot->msg.length;
783 if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
785 ext = tx_slot->msg.flags;
788 ((tx_slot->msg.flags & MSG_RTR) ? BCI_MSG_FRAME_RTR : 0) |
789 ((tx_slot->msg.flags & MSG_EXT) ? BCI_MSG_FRAME_EXT : 0);
791 can_writeb(BCI_MSG_SIZE - 2, msg_addr + BCI_MSG_NUM);
792 can_writeb(BCI_MSG_TYPE_CAN, msg_addr + BCI_MSG_TYPE);
793 can_writeb(frame_info, msg_addr + BCI_MSG_FRAME);
794 if (frame_info & BCI_MSG_FRAME_EXT)
796 /* extended frame - 29 bit identifier */
797 /* the ID is stored in motorola format (big endian), left justified */
798 tmp32 = be32_to_cpu(tx_slot->msg.id) << 3;
799 memcpy_toio(msg_addr + BCI_MSG_ID, &tmp32, 4);
801 memcpy_toio(msg_addr + BCI_MSG_EXT_DATA, tx_slot->msg.data, len);
804 /* standard frame - 11 bit identifier */
805 /* the ID is stored in motorola format (big endian), left justified */
806 tmp16 = be16_to_cpu(tx_slot->msg.id) << 5;
807 memcpy_toio(msg_addr + BCI_MSG_ID, &tmp16, 2);
809 memcpy_toio(msg_addr + BCI_MSG_STD_DATA, tx_slot->msg.data, len);
812 dump_mem(msg_addr, BCI_MSG_SIZE);
815 queue->idx = (queue->idx + 1) % BCI_QUEUE_SIZE;
816 /* mark the buffer as full */
817 can_writeb(BCI_MSG_STATUS_FULL, msg_addr + BCI_MSG_STATUS);
818 /* wake up the controller */
819 ipci165_generate_irq(chip->hostdevice);
821 /* next message address */
822 msg_addr = queue_addr + queue->idx * BCI_MSG_SIZE;
824 /* Do local transmitted message distribution if enabled. */
825 /* This code should not be called directly there, because it breaks strict
826 behavior of queues if O_SYNC is set. */
828 obj->tx_slot->msg.flags |= MSG_LOCAL;
829 canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
831 /* Free transmitted slot */
832 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
839 * ipci165_irq_sync_activities - Synchronized access to write handler
840 * @chip: pointer to chip state structure
841 * @obj: pointer to attached queue description
843 * Return Value: The function always returns zero
844 * File: src/ipci165.c
846 void ipci165_irq_sync_activities(struct canchip_t *chip, struct msgobj_t *obj)
848 while(!can_msgobj_test_and_set_fl(obj,TX_LOCK))
850 if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST))
852 ipci165_irq_write_handler(chip, obj);
855 can_msgobj_clear_fl(obj,TX_LOCK);
856 if(can_msgobj_test_fl(obj,TX_REQUEST))
858 /* if(can_msgobj_test_fl(obj,FILTCH_REQUEST) && !obj->tx_slot)
865 * ipci165_irq_chip_handler - ISR for dedicated chip
866 * @chip: pointer to chip state structure
868 * The main purpose of this function is to perform all necessary channel
869 * operations as a reaction on signalled interrupt.
870 * File: src/ipci165.c
872 void ipci165_irq_chip_handler(struct canchip_t *chip)
874 struct msgobj_t *obj = chip->msgobj[0];
875 struct ipci165_chip_t *chip_data = chip->chip_data;
876 struct bci_queue_t *queue;
878 DEBUGMSG ("ipci165_irq_chip_handler[%i]\n",chip->chip_idx);
880 /* check receive queue for messages */
881 queue = &chip_data->rx_queue;
882 if (can_readb(queue->addr + queue->idx * BCI_MSG_SIZE + BCI_MSG_STATUS)
883 == BCI_MSG_STATUS_FULL)
884 ipci165_irq_read_handler(chip, obj);
886 queue = &chip_data->tx_queue;
887 /* if (can_readb(queue->addr + queue->idx * BCI_MSG_SIZE + BCI_MSG_STATUS)
888 == BCI_MSG_STATUS_FREE) */
890 can_msgobj_set_fl(obj,TX_REQUEST);
892 /* calls unican_irq_write_handler synchronized with other invocations */
893 ipci165_irq_sync_activities(chip, obj);
901 * ipci165_irq_handler - Interrupt service routine
902 * @irq: interrupt vector number, this value is system specific
903 * @dev_id: driver private pointer registered at time of request_irq() call.
904 * The CAN driver uses this pointer to store relationship of interrupt
905 * to chip state structure - @struct canchip_t
906 * @regs: system dependent value pointing to registers stored in exception frame
908 * The interrupt handler is activated when the ipci165 controller generates
909 * an interrupt as a reaction an internal state change. The interrupt is
910 * acknowledged and ipci165_irq_chip_handler is called for every channel.
911 * File: src/ipci165.c
913 can_irqreturn_t ipci165_irq_handler(CAN_IRQ_HANDLER_ARGS(irq_number, dev_id))
916 struct candevice_t *candev = (struct candevice_t *)dev_id;
918 can_ioptr_t crm_addr = candev->aux_base_addr;
919 can_ioptr_t ucr1_addr = crm_addr + CRM_UCR + 1;
920 struct canchip_t *chip;
924 /* DEBUGMSG ("ipci165_irq_handler\n"); */
926 /* read interrupt control register (byte 0) */
927 icr = can_readb(crm_addr + CRM_ICR);
929 if ((icr & 0x44) == 0x44)
931 DEBUGMSG ("ipci165_irq_handler: pending interrupt\n");
933 /* confirm pending interrupt */
934 can_writeb(can_readb(ucr1_addr) | 0x01, ucr1_addr);
935 can_writeb(can_readb(ucr1_addr) & ~0x01, ucr1_addr);
937 /* call interrupt handler for every channel */
938 for (i=0 ; i < candev->nr_all_chips ; i++)
940 chip = candev->chip[i];
941 if (chip->flags & CHIP_CONFIGURED)
942 ipci165_irq_chip_handler(candev->chip[i]);
944 DEBUGMSG ("ipci165_irq_handler: interrupt handled\n");
946 retval = CANCHIP_IRQ_HANDLED;
948 DEBUGMSG ("ipci165_irq_handler: not our interrupt\n");
949 retval = CANCHIP_IRQ_NONE;
952 return CAN_IRQ_RETVAL(retval);
956 * ipci165_wakeup_tx - Wakeup TX processing
957 * @chip: pointer to chip state structure
958 * @obj: pointer to message object structure
960 * Function is responsible for initiating message transmition.
961 * It is responsible for clearing of object TX_REQUEST flag
963 * Return Value: negative value reports error.
964 * File: src/ipci165.c
966 int ipci165_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
968 DEBUGMSG ("ipci165_wakeup_tx\n");
969 can_preempt_disable();
971 can_msgobj_set_fl(obj,TX_REQUEST);
973 /* calls ipci165_irq_write_handler synchronized with other invocations
974 from kernel and IRQ context */
975 ipci165_irq_sync_activities(chip, obj);
977 can_preempt_enable();
978 DEBUGMSG ("ipci165_wakeup_tx: finished\n");
983 void ipci165_do_tx_timeout(unsigned long data)
985 struct msgobj_t *obj=(struct msgobj_t *)data;
987 DEBUGMSG ("ipci165_do_tx_timeout\n");
989 can_preempt_disable();
991 can_msgobj_set_fl(obj,TX_REQUEST);
993 /* calls ipci165_irq_write_handler synchronized with other invocations
994 from kernel and IRQ context */
995 ipci165_irq_sync_activities(obj->hostchip, obj);
997 can_preempt_enable();
998 DEBUGMSG ("ipci165_do_tx_timeout: finished\n");
1002 * ipci165_attach_to_chip: - attaches to the chip, setups registers and state
1003 * @chip: pointer to chip state structure
1005 * Return Value: negative value reports error.
1006 * File: src/ipci165.c
1008 int ipci165_attach_to_chip(struct canchip_t *chip)
1014 * ipci165_release_chip: - called before chip structure removal if %CHIP_ATTACHED is set
1015 * @chip: pointer to chip state structure
1017 * Return Value: negative value reports error.
1018 * File: src/ipci165.c
1020 int ipci165_release_chip(struct canchip_t *chip)
1022 ipci165_stop_chip(chip);
1023 /* disable interrupts in the hardware, etc. */
1027 /* * * iPC-I 165/PCI Board Functionality * * */
1030 * ipci165_request_io - Reserve io or memory range for can board
1031 * @candev: pointer to candevice/board which asks for io. Field @io_addr
1032 * of @candev is used in most cases to define start of the range
1034 * Return Value: The function returns zero on success or %-ENODEV on failure
1035 * File: src/ipci165.c
1037 int ipci165_request_io(struct candevice_t *candev)
1039 unsigned long dpram_addr; /* physical address before remap for this function */
1040 unsigned long crm_addr; /* physical address before remap for this function */
1041 unsigned long fix_addr; /* physical address before remap for this function */
1044 DEBUGMSG ("ipci165_request_io\n");
1046 crm_addr = pci_resource_start(candev->sysdevptr.pcidev,0);
1047 dpram_addr = pci_resource_start(candev->sysdevptr.pcidev,2);
1049 DEBUGMSG ("ipci165_request_io: crm = 0x%lx, dpram = 0x%lx\n",crm_addr, dpram_addr);
1051 /* verify, if our HW is buggy, and try to fix it */
1053 if (test_bit (7, &crm_addr))
1055 CANMSG ("Wrong PCI base address [0x%lx](PLX PCI9050 bug)!\n", dpram_addr);
1057 fix_addr = pci_resource_start(candev->sysdevptr.pcidev,3);
1061 CANMSG ("This card was not fixed!\n");
1063 if (candev->aux_base_addr == NULL)
1065 CANMSG ("You have to specify IO address parameter!\n");
1068 CANMSG ("Using specified IO address value for the memory [0x%lx]\n",
1069 can_ioptr2ulong(candev->aux_base_addr));
1073 CANMSG ("Fixed card. Using of 3 region [0x%lx]\n", fix_addr);
1074 candev->aux_base_addr = fix_addr;
1077 pci_write_config_dword (candev->sysdevptr.pcidev,
1078 PCI_BASE_ADDRESS_0, fix_addr);
1082 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
1083 if(pci_request_region(candev->sysdevptr.pcidev, 2, "kv_ipci165_dpram") == 0)
1085 if(pci_request_region(candev->sysdevptr.pcidev, 0, "kv_ipci165_reg") == 0)
1087 #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1088 if(pci_request_regions(candev->sysdevptr.pcidev, "kv_ipci165") == 0)
1090 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1092 if ((candev->dev_base_addr = ioremap(dpram_addr,
1093 pci_resource_len(candev->sysdevptr.pcidev,2))))
1095 DEBUGMSG ("ipci165_request_io: dpram remapped to 0x%lx\n", candev->dev_base_addr);
1097 if ((candev->aux_base_addr = ioremap(crm_addr,
1098 pci_resource_len(candev->sysdevptr.pcidev,0))))
1100 DEBUGMSG ("ipci165_request_io: crm remapped to 0x%lx\n", can_ioptr2ulong(candev->aux_base_addr));
1101 /* all resources has been allocated */
1103 /* Because of my mapping, I cannot use the
1104 can_base_addr_fixup(candev, remap_addr) to remap the addresses */
1105 for(i=0;i<candev->nr_all_chips;i++)
1107 candev->chip[i]->chip_base_addr = candev->dev_base_addr;
1108 for(j=0;j<candev->chip[i]->max_objects;j++)
1109 candev->chip[i]->msgobj[j]->obj_base_addr = candev->dev_base_addr;
1114 } else CANMSG("Unable to remap memory at: 0x%lx\n", crm_addr);
1115 iounmap(candev->aux_base_addr);
1117 } else CANMSG("Unable to remap memory at: 0x%lx\n", dpram_addr);
1118 iounmap(candev->dev_base_addr);
1120 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
1121 pci_release_region(candev->sysdevptr.pcidev, 0);
1122 } else CANMSG("Request of kv_ipci165_reg range failed\n");
1124 pci_release_region(candev->sysdevptr.pcidev, 2);
1125 } else CANMSG("Request of kv_ipci165_dpram range failed\n");
1127 #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1128 pci_release_regions(candev->sysdevptr.pcidev);
1129 } else CANMSG("Request of kv_ipci165 regions failed\n");
1130 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1136 * ipci165_release_io - Free reserved io memory range
1137 * @candev: pointer to candevice/board which releases io
1139 * Return Value: The function always returns zero
1140 * File: src/ipci165.c
1142 int ipci165_release_io(struct candevice_t *candev)
1144 struct ipci165_chip_t *chip_data;
1147 /* disable irq on HW */
1148 ipci165_disconnect_irq(candev);
1151 /* terminate the kernel threads */
1152 for (i = 0 ; i < candev->nr_all_chips ; i++)
1154 chip_data = (struct ipci165_chip_t *)candev->chip[i]->chip_data;
1155 stop_kthread(&chip_data->restart_thread);
1159 iounmap(candev->aux_base_addr);
1160 iounmap(candev->dev_base_addr);
1162 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))
1163 pci_release_region(candev->sysdevptr.pcidev, 2);
1164 pci_release_region(candev->sysdevptr.pcidev, 0);
1165 #else /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1166 pci_release_regions(candev->sysdevptr.pcidev);
1167 #endif /*(LINUX_VERSION_CODE > KERNEL_VERSION(2,4,21))*/
1173 * ipci165_download_fw - Download FW into CAN hardware
1174 * @candev: Pointer to candevice/board structure
1176 * Return Value: returns zero on success
1177 * File: src/ipci165.c
1179 int ipci165_download_fw(struct candevice_t *candev)
1181 can_ioptr_t dpram_addr = candev->dev_base_addr;
1182 char board_name[BOARD_NAME_LEN+1];
1183 char hw_version[HW_VERSION_LEN+1];
1184 char mode[MODE_LEN+1];
1186 struct ipci165_fw_t *fwArray = ipci165_fw;
1189 DEBUGMSG ("ipci165_download_fw\n");
1191 /* read name and version */
1192 memcpy_fromio (board_name, dpram_addr + BOARD_NAME_OFS, BOARD_NAME_LEN);
1193 board_name[BOARD_NAME_LEN] = 0;
1195 memcpy_fromio (hw_version, dpram_addr + HW_VERSION_OFS, HW_VERSION_LEN);
1196 hw_version[HW_VERSION_LEN] = 0;
1198 CANMSG ("Board Name: %s\n", board_name);
1199 CANMSG ("HW Version: %s\n", hw_version);
1202 if ((hw_version[0] != 'V') && (hw_version[0] != 'v'))
1204 CANMSG ("This board is too old and not supported by the BCI !\n");
1209 /* detect & test mode */
1210 memcpy_fromio (mode, dpram_addr + MODE_OFS, MODE_LEN);
1213 if (strncmp (mode, "PC-Loader V", 11))
1215 CANMSG ("Unknown mode [%s], can't download firmware!\n",mode);
1219 while (fwArray->len)
1222 can_writeb(LD_CMD_DOWNLOAD, dpram_addr + OF_LD_CMD);
1223 can_writeb(fwArray->len, dpram_addr + OF_LD_NUM);
1224 can_writeb(0, dpram_addr + OF_LD_NUM + 1);
1226 can_writel(fwArray->addr, dpram_addr + OF_LD_ADDRESS);
1227 /* can_writel already performes the cpu_to_le32 conversion by itself */
1228 /* can_writel(cpu_to_le32(fwArray->addr), dpram_addr + OF_LD_ADDRESS); */
1230 memcpy_toio(dpram_addr + OF_LD_DATA, fwArray->a_data, fwArray->len);
1233 dump_mem((void *)(dpram_addr + OF_LD_SYNC), fwArray->len + 8);
1235 /* buffer is prepared, set flag for loader */
1236 can_writeb(1, dpram_addr + OF_LD_SYNC);
1238 /* update pointer */
1241 /* wait for the loader */
1243 while (can_readb(dpram_addr + OF_LD_SYNC) != 0)
1248 /* timeout occured */
1249 CANMSG ("Firmware download failed!\n");
1254 CANMSG ("Firmware downladed successfully\n");
1257 can_writeb(LD_CMD_START_FW, dpram_addr + OF_LD_CMD);
1258 can_writeb(1, dpram_addr + OF_LD_SYNC);
1259 ipci165_delay (500);
1265 * ipci165_reset - Hardware reset routine
1266 * @candev: Pointer to candevice/board structure
1268 * Return Value: The function returns zero on success or %-ENODEV on failure
1269 * File: src/ipci165.c
1271 int ipci165_reset(struct candevice_t *candev)
1273 can_ioptr_t crm_addr = candev->aux_base_addr;
1274 unsigned long test_data;
1275 char buffer[BCI_CMD_MAX_LEN];
1278 struct canchip_t *chip;
1279 struct ipci165_chip_t *chip_data;
1281 DEBUGMSG ("ipci165_reset: hardware reset\n");
1284 ucr = can_readb(crm_addr + CRM_UCR + 3);
1285 can_writeb(ucr | 0x40, crm_addr + CRM_UCR + 3);
1287 can_writeb(ucr & ~0x40, crm_addr + CRM_UCR + 3);
1289 /* wait a little bit */
1293 if (ipci165_download_fw(candev)) return -ENODEV;
1295 /* enable irq on HW */
1296 if (ipci165_connect_irq(candev))
1298 CANMSG ("Interrupt routine installation for IRQ %i failed!\n",
1299 candev->sysdevptr.pcidev->irq);
1303 /* test BCI interface */
1304 test_data = 0x12345678;
1305 size = sizeof(test_data);
1306 if (bci_command(candev, CMD_TEST, size, (char *)&test_data) ||
1307 bci_response(candev, CMD_TEST, &size, (char *)&test_data) ||
1308 (test_data != ~0x12345678))
1310 CANMSG ("BCI test failed! Test pattern is %lx\n", test_data);
1314 /* get Firmware identification */
1315 /* send command, fw requests 1 dummy byte */
1316 size = BCI_CMD_MAX_LEN;
1317 if (bci_command(candev, CMD_ID, 1, (char *)&test_data) ||
1318 bci_response(candev, CMD_ID, &size, buffer))
1320 CANMSG ("Firmware Identification reading failed!\n");
1323 CANMSG ("Firmware: %s\n",buffer);
1325 /* get Firmware version */
1326 /* send command, fw requests 1 dummy byte */
1327 size = BCI_CMD_MAX_LEN;
1328 if (bci_command(candev, CMD_VERSION, 1, (char *)&test_data) ||
1329 bci_response(candev, CMD_VERSION, &size, buffer))
1331 CANMSG ("Firmware Version reading failed!\n");
1334 CANMSG ("Version: %s\n",buffer);
1336 /* get Board Info */
1337 /* send command, fw requests 1 dummy byte */
1338 size = BOARD_INFO_SIZE;
1339 if (bci_command(candev, CMD_GET_BOARD_INFO, 1, (char *)&test_data) ||
1340 bci_response(candev, CMD_GET_BOARD_INFO, &size, (char *) buffer))
1342 CANMSG ("Get Board Info failed!\n");
1346 chips = le16_to_cpu(*(unsigned short*)(buffer+OF_BOARD_INFO_CHIPS));
1347 /* shouldn't be, but who knows ... */
1348 if (chips > 2) chips = 2;
1350 CANMSG ("Chips: %i\n",chips);
1351 CANMSG ("Chip 1 Type: %s\n",buffer+OF_BOARD_INFO_CHIP1_TYPE);
1353 /* update board info */
1356 /* we have to correct the number in candev and release allocated
1358 candev->nr_all_chips = chips;
1359 canchip_done(candev->chip[1]);
1361 } else CANMSG ("Chip 2 Type: %s\n",buffer+OF_BOARD_INFO_CHIP2_TYPE);
1363 /* start kernel threads */
1364 for (i = 0 ; i < chips ; i++)
1366 chip = candev->chip[i];
1367 chip_data = (struct ipci165_chip_t *)chip->chip_data;
1368 chip_data->kthread.arg = chip;
1369 start_kthread(ipci165_kthread, &chip_data->kthread);
1372 CANMSG ("HW is up and working.\n");
1377 * ipci165_init_hw_data - Initialize hardware cards
1378 * @candev: Pointer to candevice/board structure
1380 * Return Value: The function always returns zero
1381 * File: src/ipci165.c
1383 int ipci165_init_hw_data(struct candevice_t *candev)
1385 struct pci_dev *pcidev = NULL;
1387 DEBUGMSG ("ipci165_init_hw_data\n");
1389 /* find iPC-I 165 on PCI bus */
1392 pcidev = can_pci_get_device(IPCI165_VENDOR_ID, IPCI165_DEVICE_ID, pcidev);
1396 /* check subvendor ID */
1397 if ((pcidev->subsystem_vendor != IPCI165_SUBSYSTEM_ID) &&
1398 (pcidev->subsystem_vendor != CP350_SUBSYSTEM_ID))
1401 while(can_check_dev_taken(pcidev));
1404 if (pci_enable_device (pcidev))
1406 CANMSG ("Cannot enable PCI device\n");
1407 can_pci_dev_put(pcidev);
1411 candev->sysdevptr.pcidev = pcidev;
1413 candev->nr_82527_chips=0;
1414 candev->nr_sja1000_chips=0;
1415 /* we do not know yet, whether our HW has one or two chan chips. Let's
1416 prepare configuration for maximal configuration = 2. This will be
1417 corrected later on */
1418 candev->nr_all_chips=2;
1419 candev->flags |= CANDEV_PROGRAMMABLE_IRQ*0;
1420 /* initialize device spinlock */
1421 can_spin_lock_init(&candev->device_lock);
1426 void ipci165_done_hw_data(struct candevice_t *candev)
1428 struct pci_dev *pcidev = candev->sysdevptr.pcidev;
1429 can_pci_dev_put(pcidev);
1432 #define CHIP_TYPE "ipci165"
1435 * ipci165_init_chip_data - Initialize chips
1436 * @candev: Pointer to candevice/board structure)
1437 * @chipnr: Number of the CAN chip on the hardware card
1439 * Return Value: The function always returns zero
1440 * File: src/ipci165.c
1442 int ipci165_init_chip_data(struct candevice_t *candev, int chipnr)
1444 struct canchip_t *chip = candev->chip[chipnr];
1445 struct ipci165_chip_t *chip_data;
1447 DEBUGMSG ("ipci165_init_chip_data\n");
1449 chip->chip_type = CHIP_TYPE;
1450 chip->chip_base_addr = 0; /* mapping not known yet */
1451 chip->clock = 10000000;
1452 chip->int_clk_reg = 0x0;
1453 chip->int_bus_reg = 0x0;
1454 chip->max_objects = 1;
1457 /* initialize interrupt handling only for channel 0. The interrupt
1458 is shared between the channels so we have to work it out in one
1459 interrupt routine. */
1462 chip->chipspecops->irq_handler=ipci165_irq_handler;
1463 chip->chip_irq=candev->sysdevptr.pcidev->irq;
1464 chip->flags |= CHIP_IRQ_PCI;
1467 chip->chipspecops->irq_handler=NULL;
1470 chip->chipspecops->irq_handler = NULL;
1472 chip->flags |= CHIP_IRQ_CUSTOM;
1475 chip_data = can_checked_malloc(sizeof(struct ipci165_chip_t));
1476 if(!chip_data) return -ENOMEM;
1477 chip_data->rx_queue.idx = 0;
1478 chip_data->rx_queue.addr = 0;
1479 chip_data->tx_queue.idx = 0;
1480 chip_data->tx_queue.addr = 0;
1481 chip->chip_data = chip_data;
1483 CANMSG("initializing ipci165 chip operations\n");
1484 chip->chipspecops->attach_to_chip=ipci165_attach_to_chip;
1485 chip->chipspecops->release_chip=ipci165_release_chip;
1486 chip->chipspecops->chip_config=ipci165_chip_config;
1487 chip->chipspecops->baud_rate=ipci165_baud_rate;
1488 chip->chipspecops->set_btregs=ipci165_set_btregs;
1489 chip->chipspecops->start_chip=ipci165_start_chip;
1490 chip->chipspecops->stop_chip=ipci165_stop_chip;
1491 chip->chipspecops->pre_read_config=ipci165_pre_read_config;
1492 chip->chipspecops->wakeup_tx=ipci165_wakeup_tx;
1493 chip->chipspecops->filtch_rq=NULL;
1494 chip->chipspecops->irq_accept=NULL;
1496 chip->chipspecops->standard_mask=NULL;
1497 chip->chipspecops->extended_mask=NULL;
1498 chip->chipspecops->message15_mask=NULL;
1499 chip->chipspecops->clear_objects=NULL;
1500 chip->chipspecops->config_irqs=NULL;
1501 chip->chipspecops->pre_write_config=NULL;
1502 chip->chipspecops->send_msg=NULL;
1503 chip->chipspecops->check_tx_stat=NULL;
1504 chip->chipspecops->remote_request=NULL;
1505 chip->chipspecops->enable_configuration=NULL;
1506 chip->chipspecops->disable_configuration=NULL;
1512 * ipci165_init_obj_data - Initialize message buffers
1513 * @chip: Pointer to chip specific structure
1514 * @objnr: Number of the message buffer
1516 * Return Value: The function always returns zero
1517 * File: src/ipci165.c
1519 int ipci165_init_obj_data(struct canchip_t *chip, int objnr)
1521 struct msgobj_t *obj=chip->msgobj[objnr];
1523 DEBUGMSG ("ipci165_init_obj_data\n");
1525 obj->obj_base_addr = 0; /* not known yet */
1526 obj->tx_timeout.function = ipci165_do_tx_timeout;
1527 obj->tx_timeout.data = (unsigned long)obj;
1532 * ipci165_program_irq - Program interrupts
1533 * @candev: Pointer to candevice/board structure
1535 * Return value: The function returns zero on success or %-ENODEV on failure
1536 * File: src/ipci165.c
1538 int ipci165_program_irq(struct candevice_t *candev)
1544 * ipci165_register - Register Board Support Functions
1545 * @candev: Pointer to hardware/board specific functions
1547 * Return value: The function returns zero on success or %-ENODEV on failure
1548 * File: src/ipci165.c
1550 int ipci165_register(struct hwspecops_t *hwspecops)
1552 hwspecops->request_io = ipci165_request_io;
1553 hwspecops->release_io = ipci165_release_io;
1554 hwspecops->reset = ipci165_reset;
1555 hwspecops->init_hw_data = ipci165_init_hw_data;
1556 hwspecops->done_hw_data = ipci165_done_hw_data;
1557 hwspecops->init_chip_data = ipci165_init_chip_data;
1558 hwspecops->init_obj_data = ipci165_init_obj_data;
1559 hwspecops->write_register = NULL;
1560 hwspecops->read_register = NULL;
1561 hwspecops->program_irq = ipci165_program_irq;
1566 void dump_mem(char *ptr, int size)
1569 unsigned char str[80], buf[16];
1572 for (; size > 0; size -= 16)
1574 to = size > 16 ? 16 : size;
1575 memcpy (buf,ptr, to);
1577 for (j = 0; j < to ; j++)
1578 strp += sprintf(strp, "%02x ",buf[j]);
1579 for (; j < 16 ; j++)
1580 strp += sprintf(strp, " ");
1581 for (j = 0; j < to ; j++)
1582 *strp++= isprint(buf[j]) ? buf[j] : '.';
1584 DEBUGMSG ("[%lx] %s\n", (long unsigned)ptr, str);