-/* c_can_irq.c - Hynix HMS30c7202 ARM IRQ handling code
- * Linux CAN-bus device driver.
- * Written by Sebastian Stolzenberg email:stolzi@sebastian-stolzenberg.de
- * Based on code from Arnaud Westenberg email:arnaud@wanadoo.nl
- * and Ake Hedman, eurosource, akhe@eurosource.se
- * Rewritten for new CAN queues by Pavel Pisa - OCERA team member
- * email:pisa@cmp.felk.cvut.cz
- * This software is released under the GPL-License.
- * Version lincan-0.3 17 Jun 2004
- */
-
+/**************************************************************************/
+/* File: c_can_irq.c - generic IRQ C_CAN Bosch IP core handling */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
+/* Copyright (C) 2004 Sebastian Stolzenberg <stolzi@sebastian-stolzenberg.de> */
+/* Funded by OCERA and FRESCOR IST projects */
+/* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
+/* and Ake Hedman, eurosource <akhe@eurosource.se> */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
+
#include "../include/can.h"
#include "../include/can_sysdep.h"
#include "../include/main.h"
#include "../include/c_can.h"
-union c_can_data
-{
- unsigned short wdata[4];
- unsigned char bdata[8];
+union c_can_data {
+ unsigned short wdata[4];
+ unsigned char bdata[8];
};
-
-
// prototypes
-inline void c_can_irq_read_handler( struct chip_t *pchip, int idxobj, u32 msgid );
+inline void c_can_irq_read_handler(struct canchip_t *pchip, int idxobj,
+ u32 msgid);
-inline void c_can_irq_write_handler( struct chip_t *pchip, int idxobj);
+inline void c_can_irq_write_handler(struct canchip_t *pchip, int idxobj);
-void c_can_irq_rtr_handler( struct chip_t *pchip, int idxobj, u32 msgid );
+void c_can_irq_rtr_handler(struct canchip_t *pchip, int idxobj, u32 msgid);
u16 readMaskCM = IFXCM_ARB | IFXCM_CNTRL | IFXCM_CLRINTPND
- | IFXCM_TRND | IFXCM_DA | IFXCM_DB;
+ | IFXCM_TRND | IFXCM_DA | IFXCM_DB;
u16 msgLstReadMaskCM = IFXCM_CNTRL;
-u16 msgLstWriteMaskCM = IFXCM_CNTRL | IFXCM_WRRD;
+u16 msgLstWriteMaskCM = IFXCM_CNTRL | IFXCM_WRRD;
///////////////////////////////////////////////////////////////////////////////
// c_can_irq_write_handler
// Send a message from the output fifo ( if any ).
//
-inline void c_can_irq_write_handler( struct chip_t *pchip, int idxobj)
+inline void c_can_irq_write_handler(struct canchip_t *pchip, int idxobj)
{
int cmd;
struct msgobj_t *pmsgobj = pchip->msgobj[idxobj];
DEBUGMSG("(c%dm%d)calling c_can_irq_write_handler(...)\n",
- pchip->chip_idx, pmsgobj->object);
+ pchip->chip_idx, pmsgobj->object);
- if(pmsgobj->tx_slot){
+ if (pmsgobj->tx_slot) {
/* Do local transmitted message distribution if enabled */
- if (processlocal){
+ if (processlocal) {
+ /* fill CAN message timestamp */
+ can_filltimestamp(&pmsgobj->tx_slot->msg.timestamp);
+
pmsgobj->tx_slot->msg.flags |= MSG_LOCAL;
- canque_filter_msg2edges(pmsgobj->qends, &pmsgobj->tx_slot->msg);
+ canque_filter_msg2edges(pmsgobj->qends,
+ &pmsgobj->tx_slot->msg);
}
/* Free transmitted slot */
- canque_free_outslot(pmsgobj->qends, pmsgobj->tx_qedge, pmsgobj->tx_slot);
- pmsgobj->tx_slot=NULL;
+ canque_free_outslot(pmsgobj->qends, pmsgobj->tx_qedge,
+ pmsgobj->tx_slot);
+ pmsgobj->tx_slot = NULL;
}
-
// Get ready to send next message
- spin_lock( &c_can_spwlock );
+ spin_lock(&c_can_spwlock);
- cmd=canque_test_outslot(pmsgobj->qends, &pmsgobj->tx_qedge, &pmsgobj->tx_slot);
- if(cmd<0){
+ cmd =
+ canque_test_outslot(pmsgobj->qends, &pmsgobj->tx_qedge,
+ &pmsgobj->tx_slot);
+ if (cmd < 0) {
DEBUGMSG("(c%dm%d)Nothin to write\n",
- pchip->chip_idx, pmsgobj->object);
- spin_unlock( &c_can_spwlock );
+ pchip->chip_idx, pmsgobj->object);
+ spin_unlock(&c_can_spwlock);
return;
}
-
// Send the message
- if ( pchip->chipspecops->send_msg( pchip, pmsgobj,&pmsgobj->tx_slot->msg) ) {
+ if (pchip->chipspecops->
+ send_msg(pchip, pmsgobj, &pmsgobj->tx_slot->msg)) {
pmsgobj->ret = -1;
- canque_notify_inends(pmsgobj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND);
- canque_free_outslot(pmsgobj->qends, pmsgobj->tx_qedge, pmsgobj->tx_slot);
- pmsgobj->tx_slot=NULL;
- spin_unlock( &c_can_spwlock );
+ canque_notify_inends(pmsgobj->tx_qedge,
+ CANQUEUE_NOTIFY_ERRTX_SEND);
+ canque_free_outslot(pmsgobj->qends, pmsgobj->tx_qedge,
+ pmsgobj->tx_slot);
+ pmsgobj->tx_slot = NULL;
+ spin_unlock(&c_can_spwlock);
DEBUGMSG("(c%dm%d)c_can_irq_handler: Unable to send message\n",
- pchip->chip_idx, pmsgobj->object );
+ pchip->chip_idx, pmsgobj->object);
return;
} else {
// Another message sent
- #ifdef CAN_WITH_STATISTICS
+#ifdef CAN_WITH_STATISTICS
pchip->stat.cntTxPkt++;
pchip->stat.cntTxData += pmsgobj->tx_slot->length;
- #endif /*CAN_WITH_STATISTICS*/
+#endif /*CAN_WITH_STATISTICS */
}
- spin_unlock( &c_can_spwlock );
+ spin_unlock(&c_can_spwlock);
// Wake up any waiting writer
return;
// Message received form the line. Write it in the input fifo->
//
-inline void c_can_irq_read_handler( struct chip_t *pchip,
- int idxobj, u32 msgid )
+inline void c_can_irq_read_handler(struct canchip_t *pchip,
+ int idxobj, u32 msgid)
{
- int i=0;
- u16 bDataAvail=1 ;
+ int i = 0;
+ u16 bDataAvail = 1;
u16 msgCntlReg = 0;
union c_can_data readData;
struct msgobj_t *pmsgobj = pchip->msgobj[idxobj];
-
+
DEBUGMSG("(c%dm%d)calling c_can_irq_read_handler(...)\n",
- pchip->chip_idx, pmsgobj->object);
-
- while ( bDataAvail ) {
-
- #ifdef CAN_WITH_STATISTICS
+ pchip->chip_idx, pmsgobj->object);
+
+ while (bDataAvail) {
+
+#ifdef CAN_WITH_STATISTICS
pchip->stat.cntRxFifoOvr++;
- #endif /*CAN_WITH_STATISTICS*/
+#endif /*CAN_WITH_STATISTICS */
// Message length
- msgCntlReg = c_can_read_reg_w( pchip, CCIF1DMC );
-
+ msgCntlReg = c_can_read_reg_w(pchip, CCIF1DMC);
+
pmsgobj->rx_msg.length = msgCntlReg & 0x000F;
-
+
// Message id
- pmsgobj->rx_msg.id = (u32)msgid;
-
+ pmsgobj->rx_msg.id = (u32) msgid;
+
// Fetch message bytes
if (pmsgobj->rx_msg.length > 0)
readData.wdata[0] = c_can_read_reg_w(pchip, CCIF1DA1);
readData.wdata[2] = c_can_read_reg_w(pchip, CCIF1DB1);
if (pmsgobj->rx_msg.length > 6)
readData.wdata[3] = c_can_read_reg_w(pchip, CCIF1DB2);
-
- for ( i=0; i < pmsgobj->rx_msg.length; i++ ) {
- pmsgobj->rx_msg.data[ i ] = readData.bdata[i];
+
+ for (i = 0; i < pmsgobj->rx_msg.length; i++) {
+ pmsgobj->rx_msg.data[i] = readData.bdata[i];
}
DEBUGMSG("(c%dm%d)Received Message:\n",
- pchip->chip_idx, pmsgobj->object);
- DEBUGMSG(" id = %ld\n",
- pmsgobj->rx_msg.id);
- DEBUGMSG(" length = %d\n",
- pmsgobj->rx_msg.length);
- for ( i=0; i < pmsgobj->rx_msg.length; i++ )
- DEBUGMSG(" data[%d] = 0x%.2x\n", i, pmsgobj->rx_msg.data[i]);
-
+ pchip->chip_idx, pmsgobj->object);
+ DEBUGMSG(" id = %ld\n", pmsgobj->rx_msg.id);
+ DEBUGMSG(" length = %d\n", pmsgobj->rx_msg.length);
+ for (i = 0; i < pmsgobj->rx_msg.length; i++)
+ DEBUGMSG(" data[%d] = 0x%.2x\n", i,
+ pmsgobj->rx_msg.data[i]);
+
+ /* fill CAN message timestamp */
+ can_filltimestamp(&pmsgobj->rx_msg.timestamp);
+
canque_filter_msg2edges(pmsgobj->qends, &pmsgobj->rx_msg);
-
- #ifdef CAN_WITH_STATISTICS
+
+#ifdef CAN_WITH_STATISTICS
// Another received packet
pchip->stat.cntRxPkt++;
// Add databytes read to statistics block
pchip->stat.cntRxData += pmsgobj->rx_msg.length;
- #endif /*CAN_WITH_STATISTICS*/
-
- spin_unlock( &c_can_sprlock );
+#endif /*CAN_WITH_STATISTICS */
// Check if new data arrived
if (c_can_if1_busycheck(pchip)) ;
c_can_write_reg_w(pchip, readMaskCM, CCIF1CM);
- c_can_write_reg_w(pchip, idxobj+1, CCIF1CR);
+ c_can_write_reg_w(pchip, idxobj + 1, CCIF1CR);
if (c_can_if1_busycheck(pchip)) ;
- if ( !( ( bDataAvail = c_can_read_reg_w( pchip, CCIF1DMC ) ) &
- IFXMC_NEWDAT ) ) {
+ if (!((bDataAvail = c_can_read_reg_w(pchip, CCIF1DMC)) &
+ IFXMC_NEWDAT)) {
break;
}
- if ( bDataAvail & IFXMC_MSGLST ) {
+ if (bDataAvail & IFXMC_MSGLST) {
CANMSG("(c%dm%d)c-can fifo full: Message lost!\n",
- pchip->chip_idx, pmsgobj->object);
+ pchip->chip_idx, pmsgobj->object);
}
}
// while
}
-void c_can_irq_sync_activities(struct chip_t *chip, struct msgobj_t *obj)
+///////////////////////////////////////////////////////////////////////////////
+// c_can_irq_update_filter
+//
+// update acceptance filter for given object.
+//
+
+void c_can_irq_update_filter(struct canchip_t *pchip, struct msgobj_t *obj)
+{
+ struct canfilt_t filt;
+
+ if(canqueue_ends_filt_conjuction(obj->qends, &filt)) {
+ obj->rx_preconfig_id=filt.id;
+
+ if (filt.flags&MSG_EXT)
+ can_msgobj_set_fl(obj,RX_MODE_EXT);
+ else
+ can_msgobj_clear_fl(obj,RX_MODE_EXT);
+
+ c_can_mask(obj, filt.mask, 0);
+
+ c_can_pre_read_config(pchip, obj);
+
+ CANMSG("c_can_irq_update_filter: obj #%d\n",obj->object);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// c_can_irq_sync_activities
+//
+// ensure, that not requests for object activities are serialized.
+//
+
+void c_can_irq_sync_activities(struct canchip_t *pchip, struct msgobj_t *obj)
{
- while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)) {
+ while (!can_msgobj_test_and_set_fl(obj, TX_LOCK)) {
- /*if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST)) {
- if(canobj_read_reg(chip,obj,iMSGCTL1)&TXRQ_RES)
- i82527_irq_write_handler(chip, obj);
+ if(can_msgobj_test_and_clear_fl(obj,TX_REQUEST)) {
+ int cctreqx;
+ int idxobj = obj->object-1;
+
+ if(idxobj<0) {
+ DEBUGMSG("c_can_irq_sync_activities wrong idxobj\n");
+ break;
+ }
+
+ if(idxobj < 16)
+ cctreqx = c_can_read_reg_w(pchip, CCTREQ1);
+ else
+ cctreqx = c_can_read_reg_w(pchip, CCTREQ2);
+
+ if (!(cctreqx & (1 << (idxobj & 0xf)))) {
+ can_msgobj_clear_fl(obj, TX_REQUEST);
+ c_can_irq_write_handler(pchip, idxobj);
+ }
}
if(!obj->tx_slot) {
if(can_msgobj_test_and_clear_fl(obj,FILTCH_REQUEST)) {
- i82527_irq_update_filter(chip, obj);
+ c_can_irq_update_filter(pchip, obj);
}
- }*/
- /* FIXME: these functionality has to be implemented to start TX */
+ }
+
+ can_msgobj_clear_fl(obj, TX_LOCK);
- can_msgobj_clear_fl(obj,TX_LOCK);
- if(can_msgobj_test_fl(obj,TX_REQUEST))
+ mb();
+
+ if (can_msgobj_test_fl(obj, TX_REQUEST))
continue;
- if(can_msgobj_test_fl(obj,FILTCH_REQUEST) && !obj->tx_slot)
+ if (can_msgobj_test_fl(obj, FILTCH_REQUEST) && !obj->tx_slot)
continue;
break;
}
}
-
///////////////////////////////////////////////////////////////////////////////
// c_can_irq_handler
//
-can_irqreturn_t c_can_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
+int c_can_irq_handler(int irq, struct canchip_t *pchip)
{
struct rtr_id *rtr_search = hardware_p->rtr_queue;
- struct chip_t *pchip = (struct chip_t *)dev_id;
u16 chip_status;
- int id0=0, id1=0;
+ int id0 = 0, id1 = 0;
u16 errcount = 0;
u16 irqreg = 0;
u32 msgid = 0;
u16 tempCntlReg = 0;
- //#ifdef CAN_DEBUG
- // u32 intCntrVAddr = 0;
- //#endif
- //unsigned short flags = 0;
-
- //if (pchip->ntype != CAN_CHIPTYPE_C_CAN) {
- // DEBUGMSG("\n(c%d)IRQ not for c_can_irq_handler(...)\n", pchip->chip_idx);
- // return;
- //}
-
- irqreg = c_can_read_reg_w( pchip, CCINTR );
-
- if(!irqreg) {
- DEBUGMSG( "\n(c%d)IRQ handler: addr=%.8lx spurious interrupt\n",
- pchip->chip_idx,
- (long)( pchip->/*v*/chip_base_addr/* + CCSR*/));
- return CAN_IRQ_NONE;
- }
-
- DEBUGMSG( "\n(c%d)IRQ handler: addr=%.8lx irqreg=0x%.4x\n",
- pchip->chip_idx,
- (long)( pchip->/*v*/chip_base_addr/* + CCSR*/),
- irqreg);
-
-
- #ifdef REGDUMP
- c_can_registerdump(pchip);
- #endif
+ irqreg = c_can_read_reg_w(pchip, CCINTR);
-/*
-#ifdef CAN_DEBUG
- if ( (!( intCntrVAddr = (u32)ioremap( 0x80024000, 0xCD ) ))) {
- DEBUGMSG("Failed to map Interrupt Controller IO-memory\n");
+ if (!irqreg) {
+ DEBUGMSG("\n(c%d)IRQ handler: addr=%.8lx spurious interrupt\n",
+ pchip->chip_idx,
+ (long)(pchip-> /*v */ chip_base_addr /* + CCSR */ ));
+ return CANCHIP_IRQ_NONE;
}
- else {
- DEBUGMSG( "Mapped Interrupt Controller IO-memory: 0x%lx - 0x%lx to 0x%lx\n",
- (unsigned long)0X80024000,
- (unsigned long)0X800240CC,
- (unsigned long)intCntrVAddr);
- }
+ DEBUGMSG("\n(c%d)IRQ handler: addr=%.8lx irqreg=0x%.4x\n",
+ pchip->chip_idx,
+ (long)(pchip-> /*v */ chip_base_addr /* + CCSR */ ),
+ irqreg);
- DEBUGMSG("Current Interrupt Status Register (ISR): 0x%4.4lx\n",
- (long)readl(intCntrVAddr + 4));
- DEBUGMSG("Current Interrupt ID: %d\n",
- (int)(readl(intCntrVAddr + 0x90) & 0xF));
- iounmap( (void*)intCntrVAddr);
- DEBUGMSG( "Unmapped Interrupt Controller IO-memory: 0x%lx\n",
- (unsigned long)intCntrVAddr);
+#ifdef REGDUMP
+ c_can_registerdump(pchip);
#endif
-*/
- while ( irqreg ){
+
+ while (irqreg) {
// Handle change in status register
-
- if ( irqreg == INT_STAT ) {
- chip_status = c_can_read_reg_w( pchip, CCSR );
- DEBUGMSG( "(c%d)Status register: 0x%x\n",
- pchip->chip_idx, chip_status );
-
- if ( chip_status & SR_EWARN ) {
+
+ if (irqreg == INT_STAT) {
+ chip_status = c_can_read_reg_w(pchip, CCSR);
+ DEBUGMSG("(c%d)Status register: 0x%x\n",
+ pchip->chip_idx, chip_status);
+
+ if (chip_status & SR_EWARN) {
// There is an abnormal # of errors
- #ifdef CAN_WITH_STATISTICS
+#ifdef CAN_WITH_STATISTICS
pchip->stat.cntWarnings++;
- #endif /*CAN_WITH_STATISTICS*/
- errcount = c_can_read_reg_w( pchip, CCEC);
- DEBUGMSG("(c%d)stat: c_can_irq_handler: Abnormal number of Errors Warning\n"
- " txErr=%d, rxErr=%d\n",
- pchip->chip_idx, (errcount&0x00ff), ((errcount&0x7f00)>>8));
+#endif /*CAN_WITH_STATISTICS */
+ errcount = c_can_read_reg_w(pchip, CCEC);
+ DEBUGMSG
+ ("(c%d)stat: c_can_irq_handler: Abnormal number of Errors Warning\n"
+ " txErr=%d, rxErr=%d\n",
+ pchip->chip_idx, (errcount & 0x00ff),
+ ((errcount & 0x7f00) >> 8));
/*
- // this code deactivates the chip if the transmiterrorcounter grew above 127
- if ((pchip->stat.cntWarnings > 100) && ((errcount&0x00ff) > 127))
- {
- CANMSG("(c%d)to much Errornumber warnings (>100), deactivating chip",
- pchip->chip_idx);
- pchip->config_irqs(pchip, 0);
- pchip->enable_configuration(pchip);
- pchip->clear_objects(pchip);
- pchip->flags &= ~CHANNEL_CONFIGURED;
- return;
- }*/
+ // this code deactivates the chip if the transmiterrorcounter grew above 127
+ if ((pchip->stat.cntWarnings > 100) && ((errcount&0x00ff) > 127))
+ {
+ CANMSG("(c%d)to much Errornumber warnings (>100), deactivating chip",
+ pchip->chip_idx);
+ pchip->config_irqs(pchip, 0);
+ pchip->enable_configuration(pchip);
+ pchip->clear_objects(pchip);
+ pchip->flags &= ~CHANNEL_CONFIGURED;
+ return;
+ } */
}
- if ( chip_status & SR_EPASS ) {
+ if (chip_status & SR_EPASS) {
// There is an abnormal # of errors
- #ifdef CAN_WITH_STATISTICS
+#ifdef CAN_WITH_STATISTICS
pchip->stat.cntErrPassive++;
- #endif /*CAN_WITH_STATISTICS*/
- DEBUGMSG("(c%d)stat: c_can_irq_handler: Chip entering Error Passive Mode\n",
- pchip->chip_idx);
+#endif /*CAN_WITH_STATISTICS */
+ DEBUGMSG
+ ("(c%d)stat: c_can_irq_handler: Chip entering Error Passive Mode\n",
+ pchip->chip_idx);
}
- if ( chip_status & SR_BOFF ) {
+ if (chip_status & SR_BOFF) {
// We have a bus off condition
- #ifdef CAN_WITH_STATISTICS
+#ifdef CAN_WITH_STATISTICS
pchip->stat.cntBusOff++;
- #endif /*CAN_WITH_STATISTICS*/
+#endif /*CAN_WITH_STATISTICS */
//pchip->fifo->tx_in_progress = 0;
//reset init bit
- CANMSG("(c%d)stat: c_can_irq_handler: Bus Off\n",
- pchip->chip_idx);
+ CANMSG
+ ("(c%d)stat: c_can_irq_handler: Bus Off\n",
+ pchip->chip_idx);
/*if (pchip->stat.cntBusOff > 100)
- {
- CANMSG("(c%d)to much busoff warnings (>100), deactivating chip",
- pchip->chip_idx);
- pchip->config_irqs(pchip, 0);
- pchip->enable_configuration(pchip);
- pchip->clear_objects(pchip);
- pchip->flags &= ~CHANNEL_CONFIGURED;
- return;
- }
- else*/
+ {
+ CANMSG("(c%d)to much busoff warnings (>100), deactivating chip",
+ pchip->chip_idx);
+ pchip->config_irqs(pchip, 0);
+ pchip->enable_configuration(pchip);
+ pchip->clear_objects(pchip);
+ pchip->flags &= ~CHANNEL_CONFIGURED;
+ return;
+ }
+ else */
CANMSG("(c%d)try to reconnect",
- pchip->chip_idx);
- pchip->chipspecops->disable_configuration(pchip);
+ pchip->chip_idx);
+ pchip->chipspecops->
+ disable_configuration(pchip);
}
if (chip_status & SR_TXOK) {
- DEBUGMSG("(c%d)stat: Transmitted a Message successfully\n",
- pchip->chip_idx);
- c_can_write_reg_w(pchip, chip_status & ~SR_TXOK, CCSR);
+ DEBUGMSG
+ ("(c%d)stat: Transmitted a Message successfully\n",
+ pchip->chip_idx);
+ c_can_write_reg_w(pchip, chip_status & ~SR_TXOK,
+ CCSR);
}
-
+
if (chip_status & SR_RXOK) {
- DEBUGMSG("(c%d)stat: Received a Message successfully\n",
- pchip->chip_idx);
- c_can_write_reg_w(pchip, chip_status & ~SR_RXOK, CCSR);
+ DEBUGMSG
+ ("(c%d)stat: Received a Message successfully\n",
+ pchip->chip_idx);
+ c_can_write_reg_w(pchip, chip_status & ~SR_RXOK,
+ CCSR);
}
-
- #ifdef CAN_WITH_STATISTICS
+#ifdef CAN_WITH_STATISTICS
// Errors to statistics
- switch( chip_status & 0x07 )
- {
- case SRLEC_NE: // No error
- break;
- case SRLEC_SE: // Stuff error
- pchip->stat.cntStuffErr++;
- break;
- case SRLEC_FE: // Form error
- pchip->stat.cntFormErr++;
- break;
- case SRLEC_AE: // Ack error
- pchip->stat.cntAckErr++;
- break;
- case SRLEC_B1: // Bit 1 error
- pchip->stat.cntBit1Err++;
- break;
- case SRLEC_B0: // Bit 0 error
- pchip->stat.cntBit0Err++;
- break;
- case SRLEC_CR: // CRC error
- pchip->stat.cntCrcErr++;
- break;
- case 7: // unused
- break;
+ switch (chip_status & 0x07) {
+ case SRLEC_NE: // No error
+ break;
+ case SRLEC_SE: // Stuff error
+ pchip->stat.cntStuffErr++;
+ break;
+ case SRLEC_FE: // Form error
+ pchip->stat.cntFormErr++;
+ break;
+ case SRLEC_AE: // Ack error
+ pchip->stat.cntAckErr++;
+ break;
+ case SRLEC_B1: // Bit 1 error
+ pchip->stat.cntBit1Err++;
+ break;
+ case SRLEC_B0: // Bit 0 error
+ pchip->stat.cntBit0Err++;
+ break;
+ case SRLEC_CR: // CRC error
+ pchip->stat.cntCrcErr++;
+ break;
+ case 7: // unused
+ break;
}
- #endif /*CAN_WITH_STATISTICS*/
+#endif /*CAN_WITH_STATISTICS */
//return; // continue?
} else {
- if (irqreg >0 && irqreg <33) {
+ if (irqreg >= 1 && irqreg <= 32) {
struct msgobj_t *pmsgobj;
int idxobj;
-
+
//get id
- idxobj = irqreg-1;
- pmsgobj=pchip->msgobj[idxobj];
-
+ idxobj = irqreg - 1;
+ pmsgobj = pchip->msgobj[idxobj];
+
//DEBUGMSG( "Interrupt handler: addr=%lx devid=%lx irqreq=%x status=0x%x\n",
- // (unsigned long)pchip->vbase_addr + iIRQ,
+ // (unsigned long)pchip->vbase_addr + iIRQ,
// (unsigned long)dev_id,
// irqreg,
// statreg );
//
- spin_lock( &c_can_if1lock );
-
+ spin_lock(&c_can_if1lock);
+
//Message Lost Check
- if (c_can_if1_busycheck(pchip)) ; /*??????????*/
- c_can_write_reg_w(pchip, msgLstReadMaskCM, CCIF1CM);
- c_can_write_reg_w(pchip, idxobj+1, CCIF1CR);
-
- if (c_can_if1_busycheck(pchip)) ; /*??????????*/
- tempCntlReg = c_can_read_reg_w( pchip, CCIF1DMC );
+ if (c_can_if1_busycheck(pchip)) ; /*?????????? */
+ c_can_write_reg_w(pchip, msgLstReadMaskCM,
+ CCIF1CM);
+ c_can_write_reg_w(pchip, idxobj + 1, CCIF1CR);
+
+ if (c_can_if1_busycheck(pchip)) ; /*?????????? */
+ tempCntlReg = c_can_read_reg_w(pchip, CCIF1DMC);
if (tempCntlReg & IFXMC_MSGLST) {
CANMSG("(c%dm%d)Chip lost a message\n",
- pchip->chip_idx, pmsgobj->object);
- #ifdef CAN_WITH_STATISTICS
+ pchip->chip_idx,
+ pmsgobj->object);
+#ifdef CAN_WITH_STATISTICS
pchip->stat.cntMsgLst++;
- #endif /*CAN_WITH_STATISTICS*/
-
+#endif /*CAN_WITH_STATISTICS */
+
//Reset Message Lost Bit
- tempCntlReg = tempCntlReg & (~IFXMC_MSGLST);
- c_can_write_reg_w(pchip, tempCntlReg, CCIF1DMC);
- c_can_write_reg_w(pchip, msgLstWriteMaskCM, CCIF1CM);
- c_can_write_reg_w(pchip, idxobj+1, CCIF1CR);
+ tempCntlReg =
+ tempCntlReg & (~IFXMC_MSGLST);
+ c_can_write_reg_w(pchip, tempCntlReg,
+ CCIF1DMC);
+ c_can_write_reg_w(pchip,
+ msgLstWriteMaskCM,
+ CCIF1CM);
+ c_can_write_reg_w(pchip, idxobj + 1,
+ CCIF1CR);
}
-
//transfer Message Object to IF1 Buffer
if (c_can_if1_busycheck(pchip)) ;
+
c_can_write_reg_w(pchip, readMaskCM, CCIF1CM);
- c_can_write_reg_w(pchip, idxobj+1, CCIF1CR);
+ c_can_write_reg_w(pchip, idxobj + 1, CCIF1CR);
if (c_can_if1_busycheck(pchip)) ;
- if (c_can_read_reg_w(pchip, CCIF1A2) & IFXARB2_DIR) {
- spin_unlock( &c_can_if1lock );
- c_can_irq_write_handler(pchip,idxobj);
+ if (c_can_read_reg_w(pchip, CCIF1A2) &
+ IFXARB2_DIR) {
+ DEBUGMSG("c_can_irq_write_handler idxobj=%d, msgid=%d\n",idxobj,msgid);
+ spin_unlock(&c_can_if1lock);
+ c_can_irq_write_handler(pchip, idxobj);
+
+ if(!pmsgobj->tx_slot){
+ if(can_msgobj_test_and_clear_fl(pmsgobj, FILTCH_REQUEST)) {
+ c_can_irq_update_filter(pchip, pmsgobj);
+ }
+ }
} else {
- if (can_msgobj_test_fl(pmsgobj,RX_MODE_EXT)) {
- id0=c_can_read_reg_w(pchip, CCIF1A1);
- id1=(c_can_read_reg_w(pchip, CCIF1A2)&0x1FFF)<<16;
- msgid= id0|id1;
+ if (can_msgobj_test_fl
+ (pmsgobj, RX_MODE_EXT)) {
+ id0 =
+ c_can_read_reg_w(pchip,
+ CCIF1A1);
+ id1 =
+ (c_can_read_reg_w
+ (pchip,
+ CCIF1A2) & 0x1FFF) << 16;
+ msgid = id0 | id1;
} else {
- msgid=((c_can_read_reg_w(pchip, CCIF1A2)&0x1FFC)>>2)&0x7FF;
+ msgid =
+ ((c_can_read_reg_w
+ (pchip,
+ CCIF1A2) & 0x1FFC) >> 2)
+ & 0x7FF;
}
- spin_unlock( &c_can_if1lock );
+ spin_unlock(&c_can_if1lock);
spin_lock(&hardware_p->rtr_lock);
- while ( rtr_search != NULL )
- {
- if ( rtr_search->id == msgid ) {
+ while (rtr_search != NULL) {
+ if (rtr_search->id == msgid) {
break;
}
rtr_search = rtr_search->next;
}
spin_unlock(&hardware_p->rtr_lock);
- spin_lock( &c_can_if1lock );
+ spin_lock(&c_can_if1lock);
//transfer Message Object to IF1 Buffer
if (c_can_if1_busycheck(pchip)) ;
- c_can_write_reg_w(pchip, readMaskCM, CCIF1CM);
- c_can_write_reg_w(pchip, idxobj+1, CCIF1CR);
-
+ c_can_write_reg_w(pchip, readMaskCM,
+ CCIF1CM);
+ c_can_write_reg_w(pchip, idxobj + 1,
+ CCIF1CR);
+
if (c_can_if1_busycheck(pchip)) ;
-
- if ( ( rtr_search != NULL ) && (rtr_search->id == msgid ) ) {
- c_can_irq_rtr_handler( pchip, idxobj, msgid );
+
+ if ((rtr_search != NULL)
+ && (rtr_search->id == msgid)) {
+ c_can_irq_rtr_handler(pchip,
+ idxobj,
+ msgid);
} else {
- c_can_irq_read_handler( pchip, idxobj, msgid );
+ c_can_irq_read_handler(pchip,
+ idxobj,
+ msgid);
}
- spin_unlock( &c_can_if1lock );
-
- //}
+ spin_unlock(&c_can_if1lock);
+
}
- //else
+ //else
}
- //if
+ //if (irqreg >= 1 && irqreg <= 32)
}
// Get irq status again
- irqreg = c_can_read_reg_w( pchip, CCINTR );
+ irqreg = c_can_read_reg_w(pchip, CCINTR);
}
- return CAN_IRQ_HANDLED;
+ return CANCHIP_IRQ_HANDLED;
}
///////////////////////////////////////////////////////////////////////////////
// c_can_irq_rtr_handler
//
-void c_can_irq_rtr_handler( struct chip_t *pchip, int idxobj, u32 msgid )
+void c_can_irq_rtr_handler(struct canchip_t *pchip, int idxobj, u32 msgid)
{
- short int i=0;
+ short int i = 0;
struct rtr_id *prtr_search = hardware_p->rtr_queue;
union c_can_data rtrData;
-
- spin_lock( &hardware_p->rtr_lock );
-
+
+ spin_lock(&hardware_p->rtr_lock);
+
prtr_search->rtr_message->id = msgid;
prtr_search->rtr_message->length =
- ( c_can_read_reg_w( pchip, CCIF1DMC ) & 0x000f);
-
+ (c_can_read_reg_w(pchip, CCIF1DMC) & 0x000f);
+
// Fetch message bytes
if (prtr_search->rtr_message->length > 0)
rtrData.wdata[0] = c_can_read_reg_w(pchip, CCIF1DA1);
rtrData.wdata[2] = c_can_read_reg_w(pchip, CCIF1DB1);
if (prtr_search->rtr_message->length > 6)
rtrData.wdata[3] = c_can_read_reg_w(pchip, CCIF1DB2);
-
- for ( i=0; i<prtr_search->rtr_message->length; i++ ) {
- prtr_search->rtr_message->data[ i ] = rtrData.bdata[i];
+
+ for (i = 0; i < prtr_search->rtr_message->length; i++) {
+ prtr_search->rtr_message->data[i] = rtrData.bdata[i];
}
-
- spin_unlock( &hardware_p->rtr_lock );
- wake_up_interruptible( &prtr_search->rtr_wq );
+
+ spin_unlock(&hardware_p->rtr_lock);
+ wake_up_interruptible(&prtr_search->rtr_wq);
return;
}
-