X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/4cf24de229090b1ab6279570a564d224e13dd706..2827b727d2910a3b48f9de7d67b3a67f59e256c7:/lincan/src/irq.c diff --git a/lincan/src/irq.c b/lincan/src/irq.c index 92ce53e..26d0cf7 100644 --- a/lincan/src/irq.c +++ b/lincan/src/irq.c @@ -1,298 +1,19 @@ /* irq.c * Linux CAN-bus device driver. * Written by Arnaud Westenberg email:arnaud@wanadoo.nl + * 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 0.7 6 Aug 2001 + * Version lincan-0.2 9 Jul 2003 */ -#include -#if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS) -#define MODVERSIONS -#endif - -#if defined (MODVERSIONS) -#include -#endif - -#include -#include - -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19)) -#include -#else -#include -#endif - +#include "../include/can.h" +#include "../include/can_sysdep.h" #include "../include/main.h" #include "../include/irq.h" -#include "../include/i82527.h" -#include "../include/sja1000.h" - -void i82527_irq_rtr_handler(void); -void sja1000_irq_read_handler(void); -void sja1000_irq_write_handler(void); - -void (*put_reg)(unsigned char data, unsigned long address); -unsigned (*get_reg)(unsigned long address); - -struct chip_t *chip=NULL; -struct candevice_t *device=NULL; -unsigned object=0,irq_register=0; -unsigned long msgbase=0; -struct canfifo_t *fifo=NULL; -unsigned long message_id=0; -struct rtr_id *rtr_search; - -inline void i82527_irq_write_handler(void) -{ - put_reg((MVAL_RES|TXIE_RES|RXIE_RES|INTPD_RES),msgbase+iMSGCTL0); - - fifo->tx_readp++; - if (fifo->tx_readp >= fifo->buf_tx_entry + MAX_BUF_LENGTH) - fifo->tx_readp = fifo->buf_tx_entry; - if (fifo->tx_readp == fifo->tx_writep) { // Output buffer is empty - fifo->tx_in_progress = 0; - if (waitqueue_active(&fifo->writeq)) { - chip->msgobj[object]->ret = 0; - wake_up_interruptible(&fifo->writeq); - } - return; - } - if (chip->chipspecops->pre_write_config(chip, chip->msgobj[object], - fifo->tx_readp)) { - if (waitqueue_active(&fifo->writeq)) { - chip->msgobj[object]->ret = -1; - wake_up_interruptible(&fifo->writeq); - return; - } - } - if (chip->chipspecops->send_msg(chip, chip->msgobj[object], - fifo->tx_readp)) { - if (waitqueue_active(&fifo->writeq)) { - chip->msgobj[object]->ret = -1; - wake_up_interruptible(&fifo->writeq); - return; - } - } -} - -inline void i82527_irq_read_handler(void) -{ - int i=0, tmp=1 ; - - while (tmp) { - put_reg((RMPD_RES|TXRQ_RES|MLST_RES|NEWD_RES), msgbase + - iMSGCTL1); - put_reg((MVAL_SET|TXIE_RES|RXIE_SET|INTPD_RES), msgbase + - iMSGCTL0); - - fifo->rx_writep->length =(get_reg(msgbase+iMSGCFG) & 0xf0) >> 4; - fifo->rx_writep->id = message_id; - for (i=0; i < fifo->rx_writep->length; i++) - fifo->rx_writep->data[i] = get_reg(msgbase+iMSGDAT0+i); - -//FIXME: Add buffer overflow check, currently it's silently over written! - - fifo->rx_writep++; - if (fifo->rx_writep >= fifo->buf_rx_entry + MAX_BUF_LENGTH) - fifo->rx_writep = fifo->buf_rx_entry; - - if (!((tmp=get_reg(msgbase + iMSGCTL1)) & NEWD_SET)) { - break; - } - - if (tmp & MLST_SET) - CANMSG("Message lost!\n"); - - } - if (waitqueue_active(&fifo->readq)) { - wake_up_interruptible(&fifo->readq); - } -} - -void i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs) -{ - int id0=0, id1=0, id2=0, id3=0; - - chip=(struct chip_t *)dev_id; - device=(struct candevice_t *)chip->hostdevice; - - put_reg=device->hwspecops->write_register; - get_reg=device->hwspecops->read_register; - - if ( (chip->flags & SEGMENTED) != 0) - irq_register = get_reg(chip->chip_base_addr+iIRQ+SPACING); - else - irq_register = get_reg(chip->chip_base_addr+iIRQ); - - while (irq_register) { - - if (irq_register == 0x01) { - DEBUGMSG("Status register: 0x%x\n",get_reg(chip->chip_base_addr+iSTAT)); - return; - } - - if (irq_register == 0x02) - object = 14; - else - object = irq_register-3; - fifo=chip->msgobj[object]->fifo; - msgbase=chip->msgobj[object]->obj_base_addr; - - if (get_reg(msgbase+iMSGCFG) & MCFG_DIR) { - i82527_irq_write_handler(); - } - else { - - if (extended) { - id0=get_reg(msgbase+iMSGID3); - id1=get_reg(msgbase+iMSGID2)<<8; - id2=get_reg(msgbase+iMSGID1)<<16; - id3=get_reg(msgbase+iMSGID0)<<24; - message_id=(id0|id1|id2|id3)>>3; - } - else { - id0=get_reg(msgbase+iMSGID1); - id1=get_reg(msgbase+iMSGID0)<<8; - message_id=(id0|id1)>>5; - } - - spin_lock(&hardware_p->rtr_lock); - rtr_search=hardware_p->rtr_queue; - while (rtr_search != NULL) { - if (rtr_search->id == message_id) - break; - rtr_search=rtr_search->next; - } - spin_unlock(&hardware_p->rtr_lock); - if ((rtr_search!=NULL) && (rtr_search->id==message_id)) - i82527_irq_rtr_handler(); - else - i82527_irq_read_handler(); - } - - if ( (chip->flags & SEGMENTED) != 0) - irq_register=get_reg(chip->chip_base_addr+iIRQ+SPACING); - else - irq_register=get_reg(chip->chip_base_addr+iIRQ); - } - -} - -void i82527_irq_rtr_handler(void) -{ - short int i=0; - - put_reg((MVAL_RES|TXIE_RES|RXIE_RES|INTPD_RES),msgbase + iMSGCTL0); - put_reg((RMPD_RES|TXRQ_RES|MLST_RES|NEWD_RES),msgbase + iMSGCTL1); - - spin_lock(&hardware_p->rtr_lock); - - rtr_search->rtr_message->id=message_id; - rtr_search->rtr_message->length=(get_reg(msgbase + iMSGCFG) & 0xf0)>>4; - for (i=0; irtr_message->length; i++) - rtr_search->rtr_message->data[i]=get_reg(msgbase+iMSGDAT0+i); - - spin_unlock(&hardware_p->rtr_lock); - - if (waitqueue_active(&rtr_search->rtr_wq)) - wake_up_interruptible(&rtr_search->rtr_wq); -} - -void sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs) -{ - chip=(struct chip_t *)dev_id; - device=(struct candevice_t *)chip->hostdevice; - - put_reg=device->hwspecops->write_register; - get_reg=device->hwspecops->read_register; - - irq_register=get_reg(chip->chip_base_addr+SJAIR); -// DEBUGMSG("sja1000_irq_handler: SJAIR:%02x\n",irq_register); -// DEBUGMSG("sja1000_irq_handler: SJASR:%02x\n", -// get_reg(chip->chip_base_addr+SJASR)); - - if ((irq_register & (IR_WUI|IR_DOI|IR_EI|IR_TI|IR_RI)) == 0) - return; - - fifo=chip->msgobj[0]->fifo; - msgbase=chip->msgobj[0]->obj_base_addr; - - if ((irq_register & IR_RI) != 0) - sja1000_irq_read_handler(); - if ((irq_register & IR_TI) != 0) - sja1000_irq_write_handler(); - if ((irq_register & (IR_EI|IR_DOI)) != 0) { - // Some error happened -// FIXME: chip should be brought to usable state. Transmission cancelled if in progress. -// Reset flag set to 0 if chip is already off the bus. Full state report - CANMSG("Error: status register: 0x%x irq_register: 0x%02x\n", - get_reg(chip->chip_base_addr+SJASR), irq_register); - chip->msgobj[0]->ret=-1; - if (waitqueue_active(&fifo->writeq)) - wake_up_interruptible(&fifo->writeq); - if (waitqueue_active(&fifo->readq)) - wake_up_interruptible(&fifo->readq); - } - - return; -} -void sja1000_irq_read_handler(void) -{ - int i=0, id=0, tmp=1; - - while (tmp) { - id = get_reg(msgbase+SJARXID0) | (get_reg(msgbase+SJARXID1)<<8); - fifo->buf_rx_entry[fifo->head].length = id & 0x0f; - fifo->buf_rx_entry[fifo->head].flags = id&ID0_RTR ? MSG_RTR : 0; - fifo->buf_rx_entry[fifo->head].timestamp = 0; - fifo->buf_rx_entry[fifo->head].cob = 0; - fifo->buf_rx_entry[fifo->head].id = id>>5; - - for (i=0; ibuf_rx_entry[fifo->head].length; i++) - fifo->buf_rx_entry[fifo->head].data[i]=get_reg(msgbase + - SJARXDAT0 + i); - - put_reg(CMR_RRB,msgbase+SJACMR); - - fifo->head++; - if (fifo->head >= MAX_BUF_LENGTH-1) - fifo->head=0; - - tmp=(get_reg(msgbase+SJASR) & SR_RBS); - } - if (waitqueue_active(&fifo->readq)) - wake_up_interruptible(&fifo->readq); -} -void sja1000_irq_write_handler(void) -{ - fifo->tx_readp++; - if (fifo->tx_readp >= fifo->buf_tx_entry + MAX_BUF_LENGTH) - fifo->tx_readp = fifo->buf_tx_entry; - if (fifo->tx_readp == fifo->tx_writep) { // Output buffer is empty - fifo->tx_in_progress = 0; - if (waitqueue_active(&fifo->writeq)) { - chip->msgobj[object]->ret = 0; - wake_up_interruptible(&fifo->writeq); - } - return; - } - if (chip->chipspecops->pre_write_config(chip, chip->msgobj[object], - fifo->tx_readp)) { - if (waitqueue_active(&fifo->writeq)) { - chip->msgobj[object]->ret = -1; - wake_up_interruptible(&fifo->writeq); - return; - } - } - if (chip->chipspecops->send_msg(chip, chip->msgobj[object], - fifo->tx_readp)) { - if (waitqueue_active(&fifo->writeq)) { - chip->msgobj[object]->ret = -1; - wake_up_interruptible(&fifo->writeq); - return; - } - } +can_irqreturn_t dummy_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { + CANMSG("dummy_irq_handler called irq %d \n", irq); + return CAN_IRQ_NONE; }