LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Kernel (https://www.linuxquestions.org/questions/linux-kernel-70/)
-   -   Problem in interrupt handler for uart 16550 (https://www.linuxquestions.org/questions/linux-kernel-70/problem-in-interrupt-handler-for-uart-16550-a-440858/)

mrinal mishra 05-02-2006 07:33 AM

Problem in interrupt handler for uart 16550
 
Hi,
i am writing a serial driver for UART 16550 .For that i have recompiled the kernel and inserted generic driver as a module.in OPEN i have initialized all the registers and at the end i have enabled the interrupts .Handler is registered succesfully .interrupt is generated but sequence is not going into handler.
PLEASE HELP ME

sundialsvcs 05-02-2006 03:59 PM

Kinda hard to do that, friend. We don't have your code, and what is more, probably couldn't do too much to help. Try looking for other examples of serial-device-driver code. Compare their code to yours...

mrinal mishra 05-03-2006 01:07 AM

this is my code in kernel space
#define MODULE
#define __KERNEL__
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/sched.h>
#include<linux/interrupt.h>
#include<linux/fs.h>
#include<asm/current.h>
#include<linux/ioport.h>
#include<asm/io.h>
#include<errno.h>
#include<asm/uaccess.h>
#include<linux/init.h>
#include<linux/delay.h>
#include "defs.h"
#include "serialcmd.h"
#define MAX 20
#define NAME lifo
MODULE_LICENSE("GPL");
static INT32S divisor;
static INT8U setparity;
static INT8U kbuff[MAX];
static INT32U i,result,STAT,time_out=0;
static BOOLEAN FLAG=0;

DECLARE_WAIT_QUEUE_HEAD(my_q);

static INT32S lifo_open(struct inode *, struct file *);
ssize_t lifo_read(struct file *,char *,size_t , loff_t *);
ssize_t lifo_write(struct file *,const char *,size_t , loff_t *);
static int lifo_close(struct inode *,struct file *);
static int lifo_ioctl(struct inode *inode,struct file *filep,unsigned int cmd,unsigned long arg);

static int lifo_ioctl(struct inode *inode,struct file *filep,unsigned int cmd,unsigned long arg)
{
time_out=arg;
}

void serial_handler(INT32S irq_num,void *dev_id,struct pt_regs *regs)
{
printk("\n Irq number is %d ", irq_num);
static INT8U ch;
static INT32U len;
STAT = inb_p(IIR);
printk("\n status is %x",STAT);
STAT &=0x06;
printk("\n Change due to ANDing with 0x06 in status is %x",STAT);
switch(STAT)
{
/*writing the characters to transmit register */
case 2:
len = strlen(kbuff);
if(FLAG == 1)
{
for(i=0; i<len; i++)
outb_p(kbuff[i],BASE+0);
i=0;
FLAG = 0;
}
break;
/* reading the characters from the receive register */

case 4:
i = 0;
while((ch = inb_p(BASE+0)) !='\0')
kbuff[i++] = ch;
break;
default:
break;
}
}

static INT32S lifo_open(struct inode *inode, struct file *filep)
{
static int result;
printk("\n In open , Initialising all needed registers\n");
outb(0x07, IER);
outb(0x87, FCR);
outb(0x03, LCR);

result = request_irq(4,serial_handler,0,"my_origin",(void*)1234);
if(result < 0)
{
printk("\n Error in requesting Irq\n");
return result;
}
printk("\n Handler is requested\n");
return 0;
}

/*Here we will get the irq line no. and the control will be transferred to serial_handler which is interrupt handler*/


ssize_t lifo_read(struct file *filep,char *ubuff,size_t len, loff_t *offset)
{
time_out=time_out*101;
printk("\n In read \n");
if (i==0)
{
copy_to_user(ubuff,"\n No data available\n",20);
/* if(time_out==0)
{
sleep_on(&my_q);
copy_to_user((void *)ubuff,(void *)kbuff,i);
}
else
{
sleep_on_timeout(&my_q,time_out);
copy_to_user((void *)ubuff,(void *)kbuff,i);
time_out=0;
}*/

}
else
{
printk("i=%d",i);
printk("time out=%d",time_out);
copy_to_user((void *)ubuff,(void *)kbuff,i);
}
return i;
}

ssize_t lifo_write(struct file *filep,const char *ubuff,size_t len, loff_t *offset)

{
STAT = inb_p(LCR);
STAT &= 0x7f;
outb(STAT,LCR);
result=copy_from_user((void *)kbuff,(void *)ubuff,20);
FLAG = 1;
printk("\n Write succeed %c \n",ubuff[0]);
wake_up(&my_q);
return 0;
}
static int lifo_close(struct inode *inode,struct file *filep)
{
free_irq(4,(void *)1234);
printk("\nWe've closed the device");
return 0;
}


struct file_operations fops=
{
open: lifo_open,
read: lifo_read,
release: lifo_close,
write: lifo_write,
ioctl: lifo_ioctl
};


int register_dd(void)
{
int result;
printk("\nThe device is registerered");
result=register_chrdev(254,"lifo",&fops);
if(result<0)
{
printk("error");
return(result);
}
return 0;
}
void unregister_dd(void)
{
printk("\nThe device is unregistered");
unregister_chrdev(254,"lifo");
}
module_init(register_dd);
module_exit(unregister_dd);

I have recompiled the kernel 2.4.21-ELsmp and inserted Generic driver as module also
and i have removed serial moule also and inserted my own module but unable to go into interrupt handler.my user space code is
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include"serialcmd.h"
#define MAX 20
main()
{
int fd,ch,choice,result,time_out,cont;
char ubuff[MAX];
do
{
system("clear");
printf("\nEnter 1 to open the serial device");
printf("\nEnter 2 to close the serial device");
printf("\nEnter 3 to read from the serial device");
printf("\nEnter 4 to write to the serial device");
printf("\nEnter your choice:");
scanf("%d",&choice);
switch(choice)
{
case 1:
fd=open("/dev/lifo",O_RDWR);

if(fd==-1)
{
perror("\nError in opening the device");
return -1;
}
break;
case 2:
result=close(fd);
if(result=-1)
{
perror("\nError in closing the device");
return -1;
}
break;
case 3:
system("clear");
printf("\nPress '1' to read characters\n");
printf("\nPress '2' to read timed out charaters\n");
fflush(stdout);
printf("\nEnter your choice:\n");
fflush(stdin);
scanf("%d",&ch);
switch(ch)
{
case 1:
result=read(fd,ubuff,strlen(ubuff));
printf("%s",ubuff);
break;
case 2:
printf("\nEnter the time out value in seconds:");
scanf("%d",&time_out);
result=ioctl(fd,TIME_OUT,time_out);
/* if(result=-1)
{
perror("\nError in closing the device");
return -1;
}*/
result=read(fd,ubuff,strlen(ubuff));
/*if(result=-1)
{
perror("\nError in closing the device");
return -1;
}*/
printf("%s",ubuff);
break;
default:
printf("\nEnter a valid choice");

}
break;
case 4:
printf("\nEnter the string to write:");
scanf("%s",ubuff);
result=write(fd,ubuff,strlen(ubuff));

/*if(result=-1)
{
perror("\nError in closing the device");
return -1;
}*/
break;

default:
printf("\nEnter a valid choice");

}
system("clear");
printf("\nEnter 1 to continue, any other key to exit:");
fflush(stdin);
scanf("%d",&cont);
}while(cont==1);
}

ANY device driver specialist help me please.

mrinal mishra 05-05-2006 12:00 AM

hi all ,
control is not gonig in Interrupt handler ,i have checked IIR register
it is showing that interrupt has occured .i have already given my code
i have also checked /proc/interrupt it is not showing any entry for IRQ 4
please anyone help me to sort out this problem.
thanks&regards
Mrinal


All times are GMT -5. The time now is 07:17 PM.