- if (extended) {
- 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=(*read_reg)(msgbase+iMSGID1);
- id1=(*read_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(chip, msgobj, rtr_search, message_id);
- else
- i82527_irq_read_handler(chip, msgobj, message_id);
- }
-
- if ( (chip->flags & SEGMENTED) != 0)
- irq_register=can_read_reg(chip, iIRQ+SPACING);
- else
- irq_register=can_read_reg(chip, iIRQ);
- }
-
-}
-
-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;
- 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=((*read_reg)(msgbase + iMSGCFG) & 0xf0)>>4;
- for (i=0; i<rtr_search->rtr_message->length; i++)
- rtr_search->rtr_message->data[i]=(*read_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)
-{
- unsigned irq_register;
- struct chip_t *chip=(struct chip_t *)dev_id;
- struct msgobj_t *msgobj;
- struct canfifo_t *fifo;
-
- irq_register=can_read_reg(chip, SJAIR);
-// DEBUGMSG("sja1000_irq_handler: SJAIR:%02x\n",irq_register);
-// DEBUGMSG("sja1000_irq_handler: SJASR:%02x\n",
-// can_read_reg(chip, SJASR));
-
- if ((irq_register & (IR_WUI|IR_DOI|IR_EI|IR_TI|IR_RI)) == 0)
- return;
-
- msgobj=chip->msgobj[0];
- fifo=msgobj->fifo;
-
- if ((irq_register & IR_RI) != 0)
- sja1000_irq_read_handler(chip, msgobj);
- if ((irq_register & IR_TI) != 0)
- 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",
- can_read_reg(chip, 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(struct chip_t *chip, struct msgobj_t *msgobj)
-{
- int i=0, id=0;
- struct canfifo_t *fifo=msgobj->fifo;
-
- 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->rx_writep->length; i++)
- fifo->rx_writep->data[i]=can_read_reg(chip, SJARXDAT0 + i);
-
- can_write_reg(chip, CMR_RRB, SJACMR);
-
- 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);
-
- if (waitqueue_active(&fifo->readq))
- wake_up_interruptible(&fifo->readq);
-}
-
-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)) {
- msgobj->ret = 0;
- wake_up_interruptible(&fifo->writeq);
- }
- return;
- }
- if (chip->chipspecops->pre_write_config(chip, msgobj, fifo->tx_readp)) {
- if (waitqueue_active(&fifo->writeq)) {
- msgobj->ret = -1;
- wake_up_interruptible(&fifo->writeq);
- return;
- }
- }
- if (chip->chipspecops->send_msg(chip, msgobj, fifo->tx_readp)) {
- if (waitqueue_active(&fifo->writeq)) {
- msgobj->ret = -1;
- wake_up_interruptible(&fifo->writeq);
- return;
- }
- }
-}