X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/4cf24de229090b1ab6279570a564d224e13dd706..786c7d54e8d820e89997e507c29ea716c0d55fd9:/lincan/src/irq.c diff --git a/lincan/src/irq.c b/lincan/src/irq.c index 92ce53e..caf0ac6 100644 --- a/lincan/src/irq.c +++ b/lincan/src/irq.c @@ -17,7 +17,7 @@ #include #include -#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19)) +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,0)) #include #else #include @@ -28,24 +28,29 @@ #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 i82527_irq_rtr_handler(struct chip_t *chip, struct msgobj_t *msgobj, + struct rtr_id *rtr_search, unsigned long message_id); +void sja1000_irq_read_handler(struct chip_t *chip, struct msgobj_t *msgobj); +void sja1000_irq_write_handler(struct chip_t *chip, struct msgobj_t *msgobj); -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; +/*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) +inline void i82527_irq_write_handler(struct chip_t *chip, struct msgobj_t *msgobj) { - put_reg((MVAL_RES|TXIE_RES|RXIE_RES|INTPD_RES),msgbase+iMSGCTL0); + struct canfifo_t *fifo=msgobj->fifo; + unsigned long msgbase=msgobj->obj_base_addr; + void (*write_reg)(unsigned char data, unsigned long address); + unsigned (*read_reg)(unsigned long address); + write_reg=chip->hostdevice->hwspecops->write_register; + read_reg=chip->hostdevice->hwspecops->read_register; + + (*write_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) @@ -53,43 +58,48 @@ inline void i82527_irq_write_handler(void) 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; + msgobj->ret = 0; wake_up_interruptible(&fifo->writeq); } return; } - if (chip->chipspecops->pre_write_config(chip, chip->msgobj[object], - fifo->tx_readp)) { + if (chip->chipspecops->pre_write_config(chip, msgobj, fifo->tx_readp)) { if (waitqueue_active(&fifo->writeq)) { - chip->msgobj[object]->ret = -1; + msgobj->ret = -1; wake_up_interruptible(&fifo->writeq); return; } } - if (chip->chipspecops->send_msg(chip, chip->msgobj[object], - fifo->tx_readp)) { + if (chip->chipspecops->send_msg(chip, msgobj, fifo->tx_readp)) { if (waitqueue_active(&fifo->writeq)) { - chip->msgobj[object]->ret = -1; + msgobj->ret = -1; wake_up_interruptible(&fifo->writeq); return; } } } -inline void i82527_irq_read_handler(void) +inline void i82527_irq_read_handler(struct chip_t *chip, struct msgobj_t *msgobj, + unsigned long message_id) { int i=0, tmp=1 ; - + struct canfifo_t *fifo=msgobj->fifo; + unsigned long msgbase=msgobj->obj_base_addr; + void (*write_reg)(unsigned char data, unsigned long address); + unsigned (*read_reg)(unsigned long address); + write_reg=chip->hostdevice->hwspecops->write_register; + read_reg=chip->hostdevice->hwspecops->read_register; + while (tmp) { - put_reg((RMPD_RES|TXRQ_RES|MLST_RES|NEWD_RES), msgbase + + (*write_reg)((RMPD_RES|TXRQ_RES|MLST_RES|NEWD_RES), msgbase + iMSGCTL1); - put_reg((MVAL_SET|TXIE_RES|RXIE_SET|INTPD_RES), msgbase + + (*write_reg)((MVAL_SET|TXIE_RES|RXIE_SET|INTPD_RES), msgbase + iMSGCTL0); - fifo->rx_writep->length =(get_reg(msgbase+iMSGCFG) & 0xf0) >> 4; + fifo->rx_writep->length =((*read_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); + fifo->rx_writep->data[i] = (*read_reg)(msgbase+iMSGDAT0+i); //FIXME: Add buffer overflow check, currently it's silently over written! @@ -97,7 +107,7 @@ inline void i82527_irq_read_handler(void) 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)) { + if (!((tmp=(*read_reg)(msgbase + iMSGCTL1)) & NEWD_SET)) { break; } @@ -114,21 +124,30 @@ 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; + unsigned irq_register; + unsigned object; + struct chip_t *chip=(struct chip_t *)dev_id; + struct msgobj_t *msgobj; + unsigned long msgbase; + unsigned long message_id; + struct rtr_id *rtr_search; + void (*write_reg)(unsigned char data, unsigned long address); + unsigned (*read_reg)(unsigned long address); + write_reg=chip->hostdevice->hwspecops->write_register; + read_reg=chip->hostdevice->hwspecops->read_register; + + /*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); + irq_register = can_read_reg(chip, iIRQ+SPACING); else - irq_register = get_reg(chip->chip_base_addr+iIRQ); + irq_register = can_read_reg(chip, iIRQ); while (irq_register) { if (irq_register == 0x01) { - DEBUGMSG("Status register: 0x%x\n",get_reg(chip->chip_base_addr+iSTAT)); + DEBUGMSG("Status register: 0x%x\n",can_read_reg(chip, iSTAT)); return; } @@ -137,24 +156,24 @@ void i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs) else object = irq_register-3; - fifo=chip->msgobj[object]->fifo; - msgbase=chip->msgobj[object]->obj_base_addr; + msgobj=chip->msgobj[object]; + msgbase=msgobj->obj_base_addr; - if (get_reg(msgbase+iMSGCFG) & MCFG_DIR) { - i82527_irq_write_handler(); + if ((*read_reg)(msgbase+iMSGCFG) & MCFG_DIR) { + i82527_irq_write_handler(chip, msgobj); } 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; + id0=(*read_reg)(msgbase+iMSGID3); + id1=(*read_reg)(msgbase+iMSGID2)<<8; + id2=(*read_reg)(msgbase+iMSGID1)<<16; + id3=(*read_reg)(msgbase+iMSGID0)<<24; message_id=(id0|id1|id2|id3)>>3; } else { - id0=get_reg(msgbase+iMSGID1); - id1=get_reg(msgbase+iMSGID0)<<8; + id0=(*read_reg)(msgbase+iMSGID1); + id1=(*read_reg)(msgbase+iMSGID0)<<8; message_id=(id0|id1)>>5; } @@ -167,32 +186,38 @@ void i82527_irq_handler(int irq, void *dev_id, struct pt_regs *regs) } spin_unlock(&hardware_p->rtr_lock); if ((rtr_search!=NULL) && (rtr_search->id==message_id)) - i82527_irq_rtr_handler(); + i82527_irq_rtr_handler(chip, msgobj, rtr_search, message_id); else - i82527_irq_read_handler(); + i82527_irq_read_handler(chip, msgobj, message_id); } if ( (chip->flags & SEGMENTED) != 0) - irq_register=get_reg(chip->chip_base_addr+iIRQ+SPACING); + irq_register=can_read_reg(chip, iIRQ+SPACING); else - irq_register=get_reg(chip->chip_base_addr+iIRQ); + irq_register=can_read_reg(chip, iIRQ); } } -void i82527_irq_rtr_handler(void) +void i82527_irq_rtr_handler(struct chip_t *chip, struct msgobj_t *msgobj, + struct rtr_id *rtr_search, unsigned long message_id) { 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); + unsigned long msgbase=msgobj->obj_base_addr; + void (*write_reg)(unsigned char data, unsigned long address); + unsigned (*read_reg)(unsigned long address); + write_reg=chip->hostdevice->hwspecops->write_register; + read_reg=chip->hostdevice->hwspecops->read_register; + + (*write_reg)((MVAL_RES|TXIE_RES|RXIE_RES|INTPD_RES),msgbase + iMSGCTL0); + (*write_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; + rtr_search->rtr_message->length=((*read_reg)(msgbase + iMSGCFG) & 0xf0)>>4; for (i=0; irtr_message->length; i++) - rtr_search->rtr_message->data[i]=get_reg(msgbase+iMSGDAT0+i); + rtr_search->rtr_message->data[i]=(*read_reg)(msgbase+iMSGDAT0+i); spin_unlock(&hardware_p->rtr_lock); @@ -202,33 +227,32 @@ void i82527_irq_rtr_handler(void) 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; + unsigned irq_register; + struct chip_t *chip=(struct chip_t *)dev_id; + struct msgobj_t *msgobj; + struct canfifo_t *fifo; - irq_register=get_reg(chip->chip_base_addr+SJAIR); + irq_register=can_read_reg(chip, SJAIR); // DEBUGMSG("sja1000_irq_handler: SJAIR:%02x\n",irq_register); // DEBUGMSG("sja1000_irq_handler: SJASR:%02x\n", -// get_reg(chip->chip_base_addr+SJASR)); +// can_read_reg(chip, 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; + msgobj=chip->msgobj[0]; + fifo=msgobj->fifo; if ((irq_register & IR_RI) != 0) - sja1000_irq_read_handler(); + sja1000_irq_read_handler(chip, msgobj); if ((irq_register & IR_TI) != 0) - sja1000_irq_write_handler(); + sja1000_irq_write_handler(chip, msgobj); 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); + can_read_reg(chip, SJASR), irq_register); chip->msgobj[0]->ret=-1; if (waitqueue_active(&fifo->writeq)) wake_up_interruptible(&fifo->writeq); @@ -238,61 +262,66 @@ void sja1000_irq_handler(int irq, void *dev_id, struct pt_regs *regs) return; } -void sja1000_irq_read_handler(void) + +void sja1000_irq_read_handler(struct chip_t *chip, struct msgobj_t *msgobj) { - int i=0, id=0, tmp=1; + int i=0, id=0; + struct canfifo_t *fifo=msgobj->fifo; - 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; + do { + id = can_read_reg(chip, SJARXID0) | (can_read_reg(chip, SJARXID1)<<8); + fifo->rx_writep->length = id & 0x0f; + fifo->rx_writep->flags = id&ID0_RTR ? MSG_RTR : 0; + fifo->rx_writep->timestamp = 0; + fifo->rx_writep->cob = 0; + fifo->rx_writep->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); + for (i=0; irx_writep->length; i++) + fifo->rx_writep->data[i]=can_read_reg(chip, SJARXDAT0 + i); - put_reg(CMR_RRB,msgbase+SJACMR); + can_write_reg(chip, CMR_RRB, SJACMR); - fifo->head++; - if (fifo->head >= MAX_BUF_LENGTH-1) - fifo->head=0; + fifo->rx_writep++; + if (fifo->rx_writep >= fifo->buf_rx_entry + MAX_BUF_LENGTH) + fifo->rx_writep = fifo->buf_rx_entry; + + } while(can_read_reg(chip, SJASR) & SR_RBS); - tmp=(get_reg(msgbase+SJASR) & SR_RBS); - } if (waitqueue_active(&fifo->readq)) wake_up_interruptible(&fifo->readq); } -void sja1000_irq_write_handler(void) +void sja1000_irq_write_handler(struct chip_t *chip, struct msgobj_t *msgobj) { + struct canfifo_t *fifo=msgobj->fifo; + 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; + msgobj->ret = 0; wake_up_interruptible(&fifo->writeq); } return; } - if (chip->chipspecops->pre_write_config(chip, chip->msgobj[object], - fifo->tx_readp)) { + if (chip->chipspecops->pre_write_config(chip, msgobj, fifo->tx_readp)) { if (waitqueue_active(&fifo->writeq)) { - chip->msgobj[object]->ret = -1; + msgobj->ret = -1; wake_up_interruptible(&fifo->writeq); return; } } - if (chip->chipspecops->send_msg(chip, chip->msgobj[object], - fifo->tx_readp)) { + if (chip->chipspecops->send_msg(chip, msgobj, fifo->tx_readp)) { if (waitqueue_active(&fifo->writeq)) { - chip->msgobj[object]->ret = -1; + msgobj->ret = -1; wake_up_interruptible(&fifo->writeq); return; } } } + +void dummy_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { + CANMSG("dummy_irq_handler called irq %d \n", irq); +}