#include <linux/sched.h>
#include <linux/version.h>
-#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19))
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,0))
#include <asm/spinlock.h>
#else
#include <linux/spinlock.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 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)
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!
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;
}
{
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;
}
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;
}
}
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; i<rtr_search->rtr_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);
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);
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; i<fifo->buf_rx_entry[fifo->head].length; i++)
- fifo->buf_rx_entry[fifo->head].data[i]=get_reg(msgbase +
- SJARXDAT0 + i);
+ for (i=0; i<fifo->rx_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);
+}