인터럽트 등록이 안됩니다..
글쓴이: goodlsc / 작성시간: 금, 2009/03/13 - 12:16오후
rmmod lp
rmmod parport_pc
insmod parport_pc io=0x378 irq=none
후에 밑의 코드를
insmod int_dev.ko
하는데 irq할당이 안됩니다..
굳이 7번을 안주고 28번 등등을 줘도
vi /proc/interrupts에 보이질 않는데요
왜이런거죠? 컴파일시 warning과 관련이 있는 것인지...
디바이스 드라이버 코드는 아래 있습니다.
원 소스에서 SA_INTERRUPT 만 IRQF_DISABLED 로 바꿨습니다...최신커널에서 플래그네임이 바뀌어서요
헤더에 꺽쇠넣으니 헤더명이 안보여서 뺏습니다... ㅜㅜ
///////////////////////////////////////////////////////
#include linux/init.h
#include linux/module.h
#include linux/kernel.h
#include linux/fs.h
#include linux/errno.h
#include linux/types.h
#include linux/fcntl.h
#include asm/uaccess.h
#include asm/io.h
#include linux/time.h
#include linux/timer.h
#include linux/interrupt.h
#define INT_DEV_NAME "intdev"
#define INT_DEV_MAJOR 240
#define INT_WRITE_ADDR 0x0378
#define INT_READ_ADDR 0x0379
#define INT_CTRL_ADDR 0x037A
#define PRINT_IRQ 7
#define PRINT_IRQ_ENABLE_MASK 0x10
#define INT_BUFF_MAX 64
typedef struct
{
unsigned long time;
} __attribute__ ((packed)) R_INT_INFO;
R_INT_INFO intbuffer[INT_BUFF_MAX];
int intcount = 0;
void int_clear( void )
{
int lp;
for( lp = 0; lp < INT_BUFF_MAX; lp++ )
{
intbuffer[lp].time = 0;
}
intcount = 0;
}
irqreturn_t int_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
if( intcount < INT_BUFF_MAX )
{
intbuffer[intcount].time = get_jiffies_64();
intcount++;
}
return IRQ_HANDLED;
}
int int_open (struct inode *inode, struct file *filp)
{
if( !request_irq( PRINT_IRQ , int_interrupt, IRQF_DISABLED, INT_DEV_NAME, NULL) )
{
outb( PRINT_IRQ_ENABLE_MASK, INT_CTRL_ADDR );
}
int_clear();
return 0;
}
ssize_t int_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
int readcount;
char *ptrdata;
int loop;
readcount = count / sizeof( R_INT_INFO );
if( readcount > intcount ) readcount = intcount;
ptrdata = (char * ) &intbuffer[0];
for( loop = 0; loop < readcount * sizeof(R_INT_INFO); loop++ )
{
put_user( ptrdata[loop], (char *) &buf[loop] );
}
return readcount * sizeof( R_INT_INFO );
}
ssize_t int_write (struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
unsigned char status;
int loop;
int_clear();
for( loop = 0; loop < count; loop++ )
{
get_user( status, (char *) buf );
outb( status , INT_WRITE_ADDR );
}
return count;
}
int int_release (struct inode *inode, struct file *filp)
{
outb( 0x00, INT_CTRL_ADDR );
free_irq( PRINT_IRQ , NULL );
return 0;
}
struct file_operations int_fops =
{
.owner = THIS_MODULE,
.read = int_read,
.write = int_write,
.open = int_open,
.release = int_release,
};
int int_init(void)
{
int result;
result = register_chrdev( INT_DEV_MAJOR, INT_DEV_NAME, &int_fops);
if (result < 0) return result;
return 0;
}
void int_exit(void)
{
unregister_chrdev( INT_DEV_MAJOR, INT_DEV_NAME );
}
module_init(int_init);
module_exit(int_exit);
MODULE_LICENSE("Dual BSD/GPL"); Forums:


특이하게 open에 IRQ 자원을 요청하도록 되어 있군요.
해당 디바이스 파일을 열어본 뒤에 확인해 보시면 될 듯 합니다.
댓글 달기