인터럽트 등록이 안됩니다..
글쓴이: 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 자원을 요청하도록 되어 있군요.
해당 디바이스 파일을 열어본 뒤에 확인해 보시면 될 듯 합니다.
댓글 달기