www.pudn.com > 422.rar > irq.c


/* irq.c
  * Linux serial-bus device driver.
 * Written by wang song yue--bupt   email:wsy5228@sina.com
 * This software is released under the GPL-License.
 * Version 0.1  28 october 2005
 */

#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/main.h"
#include "../include/irq.h"
#include "../include/s16c554.h"

void s16c554_irq_read_handler(void);
void s16c554_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;

void s16c554_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
  printk("i am in s16c554_irq_handler now!\n");
	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(ISR);
//	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 & (0x01))              //there is no any interrupt!
		return;

	fifo=chip->msgobj[0]->fifo;
	msgbase=chip->msgobj[0]->obj_base_addr;

	if (irq_register & (0x04))                   //there is read interrupt!
		s16c554_irq_read_handler();
	if (irq_register & (0x02))                   //there is write interrupt
		s16c554_irq_write_handler();
	if ((irq_register & (0x06)) != 0) {          //there is error intrupt!  
		// 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(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 s16c554_irq_read_handler(void)
{
	int i=0, tmp=1;
printk("i am in s16c554_irq_read_handler!!\n");
	while (tmp) {
                fifo->head=0;
		fifo->buf_rx_entry[fifo->head].data[i] = get_reg(RHR);
		fifo->buf_rx_entry[fifo->head].length++;
               i++;

		fifo->head++;
		tmp=(get_reg(LSR) & (0x01))&&(i<64);
	}
	if (waitqueue_active(&fifo->readq))
		wake_up_interruptible(&fifo->readq);
}

void s16c554_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;
		      }
               	}

	}