Following is the code prepared by me.Only interrupt is left working on it.It is done for a loop back process.Any mistake … leave the comments
#include”header.h”
static int my_proc (char * buf, char ** start,off_t off, int count)
{
int intr_id,lsr,msr,len=0;
int baudrate,div_lacth,lcr;
#ifdef PRINT
printk(KERN_INFO “Begin : ‘%s’\n”,__func__);
#endif
intr_id = inb(SERIAL_IIR);
lsr = inb(SERIAL_LSR);
msr = inb(SERIAL_MSR);
lcr = inb(SERIAL_LCR);
outb(lcr | 0×80 , SERIAL_LCR);
div_lacth = inw(SERIAL_DLL);
outb(lcr,SERIAL_LCR);
baudrate = CLOCKRATE / div_lacth;
len = len + sprintf(buf+len, “Baudrate = %d\n”,baudrate);
len = len + sprintf(buf+len, “Data Format = %d\n”, 5+(lcr & 3));
len = len + sprintf(buf+len, “MSR = %02x\n”,msr);
len = len + sprintf(buf+len, “LSR = %02x\n”,lsr);
len = len + sprintf(buf+len, “Interrupt ID = %02x\n”,intr_id);
len = len + sprintf(buf+len, “\n”);
#ifdef PRINT
printk(KERN_INFO “Exit : ‘%s’\n”,__func__);
#endif
return len;
}
static int my_open(struct inode *inode, struct file *filp)
{
#ifdef PRINT
printk(KERN_INFO “Begin :’%s’\n”,__func__);
printk(KERN_INFO “Device_Open = %d\n”,Device_Open);
#endif
if(Device_Open)
{
#ifdef PRINT
printk(KERN_INFO “The driver is busy\n”);
#endif
return -EBUSY;
}
Device_Open ++;
//MOD_INC_USE_COUNT(THIS_MODULE);
try_module_get(THIS_MODULE);
#ifdef PRINT
printk(KERN_INFO “Exit :’%s’\n”,__func__);
#endif
return 0;
}
static int my_release(struct inode *inode, struct file *filp)
{
#ifdef PRINT
printk(KERN_INFO “Begin :’%s’\n”,__func__);
#endif
Device_Open –;
#ifdef PRINT
printk(KERN_INFO “Decrementing the value of Device_Open, new value is %d\n”,Device_Open);
#endif
//MOD_INC_COUNT(THIS_MODULE);
module_put(THIS_MODULE);
#ifdef PRINT
printk(KERN_INFO “Decrementing the count in the kernel\n”);
#endif
#ifdef PRINT
printk(KERN_INFO “Exit :’%s’\n”,__func__);
#endif
return 0;
}
int my_ioctl(struct inode *inode, struct file *filp, unsigned int request, unsigned long address)
{
int lcr,div_lacth,baudrate = 0 ;
int *there = (int *) address;
#ifdef PRINT
printk(KERN_INFO “Begin :’%s’\n”,__func__);
#endif
switch(request)
{
case IOCTL_GET_BAUDRATE:
lcr = inb(SERIAL_LCR);
outb(inb(SERIAL_LCR) | 0×80, SERIAL_LCR);
div_lacth = inw(SERIAL_DLL);
outb(lcr,SERIAL_LCR);
if(div_lacth > 0)
{
baudrate = CLOCKRATE / div_lacth;
#ifdef PRINT
printk(KERN_INFO “div_lacth = %d\n”,div_lacth);
printk(KERN_INFO “baudrate = %d\n”,baudrate);
printk(KERN_INFO “Clockrate = %d”,CLOCKRATE);
#endif
}
if(copy_to_user(there, &baudrate, 4))
{
#ifdef PRINT
#endif
return -EFAULT;
}
return 0;
break;
case IOCTL_SET_BAUDRATE:
if(copy_from_user(&baudrate, there, 4))
{
#ifdef PRINT
#endif
return -EFAULT;
}
if((baudrate CLOCKRATE))
{
#ifdef PRINT
#endif
return -EFAULT;
}
div_lacth = CLOCKRATE / baudrate;
lcr = inb(SERIAL_LCR);
outb(inb(SERIAL_LCR)| 0×80, SERIAL_LCR);
outw(div_lacth,SERIAL_DLL);
outb(lcr,SERIAL_LCR);
return 0;
break;
}
#ifdef PRINT
printk(KERN_INFO “Exit :’%s’\n”,__func__);
#endif
return -EINVAL;
}
ssize_t my_read(struct file *filp, char *buf, size_t len, loff_t *pos)
{
unsigned char data;
int count,i,lsr;
#ifdef PRINT
printk(KERN_INFO “Begin :’%s’\n”,__func__);
#endif
lsr = inb(SERIAL_LSR);
#ifdef PRINT
printk(KERN_INFO “The LSR status is %04x\n”,lsr);
printk(KERN_INFO “The LSR status is %04x\n”,inb(SERIAL_LSR));
#endif
if((lsr & 0×01) == 0)
{
if(filp->f_flags & O_NONBLOCK)
{
#ifdef PRINT
printk(KERN_INFO “A NONBLOCK flag is on, exiting now\n”);
#endif
return 0;
}
}
count = 0;
for (i=0;if_flags & O_NONBLOCK)
#ifdef PRINT
printk(KERN_INFO “A NONBLOCK flag is on, exiting now\n”);
#endif
return 0;
}
count = 0;
for(i=0;i<len;i++)
{
if(copy_from_user(&data,buf+i,1))
{
#ifdef PRINT
printk(KERN_INFO "Unable to read macro failed\n");
#endif
return -EFAULT;
}
while((inb(SERIAL_LSR) & 0×20) == 0×00);
outb(data,SERIAL_TX_REG);
++count;
if((inb(SERIAL_MASK) & 0×01) != 0×01)
{
#ifdef PRINT
printk(KERN_INFO "the writer is not sending data to reciver\n");
#endif
break;
}
}
#ifdef PRINT
printk(KERN_INFO "Exit :'%s'\n",__func__);
#endif
return count;
}
static dev_t serial_setup_cdev (struct serial_dev *ldev , int i)
{
dev_t ldevno;
int result;
#ifdef PRINT
printk(KERN_INFO "Begin :'%s'\n",__func__);
#endif
ldevno = MKDEV(serial_major,serial_minor);
cdev_init(&ldev[i].cdev,&fops);
ldev[i].cdev.owner = THIS_MODULE;
ldev[i].cdev.ops = &fops;
result = cdev_add(&ldev[i].cdev,ldevno,ndevice);
#ifdef PRINT
printk(KERN_INFO "result = %d\n",result);
printk(KERN_INFO "device no : %d\t,minor number = %d\n",i,serial_minor);
#endif
serial_minor++;
#ifdef PRINT
printk(KERN_INFO "Exit :'%s'\n",__func__);
#endif
return 0;
}
static int __init my_init(void)
{
int ret,i;
#ifdef PRINT
printk(KERN_INFO "Begin :'%s'\n",__func__);
#endif
#ifdef PRINT
//printk(KERN_INFO "Current value of jiffies is %ld\n",j1);
printk(KERN_INFO "Major = %d\tMinor = %d\n",serial_major,serial_minor);
#endif
if(serial_major)
{
devno = MKDEV(serial_major,serial_minor);
ret = register_chrdev_region(devno, ndevice, device_name);
}
else
{
ret = alloc_chrdev_region(&devno, serial_minor, ndevice, device_name);
serial_major = MAJOR(devno);
#ifdef PRINT
printk(KERN_INFO "Major number allocated is %d\n",serial_major);
#endif
}
if(ret comm,current->pid);
#endif
if(serial_major)
{
serial_dev = (struct serial_dev *) kmalloc (sizeof(struct serial_dev),GFP_KERNEL);
if(!serial_dev)
{
#ifdef PRINT
printk(KERN_WARNING “Unable to allocate the memory for the device\n”);
#endif
return -ENOMEM;
}
#ifdef PRINT
printk(KERN_WARNING “allocate the memory for the device\n”);
#endif
memset(serial_dev, 0, sizeof(struct serial_dev));
for(i=0;icomm,current->pid);
#endif
//changing the register
#ifdef PRINT
printk(KERN_INFO “Setting the default values to the register…now\n”);
#endif
outb(0×00,SERIAL_IER); //disable the IER
outb(0×00,SERIAL_FIFO); //disable the FIFO
outb(0×00,SERIAL_MCR); //MCR = 0
#ifdef PRINT
printk(KERN_INFO “Setting the default values to the register done successfully\n”);
#endif
#ifdef PRINT
printk(KERN_INFO “Exit :’%s’\n”,__func__);
#endif
}
module_init(my_init);
module_exit(my_exit);